Migrating a large SVN repository to Mercurial on Windows

22. March 2012 14:06

I couldn't find any good guide for doing this, so I figured I'll write my own guide based on my experiences from converting a huge SVN repo. There are a few differences between Windows and other platforms which can take you by surprise if you're not prepared.

What worked best for me was to split up the migration into three steps:

  1. Creating a local copy of the SVN repository (will speed up conversion)
  2. Converting to Mercurial - locally
  3. Pushing the new Mercurial repository to it's destination server.

Creating a local copy of the SVN repository

First, create an empty local repository that will store the mirrored repository locally:

svnadmin create svnrepofolder

Next, you'll need to enable revision properties to be changed:

echo exit 0 > svnrepofolder\hooks\pre-revprop-change.bat

The actual conversion is done using the svnsync command, as following:

svnsync init file:///c:/path/to/svnrepofolder http://svn.server/path/to/reponame
svnsync sync file:///c:/path/to/svnrepofolder http://svn.server/path/to/reponame

You can specify usename and password using --source-username and --source-password options (type svnsync help init for more info).

Converting to Mercurial

Make sure you have an empty local Mercurial repository - usually done by cloning a newly created master repository.

hg clone http://mercurial.server/reponame hgrepofolder

Before converting, you need to enable the convert extension in Mercurial. This is done by adding/editing the following lines in Mercurial.ini (which resides in C:\Users\username\ in Windows Vista or later):

convert = 

If you have TortoiseHg installed, this can also be done in Global settings -> Extensions by checking "convert".

Next you're off to do the actual conversion. There are many settings you may tweak, but I'd like to keep it simple here:

hg convert file:///c:/path/to/svnrepofolder hgrepofolder

This command will convert the trunk and all branches and tags found in the \trunk, \branches and \tags folders - appropriately. If your naming scheme is different, you can configure alternate folder paths.

Pushing the new repository to its destination server

After the conversion, the new folder is empty, except a hidden .hg folder. That is because you need to update to a specific branch/trunk. Don't let that worry you - things work differently in Mercurial than in SVN.

To push the repository to its destination server, simply use:

hg push http://mercurial.server/reponame