Sunday, February 13, 2011

How to use Bitbucket's free private Mercurial repositories with Git

Update: Since I wrote this post, bitbucket has added native Git support. Are you spotting a pattern here? Anyway, I'll leave the rest of the post here for the historians.

When Atlassian bought bitbucket in September 2010 one of the first things they did was to allow single users an unlimited amount of private repositories for free. If you want to create an backup of your own code without making the source available this seems like a difficult offer to beat. I've been using it for some months to do exactly this.
The only problem is that bitbucket uses Mercurial, what if you prefer git as your day to day version control? No worries as the Atlassians might say, you can bridge from Git to Mercurial using hg-git and a bit of fiddling. Here's what I did to set this all up, in case I forget later.

I use Ubuntu 10.04 and although hg-git is in the repositories it is an older version. Instead I installed python-dulwich via apt-get install python-dulwich, cloned the repository at and then added a suitable entry to my ~/.hgrc file:
hggit = /path/to/hg-git/hggit
The first gotcha is that hg-git can't clone a local file:// repository. When you try it, you get an error like this:
/tmp$ hg clone file:///home/rich/projects/test destination directory: test importing Hg objects into Git fatal: 'file:///home/rich/projects/test' does not appear to be a git repository abort: the remote end hung up unexpectedly
The workaround is to serve the repositories using the git-daemon and then clone them using the default git network protocol. I have the code I want to back-up in a directory ~/projects, so I start the git daemon to export all of them:
git daemon --verbose --export-all --base-path=~/projects/ --export-all
That is not particularly secure, but it isn't available outside my home network and means I can clone each repository using hg with the hg-git plugin enabled:
hg clone git://localhost/name name-hg
Once I have a local Mercurial clone, it is easy to set up the push to bitbucket. That is just vanilla Mercurial configuration. In name-hg/.hg/hgrc I added the bitbucket path so the full configuration looks like this:
default = git://localhost/name
bb =
Now name and project depend on the local name and the remote bitbucket project name, but hopefully you get the idea. I push this out to the server with hg push bb. Next time I want to copy all the changes I've made in the git repository since the last backup, I fire up the git-daemon, sync up the mercurial repository then push out the changes. I have a script that does all this, which boils down to the following:
#!/bin/sh # backup git repos to bitbucket private repos... cd ~/projects git daemon --verbose  --export-all --base-path=~/projects/ --export-all & for name in project1 project2 ; do     # echo "did this once... not needed again"     # hg clone git://localhost/${name} ${name}-hg     cd ~/projects/${name}-hg || exit 1     hg pull || exit 1     hg update || exit 1     hg push bb || exit 1 done
This way I can use git for day to day hacking, and have a secure backup on a server somewhere for if the worst happens.

1 comment:

  1. Great instructions -- thanks for the post, Rich! Glad you're finding Bitbucket useful.


Note: only a member of this blog may post a comment.