I've been thinking a lot about best practices regarding branching in distributed version control systems such as git an mercurial (the two dvcs's I have experience with and use on a daily basis).

The way I've been doing it is slightly different in each of these, but generally follows these guidelines:

  • master branch - concurrent with production code
  • development branch - concurrent with "beta" code
  • feature branches - for feature development

Development is done in a feature branch (usually created off of the master branch, so we know we're working with a stable code base), and when dev is completed, reviewed, and developer-tested, it's pushed/merged into the development/beta branch, put out on a beta server, and tested.

If all goes well, the feature is approved, and we can merge it into the master/stable branch, stage it, do final testing, and get it into production.

If it doesn't go well, though, things break down. If, for instance, a feature is scrapped or just delayed indefinitely, we probably want to remove it from the dev/beta branch. However, since merges from master/stable (hotfixes, content changes, etc.), and other new features have probably been put into the dev branch, it becomes difficult to remove a single feature from that branch.

I'm coming to the conclusion that this workflow is just broken, but it seems like it should work. So, specifically:

  • Is it possible to remove a particular feature from this type of branch?
  • Is this just a broken workflow?

And more generally:

  • Given long-term development of features, and a need to have a branch concurrent with live, what are the best practices involved in dvcs?
  • Consider Branching Strategies - while it has a central server mentality, it is still a very good read. I'm not as familiar with DVCS to be able to say how to handle this in such an environment - thus a comment rather than an answer.
    – user40980
    Commented May 1, 2013 at 20:54
  • possible duplicate of To branch or not to branch?
    – gnat
    Commented May 2, 2013 at 1:44
  • @gnat: the question you linked to does not seem to be a duplicate, since it does not deal with the question of "unmerging" a feature at a later point in time. Or am I missing something?
    – Doc Brown
    Commented May 2, 2013 at 7:33
  • @DocBrown I think you miss more-generally part of the question, "Given long-term development of features, and a need to have a branch concurrent with live, what are the best practices involved in dvcs?"
    – gnat
    Commented May 2, 2013 at 16:38
  • In case it was unclear, the "specifically" part of the question was the important part. When posting questions to SE sites, I try to post specific, answerable questions. This one just happened to include a request for more general data as well.
    – Ryan Kinal
    Commented May 3, 2013 at 14:49

2 Answers 2


I think the workflow at its core is fine and basically follows the ideas presented here: A successful Git branching model. However, I think the reason it breaks down for you is because you are essentially "off by one" in the merging and testing process:

  • Feature branches should be based off of the development branch instead of the stable/master branch. Long-term features are continuously rebased on top of the development branch.
  • Feature branches should only be merged into the development branch when they are ready and approved for next release (i.e. when merged, it will definitely go into the next release.)
  • When preparing a new release, a release branch is made off the development branch where final testing is done before merged into the stable/master branch for production.

Things definitely gets a little more complicated when a feature depends on another feature not yet merged into development, but as Doc Brown mentioned in his answer, I think "feature toggles" is a good idea here. The nearly completed features are merged into development, but disabled for production use. Dependent features are then rebased on top of development and merged when ready.

  • Ooh! I think your link made an interesting point regarding merging. git has an option on merge (--no-ff) that allows you to treat the merge has a single changeset, rather than merging each changeset separately. That would make it a lot easier to backout/rollback/revert a feature. Now to research similar techniques for mercurial.
    – Ryan Kinal
    Commented May 2, 2013 at 5:16
  • I'm not sure I entirely agree with the branching model presented in the link. Of course, it depends a lot on the release schedule - in my situation, we don't really have one, so I think it's best to be developing off of known, stable code. Or maybe that's where our workflow breaks down - the fact that we don't have a release schedule.
    – Ryan Kinal
    Commented May 2, 2013 at 5:24

I think removing an already integrated feature after a merge is hard with most VCS (or DVCS), so you should make sure that this situation happens as seldom as possible. Some ideas:

  • If you have a feature for which the approval is at stake (for example, you need a usability test first before you are sure that you are creating the "right" thing), make sure your testers make that usabilty test already with a version from the feature branch, before integrating it into development branch. So you can avoid the integration if the feature is at stake

  • To my experience small feature slices have a lower risk of getting scrapped or delayed than big ones, since one can make them much easier and quicker production-ready. So try harder to make feature slices as small as possible.

  • If you have a more complex feature, consisting of a dozen (or more) feature slices, and you want the final user to see that complex feature only as all-or-nothing, introduce feature toggles into your code, and use a feature branch for each slice, not for the whole thing. This does not really make it easier to "unmerge" any feature code afterwards, but if, for example, after the integration of half of the feature slices into the dev branch someone decides not to complete the whole thing for the next release, you can leave the finished feature slices in the dev branch, without activating the feature toggle. So your users will not notice that there is a half-completed feature in there.

EDIT: If you really get into the need of "dismanteling" a feature at a point in time where parts of it have been integrated into the dev branch and got mixed-up with other changesets, you have the option of using a separate feature branch (or should I say "feature-like branch"?) for that task. You change and/or delete the relevant parts of the code within that branch, developer-test it and then integrate that change set into the dev branch again.

EDIT2: read this blog post of Martin Fowler for more information about feature toggles.

  • Feature toggles are definitely an interesting idea, and something I'll consider. I get the feeling it would be an architectural change, but it might be worth it.
    – Ryan Kinal
    Commented May 2, 2013 at 5:19
  • @RyanKinal: feature toggles seldom need an architectural change, at least not as long as the "feature entry point" for the user is small. Another thing: read my edit about how to efficiently remove a feature at a late point in time.
    – Doc Brown
    Commented May 2, 2013 at 6:08
  • Feature toggles are actually a really bad idea. If the are on, they do nothing but uglify the code. If they are turned off for a longer time, they will contain rotten code. They add a lot of complexity, too (is it version 1.2.1 with X:on, Y:on, Z:off, or 1.2.1 with X:off, Y:on, Z:on, etc). Just don't do it.
    – Wilbert
    Commented May 2, 2013 at 9:46
  • @Wilbert: "feature toggles" are not good or bad "per se", it is a tool which can be used and misused like anything else. The idea here is to turn them on in dev branch (to allow step-by-step integration and testing) without finally delivering the feature to production until it is complete. But I agree that one has to be careful not to let those things happen you described in your comment.
    – Doc Brown
    Commented May 2, 2013 at 10:01
  • I guess feature toggles have a certain use-case - usually one where, as @DocBrown mentioned, the feature has a small entry point. Fortunately, my latest scrapped/indefinitely-delayed feature does have a (relatively) small entry point, and can be toggled rather easily by just changing a couple lines of code. More "integrated" features, I think, are less likely to be toggleable.
    – Ryan Kinal
    Commented May 2, 2013 at 13:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.