Hg

Mercurial with a Subversion central repository

This How-To is for developers wishing to use Mercurial (Hg) on their Windows development boxes when the source code is in a central Subversion (SVN) repository.

Install TortoiseHg.

In a Windows development environment the easiest way to get started with Hg is to install TortoiseHg. The Windows Explorer extension not only makes it easy to work with files by using icon overlays and context menus but also packages up Python, the SVN bindings and a large number of Hg extensions that will prove very useful.

If you are behind a proxy you must first configure Hg with the proxy settings. Use the TortoiseHg context menu and Global Settings > Proxy.

Working with SVN.

Given that you are working against a central SVN repository then Hg has a number of extensions that can talk to the SVN repo. I use HgSubversion. To install this extension you need to clone the hgsubversion repo:

hg clone http://bitbucket.org/durin42/hgsubversion c:\hgsvn

Use the TortoiseHg context menu and Global Settings > Edit File.

[extensions]
hgsubversion = c:\hgsvn

Start with a single project. It’s better to clone the whole repo, the trunk, branches and tags, rather than just a branch. This way you only need to do the clone once – clones can take a while. Create a project folder, i.e. c:\development\local\myproject, change to it and then clone the SVN repo:

hg clone sv://subversion/myproject/

Ignore.

It’s best to set up the ignore list for Hg now. Save this as .hgignore and copy it to the root of your local Hg clone (next to .hg).

# Mercurial .hgignore file template by Abdullin.com
# For syntax see: http://linux.die.net/man/5/hgignore
# Source: http://bitbucket.org/abdullin/snippets/

# Visual Studio
glob:*.user
glob:*.suo
glob:*.cache
glob:_ReSharper.*/
relre:/obj/
relre:/bin/
relre:/Bin/

# Subversion
glob:.svn/
glob:_svn/

# Build structure
relre:^Build/

# Misc
glob:Thumbs.db
glob:*.bak
glob:*.log

Local Development.

If you use local branches and merge them in your local Hg repo you won’t be able to push changes to SVN.

If you commit often then you will end up with lots of changesets to push to SVN that will make it harder to see what the intention of your update was.

A good way to solve both problems is to submit patches to the central repo. Hg has an extension for patch management called Mercurial Queues (MQ).

Mercurial Queues.

Mercurial Queues (MQ) provides patch management integrated with Hg. This is incredibly useful for packaging up a lot of small changes that you record as you work locally into a single submission to the central repo. You can also work on a number of patches concurrently.

Enable the MQ extension in Hg, TortoiseHg > Global Settings > Extensions and check ‘mq’. In the mercurial.ini set diffs to use the git format.

[diff]
git = True

In the Hg Repository Explorer you can create a new patch from the latest revision. This means you will need to commit something you want to go into a patch before you can create the patch. The other way is to use the command line.

hg qnew mylatestpatch

qnew will include the latest changes found in the working directory.

qfold

One way to work with plenty of local commits but to have a single, tidy submission to the central repo is to use MQ’s qfold to create a patch.

Once you have some changesets you wish to publish you convert them into patches. In Hg Repository Explorer use the context menu on the latest changeset first: Mercurial Queues > Import Revision to MQ. Repeat for each of the changesets. Next, unapply the latest patches until just the earliest is still applied. Now at the command line use qfold. When you refresh Hg Repository Explorer you will see a single patch. Use the patch context menu’s ‘Finish Applied’ to change the patch into a single changeset you can push to the central repo.

For example, you have three changesets: 16; 17 and 18. You then create three patches: 16.diff; 17.diff and 18.diff. You unapply 17.diff and 18.diff then go to the command line:

hg qfold 17
hg qfold 18

Now you have a single patch, 16.diff, that contains all the work commited in the original three changesets.

Advertisements