|

On Branching

Branching is a common practice in code versioning. To my experience, a branch is usually seen as a playground for experiments with brand new features. As far as I can tell, branches have typically been used as a natural shield against tight deadlines. Let’s branch out, see how it goes and take a qualified decision of what to merge back to trunk when the worst is over (i.e. post-delivery). There are several reasons for why this is not a good idea.


Okay, saying that long-lived branches, a.k.a. the Feature Branch pattern, are evil is old news. Since I have seen this practice way too often I was thinking that a quick summary wouldn’t harm. First of all, there is nothing wrong with branching as such. How would one work in parallel with others if branching was not an option? 

With the emergence of distributed version control systems branching has become extremely easy and flexible. In git, for instance, a branch is merely a pointer to a certain commit. It is so quick and cheap to create that developers are encouraged to work with branches extensively. That is of a great value especially in open source, where a large community of (untrusted) contributors can easily participate in the project. Pure joy, so it is.

Merging, on the other hand, involves some thinking time. Code review in the first place, but more importantly resolving conflicts is a manual process. More often than not discussions are needed so that the right decision can be made. Beware of semantic conflicts.

As there is no an easy way of going about conflicts, they are clearly undesirable. To ensure conflicts rarely occur, code merge has to happen on a daily basis. Obviously, that undermines the original idea of a branch as a safe sandbox. And rightly so. The principle of least surprise dictates to deal with problems as early as possible. Well, that’s all sound, however there always is some phony deadline around. Promoting unfinished work to production just does not feel right.

Feature Toggle and Branch by Abstraction to the rescue. It is fair to mention that both of these patterns apply to source code design and have little to do with the actual code versioning. Needless to say that the code, or at least the relevant parts of it, have to be in a reasonably good shape before these practices can even be considered. A rough overview:

Feature Toggle
  • enables to hide / switch off any incomplete features
  • incomplete code is still delivered but cannot be accessed
  • requires easily configurable application and high code modularization

Branch by Abstraction
  • suitable for large-scale changes (swapping an ORM provider)
  • the original implementation gets hidden behind an interface
  • gradually, a new implementation is built up behind the scenes
  • requires fairly well structured code, otherwise it is tough to build up that additional layer

To conclude, I really like the emphasis on the integration part of the Continuous Integration. Without daily merges there is no CI, only perfectly isolated continuous builds. 

Resources:

Similar Posts