Branch-per-feature, and it's another world
Posted by fabriziogiudici on August 9, 2009 at 3:41 PM EDT
After some experimenting and after moving all my projects to Mercurial repositories at Kenai, I've at last started regular working with it. Well, it's another world - I've already blogged a bit about some cool features of working with a Distributed SCM.Today I'd like to talk about "branch-per-feature". It's a mode of working in which you create a branch of your repository for every feature (bug or RFE) you're working on (with the exception of very small and predictable fixes). In contrast with the most typical way in which people work with branches - i.e. for entirely new work, or for maintaining past releases - branch-per-feature implies branching at finer grain. If you're working on - say - seven issues at a time, this means you have seven branches active in addition to the default one. As soon as the work on a feature is completed (which for me means as soon as the related tests are successful) you merge the branch to the default one and then close it.
For instance, at the moment these are the branches in jrawio:
[Mistral:Projects/jrawio/src] fritz% hg branches --closed | sort 2.0 540:0dd29bb11aec default 556:a9e02a1f070d (inactive) fix-JRW-120 562:a82b7ed21b94 fix-JRW-162-and-JRW-194 367:e75735d2055c fix-JRW-187-1 408:1a0cbede4cb8 (closed) fix-JRW-203-1 558:92fcd592cc51 fix-JRW-6 560:eb9031bec74c nef-fixes-1 555:9ecb14834d0f (inactive) src 286:d9692def01a2 (closed)
Forget "src" which was created by the tool used for import the repository from Subversion; you can see the "default" branch, the "2.0" branch where I'm experimenting with brand new stuff, and all the others are branches related to specific issues (sometimes multiple issues are grouped together if I think - or preliminary investigation has suggested that - the solution is similar).
The biggest advantage of this approach is that you're virtually always read for making a release: in fact, by construction, the default branch is always in good shape (i.e. all or most tests are successful). For instance, I'm thinking of planning fixed-interval releases (e.g. every 2 or 3 weeks) every time putting into it the set of features that have been completed (eventually, I could skip a release if in the meantime no features came to completion). In this perspective, I've still to fix some issues with Hudson and my workflow, but at the end of the story I should be able to make a release with just the pressure of a button in Hudson.
This sounds really good especially with jrawio, whose work requires a lot of reverse-engineering investigation, often taking many days (or weeks) interleaved with other work. In the past, working always on the trunk was one of the main reasons for which I wasn't able to plan regular releases; with Mercurial and branch-per-feature I has been able to publish 1.5.{0, 1, 2} in one month.
Of course, this is not a free lunch. The idea works well if different features impact mostly on different part of the code, mostly different classes. But this is what OO design brings, right? And in fact this is what I'm experiencing with jrawio. As usual, long-lived branches will benefit from periodical synchronization with the default branch, so that they don't get too different at the point that merge raises conflicts. Another point is your capability to mentally track all the branches, and eventually sharing the information with other committers. But this is easy: with Jira, I just added a custom field "Progress in branch" where I document, for every issue, where the work is being done.
What I'm missing is a graphic tool to display branches and merges - Mercurial provides a simple web-based graph feature, but it's too cluttered to be useful. I'm seriously thinking of writing a specific plug-in for NetBeans, that could be easily made thanks to the Visual Library. I have still to figure out whether such a tool was really useful or only cool ;-)
Before finishing, I must say that you don't need to use Mercurial or Git for working in the branch-per-feature way; indeed any SCM supporting branching should do (for instance, this guy has just started a series of posts about branch-per-feature and he's using Subversion). It's that Mercurial handles branches in a much simpler (and faster) way, and for me it changed my way of working.

Related Topics >>
Blog Links >>
- Login or register to post comments
- Printer-friendly version
- fabriziogiudici's blog
- 1958 reads






Comments
Hi, a few follow-up
by aebbert - 2010-10-23 13:56
Hi,
a few follow-up questions:
Thanks,
Andreas
Hej, are you aware of the
by haukeingmar - 2010-11-11 13:24
Hej,
are you aware of the fine article Martin Fowler wrote about Feature Branches and some of the caveats? You can find it here: http://martinfowler.com/bliki/FeatureBranch.html
by davidpthomas - 2009-08-09 23:28
I agree that reasonably sized activities are worthy of their own configuration. I used cvs for 6 years and converted to svn many years ago. I still employ this pattern today. But the periodic synchronization of your project branch, with it's parent, is laborious... not bad with 4 developers, but painfully unscaleable with 40+... and as you mention, not having a graphical view is tough to gauge activity and progress (or divergence). I still use svn for small projects, and am interested in mercurial for an alternate DSCM. But for production projects, I'm very satisfied with accurev. It is commercial, but parent-child inheritance eliminates "periodic syncs" and provides a good java-based UI for viewing configurations and relationships. Child streams (not branches) dynamically inherit new changes from their parent...grandparent... etc. I found this the most unique difference between the traditional branch-based tools. I'll still use branch tools for smaller teams and the branch-per-feature is essential to create just-enough-stability. But required periodic merging and lack of visibility forced me to look beyond....by felipegaucho - 2009-08-09 19:52
Soon I will join your Mercurial trip: https://kenai.com/hg/puj~arena and I will use our Hudson to continuously integrate its artifacts.. let's see... branch per feature seems a nice to have feature...