Thursday, 1 November 2012

Mercurial offers a variety of approaches to branching, including “named branches”, “bookmarks” (most similar to git), “anonymous branches” and using clones. For a good comparison of these techniques, I suggest reading Steve Losh’s Guide to Mercurial Branching, which explains it well although is a little out of date now.

In this article I will walk through the process of how you can use a named branch for maintenance releases, and the workflow for both contributors and for accepting contributions. I’ll explain at the end why I’ve decided that named branches are the best option for NAudio.

Now we’ve released version 1, let’s start work on version 2. No branches have been made yet.

// more changes
hg commit -m "beginning work on v2"

Step 2: Creating a Maintenance Branch

Now we’ve had a bug report and need to fix version 1, without shipping any of our version 2 changes. We’ll create a branch by going back to the v1.0 commit (revision 1 in our repository) and using the branch command

// go back to v1 release
hg update 1
// create a named branch
hg branch "v1.0 maintenance"
// branch will be created when we commit to it
// fix the bug
hg commit -m "bugfix for v1.0"

Step 3: Switching between branches

To get back to working on our main branch (which is called the default branch in Mercurial), we simply use the update command:

// get back onto the v2 branch:
hg update default
// make changes
hg commit -m "more work on v2"

Step 4: Making forks

Imagine at this point, we have a couple of contributors, who want to fork our repository and make some changes.

Our first contributor makes a clone, and is contributing a v2 feature, so they can simply commit to the default branch:

Now we can do the same with the contribution on the maintenance branch (n.b. hg merge won’t do anything if you are still on the default branch, as it knows that the contribution is on a different branch):

And that is pretty much all you need to know to work with named branches. With your repository in this state you still have two branches (default and v1.0 maintenance) which you can continue work on separately. Here’s a screenshot of a repository which has had the steps above performed on it:

Why Named branches?

I actually think that branching with clones is easier for users to understand than named branches, but for NAudio it is not a viable option. This is because CodePlex allows only one repository per project. I’d either have to create a new project for each NAudio maintenance branch, or create a fork, but both options would cause confusion.

Anonymous branches are a bad idea because you open the door to merge the wrong things together, and it’s hard to keep track of which head relates to what. Their use is mainly limited to short-lived, experimental branches.

Bookmarks are appealing as they are closest to the git philosophy, but because Mercurial requires you to explicitly ask to push them, and there can be naming collisions, I think they are best used simply as short-lived markers for local development (I might do another blog post on the workflow for this).

So with NAudio I am thinking of creating a single maintenance branch for each major release (only created when it is needed). Most people who fork can just ignore the maintenance branch and work exclusively in the default branch (I can always use hg transplant to move a fix into a maintenance branch).

About Me

Mark HeathI'm a software developer, based in Southampton, UK specialising in .NET, trying to keep up with best practices and latest technologies. In my spare time, I maintain a variety of open source .NET applications, and this blog is for sharing things I discover along the way. Read more....