From RCS to Mercurial

I've been a happy user of RCS for years (in fact, my software engineering course at university was held by Walter Tichy, the original author of RCS). The good old Revision Control System may be a dinosaur, but it served me well for my configuration files and scripts.

Over the last few years, however, new and fancy revision control systems have entered the scene. My current choice is Mercurial, because it's easy to use, popular, and well documented.

Update: Mercurial now supports CVS conversion without using Taylor. Seethis blog postingor the comments below for instructions.

Since I needed some data to experiment with, I decided to switch my old RCS files over to Mercurial. Of course I wanted to keep the revision history, so a migration path was needed. For the conversion I used Tailor, a tool for converting between various version control systems. RCS is a bit dated, so it isn't supported directly. But since the RCS file format is used in CVS, too, the natural upgrade path lead me to CVS and from there to Mercurial. This article shows how the conversion can be done.

So, first of all, we create a fresh local CVS repository somewhere:

cvs -d /var/tmp/cvsroot init

The next step is to create a module inside the repository (scripts in this case), to create the desired directory structure (none in the example) and copy the RCS files there. The RCS files shouldn't be locked as this could cause trouble.

cd /var/tmp/cvsroot
mkdir scripts
cd scripts
cp /path/to/repo/servehttp,v .
cp /path/to/repo/b,v .

If you have a large number of files, it might be a good idea to automatize this using a script. Note that usually it's no good idea to manipulate a CVS repository manually, but this is only for conversion. To make sure everything worked, we can check out the new module:

cvs -d :local:/var/tmp/cvsroot co scripts

If everything worked as expected, we have a fully functional CVS repository that can be converted using Tailor.

Unfortunately, tailor-0.9.28 doesn't work together with Mercurial 0.9.4, which is exactly the situation you find on Ubuntu 7.10. This incompatibility has already been fixed in tailor-0.9.30 and fortunately, you don't have to install the new version. Extracting the tarball and executing the script from there works fine.

python tailor -v --source-kind cvs --target-kind hg
  --repository :local:/var/tmp/cvsroot
  --module scripts --start-revision INITIAL > scripts.tailor

This creates a configuration file named scripts.tailor that has to be adjusted manually before the actual conversion. According to the documentation the purpose of the call above is to generate a template configuration file.

The configuration file should look like this:

verbose = True

target = hg:target
start-revision = INITIAL
root-directory = /tmp/tailor-0.9.30
state-file = tailor.state
source = cvs:source
subdir = scripts
patch-name-format =


module = scripts
repository = :local:/var/tmp/cvsroot

The defaults should mostly be finde, all I changed was the subdir setting and the patch-name-format to get better revision logs. More information about this can be found in the Mercurial wiki.

After adjusting the configuration it's time to actually create the new Mercurial repository (this may take a while):

python tailor --configfile scripts.tailor

We change to the created repository and make sure all revisions have been migrated:

cd scripts
hg log

That's it. You can remove the CVS directory as soon as you're confident that everything worked as expected. As a last step you might want to update the .hgignore file.