Bitbucket: Converting Hg repositories to Git

Recently I started using Bitbucket for private repository hosting for a project I’m working on. While I had no experience with Mercurial, I figured it can’t be that tricky – and Bitbucket offers free private hosting which is what this project needed (couldn’t go public, couldn’t pay, didn’t have the time to set up self-hosted SCM hosting).

All in all I like Bitbucket (although I have to admit on most aspects they seem to fall behind GitHub), but not so much using Mercurial – for all sorts of reasons it felt quirky and less polished than Git, which honestly I have much more experience with.

So following Bitbucket’s big announcement on Git support, I’ve decided to migrate my repositories from Hg to Git, while keeping them on Bitbucket and maintaining repository history. I’m happy to say it was relatively a piece of cake to successfully achieve. Here is what I did:

Step 1: Set up your repositories

First, I renamed my old Hg repository through Mercurial’s web interface, to something like “MyProject” to “MyProject Hg”. This changes the repository URL, but since I wasn’t planning on using it anymore that doesn’t really matters – plus you can always rename back if things go bad.

Then, I created a new Git repository with the name of the previous repository, e.g. “MyProject”. Again, that can be easily done from Bitbucket’s Web interface.

Step 2: Install the Mercurial hggit plugin

The hggit plugin allows your Mercurial command line tool hg to talk to git repositories – that is push and pull from Git. Installing it is easy, as it is probably available from your package manager. On Mac, if you use Macports, you can run:

  $ sudo port install py26-hggit

While on Ubuntu, run:

  $ sudo aptitude install mercurial-git

Then, make sure to load the plugin by adding the following lines to your ~/.hgrc file:

  [extensions]
  hggit=

Congratulations: Your hg command now speaks Git!

Step 3: Push your code into your Git repository

To push your code into your new Git repository, you basically need to run two commands:

First, create a Mercurial bookmark that references master to your default branch. This will help Git create the right refs later on:

  $ cd ~/myproject-hg-repo/
  $ hg bookmark -r default master

Next, simply push your code into the newly created Git repository:

  $ hg push git+ssh://git@bitbucket.org:shaharevron/myproject.git

Of course, make sure to change the repository URL to the URL of your new Git repository. To make sure hg understands you’re referring to a Git repository, if using SSH add the git+ssh:// prefix to the URL. This should push your entire repository to the new Git repository, and within a few seconds up to a few minutes (depending on how big your repository is), you should be able to see all your old commits in the new Git repo.

Step 4: Switch your local repository to use Git

Now that your new Git repo is up at Bitbucket, you’ll need to switch to using Git locally. There are two paths you can take here: the safe one, is to simply git clone your code to a new working directory and work from there. It’s safe, and will work well. However, if you’re a cowboy like me, and are too lazy to create a new IDE project on a different directory, you can in fact simply switch to working with Git on the same directory (but I still seriously recommend you ensure Bitbucket really does have your code as backup…).

Here is how to do it. From the local repository directory, run:

  $ git init
  $ git remote add origin git@bitbucket.org:shaharevron/myproject.git
  $ git pull origin master
  $ git reset --hard HEAD

Again, replace the repository URL with your own. This will “merge” everything in your Git repo into the local working directory. You will need to create a new .gitignore file if needed – and can now simply delete the .hg directory, as it is no longer needed. You can now happily use Git with your Bitbucket code.

While there shouldn’t be any problems, I also recommend keeping your old Hg repository around on Bitbucket for a few days, just to make sure nothing blows up – and delete it from Bitbucket’s web interface once you’re sure everything works well.

8 thoughts on “Bitbucket: Converting Hg repositories to Git

  1. Pingback: Bitbucket: Converting Hg repositories to Git | Pseudo Random Bytes | Code IT | Scoop.it

  2. Pingback: Converting Hg repositories to Git – Bitbucket blog

  3. Instead use hggit you may use hg-fast-export.

    1. Create new git repo at Bitbucket.
    2. git clone git://repo.or.cz/fast-export.git
    3. mkdir new_git_repo
    4. cd new_git_repo
    5. git init
    6. /path/to/hg-fast-export.sh -r /path/to/hg_repo
    7. git checkout HEAD
    8. git remote add origin git@bitbucket.org:shaharevron/myproject.git
    9. git push origin master

  4. I think it’s interesting that you find hg less polished and more quirky than git. I feel like the opposite is the case. It seems to me that hg’s commands are more straightforward, but then again I haven’t worked with git long enough to form a true opinion. The git/hg command equivalence guide at http://mercurial.selenic.com/wiki/GitConcepts shows the differences between the two pretty well.

    • To be honest I just have more experience with Git and whenever it comes to dealing with more advanced operations like merging and branching, I find Git more convenient but it’s probably simply lack of experience with Hg. I just prefer to stick to the tools I know and work well than learn new ones – but I’m sure that if I was more familiar with Hg it might have been otherwise.

  5. When converting hg repos to git, would you lose the issue tracker and wiki information that you had as part of your original hg repo?

    • Unfortunately as far as I have seen yes – I did not find a way to export / import / convert issues and Wiki to the new repo. If you find a way I’d love to know about it :)

    • I just checked, and if you really want Bitbucket provides a REST-style API to access issue trackers and Wiki pages, among other things.

      You can do things like get all your issues (or all open ones), create new issues etc. using a fairly simple REST/JSON API. So if you really need to migrate stuff, I’m sure you can easily write a little script / program in virtually any modern programming language to handle this migration.

      The API documentation is here: http://confluence.atlassian.com/display/BITBUCKET/Using+the+Bitbucket+REST+APIs

      I also talked with someone at Bitbucket and he mentioned I could ask their support to help me migrate – but in my case, I have just a few bugs so I am not going to bother with migration.

      Shahar.