One of the particularly nice things about working with a distributed revision control tool these days is that I can sidestep the choice of winning tool. Thanks to Scott Chacon and Augie Fackler’s excellent hg-git extension, I can use Mercurial and collaborate almost seamlessly with git users. This is exactly what I did when working with Johan on the new I/O manager subsystem in GHC 7, and the experience was generally very smooth.
The only mild annoyance has been that I’d prefer to also not be forced to choose a hosting winner: although bitbucket is pretty good, github is currently far slicker, and has a much larger community of potential collaborators.
I’ve hosted most of my code on bitbucket for quite a while. Until this morning, I had a somewhat awkward way to mirror code to github. I just automated the problem away.
My automation scheme is implemented as a Mercurial hook. Here’s how I’ve enabled it in my
$HOME/.hgrc file:
[hooks] post-push = python:/home/bos/share/python/github\_mirror.py:post\_push
That github_mirror.py hook is very simple. Every time I push, it checks to see if I’m pushing
to a bitbucket repository, and if so checks my local repo’s .hg/hgrc file to see if I have a
mirror on github. If I do, it pushes to github, too.
from mercurial import commands
def post_push(ui, repo, pats, opts, \*args, \**kwargs):
dest = pats and pats[0]
dest = ui.expandpath(dest or 'default-push', dest or 'default')
if 'bitbucket.org' in dest:
github = ui.config('paths', 'github')
if github:
return commands.push(ui, repo, github, **opts)
ui.warn('no github mirror!?\n')
How do I tell Mercurial that I have a girhub mirror? In a repo’s .hg/hgrc file, I have
something like this (taken from a real repo):
[paths] default = http://bitbucket.org/bos/pcap default-push = ssh://hg@bitbucket.org/bos/pcap github = git+ssh://git@github.com/bos/pcap.git
The github_mirror.py hook looks for that github key in the paths section of the file, and
uses it if present.