DEV Community

Cover image for Let My People Go: the Hg to Git evacuation process.
circular firing squad captain
circular firing squad captain

Posted on

Let My People Go: the Hg to Git evacuation process.

When bitbucket recently announced the impending doom of mercurial support come May 2020, I knew my time had come. My various projects and Open Source contributions could abide bitbucket no more.

It was time -- cringe -- to figure out how to export my mercurial repositories to git.

(TL;DR — fast-export worked for me, but with a catch. See below.)

I’ve been observing for some time how cannot quite measure up to the potential of when it comes to promoting the building of Open Source Software. It seems I've just been waiting for that proverbial kick in the pants to get off my adverbial butt and lead my ragtag bunch of repos out of the feature-desert of bitbucket and into the Open Source promised land of github.

(Now, I too shall have all manner of pieces of CI/CD flair on my READMEs!)

My procrastination all centered around transitioning from mercurial (hg) to git. I have no shortage of experience in git, here in 2019 where we are long past the ambiguity of whether mercurial or git would become the source control worship of choice.

However, dark ominous clouds swirled around shuttling my repository histories from one system to the next.

For when I went looking for utilities to help with this process, I found but two:

Very quickly did I audition both, and out of the box both were failures.
Argh! Why, O great and powerful Open Source, do you torment me so?

As ultimately I did not get hg-git working, this article will simply detail the steps I took to get fast-export to perform the correct rituals, along with the main problem I encountered and how I solved it.

The Logical Steps

or, what we’re trying to accomplish:

  • Create a new empty git repo to serve as the target container for your export.
  • Locally, set up your mercurial repo as a git repo. Set settings to make sure git ignores hg effluvia.
  • Configure the repo to take the newly-created git repo from step 1 as its remote.
  • Perform the export of HG history using fast-export.
  • git commit && git push —set-upstream origin master
  • Check new repo on github to make sure everything’s there.

The Practical Steps

or, what we actually have to do.

First off, you should go create a new empty git repo on whatever service you're using. Make sure you keep handy the remote information for use later on in the process.

Now I'm going to take the unusual step of starting with the problem that occurs in the middle, so that the instructions as a whole make more sense.

When running the script, many people encounter the following unhelpful error message:

 Traceback (most recent call last):
   File "/home/nthmost/fast-export-190107/", line 7, in <module>
     from mercurial.scmutil import revsymbol
 ImportError: cannot import name revsymbol

This means it definitely didn’t do the export. What should we do?

Well, it turns out that several releases of the fast-export tool over the past year or more have been unreliable. I found, by poking around the Issues, that the only reliable recent-enough release is tagged “v180317”.

So what you should do is the following:

  • git clone
  • cd fast-export
  • git checkout tags/v180317

Once you have this specific version of fast-export, now you can continue on with the next steps:

  • cd /your/target/repo
  • git init
  • ../fast-export/ -r /your/hg/repo
  • git remote add origin
  • git commit
  • git push —set-upstream origin master

Note that it’s entirely kosher simply to do all the git work directly within the mercurial directory you started with. If so, you can just replace /your/hg/repo with a . for the fast-export command.

If you want to keep on using mercurial with git, then you should probably get hg-git working; otherwise, I’d recommend only continuing to develop this project after you’ve cloned from the git repo afresh and wiped out all traces of your former mercurial life. 🙂

That’s all! I hope that’s perhaps saved you a few minutes of banging your head on a keyboard. Keep the faith!

Top comments (3)

zer0pants profile image
Mike Roberts

I read your post earlier today and it was great.

Just posted this really basic method for converting your repos from hg to git which might be sufficient for some:

Additional tips:

Resolving issues with Authors:

Reference: Atlassian - probably the best guide I've seen

hg log | grep user: | sort | uniq | sed 's/user: *//' > ../authors.txt

# Edit this file as described in the reference above.
# When running the import command don't forget the -A flag and to reference this file

Resolving issues with branch names

Unnamed heads - reference

  • Basically checkout the revision. Branch off. Make a commit to persist the branch

Cannot lock ref - reference

  • Basically same method as authors but now for branches.
  • Map the problem branch to something not problematic
  • In the below example the branch release is an issue
hg log | grep branch: | sort | uniq | sed 's/branch: *//' > ../branches.txt

# branches.txt (before)

# branches.txt (after)


Hope it helps someone out there!

nthmost profile image
circular firing squad captain • Edited

In case it's hard to understand why anyone would put ALL their repositories into mercurial, the short story is that git was really not up the task 8+ years ago. (Or, it kinda worked but you had to MAKE it work.)

A friend wrote this article detailing the laborious decision progression from CVS to mercurial to git.

chadcrockett profile image

thanks, currently in same situation, going to try your suggestion