Friday, March 12, 2010

Converting a Mercurial Repo to Git

Using OS X 10.6.2 with Mercurial installed (via Macports) and trying to use that Ben Hood posted about and Paul D. referred me to, I got the error:
ImportError: No module named mercurial
and according to dynamicproxy this meant my PYTHONPATH env variable needed to be setup to include site-packages and site-packages/mercurial dirs.

However, I had trouble at first finding those. In /usr/lib/python2.6/ there was no site-packages. In /Library/Python/2.6/site-packages/ there was no mercurial directory. I had also read that site-packages could be under ~/.local/, but I didn't have a ~/.local/. I figured out that I did in fact have a site-packages dir with mercurial dir in it by doing this:

$ which hg
I found the symlinked dir via:
$ ls -la /opt/local/bin/hg
lrwxr-xr-x  1 root  wheel  66 Nov 30 11:27 /opt/local/bin/hg -> /opt/local/Library/Frameworks/Python.framework/Versions/2.6/bin/hg
Then I looked under that dir to find mercurial:
$ find /opt/local/Library/Frameworks/Python.framework/Versions/2.6 -name mercurial
Of course, with the power of multiple backticks, you could shorten that to:
$ find `dirname \`dirname \\\`readlink -f \\\\\\\`which hg\\\\\\\`\\\`\`` -name mercurial

I added the following to ~/ (notice the two paths in PYTHONPATH that were set to the path above and its parent dir) and killed/restarted

export LC_CTYPE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export PYTHONPATH=/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages:/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/mercurial:$PYTHONPATH
(note: before blinding copying and pasting that, you need to be sure that is the path to those dirs. See above.)

If you want the repository to be hosted remotely, you may want to create an empty remote git repository that you will push the migrated hg repo to. This step is optional if you are just going to keep the git repo locally.

$ ssh username@someserver
$ sudo su - someotherusername
$ mkdir -p /path/to/remote/repo
$ chmod 775 /path/to/remote/repo
$ cd /path/to/remote/repo
$ git --bare init (with whatever options you want, for example: --shared=group)
Then, Ctrl-D twice to get back to your local environment.

Back on my mac, I was able to successfully use per Ben Hood here:

$ git clone git://
$ git init-db
$ ../fast-export/ -r PATH_TO_LOCAL_HG_REPO
$ git remote add origin (remote repo path like username@someserver:/path/to/dir )
$ git push origin master
Then just to have a clean clone, go to a directory that should contain your git project directory and do this to get the converted git repo:
$ git clone ssh://username@someserver/path/to/remote/repo
Finally, you will probably want to create at least an additional branch in addition to production for development or testing and then track that branch.

First, per DJWonk's post, you may either want to enable automatic branch tracking globally via:

$ git config --global branch.autosetupmerge true
or do it for this repository:
$ git config branch.autosetupmerge true
Then, do the following to create a local branch (first line), make it remote (second line), and track it (rest of lines) (per Eli Kalderon's post that was recommended in DJWonk's post about tracking git branches):
$ git checkout -b development
$ git push origin development
$ git checkout master
$ git branch -f development origin/development
$ git checkout development


C.smail said...

Been trying to do this all day, and this is the best guide yet. I also had the problem that PYTHONPATH wasn't set. Thanks a bunch!

Gary S. Weaver said...

Thx! Glad it helped!