Thursday, December 19, 2013

Pushing from Mercurial to an empty, non-bare Git repo on Windows

Today there's good, 2-way integration between Git and Mercurial. Git has hg-git which is an extension that allows you to clone, push and pull git repos. Likewise Git has git-remote-hg for interacting with Mercurial-repos. Both of these extension come pre-compiled with the git and hg-installations I'm using on Windows, so getting them to work was simply a matter of configuration.

What wasn't that simple though, was getting the first push through. I had an empty repo at Visual Studio Online which I wanted to populate with the check-in history of my Mercurial repo. I met obstacles because non-bare Git repo's doesn't appreciate being pushed to by Mercurial. See this article on bare vs non-bare repos for more info. So then I tried pulling from git instead, but that was equally challenging because I needed Python-support in Git for the git-remote-hg extension to work. Apparently that is not supported in Windows.

Solution: Create an intermediary bare git-repo.

So, here's the receipe of command you need to execute in order to complete the conversion. I'm not including the CD-commands - the foledr you need to be in is indicated on each line. Assumptions:

  1. HgSource is the source repository with a history
  2. GitTarget is the empty, non-bare git-repo you want to push to
  3. c:\GitTempTarget is simply an empty Windows folder

c:\GitTarget> git config --local receive.denyCurrentBranch warn
 c:\GitTempTarget> git --bare init
 c:\HgSource> hg push c:\GitTempTarget
 c:\HgGitTempTarget> git push c:\GitTarget master
 c:\HgGitTarget> git config --local --unset receive.denyCurrentBranch

Note: This is a one-time conversion of the repository. I have tried pushing consecutive changesets from HgSource directly to HgGitTarget without success. If anyone know how to achieve that, please drop a comment below.

2 comments: