Mercurial to Git Migration
Wha? You have hg repos?
I was always a fan of Mercurial. It gave me the benefits of git, while also giving me the benefits of absolute order of commits.
While I used git for work (and svn/cvs/p4/etc before that), about 1/3 of my personal repos were using hg.
In fact, that was the primary reason I was hosting many of my repos on BitBucket instead of GitHub. Well, that and they allowed private forks.
If you love it so much, what’s the problem?
Atlassian announced that the were not only ending support for hg, but that they would be deleting all the Mercurial repositories.
Sure, this isn’t the first time my hosting provider has decided to remove all my repos. Queue projectlocker, google code, etc (not to mention voluntarily leaving sites like sourceforge).
I decided to write up this page in case anyone else has to do the migration and wants some tips.
The Migration
Tools
I am using Hg-Git Mercurial Plugin to do the conversion. Make sure to have that installed first.
They tell you to install easy_install
, but we just use pip
now.
Which repos?
The first step is to identify which repositories need to be migrated. You can go to https://bitbucket.org/dashboard/repositories?scm=hg to see a list of your Mercurial repos.
For the rest of this process, I will refer to old repository as “REPO” and the new one as “REPO_v2”. I thought about trying to change it in place, but did not want to risk that they would delete it anyway.
Code migration
Create REPO_v2
Go to https://bitbucket.org/repo/create and create a new repository named REPO_v2. For example, if you are replacing a repository named “MyCoolThing”, create “MyCoolThing_v2”
When creating REPO_v2, I’d recommend looking at the settings of REPO and copying the description.
I’m personally enabling the Issues and Wiki for all the new repositories. I am also NOT adding a README, because I do not want it to conflict with any existing code.
Clone both repos
Convert the hg to git
Now here’s an important part. If you have additional branches, you will have to bookmark each and every one.
Assuming hg bookmark -r source target
:
- source and target can not be the same
- do not include
origin/
in the target name
So if you have an hg branch named “IT-1” for example, you might consider doing something like hg bookmark -r IT-1 hg_IT-1
so that it’s obvious which branches were original.
Once you have bookmarked all your branches, nano .hg/hgrc
(or vi or whatever) and change the default
path entry.
Save that, then we do the conversion.
Gotcha
Out of the 29 repos I converted, there was 1 that was problematic. It had 9 years of history and had previously been through multiple VCS systems; which caused a few unsightly artifacts in things like tag names.
To resolve this, I used this at the command line to bookmark the branches:
I know it’s ugly. Here’s what it is doing:
hg heads | grep 'branch:'
Grabbing a list of branch namess/branch:[ ]*//g
Removing the word ‘branch: ‘s/^/\"/;s/$/\"/
Wrapping them in quotes so they count as 1 argumentp;s/ /_/g
Returning both the original name AND a copy with spaces replaced with underscoresxargs -n2
Passing both copies to hg bookmarkhg bookmark -r "$0" "hg_$1"
Which then prepends the ‘hg_’ to the one without spaces
Verify
You should see your code and any branches you created.
Verify in your REPO_v2 source online.
Wiki migration
The wiki migration follows the same pattern with one slight gotcha.
Remember how we chose to NOT include the README above? Well, you don’t have the option of not including the Home.md
in a default wiki.
Clone the repos
Note the ` wiki_v2` at the end of the git clone. Without that, the two will conflict.
Do the conversion
nano .hg/hgrc
and change the default
path entry.
Save that, then we do the conversion.
You may have to do some resolution here. For example, in some of my prior wikis, I had replaced Home.md
with Home.wiki
. To resolve this:
Whatever you do to resolve the conflicts on your wiki, make sure to re-bookmark before you push again.
Verify
You should see your prior wiki files.
Verify in your REPO_v2 wiki online.
Issues
Export old issues
- Go to https://bitbucket.org/YOURNAME/REPO/admin/issues/import-export
- Look under
Export Issues
- Click
Start Export
- When it is finished, download the zip file
Import the issues
- Go to https://bitbucket.org/YOURNAME/REPO_v2/admin/issues/import-export
- Look under
Export Issues
- Click
Choose File
and select your zip file. - Click
Start Import
. - The UI seems to hang before it is done; but you will get an email telling you that it is complete.
- Verify that the issues have been imported.
Cleanup
- On the top-left of REPO_v2, right-click on your project name and copy the link address
- Open https://bitbucket.org/YOURNAME/REPO/admin
- On the
Repository Details
page, scroll to the bottom - Click on
Delete Repository
- Paste in the link from REPO_v2. It should look like: https://bitbucket.org/YOUR_NAME/REPO_v2/
- Click
Delete
Repeat
Do the same process for each repository until there are no Mercurial repositories left.