Synchronizing a Mercurial repository with Git

Some weeks ago a member of the Mozilla community asked me if we can also use Github for our Mozmill test repository which was at this time only available at I agreed but only with the requirement that there has to be a simple way to synchronize both remote repositories. Then Mikeal Rogers who leads the Mozmill project pointed me to Hg-Git which is a tiny Mercurial plugin and implements the Git protocol.

Yesterday I was finally able to play around with this plugin and promptly run in a couple of problems due to wrong application dependencies. Most of my applications have been installed via MacPorts while for Mozmill and hg-git setuptools has been used. As result Mercurial wasn’t able to find the hg-git plugin. It has been taken nearly half an hour before I figured out whats going on. So for any future reference and as a tutorial for others I will give instructions below how to get this plugin working on your Mac.

To install other software on your Mac it’s mostly helpful to do this via MacPorts. The installation package and needed instructions can be found on their website. Just download the appropriate build for your version of OS X and install it.

Now use MacPorts to install Python and setuptools. The command below can take a while to execute depending on the power of your machine:
$ sudo port install python25 py-setuptools

With setuptools installed you can use easy_install to install all the remaining packages:
$ sudo easy_install mercurial hg-git

To activate the hg-git plugin the following lines have to be added to the .hgrc file in your home directory:
hgext.bookmarks =
hggit =

And that’s all! Now you can use hg-git to synchronize your local copy of the repository with the remote one via hg or git. As example I will use our Mozmill test repository which has two branches (default and mozilla1.9.1).

Create a local copy of the remote repository and change into its folder.
$ hg clone
destination directory: mozmill-tests
requesting all changes
adding changesets
adding manifests
adding file changes
added 251 changesets with 840 changes to 132 files (+1 heads)
updating to branch default
98 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd mozmill-tests/

Because we have two branches we will have to create two bookmarks. Both are used to map those branches to separate branches in the git repository. Then push all the data to the github repository:
mozmill-tests$ hg bookmark -r default master
mozmill-tests$ hg bookmark -r mozilla1.9.1 1.9.1
mozmill-tests$ hg push git+ssh://
pushing to git+ssh://
importing Hg objects into Git
creating and sending data
git::refs/heads/mozilla-1.9.1 => GIT:70300757
git::refs/heads/master => GIT:092e7cf3

If you want to pull updates from the Github repository to include those into your local version just run a normal pull command in hg with the appropriate URL:
mozmill-tests$ hg pull git+ssh://
pulling from git+ssh://
importing Hg objects into Git
Total 0 (delta 0), reused 0 (delta 0)
importing Git objects into Hg
(run 'hg update' to get a working copy)

If you do not want to add the path of the remote github repository each time you can simply add it to the .hg/hgrc file:
cat .hg/hgrc
mozmill-tests$ cat .hg/hgrc
default =
git = git+ssh://

And run this command afterward:
mozmill-tests$ hg pull -u git

As you can see it’s really simple to keep your Mercurial and Github repository in sync. Personally I will move to Github now which makes handling patches on different branches much easier.