Earlier this year, I assisted a company in designing a simple source code branching and merging plan. But of course, I have learned some things since that time. I just returned from the Microsoft ALM Conference, and I want to offer some additional insight into branching and merging. (updated 11/25/2011 after further reflection to strengthen defense of the Basic Plan recommendation)
We followed the Basic plan outlined in the Microsoft ALM Ranger’s guidance, available at http://tfsbranchingguideiii.codeplex.com/. The Basic branch design looks like this:
Be aware that the complete plan we developed was several pages with details on when to merge and why. Anyway, the guidance recommends that the trunk or Main branch be reserved for stabilizing the product. This means “no junk in the trunk.” Or more explicitly, “You should not check in changes directly to the trunk, but into a development branch that is later merged into the trunk after suitable testing.”
The team asked me “Why do we need the development branch? Can’t we just check in changes to the Main branch?” After all, that’s what they had been doing forever. The addition of a Release branch seemed like a good enough innovation to them. But they felt the Development branch added needless complexity.
Before I continue, let’s be clear what scenario I am addressing here: a team with one future development effort. There are a LOT of reasons why people want multiple dev branches: one per developer, one per feature. A compelling case is when we are developing multiple future releases that may be incompatible. It’s a painful thing to do but it happens. Anyway, we are not talking about any of those scenarios. They are cases when we know we want multiple dev branches. In this post, we are just talking about a simple case where a team needs one development branch. We are discussing whether to do that development in an isolated Development branch or the Main branch.
At the time our team was reviewing options, I did not feel strongly one way or the other. So I asked this question point-blank on the ALM blog and was given the response that the separation was what was recommended by the rangers. So I passed that on, but was left feeling unsatisfied with the answer because I did could not describe a scenario in which checking into MAIN directly really caused havoc. I had never seen that. Oh sure, I had seen cases where the build was broken for a short time. But that was rare, and it always got fixed quickly.
At the recent Microsoft ALM Summit 2011, I had a chance to put this question to some very talented programmers during a panel on Source Control Strategies, moderated by Keith Pleas. The panel included opinionated veteran developers Martin Woodward, Arlo Belshee, Jim Newkirk, and William Bartholomew, explaining why their strategies were “the best way”!
Their consensus opinion was that it was actually preferable to check in to Main. This put them into a spirited disagreement with Bill Heys, ALM Ranger, speaking for many other Rangers in defense of the recommendation to have a development branch to isolate changes from Main.
I spoke to Jim Newkirk afterwards to try to understand the core of the disagreement. He admitted that he was making some assumptions about the team doing the work. In other words, if you were doing TDD, and working in a highly collaborative environment, following all best agile practices, not taking on more than you can chew in one sprint, following best software engineering practices, and had automated unit tests, system tests, etc…, then anything you checked in should be safe.
In contrast with that modern approach, I have worked on teams where developers not only did not practice TDD, they wrote no unit tests at all. Collaboration was done after the software was delivered to the test team, not up front, refactoring was rare, and regression was common. So given that context, the additional friction caused by working in a Development branch is welcome if it gains us isolation to ensure that the software is tested and in good working order at the end of the sprint, before it is merged into the Main branch.
But this also explains why a team led by Newkirk or Woodward would find the additional step wasteful and inefficient.
One of those variable I mentioned was the tendency of some developers to bite off more than they can chew in a sprint. If they are working on a long feature, and they check in intermediate code that leaves the system broken, then this goes against our desire to have potentially shipable code at the end of a sprint. Again, this style of development is avoidable in many cases. In fact, if I know I must do a really scary refactoring or change, I may proactively create a feature branch just for that work. But sometimes you don’t know in advance that you will make a mess. And some architectures are more prone to this problem than others. Whenever I find I have created a mess like this, I simply undo all pending changes and start over, with a new refactoring strategy, informed by my recent pain. But if your team has a history of making messes like this, then a development branch gives you a chance to isolate and repair the break prior to the end of sprint delivery. But still there is no magic here. If you don’t fix the mess, you must either cherry-pick the feature sets to merge (NOT RECOMMENDED) or merge nothing.
Another variable that influences whether to have development branches is the requirement to review the code before accepting it. If you have a development branch, you can grant merge rights to only senior developers and architects, and expect them to review the code before merging it.
A counter argument I heard at the conference was that to use a branch to isolate and filter software that is poorly produced is to avoid the underlying issues. If you have a team that is not writing unit tests and not collaborating with other team members before they code, then adding a separate branch and additional time to clean up the mess before each deployment is a sad solution.
So now, based on the opinions from all these sources, I have concluded that whether to use a single development branch, or whether to develop in the Main branch, depends on the context. At least I now have some objective factors to use in evaluating the risks. To recap, some variables to investigate include
- historic facts of team performance like defect counts and regression.
- regulatory requirements for gated review and approvals
- risk of failure (not all application errors lead to bankruptcy or death) – The higher the risk, the more value in isolation.
If you think of any other items to add to the list, please comment. If a team have shown they can work safely without a Dev branch, and regulations or risk do not compell it, then why not work in the most efficient way?
However, as a last defense of the dev branch, I will say that having to merge a single dev branch into a quiet main branch should be fairly trivial. Remember that a merge tool like TFS 2010, will not alert you to every change. Only to items changed in both places. If you have developed only in Dev, it will have no trouble merging your changes silently. Thus, even a thousand source control changes may get silently merged in less than a minute. So why not use the dev branch as insurance against a new developer who makes a royal mess of the source code.