Branch By Abstraction

A lesser-known source-control best practice I've been pushing for a number of years is Branch by Abstraction.   The suggestion is that you can convene large sets of developers in a single trunk and get then to continue to commit to a single place without having to spawn "short lived feature branches" when some large change could mean that the build is going to be hosed for a number of weeks while the team gets it right.  Those branches just end up running and running....

Provisos

There are some general provisos for the single as opposed to composite trunk design, that coincide with hard-core Agile development:
  • You've broken your application into multiple components.
  • Each component into a directory inside the trunk (possibly hierarchical).
  • Each directory its own source self-contained and its own build (possibly hierarchical).
  • You have a good set of unit tests and consider them important enough to illustrate snippets of example usage.
  • Continuous Integration drives things, even for hundreds of components, that drops items into a Maven-like repository. CruiseControl has a nice <httpfile/> directive that with the <include-projects/> directive that allows you to set up the killer CI installation that is branch-ready meaning you can run without a dedicated CI administrator.
  • Your management are good at release planning.
  • Developers are in the habit of never breaking the build :-)

Your trunk may look like:

  <root>
trunk/
foo-components/
foo-api/
foo-beans/
foo-impl/
build.xml
src/
java/
test/
cruisecontrol-config-snippet.xml
remote-foo/
bar-services/
bar/
build.xml
src/
java/
test/
cruisecontrol-config-snippet.xml
bar-web-service/

So back to the problem..  

What to do when (if) your team says they want need to shift from Hibernate to iBatis (hypothetical case).  There could be thousands of classes that depend on Hibernate.  The architects might suggest that the build will be broken for weeks so a separate branch is the best place for this change.  Instead, lets try Branch by Abstraction (BBA) instead of the traditional "Branch by Source Control" (Stacy Curl coined the name by the way - I'm trying to shame him into writing a better blog article than this one).

The steps to living Branch By Abstraction

With your most responsible developers -
  1. Introduce an abstraction over the core bits of the big thing you're going to change.
  2. Update all the bits of code that were formerly using the thing directly to use it via the new abstraction.
  3. Make a second implementation of the abstraction, with unit tests that specifically test its core functionality.
  4. Update all the code from (2) to use the new implementation (still via the abstraction)*
  5. Deprecate the first implementation (or skip to 6 if you don't want a respectful grace period).
  6. Delete the first implementation (its proven there is no need for you to go back).
  7. Remove the abstraction (if it is inelegant).

Benefits

  • Only a small team is even bothered by the change.
  • You can go live at any stage - because the larger application works at all times.
  • Management can be adaptive about scheduling.
  • Avoids merge hell.
  • Introducing Abstraction helps increase understanding/modeling of piece - which is useful in itself.
Of course, BBA is not a panacea. It is just a practice that developers/architects can often do it when architects with less nerve are suggesting yet another long running feature branch.  Architects should strive to do BBA instead of new feature branches - Architects should not hope to reach a situation where they can declare at the outset that a new branch is the "only way" to achieve something.

A buddy last week was telling me of 21 significant branches who's merge order was uncertain in his nameless client.  Sucks.  He smiled wryly when I guessed Clearcase as their SCM choice.  Clearcase whether in dynamic, static or UCM modes has no place in Agile development efforts.  It is a self fulling prophesy that requires dozens of administrators a few black-belt merge-meisters and multiple branches and causes long development cycles, waterfall thinking and high staff turnover.  The only thing worse that it is PVCS (who owns it now?).  Anyone wanting a good tool for Agile development should be looking at Perforce (still my favorite cos Intellij works very well with it) or Subversion.  Subversion will overtake Perforce one year soon I guess.

When do you branch then?

Ideally for release only.
  <root>
trunk/
releases/
rel-1.0/
rel-1.1/
rel-1.2.x/
You may branch some days before release, then "production harden" the branch on a staging box.  You're not going to give permissions to all developers to that branch, just a couple who are ensuring its ready and handling later merges (one's or two's only if at all).  You branch the release from trunk of course - given that CI proved that trunk was at all times pretty solid.

As well as Stacy Curl, I'm hoping Martin writes an article on this important practice. He is better with words than me.