2011-12-04

Converting from Subversion to Mercurial on Bitbucket

I've been doing source control of personal projects on my own Subversion server for several years, but lately I've gotten interested in making some of it available so that perspective employers can see examples of my work. To do that, I setup a Stack Overflow Careers profile which acts as a resume with links to my StackExchange network profiles and projects on any of the major cloud-based source control services.

Bitbucket, hosted by Atlassian, provides free hosting for any number of repos, private or public, provided you stick to 5 or fewer total committers. It supports Git and Mercurial, probably the two most popular DVCSs today, and since I had some previous experience with Mercurial and use it every day at my current job, I opted for that.

When creating a new repo at Bitbucket, you have two options: you can create an empty repo, or import from an existing repo from (currently) one of the following sources: CodePlex, Git/GitHub, Google Code, Mercurial, SourceForge, Subversion.

In the case of Subversion, the Bitbucket importer currently only takes an export of the working copy of your trunk code base, so you won't have any of your revision history in your new repo. I'm sort of a revision history hoarder, so this wasn't going to work. Luckily they provide a small hint on how it can be accomplished (emphasis mine):
If you would like to bring your Subversion revision history with you to Bitbucket, you will need to perform an offline synchronization.
Depending on the size of your repo, the number of revisions, branches and tags in your repository this may take a while and be CPU intensive.
We recommend reading the blog entry "Goodbye Subversion, Hello Mercurial: A Migration Guide" to learn about best practices when migrating to DVCS from Subversion.
The link referenced above is a good blog entry about converting from Subversion to Mercurial, but after reading it, it still wasn't clear to me what was meant by 'offline synchronization', so that's the main reason I decided to write this post. Let's get to it.
  1. Create the repo at Bitbucket
    Choose the Create New Repository option; instead of using their import function, we're going to create an empty repo and attach our converted project to it.
  2. Create an authors mapping file
    Authors or committers are generally a system username in Subversion, but there's no restriction like that with Mercurial; for that reason, the recommendation is to use the form: Full Name <email@address.com>. To get a list of distinct committers to a particular project in Subversion, run the following command at the root of a working copy:
    svn log | egrep "^r[0-9]" | cut -d\| -f2 | sort | uniq
    The format of the authors mapping file for the conversion tool we'll be using is pretty simple:
    SubversionUsername=Full Name <email@address.com>
    If you're converting several projects, you can simply add authors to the file for successive conversions; extras won't affect the conversion process.
  3. Convert the project
    There are a couple of different plugins that help with this; it sounds like HgSubversion is the better of these, so we need to get that installed. It's really easy when following the instructions at the HgSubversion site. First clone the plugin repo:
    hg clone http://bitbucket.org/durin42/hgsubversion/ ~/hgsubversion
    Now configure it by editing ~/.hgrc and adding the following lines:
    [extensions]
    hgsubversion = ~/hgsubversion/hgsubversion
    If you don't have them already, install Mercurial bindings for Subversion; on Ubuntu:
    sudo apt-get install python-subversion
    To verify that HgSubversion is setup correctly, run the following command; if it displays an error, check your configuration, otherwise it provides a lot more detail on HgSubversion use.
    hg help hgsubversion
    Now that we're setup, run the conversion. The following command will use HgSubversion to convert your project behind the scenes when it notices that it's a Subversion URL:
    hg clone --authors YOUR_AUTHORS_FILE SVN_REPO_URL
    HgSubversion will output a line for each revision converted with the original author, so don't worry if you don't see the Mercurial username you mapped.
  4. Verify the conversion worked
    On Ubuntu I use hgk when I want a visual representation of a repo, but it's not enabled by default because of its dependency on Tk, so first we need to install that:
    sudo apt-get install tk8.5
    Once that's done, add the following to ~/.hgrc:
    [extensions]
    hgk=
    Now change into the new repo root and run hg view. An alternative to hgk is TortoiseHg; check out this answer for easy installation on Ubuntu.
  5. Point your new Mercurial repo at Bitbucket
    When you're satisfied with the conversion, edit .hg/hgrc and comment out the existing default URL and add another line for the URL shown on your repo overview on Bitbucket. Afterward it should look something like this:
    [paths]
    #default = SVN_REPO_URL
    default = BITBUCKET_REPO_URL
  6. Push the repo
    hg push
    Once authenticated, this will send all your entire project with history from your local Mercurial repo to your empty Bitbucket repo.
That's it.
If you're new to Mercurial, check out Mercurial: The Definitive Guide for basic and advanced Mercurial use.

No comments:

Post a Comment