Agile Software Development and The Mercurial SCM

Mercurial enables individual developers to rapidly make and commit incremental change-sets locally without affecting others. This poses a risk to an Agile team in that it enables isolated development. Why would Mercurial be good in this situation then? As far as I am concerned certain things have to be done on branches: examples include destabilizing projects such as experimental changes to underpinning framework, code stabilization prior to a release, and production bug fixing. Tools like SVN actually aggravate integration by making branching so complex.

Due to the difficulties of merging in SVN my company only merges fixes from the stabilization and production branches once per sprint. Mercurial makes this problem mostly disappear by designing around something that operates very much like private developer branches. In taking this approach it must absolutely make merging easy to succeed and it does. Gone is SVN's absurd revision range selection and merge to working copy. Instead you "pull" changes from another repository into your own. This does not affect your working copy and instead reconciles the acyclic revision graphs of the two repositories internally. Sounds complex, but 1) it is not, and 2) it is handled for you.

If your repository has revisions with different identifiers but common parents when compared to the other repository Mercurial knows that there is a branch. Because Mercurial uses a cryptographic hash for the revision identifiers it is able to trivially reconcile identical revisions made in separate repositories and fold them into one instead of creating unnecessary branches. In the case that a branch results from the "pull" Mercurial notifies you by saying that there are now multiple head revisions and that a merge is required. You then run "hg merge" to reconcile the branches.

Trivial differences such as files deleted/created/modified by one branch and untouched in the other are immediately applied. More complex cases are passed to a auto-merge tool (unless you are using Windows, where this is manual right now) and any non-trivial merge results are then passed on to a graphical tool like FileMerge on Mac OS X or Kdiff3 elsewhere.

Once you have an actual conflict and the graphical merge tool is up it is the same challenge that merging always is. However, with the simplicity of kicking off a merge it is easily done daily or even hourly to avoid complex conflict resolution. A day's worth of changes are much easier to merge than a month's and it makes unexpected conflicts surface much more quickly. That brings us back to Agile and Scrum by tying into developer communication.

Developing further on the topic of developer communication is direct developer to developer repository sharing. If I were working with a colleague on a project and we both used Mercurial we could push and pull changes directly from each other. Quite often this is how branches are used at my company. Why burden the central server with a peer-to-peer usage scenario? Once myself and my colleague have unit tested, documented, and reviewed the code in our sharing arrangement we can "push" those changes to the central server for backup and sharing with the larger team. This allows us to honour the scrum rules without being hamstrung by them in terms of being unable to track and preserve sub-incremental work. In effect it protects your adoption of Scrum by not forcing your developers to go against the grain of the tools and their desire to preserve their work in order to follow it.

Mercurial gives the last mile to individual developers by allowing them to manage incremental unready changes and in so doing it removes a key barrier to adopting Scrum. Subversion and Mercurial can trivially coexist even in the same working copy. Just make sure to add Mercurial's meta-files (.hg, .hgignore) svn:ignore and SVN's meta-files (.svn) to .hgignore. Now you can use Mercurial for inter-developer code sharing of unready change-sets and Subversion for authoritative production-ready code. A happy marriage at last.

Ideally, I would have axe Subversion and have Mercurial on the server for the authoritative code as well, but it is beneficial in that it creates a tool-based distinction between preserving and sharing incremental changes with peers and committing authoritative changes to the main code-base. A similar advantage is attainable with a Mercurial server setup by using separate protocols or authentication could distinguish pushing to the authoritative server from simply pushing incremental changes to your peers. As an added benefit, using Mercurial on the server also preserves the incremental changes for review if needed.

Further benefits come from the fact that Mercurial warns you if the push will create remote branches. This means that other people have pushed to the authoritative server and you should merge in their changes first. To do this you pull *from* the authoritative server so you can merge and test locally to avoid breaking the code in the repository as a result of incompatibilities between yours and the other user's changes. Once you have merged you push again and it should go through. Even if someone decides to ignore the remote branches and force the push anyway Mercurial prevents this from poisoning the working copy of the server by stopping any updates there until a merge is done. This could cause new code to be delayed in getting into a nightly build, but is not likely to occur when angry teammates come to your desk asking why you forced your changes into the authoritative repository instead of merging. It will not, however, cause the build to fail which would happen in the Subversion case.

Digg - Agile Software Development and The Mercurial SCM