I have done source code branching with a ton of teams. The pattern looks pretty much the same independent of what type of branching the team is doing. “We are doing some work that we don’t want other teams to see or get impacted by.” So it goes the team creates a branch to work on a PBI/feature, test some ideas in a Spike or begin the next version of the product. Work sails along swimmingly until the team has to merge the code with mainline (which happens 90% of the time). This is where all hell breaks loose. The team, working in isolation, has created a large amount of code that will no longer integrate with the changes that have happened along the way. At this point code is rewritten (not just refactored), new ideas are brought into the mix, tests are rewritten and so on. For those of you that have been through this, you know what I mean. Are there ways of dealing this this chaos? Sure!
- Work can minimized with regular forward integrations from the mainline.
- Keep the branch duration short.
- Use Design by Contract techniques coupled with unit and integration tests starting on day 1.
I posted at the beginning of last year that you should always branch with caution. Having given this topic a bit more retrospection, I believe branching to be dysfunctional. Here’s why. We know that as a product moves forward the knowledge about it moves forward as well. As two teams (or more) work in isolation, this knowledge diverges at what appears to be an exponential rate (you can even assume linear and get to the same place). When a branch is merged back to the mainline all the knowledge and assumptions are merged as well. This is where we have a problem. The teams need to “catch up” with each other’s knowledge. From observation, the trick here seems to be to keep the teams collaborating on ALL the code ALL the time. That way, knowledge and assumptions are shared and merge conflicts are eliminated. This is the basis of Continuous Integration (CI). The teams should work together on a single mainline with the code being built and tested in near real-time. Keep the builds fast and consider multi-stage CI or Build Pipeline techniques as the number and type of tests grow.
The question at this point is, “How do I keep unfinished work out of my releases?” There are a couple answers/approaches here. The first is to use Feature Toggles. The concept here is pretty simple, as you begin working on a feature include a config switch that allows you to turn that feature off or make it invisible. Other approaches include the use of authorization to include/exclude features in releases and in modular applications (portals) include/exclude the widget. Along with the ability to turn chunks of code on and off, you will want to make sure you have a comprehensive set of tests and the corresponding automation.
As you begin to walk down this path you will see that you are actually on your way to Continuous Delivery (CD). While a full CD approach is not for everyone, it does offer some really great ideas for keeping you product in a “always shippable” state.
UPDATE 8/27/2012: Fellow PST, Ryan Cromwell started a discussion on Scrum.org regarding this post. Check it out!
Over the last few years I have worked with teams that feel a need to using Branching as part of their “best practices” tool set. The ALM Rangers were even nice enough to show teams how to build a mature branching scenario in their Visual Studio Team Foundation Server Branching Guide 2010. PROCEED WITH CAUTION! There is a large overhead in using branching and merging. The branching part is easy, it’s the merging part that will kill you. Done infrequently, the merge process can be a huge undertaking in many cases taking days to complete. Here is a quote from the original VS 2005 Branching and Merging Primer:
A branching and merging strategy involves a tradeoff between risk and productivity. You trade the safety of working in isolation for the increased productivity of working with other people. The productivity increases come with a cost—the additional effort required for merging software assets sometime in the future.
Often, there is no need to adopt branching as the teams are small enough or using shelves will suffice. If you feel you need to branch, do so for the right reasons. What are the “right reasons?” In a nutshell, you absolutely NEED to isolate some code from other teams/repositories. Examples might include:
- Development on a new feature is continuing while the current version is releasing. (branch by feature)
- Teams are practicing design by contract and only want the final contract to be used by other teams. (branch by team)
What are some branching and merging anti-patterns to watch for? Here are few (thanks Chris Birmele):
- Merge Paranoia—avoiding merging at all cost, usually because of a fear of the consequences.
- Merge Mania—spending too much time merging software assets instead of developing them.
- Big Bang Merge—deferring branch merging to the end of the development effort and attempting to merge all branches simultaneously.
- Never-Ending Merge—continuous merging activity because there is always more to merge.
- Wrong-Way Merge—merging a software asset version with an earlier version.
- Branch Mania—creating many branches for no apparent reason.
- Cascading Branches—branching but never merging back to the main line.
- Mysterious Branches—branching for no apparent reason.
- Temporary Branches—branching for changing reasons, so the branch becomes a permanent temporary workspace.
- Volatile Branches—branching with unstable software assets shared by other branches or merged into another branch.
Note Branches are volatile most of the time while they exist as independent branches. That is the point of having them. The difference is that you should not share or merge branches while they are in an unstable state.
- Development Freeze—stopping all development activities while branching, merging, and building new base lines.
- Berlin Wall—using branches to divide the development team members, instead of dividing the work they are performing.
Remember, think long and hard about jumping into branching and merging.
Some additional reading:
Fowler on Feature Branching
Fowler on Continuous Integration