Moving my BitBucket mercurial repository to git was a lot harder than I hoped for (but moving to GitHub was easy)
Posted by jpluimers on 2015/06/10
After reading Converting Hg repositories to Git directed me into reading Bitbucket: Converting Hg repositories to Git I hoped moving my Mercurial repository on BitBucket to a Git repository would be something like following the steps.
It wasn’t.
First of all, hg-git on a Windows system requires Python or TortoiseHg. Neither of these I wanted to install for a one-off conversion.
So I took a throw-away Linux VM, and did the steps below. But let me first explain why.
Motivation
My motivation for moving away from BitBucket to GitHub, especially for projects containing markdown documentation.
When writing documentation in Markdown, being able to in-line reference pictures or have relative-references to other documents. This works perfectly in local Markdown tools (like MarkdownPad 2 or LightPaper).
But they didn’t work at all on BitBucket for a long time, and they had no hurry to fix that: site / master / issues / #6589 – Markdown relative link to image and other readme does not work — Bitbucket even though it is part of the Markdown specification. In fact, they think it is a duplicate of readme file failures as it failed there too: site / master / issues / #6315 – Relative urls in readme.md files only work half the time. BB-7521 — Bitbucket. But it didn’t just fail in readme files: it failed everywhere on BitBucket.
They do work well on GitHub, they even have documentation in Relative links in READMEs · GitHub Help. and examples at Samples / Relative links | GitLab.
This makes people leave BitBucket for GitHub.
I wrote all this 9 months ago and moved not just because of this, but because there are too many issues being open for too long.
Steps to move a Mercurial/Hg repository on BitBucket to a Git repository on GitHub
- Install ssh, git, python, mercurial and hg-git
- Added hg-git to my mercurial configuration in ~/.hg-rc
[extensions]
hggit= - Uploaded my public ssh key to my BitBucket account (otherwise you get “Permission denied (publickey).” errors) and verified it worked:
ssh -Tv git@bitbucket.orgWhich would succeed
logged in as jeroenp.
You can use git or hg to connect to Bitbucket. Shell access is disabled. - Cloned my mercurial repository into
/tmp/conferences/conferences:
hg clone https://bitbucket.org/jeroenp/conferences.hg /tmp/conferences/conferences.hg - Sanitised the commit users. Note that the command line to get the user names should be this:
cd /tmp/conferences/conferences.hg
hg log | grep user: | sort | uniq | sed 's/user: *//' > ../users.txt
cd .. - Edited the users.txt file to map the old users to the new one.
- Ran the conversion
hg convert --authors users.txt conferences.hg conferences.hg.sanitised - Created an empty git repository https://bitbucket.org/jeroenp/conferences
- Change the directory to
/tmp/conferences/conferences.hg.sanitised - Tried to push using hg-git:
hg push git+ssh://bitbucket.org/jeroenp/conferencesWhich would barf:
pushing to git+ssh://bitbucket.org/jeroenp/conferences
exporting hg objects to git
creating and sending data
["git-receive-pack '/jeroenp/conferences'"]
Permission denied (publickey).
abort: git remote error: The remote server unexpectedly closed the connection. - Same with
hg push git+ssh://bitbucket.org:jeroenp/jeroenp/conferences - Created a local git repository:
git init /tmp/conferences/conferences.git - Added that one to my ~/.hgrc
[paths]
gitbare = /tmp/conferences/conferences.git - Tried to push to the local repository:
cd cd /tmp/conferences/conferences.hg.sanitised
hg push ../conferences.git
pushing to ../conferences.git
creating and sending data
abort: git remote error: refs/heads/master failed to update - Searched for “abort: git remote error: refs/heads/master failed to update”
- Read about mercurial – hg-git push silently fails – Stack Overflow.
- removed the non-bare conferences.git tree:
rm -rf /tmp/conferences/conferences.git - Recreated a bare git repository:
git init --bare /tmp/conferences/conferences.git.bare - From the sanitised conferences mercurial repository, pushed git to the local repository:
cd /tmp/conferences/conferences.hg.sanitised
hg push ../conferences.git.bare
pushing to ../conferences.git.bare
creating and sending data - Converted the bare repository to a non-bare one to circumvent the “fatal: This operation must be run in a work tree”:
cd /tmp/conferences
git clone conferences.git.bare conferences.git - Pushed that non-bare repository to my new git repository at BitBucket:
cd conferences.git
git remote add origin.bitbucket https://jeroenp@bitbucket.org/jeroenp/conferences.git
git push -u origin.bitbucket --all
git push -u origin.bitbucket --tags - Pushed that non-bare repository to my new git repository at GitHub:
git remote add origin.github https://jpluimers@github.com/jpluimers/Conferences.git
git push -u origin.github --all
git push -u origin.github --tags - Decommissioned the Linux VM.
- Started using the GitHub repository https://github.com/jpluimers/Conferences from my regular machines.
–jeroen
via:
- Converting Hg repositories to Git | Bitbucket Blog.
- Bitbucket: Converting Hg repositories to Git | Pseudo Random Bytes.
- Words in Boxes: Migrating repositories from Bitbucket to Github.






Leave a comment