Agile Zone is brought to you in partnership with:

Matt is the Group Leader of Research Application Development in the Research Informatics Division of Information Sciences at St. Jude Children's Research Hospital in Memphis, Tennessee. Matt has been developing and supporting enterprise Java applications in support of life sciences research for St. Jude since 2001. Matt is a committer to multiple open source projects and is the founding member of the Memphis/Mid-South Java User Group. Matt is also a regular speaker on the No Fluff Just Stuff symposium series tour (as well as other major conferences), and his articles have appeared in GroovyMag and NFJS the Magazine. His current areas of interest include lean/agile software development, modularity and OSGi, mobile application development (iPhone/iPad/Android), web development (HTML5, etc.), and Groovy/Grails. Matt has posted 44 posts at DZone. You can read more from them at their website. View Full User Profile

A Case for Feature Branches

  • submit to reddit
How and when to create branches within a project's source control system can be a very touchy subject among software developers. Some folks branch like crazy, and others avoid branching altogether. Today I'd like to make a case for feature branches based on my team's experience using them to enable our development process.

While branching practice does vary quite a bit, there's a typical set of practices that many of us follow:

  1. We develop multiple features/stories/etc. in parallel on the "trunk" (or "mainline") of the codebase
  2. At the end of the cycle (iteration, release, etc.) we "tag" the trunk
  3. Many times, if preparing for release, we'll branch the trunk to do "hardening" of the release during some type of QA cycle
  4. Following the release, we'll merge our branches changes back to the trunk
  5. Later, if defects are found in production, we'll branch again to fix the defect and then merge the fixes back to the trunk

This style of development works very well in a time-boxed style of development. With time-boxed development, we select a period of time, usually one to four weeks, and commit to deliver a set of features/stories during that timebox. XP and others call these iterations, while Scrum prefers to call them "sprints." Regardless of the name, you'll deliver a certain set of functionality to your customers (or, perhaps, yourselves for internal releases) each timebox. Well, that's what will happen in an ideal world.

The world of software development, however, is far from ideal. Things can go wrong during the iteration that can and will upset this branching style:

  • Suppose we've committed to delivering a feature and started coding it. Like any good agile developer we've been checking in freely. Unfortunately, we hit a roadblock and it's clear that the feature won't be ready at the end of the timebox. What to do with all of that code that's already checked in? Rolling it back won't be trivial.
  • Suppose we have a checked-in, "completed" feature that we determine has a defect that makes much of the system unstable. What to do?
  • Suppose we're working on code that's core to the application and two different features that we've committed to lead to an impasse in how they'll affect that core code. Who wins?
  • Suppose that the business gives us change in priority. Yes, I know, you're not supposed to do that during the time-box, but what if something happens that totally throws out the value of everything in the timebox? Do we press on and deliver work that we know won't help?

After fighting the good fight for time-boxed development for a few years, our team has decided to move to continuous flow managed via a Kanban system. Our intention is to release every feature to a staging environment as it is completed. Within the staging environment our team of business analysts will verify that the feature meets their needs and signal a go/no-go for production release. All of this is highly automated and nearly happens at the push of a button.

We enable this way of working by creating a branch for each feature that we're implementing. Work proceeds normally within that branch, with the developer or feature team checking-in code at-will. Once the feature is complete and tested, it is merged into the mainline. The mainline is then deployed and the full suite of regression tests are run. Assuming these all pass, the feature is checked-in to the mainline and deployed. What does this give us in the face of the four issues that I identified?

  • Since we don't commit to delivering a set of features, but rather individual features, a certain feature being incomplete when we reach a planned release date is completely inconsequential. That code remains safely hidden in its feature branch.
  • Features with defects also lead to no worries. With multiple QC checks before code reaches the mainline, we're confident that the mainline is always stable for deployment.
  • Core code can evolve freely in this scenario. Yes, there will be a certain amount of merge pain when we bring these two lines together, but a feature that's DONE can always go LIVE, even if a competing feature isn't.
  • If the business changes priority, we can easily drop what we're doing and open new feature branches for the expedited request. Again, our mainline is safe and ready for the newest high priority.

We've been working in feature branches now for a few weeks and it has greatly increased our ability to respond to the business, try otherwise "high-risk" experiments, and create a steady flow of value into production. Your mileage may vary, but I highly recommend the practice.
Published at DZone with permission of its author, Matt Stine.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)


Sudhakar Ramasamy replied on Sat, 2010/08/28 - 8:35am

Probably one of the best explanations of why you would chose between feature branches (when delivering continuous flow with Kanban) and mainline developed (timeboxed delivery). Feature branches like you mentioned will most certainly result in more work during the merge phase. And this is multiplied many times when the source code for your application is split into several projects living in separate repository locations. You'll need to branch and merge each one where there is a change. Martin Fowler has an article that delves into the pitfalls of feature branches in more detail (

Matt Stine replied on Sun, 2010/08/29 - 6:35pm in response to: Sudhakar Ramasamy

Thanks (I think?)!

I certainly agree with your statement about the pain of merge going up with multiple projects, repositories, etc. I think the key here is to use good judgment about your repository structure. If such a complex structure is mandatory for some reason and cannot be adjusted, feature branching is probably not a good idea. That said, I think you'd be hard pressed to deliver on some of the things that I mentioned with any strategy coupled to such a complex repository structure.

Just blitzing through Martin's article (an excellent one by the way), I found that I probably hadn't highlighted an important point. I'm in no way advocating feature branches to enable development in isolation. Continuous communication in daily standup meetings, etc. are still critical. Also, keeping feature sizes small to prevent long gaps between merges are also critical. If you want to develop in isolation, you need to be explicit about your modularity - use something like Tracer Bullet Development.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.