Simply put I have the following branch setup:
MAIN
|--- DEV
|--- PROD
Most developments are done in the DEV branch. When the code is ready to test, everything is merged to the MAIN branch and published to our test environment. When tests are completed, a merge to PROD is done and everything is published to the production server. Every now and then changes (mostly bugfixes) are made on the MAIN or PROD code, but this is an exception.
I have been asked to think out a system for feature and bugfix merging. This means that separate changes in the DEV should be merged across MAIN and PROD. With our current setup this information is lost: for example features A, B and C are implemented in the DEV branch. Let's say every feature has two corresponding changesets: A1, A2, B1, B2, C1, C2. With our current way of working, everything is merged to the MAIN branch in one go. So when we want to "cherry pick" features which have to go from MAIN to PROD we can't do this because there's only one changeset on MAIN: the checkin of the merge.
How would you fix this? Do I need to change something to my branching strategy?
I'm using TFS for source control.
So when we want to "cherry pick" features which have to go from MAIN to PROD we can't do this because there's only one changeset on MAIN: the checkin of the merge.
You can write a tool to piece through the merge history, if you like, but the real answer is don't do that. When you cherry pick, you lose any guarantee that the code you tested and stabilized in the source branch will perform the same way in the target branch. Sometimes that's ok, but in your case it defeats the whole purpose of having an intermediate branch sitting between raw untested Dev checkins and your live PROD deployments.
As discussed in my favorite branch/merge video, your guiding principle should be "merge down, copy up." That is, whenever the need arises to deconstruct and/or apply code diffs, let unstable branches take the hit. (Cherry picking features out of an otherwise integrated app is one example.) Meanwhile, code that's promoted up toward stable branches like Main & Prod should always be a straight copy that matches what you've already worked so hard to stabilize in the source branch. Sounds like you're following this strategy currently; preserving it in the face of cherry picks would be my #1 motivation for using feature branches, even moreso than insulating feature teams from each others' breakages.
Managing dependencies between features is an issue, as Jim mentioned. If you can identify them in advance, the usual solution is to make sub-branch(es) that are shared by the features with the common dependency.
Feature1
\
LibA---
/ \
Feature2 \
DEV -- MAIN -- PROD
Feature3 /
\ /
LibB---
/
Feature4
Software doesn't always go as planned, of course. And this doesn't work at all if the branches that need to share code are on opposite sides of the tree (e.g. if Feature1 depends on LibA and LibB, but Feature2 is ill equipped to be part of B for structural or technical reasons).
I don't think there's any magic sauce here, you've just got to find a system where you have a revision on main for each unit you might like to cherry pick.
This can be done trivially by merging each revision individually, which is a pain, but gets you what you want.
Alternatively, you can up the granularity, by merging each feature into main one at a time. This requires that you work sequentially on features, which may be ok if you're on your own, but will be a pain if there's a few of you, since you'll have to go through a code freeze where some people have finished and others haven't.
Another way of working which you may or may not find more manageable is to have a DEV branch for each feature. In this sense, instead of having an ever existant DEV branch, have a collection of ephemeral DEV branches that only exist until the feature is completed.
The reintegration of each DEV branch will give you a clear revision in main which can be cherry picked.
You can get dependencies between dev branches. Say branch devA needs some implementation from branch devB, you'll have to merge the required parts of devB into main and then merge them down into devA. However, devA shouldn't be needing unfinished work from devB, so you should (in theory) be able to RI those parts happily anyway. And of course, since you're cherry picking into PROD, these partial integrations don't have to get published.
Given your branching strategy, I guess you've already found this, but if not, it's worth reading:
http://branchingguidance.codeplex.com/wikipage?title=html&referringTitle=Home
Related
I am looking for a specific strategy / convention that works for concurrent development with Feature branches and a database deployment tool such as DbUp, DbDeploy, ReadyRoll, etc.
We run multiple feature branches for concurrent project development.
Each branch has a dedicated development, QA and UAT environment which is deployed via Octopus deploy.
I am trying to tackle automatic database deployment with Octopus using a tool that will handle the changes applied in each of the branches.
Database changes will occur in all of the branches (including the release branch).
Most of the tools that I have seen thus far use a sequenced based approach of scripts that are checked into the VCS and deployed by the tool. The tool for the most part applies the script in an ascending filename order and most that I have seen specify to follow an approach of 1, 2, 3, etc.
This works fine for one branch.
My issue will be when feature A has 1 and Feature B has 1 - both get merged into the main branch. I now have two #1 scripts. Making it even more fun - our path to production is to merge one more time which may also have a 1. So now we have 3 #1 scripts.
There is also the problem of backward merging. Once a project is done - merge the release branch back into main and then merge again to the feature branch to reset it for the next project. In this scenario - I have two additional #1 scripts that have not been applied to the target feature branch database.
My initial solution to this is to use a julian date as the leading prefix for the sql filenames that are checked into source. I was also thinking of applying the branch name to the file along with the work item. So the sql file would follow a convention of {XXXXX_Y_ZZZZZZ.sql} where xxxxx is the julian date, y is the branch and zzzzzz is the work item from TFS.
I am looking for a specific solution to this problem. Has anyone else solved this? What did you do? What are the drawbacks? What tools did you use?
Have you looked into Readyroll's semantic versioning?
We are implementing Readyroll now, we are a small team in which it's easy to communicate and confine changes between feature branches.
We integrate to a development branch and detect conflicting changes early on and basically rewrite earlier migration scripts if necessary (which requires have a baseline of your database project to which you can revert)
On the Redgate website there is some more information about working with branches but doesn't cover your scenario exactly, switch branches with readyroll.
When looking in to tools I basically came to the conclusion it a choice between a state based approach or a migration based approach. I like readyroll's take on it, which offers a mix.
I very curious what you end up with!
I have a situation where we were working on feature branches against a main development branch ('trunk') and each release cycle, a release branch would be taken from the current development branch.
However, a release was cancelled very late on and instead we were asked to issue the previous release with only some features - after these were all integrated into the main dev branch.
So what happened was the previous release branch was taken as the base of the new mini-release, and we now have to re-apply specific changes that were already made against the development branch. I luckily still have my feature branch and it was never merged. It is based on the development branch, however my branch was taken fairly early on in the release cycle and was not updated by re-merging parent (trunk) changes - so my branch's parent is actually not too dissimilar from the new branch I need to apply it to.
I know TFS has some facilities for re-parenting and baseless merges but what is likely to work best? More importantly if I try re-parenting, can I break my branch or am I safe that I can try things, back them out and try again if there are problems?
My branch is fairly large, maybe 50 changesets applied to quite a few separate modules. I suppose I could try to apply each changeset one-by-one instead?
In my experience, baseless merges are always terrible. In most cases I find diffing and merging the two branches manually via a compare tool (like BeyondCompare) is easier and more reliable than using the TFS tooling.
That being said I would challenge you to consider going to a single main branch. We made the leap (a huge leap for us at the time) but it has paid dividends many times over at this point. The key is being Release Ready:
https://dotnetcatch.com/2016/02/16/are-you-release-ready/
The Microsoft ALM Team describe the Basic Branch Plan as needing a MAIN, DEV, and RELEASE branch.
I am working on introducing branching/merging to a new team who currently uses source control with no branches whatsoever.
I was wondering how the RELEASE branch is actually used.
Can changes be made in the DEV branch then be merged up to the MAIN branch without needing a RELEASE branch? MAIN would still be read-only. It would basically be the RELEASE branch in essence. The reason I say this is because we don't have that many changes but I want to isolate the stable code from new changes. Our concept of a "release" per say is not yet well defined. I am still working on that.
I just don't know if my team needs a RELEASE branch (considering our needs specifically).
I would appreciate some comment about the strategy of just having a MAIN and DEV branch.
Typically the release branch(es) are used for "safekeeping". Basically the same as a label.
Releases to production are usually a pretty important event, and you want to know exactly what source you released (in case you ever need to go back to it). Way back when people used to create Labels to track this, but creating Release branches is better for a couple reasons:
Labels are mutable in TFS, meaning somebody could change a label and there would be no audit trail
Branches are also mutable of course (changes can be checked in), but this can be locked down via branch specific permissions
Also if a change is made to a Release branch (which it never should be), at least you have an audit trail through history
Even though a branch looks like a heavy-weight operation creating a copy of your entire code base, in reality TFS just creates a new pointer to the same files, so the storage cost is trivial
I went the other way when I implemented TFS at a client (replaced SVN). What I did was introduce a MAIN branch and a RELEASE branch and not a DEV branch initially as that seemed very confusing to the team. It is also hard to convey the purpose of a DEV branch to an SVN familiar team initially.
The main purpose of our RELEASE branch was to preserve a historical placeholder as said in another answer. Currently we are using Git and we have a CI server that does the release process and branches to release/$version_number. I think that concept might be easier to understand and convey to your team. i.e. automatically create release branches when you actually release.
I have main and dev branches. I make changes in both and check in. I merge from main to dev and check in. Now I merge from dev to main. I have conflicts. How is this possible?
Resolving a conflict for a merge in one direction is not necessarily appropriate for a merge in another direction. In many workflows you're basically merging in order to keep two branches as similar as possible - for example, taking changes from a development branch into a production branch, and maybe moving critical bugfixes from the production branch back to a development branch. In this sort of workflow, you typically wouldn't want to diverge when merging two branches (you want that critical bugfix in both branches, after all) so it's not obvious why you would have to resolve the merge conflict both times, but that's certainly not the only workflow when working with branches.
I used to work on a Java project that had some utility libraries that we shared with a group working on a different project. At some point, our libraries needed to diverge from theirs for various reasons, so we took a branch of their project and both groups made unique changes to the library. Sometimes it happened that we would fix a bug and sometimes it would happen that they would add a new feature, so we frequently merged back and forth with each other.
You can see here that the results of merging from our branch to theirs should not necessarily be the results of merging from their branch to ours. Let's assume that there was a file where we added some new methods and maybe fixed a few bugs. And let's assume that they'd added a few different methods. When they merged our changes into their branch, they'd get a merge conflict and let's assume they took the bugfixes but did not take our new methods since they didn't need them. Now when we do a merge to get their changes into our branch, we still get a merge conflict - this allows us to take their methods into our file.
If TFS were to make some assumption about the merge from their branch into ours based on the results from our branch into theirs, it would be inaccurate.
I have a Team Project in TFS where tasks are submitted daily. I would like to work on each task independently and then merge it into the main line after testing.
Currently there is a MAIN branch and a DEV branch which is a child of MAIN. Changes are worked on in the DEV branch and then merged into MAIN when they are ready. This is done via a "cherry-pick" merge. I've been reading everywhere that cherry-pick merges are bad and you should avoid them whenever possible.
I am having trouble wrapping my head around branching and merging in TFS and was wondering if anyone had any suggestions on how to achieve this goal in TFS without having to do cherry pick merges.
Any help is appreciated.
If I left out any key information please leave a comment and I will edit my post.
I think this Codeplex documentation will be a big help:
http://tfsbranchingguideiii.codeplex.com/
The download has several PDFs that outline different scenarios and strategies and give excellent Q&A on different approaches.
The key for your scenario would be to merge all changes up to a specified version from Dev to Main. Run all tests each time code is checked into Dev (and developers get the latest Dev code, then run all tests before checking in). Ideally, if the build in the Dev branch is successful after Dev checkin, merging into Main would be a good idea. Merge frequently from Dev to Main, and run all the tests in Main after each checkin.
So even though developers work individually on specific pieces, once they check into the Dev branch they are essentially saying "this code is ready to integrate." And when merging from Dev to Main, you no longer deal with specific pieces--you merge the whole enchilada. If Developers need source control for work-in-process code, they should use TFS shelvesets and wait to check into Dev until they are "done."
You might find Timpani Software's MergeMagician tool interesting. It is a branch management and automated merging solution that works with TFS (and also Subversion). You create publish/subscribe relationships between branches, and then the server automates the merges.
MM can be used to implement all of that patterns discussed in the TFS Branching Guide that Shawn mentioned.
FYI, it is a commercial tool. I don't know of any open source tools that do anything like this that work with TFS.
Check it out at http://www.timpanisoftware.com. There's a good overview video on the home page.