My friend James Spargo recently sent me this article on feature branches by Martin Fowler in which he criticizes the “feature branching” approach to software development. In essence, feature branching endorses an approach where changes to a computer program are made in an isolated container (the “branch”) until they reach a certain level of readiness. Mr. Fowler believes, instead, that these changes should be folded in quickly so that the there is communication among the other participants in the project.
Mr Fowler is a smart man but at Brainfood we feel like our lives became less complicated and more productive with the adoption of feature branching. Our process up until then had classically been all of us pushing into a single branch and rarely keeping many branches around. The excellent and experienced staff at Eucalyptus Systems dragged us into using feature branches and we’ve stuck with it. Having experienced both approaches I’ll briefly outline what I see as the benefits to using feature branches.
Life puts you through big changes
Though Mr. Fowler prefers to steer clear of branches he does advocate the sensible policy that each commit should be “ready for production”. It isn’t clear to me how this is achievable for non-trivial refactorings. There are plenty of occasions where the changes a piece of code needs are small and can be written quickly and committed but certainly not all situations are like this. The treachery of multi-core programming can easily put you in a position where you need to rethink the way a whole group of components interact and those components may have mature and widely deployed interfaces. At the same time, the show must go on and you may have work that needs to happen immediately while a large complicated refactoring is in process. In a situation like this its hard to see how a “one branch to rule them all” approach is going to get the job done.
Protecting yourself from yourself
Another corollary of the single “always ready” branch model is that change streams probably end up staying on your desktop until they are ready. Mr. Fowler even advocates that “every commit should be ready for production”. To me this adds up to people keeping substantial chunks of work in the working directory of their desktop until they have everything working. This is a recipe for either losing a bunch of work or screwing up a bunch of useful work because you took a wrong turn halfway through. Computers break and people sometimes write bad code after working a long time. With feature branching you can push and push your changes into your own isolated branch without bothering anyone else in the project. If you take a wrong turn you will also have a series of snapshots so that you can roll the tape back to the point where you took a wrong turn.
If you work on multiple computers (home, work, laptop, etc.) pushing to branches in the team repo is also a convenient way to hand your own work between environments. You can definitely get there with a peer to peer approach but sometimes dealing with a single well connected host is easier than the VPNs and SSH proxies that may be required to get all your machines talking to each other. Sometimes, because of policy, it may not be possible at all.
Another beneficial side effect of feature branching is that your work in progress is encoded as a convenient artifact that can be passed around to other members of the team for review. In Mr. Fowler’s approach, the team finds out about your changes because they are literally stumbling across them. A formal review process doesn’t seem possible because the commits are frequent, fragmentary and continuous.
With feature branches it is a common practice for one or multiple members of the team to review your branch before it is committed. Since the changes occur in a branch there is the convenience that the work will be cleaned up and thought through before someone else has to grok it. There is more of a chance that the changes could be ill-conceived and have a lot of work in them since they occur in isolation. It seems like the cure to that problem, however, is to have other team members take a peek at your branch before you get too far along.
At some level, each time we begin typing we are potentially taking the whole team on some flight of fancy springing deep from within our mind. With feature branching the rest of the team joins that jaunt with a greater degree of complicity. When the changes are rolling into the master branch all the time you can complain but you will need to be very vigilant or you could find yourself along for the ride.
My final criticism of the CI all-in one-branch approach is that people inevitably make mistakes. I’m not talking about typos but about big conceptual miscues. In the “along for the ride” model you may find that your stream of useful changes is interleaved with some tragically misguided work and you failed to notice it because you were so focused on the task at hand. Your other team member may even realize it and be trying to unroll the changes. Unfortunately, the work is now tangled into your work and you may even depend on parts of their stuff that worked well enough for you to remain oblivious to the problems they discovered.
Certainly there is a danger to people sitting on their work with the feature branch approach. You do not want someone to carve of their own little playground and go on wild sprees of modification while the rest the project leaves them steadily behind. If you are pushing branches back to a central point, however, and tracking progress with a ticket system (we use Redmine Backlogs) then you have great management tools to fight these problems. It seems to me that with the single branch model you have intrinsic problems that can’t be fought through management tools. For us, at least, that has made feature branching seem the better model.