Mar 062011


At the very beginning I should start with some background information: I am working in a small software company in a team with 13 developers. We continuously developing a software for the medical domain with Qt as UI framework and Visual C++. Our platform is MS Windows. Until autumn 2009 we were developing with the V-model.

As the requirement and priorities of our customer changed many times, we decided to change from the V-model to SCRUM. At the same time we changed from developing all features on the trunk of our SVN repository to feature branching.

As it is recommended in the literature we updated all the feature branches every day and merged the features back, after a story was done. And here the pain stared. SVN is a great SCM repository software, but it is not made for regular merging. So we started to look for alternatives. We put an eye on Git, Hg, Bitkeeper and Perforce. With four colleagues we made a list of requirements, use cases and started an evaluation phase for several weeks. At the end  Git and Hg were the most preferred ones. During this time I looked in the net and searched for pros and contras for both of them. From all the blogs, articles and our own experience i came to the conclusion that Git and Hg offer nearly the same functionality. At the end we decided to go for Hg because of the better support with TortoiseHg, the Windows Explorer integration and the less confusion interface.

In the next chapter I try to describe our way to convert the SVN repository.

SVN Preparation

Our source repository had at that time about 90.000 revisions and its size was about 7GB and the source code had about 500,000 lines of code.

It is recommended in the Mercurial book that one should start the migration from a repository clone. I strongly can recommend to follow that way. As I am more used to Windows I started to to create the mirror within Windows XP. But Subversion does not work stable under Windows XP. The socket layer crashed several time during the cloning process and I had to reboot the system. So I tried to perform the process on a Windows Server 2003 installation. The creation of the mirror was now going well, but later the needed SVN-Dump did not went through. So I installed an Ubuntu in a virtual machine and re-did the complete process.

So if not available in the Linux installation, install svn with

sudo apt-get install subversion

Now create an empty repository

 cd {where ever one want to create the mirror}
 svnadmin create svn-mirror
 echo '#!/bin/sh' > svn-mirror/hooks/pre-revprop-change
 chmod +x svn-mirror/hooks/pre-revprop-change

Now initialize the mirror. Be aware if one does not restrict the path to a certain repository path, one gets the complete repository. The repository had about a size of 60GB. So it would need time and space to set this up.

 svnsync init file://`pwd`/svn-mirror https://{svn url} --source-username {svn user name}

The first time one is asked to accept the certificate and one has of course to enter ones password. Use the correct apostrophe! So not a ‘, but a `!

Now we initiate the sync.

 svnsync sync file://`pwd`/svn-mirror --source-username {svn user name}

This command can be repeated as often as one like. It always checks then the source repository for updates and appends them. The history and its version numbers are preserved. It is not known if copy from or copy to from outside of the given path are used in the repository.

Migration from Subversion to Mercurial

During the last years we had stored many binary files in the repository which caused the repository to grow to a size of about 7GB. So I decided that we transfer the complete file history of the last three major releases  into Hg and filter with svndump all not needed binaries from the repository. So we wanted to be able to build all versions since the last major release.

The following assumptions are made:

  • The Subversion mirror repository is here /data/svn-mirror
  • The location for the new Mercurial repository is /data/hg

Patching Hg conversion module

The Subversion conversion tool must be patched because of deficiencies inside the code. Be aware as soon one updates the Subversion packages one has to re-apply the changes! The files is under /usr/share/pyshared/hgext/convert/

Line 353
This line must contain all branches that shall be converted. All others are excluded.
Lines 354-363
These lines must be indended by 3 spaces.
Lines 366-368
These lines must be commented, otherwise the conversion will abort.

Execute the actual conversion command in a shell:

 hg convert --debug --verbose --filemap /data/svn2hg.txt --branchmap /data/branchmap.txt \
   --splicemap /data/splicemap.txt --datesort --config convert.svn.trunk={trunk path}  \
   --config convert.svn.branches={branch path} --config convert.svn.startrev={start revision} \
   --authors /data/user.txt file:///data/svn-mirror/ /data/hg | tee convert.log

Here is the description of the command in detail:

This file contains all paths which shall be excluded during the conversion, because they contains either binary files or branches, etc. that are not needed any more.
This file helps to rename branches to different, better names.
This file contains a description of additional parent and child connections. (Currently not working correctly, or I was not able to get it work)
{start revision}
This is the first revision that is taken from the Subversion repository.
A file that contains a mapping from the Subversion user names to real names that are used in Hg.


Now it is strongly recommended to do a binary comparison of the head of the Mercurial repository against the latest revision of the Subversion repository to ensure that no conversion errors happened. Be aware that the DVCS do not support empty directories and the DVCS does not support file property makros as Subversion.


We did a training over several sessions for all users about the differences between SVN and Hg before we used it in production. Then we made a cut from using SVN and started using Hg between two SCRUM sprints and no major issues came up after that. Only once we had the problem that one user used the merging functionality as it is in SVN. So he just wanted to pick a single change set and transfer it to a different branch. So at the end it was a training issue. Today everybody is really satisfied with Hg.

In the next article I will described why we use Hudson / Jenkins as build system and how we get there.

At the end I want to apologize, English is not my first language and this is my very first blog. So any kind of critics or advices to improve is welcome.