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