Feature branches and toggles

I’m a huge Martin Fowler fan, but one bit of advice I still can’t understand is the recommendation to eschew feature branches for feature toggles. The argument against feature branches are not just merge problems, but semantic merge problems, such as a method rename. This leads to a fear of refactoring, and

Indeed I see this as the decisive reason why Feature Branching is a bad idea. Once a team is afraid to refactor to keep their code healthy they are on downward spiral with no pretty end.

In practice, however, I’ve rarely seen this to be the case. In functional teams (i.e., not dysfunctional), refactorings aren’t done in isolation and without communication, no matter what the branching strategy. If you’re performing a large rename or big shift in design, or even a little shift that isn’t just adding functionality, you’re communicating, asking questions, getting feedback, whiteboarding and so on. If I’m surprised about refactoring based on a merge, this is a failure in communication from the team.

The picture Fowler shows is a Big Scary Merge:

The idea here is that the P branch, merged in, makes it difficult for the G branch to come in. But this assumes a faulty strategy – that large refactorings happen solely in feature branches. But for larger refactorings, these can be thought of features themselves (or technical debt stories, if that’s your cup of tea). I tend to have these in their own branch, once discovered, so that that refactoring makes it in as its own merge commit, or set of commits, to the mainline branch.

The alternative is a Continuous Integration/Delivery picture, where developers are more or less working straight off of the mainline branch:

From my experience, without an effective sandbox, commits actually become less frequent, as the pressure is on to have a commit “deployable”. I’m all in favor of deployable commits, but my rule is that all commits to the mainline branch are deployable. What you do in your feature branch is just Work In Progress, and I’d much rather you optimize for small steps. In my branches, I often don’t even care if tests pass, I’m just tagging mental checkpoints.

In order to mitigate merge risks, I simply make sure I don’t have long-running branches. A week is about the maximum I allow, and past that, I look at doing feature toggles. Feature toggles are actually quite useful for at least getting code in production and not turned on yet. In fact, many systems I work on have features that turn “on” at a certain date/time, so it’s rather straight forward to just code that in, deploy it early, and modify the dates for testing.

But for refactorings, those aren’t discovered through a merge if we’re doing things right. And they’re not piggy-backing a feature if we’re trying to mitigate the merge risk.

These are just my experiences however, and I can understand that there must be anecdotal reasons of folks seeing problems with feature branches (and not just long-lived branches or mixed-use branches). If you’ve seen problems, let me know in the comments!

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in Agile, ContinuousIntegration. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • kindohm

    It is typical for each developer on my team to create multiple feature branches per day and merge them all back to the default branch. We have a similar philosophy that you do and it is working great for us. I don’t understand the strong caution against feature branches. For me it has made building a product much easier.

  • Alexander Tank

    “In my branches, I often don’t even care if tests pass, I’m just tagging mental checkpoints.” So does this mean that you skip CI in your branches?

    • jbogard

      No, I still do CI in my branches, but I just don’t care quite as much. I might just push when I get to a good stopping point.

  • What? No link to my blog? Google “branch per feature”…

  • Daniel Marbach

    We use branches per user story. But we have the similar rule like you. At the end of each sprint at least all branches are either merge into main or thrown away or the PO pays for maintenance of that branch. Normally such a branch lasts for 3-4 days not more… Otherwise it is a huge mess


  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1217()

  • I believe you forget that this is also tied to what source control you’re using. Git and Hg will merge much more easily, but I’ve seen very difficult merges with SVN for example. That’s why in the past, I’ve chosen for trunk-based development (see my rationale here: http://petermorlion.blogspot.be/2011/10/trunk-based-development.html).
    This was also due to branches living longer. If you can keep it under a week, I think you can branch much more regularly.

  • I’m also a big Fowler fan and agree with you on this: Never had issues with short lived branches within good dev teams.

  • “I’m all in favor of deployable commits, but my rule is that all commits to the mainline branch are deployable.”

    Exactly. That’s the same rules I have in my org. Default better be deployable! Feature branches optimally should work, less-optimally should build, but it’s better to have a work in progress that’s totally failure inside a feature branch in the repo than on a dev’s machine disconnected.

  • Jason Roberts

    I think you can do both, it doesn’t have to be an either/or :)

    ps. i wrote a simple .Net feature toggle library: http://nuget.org/packages/FeatureToggle

  • Jason

    Thanks for posting this.

    When Martin first talked about preferring toggles over feature branches there was always a feeling in the back of my mind that something here wasn’t quite so black or white. I haven’t actually used feature toggles on a project so I can’t say I had enough experience on either side to back up my feeling.

    Thanks for clarifying it for me.

  • “Once a team is afraid to refactor to keep their code healthy they are on downward spiral with no pretty end.”

    ahhh, i changed 2 companies sin the past 1 year. i’m about to change another. the reason? lack of re-factoring, the daily basis casual one! can’t stress enough how vital it is, but is missing from most chart/diagrams of software processes. it must be an integrated part of development. PERIOD!

    however, instead of asking how to do re-factoring and branching, the right question might be: do we need branching at all? I’ve initiated a large refactoring effort, focused, where we needed re-design the whole flow. what I did was to make a clever use of namespaces. the new changes were introduced in a separate namespace. one finished and tested the new implementation all I had to do is to rename the old one to some dull name like namespaceXXX and then rename my reafactored namespaceR back to original one: namespace.

    also I’m in favor of not treating your trunk for deployments and shipping apps. use branch for each release all new features and bug fixes go to trunk, only bug-fixes got introduced in deply/ship branch.

    think not 2, but 3 times before you introduce branching and whether you really need it. NEVER create unnecessary friction for you developers!

  • Pingback: Favor Feature Toggles over Feature Branches | the pluralsight blog()

  • collinmanderson

    I’m finding features on feature branches are hard to demo to business and design folks who are not able to check out and view their own version of a website.