Convert a Mercurial repository to Git

Mercurial is a great DVCS, but the majority of programmers use Git. So, you may just as well learn how to convert a Mercurial repository to Git. Here is how to do it, fast and easy.

I’ll assume you are using a Mac or a Linux box, and that you have a src-hg directory with your Mercurial repository. We will be converting all the Mercurial changesets to Git format, and store them in the Git repository named src.

Hg-Git

When it comes to interacting between Mercurial and Git, Hg-Git is your new best friend. Start by cloning the Hg-Git repository:

hg clone https://bitbucket.org/durin42/hg-git/ /path/to/hg-git

Then install the dulwich package (that implements the Git file formats and protocol in Python):

pip install dulwich

(You may need to use sudo for this command.)

In your global Mercurial config, in ~/.hgrc, add the Hg-Git extension:

[extensions]
hggit = /path/to/hg-git/hggit

Bookmark your branches

You should make sure that all branches in the Mercurial repository have a bookmark, so there are no anonymous or named branches without a bookmark.

By convention the main branch in Git is called master. Here’s how to apply that bookmark to the current branch in the Mercurial repository:

hg bookmark master

Git init

Before you start the conversion, you have to prepare a “bare” Git repository, which will receive the exported Mercurial changesets:

mkdir -p src/.git
git init --bare src/.git

Add this new Git repository to the external paths of the Mercurial directory, by adding it to the src-hg/.hg/hgrc file:

[paths]
gitsrc=/path/to/src

Perform the conversion

Now you just have to push the changesets from Mercurial to the Git repository:

hg push gitsrc

The Mercurial changesets are then exported to Git. And you should see something like this:

pushing to /path/to/src
searching for changes
adding objects
added 1652 commits with 6114 trees and 6081 blobs
adding reference refs/heads/master

All you have left to do is clean up the Git src directory:

git config --unset core.bare
git reset --hard master

This completes the conversion. You now have a Git version of the Mercurial repository.

If you don’t want to leave Mercurial behind, you can continue to use the Mercurial repository, and push and pull changes to/from the Git repository.