Mercurial Repository to Bitbucket and Github

I love and use mercurial, but more people love git. I don't want to exclude git-lovers from my projects because they like git. It's easier to provide this than you'd think.

This walkthrough will get your existing mercurial repository:

  1. speaking to bitbucket with mercurial
  2. speaking to github with git via hg-git

This article's instructions worked as of 2012/12.

I'm assuming that you're starting with a local mercurial repository you already use and enjoy — if you've never used mercurial, see the wonderful tutorial at hginit/kiln for a great introduction.

Install / Verify hg-git

hg-git lets your mercurial installation speak natively to a git repository. It's pretty slick but it doesn't seem to like virtualenv very much. You can get weird-but-surmountable errors.

$ pip install hg-git

Verify that hggit works:

$ python
>>> import hggit

Then add it to your base mercurial config (~/.hgrc):

hgext.bookmarks=
hggit=

Quick aside: problems with hg-git and virtualenv?

I had problems with these. My mercurial application was system-installed, not tied to my python installation. My virtualenv was compeltely confused. (Now I know why everyone says "no site packages".) Check that your mercurial is tied to your virtualenv:

$ which python
$ which hg

Mine were not aligned. To get around this specific problem, you can try either of the following:

1. clear system mercurial

Easier solution if you have administrator permission: uninstall system mercurial, reinstall fresh in your virtualenv via pip install mercurial hg-git

2. override system mercurial

$ pip uninstall mercurial
$ pip upgrade --force mercurial

This will cause your virtualenv to override the stock installation.

bitbucket

Mercurial-to-bitbucket is really well defined and easy to set up. Start with Bitbucket's guide. There is nothing special to do here, and you should end up with the ability to:

$ hg push https://your_user@bitbucket.org/your_user/your_project

github

Create repository on github with desired name, preferably mirrored. I had to git init (elsewhere) and commit a trivial file (I chose an empty .gitignore file).

For convenience, add the remote targets to your ./your_project/.hg/hgrc file:

[paths]
bitbucket = ssh://hg@bitbucket.org/your_user/your_project
github = git+ssh://git@github.com/your_user/your_project.git

And finally:

# your mercurial repository
$ cd your_project
# make a bookmark of master for default, so a ref gets created that git can hang on to
$ hg bookmark -r default master
# speak mercurial to bitbucket
$ hg push bitbucket
# speak git to github
$ hg push github

Further Reading