Saturday, March 21, 2009

Creating Unrelated Branches in Mercurial

Earlier I watched Scott Chacon's excellent GitCast about using "Empty Branches", or branches that are not derivations of your main development flow. In other words, they are not descendants of your first revision. Obviously his tutorial was about how this is done in Git, but it is possible in Mercurial as well.

It's important to remember that while Git ignores commits that it cannot reach via a branch head or tag, Mercurial follows all commits. Therefore some of the steps described below are not necessary if you wish to refer to a branch head anonymously. Another caveat is that when I refer to a branch, I mean a fork in the revision history graph (you can automatically track these with bookmarks, similar to Git's branches), not what Mercurial sees as a named branch.

Starting an Unrelated Empty Branch


First let's bookmark the tip revision for easier reference later:

$ hg bookmark -r tip MainBranch

Make sure your working directory is clean, with no changes. If there are changes, either revert or commit them.

$ hg status
M test.txt
$ hg revert --all

Now set the parents of the current directory to null to start the root of a new tree.

$ debugsetparents null


Update: Some readers have pointed out that there is a much cleaner (and potentially safer) way to set the parents to null.
$ hg update -C null


Go ahead and add some files and make your first commit.

$ echo "test file" >> f1.txt
$ echo "test file" >> f2.txt
$ hg addremove
adding f1.txt
adding f2.txt
$ hg ci -m "A new separate branch."

Let's bookmark this head so it's easier to review separately from the main development tree.

$ hg bookmark NewBranch

That's it! You can now switch between these unrelated branches using hg update -C. Remember that the bookmarks are simply for convenience, you can always refer to the heads anonymously if you would like. These separate branches have several uses. Scott Chacon mentions creating one for documentation, or for the website for the project. While these branches are part of the project, they are unrelated to the main code base. You could also use these branches to store an alternate version of the project that doesn't share much of the same code.

Using Unrelated Branches

Here are a few usage examples.

# Check out the main project tree
$ hg update -C MainBranch
# Check out the alternate tree
$ hg update -C NewBranch
# View only the history for the main tree
$ hg view MainBranch
# View only the history for the alternative tree
$ hg view NewBranch


Enjoy!