The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 2,572 other followers

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.


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 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

  1. Install ssh, git, python, mercurial and hg-git
  2. Added hg-git to my mercurial configuration in ~/.hg-rc


  3. Uploaded my public ssh key to my BitBucket account (otherwise you get “Permission denied (publickey).” errors) and verified it worked:

    ssh -Tv

    Which would succeed

    logged in as jeroenp.
    You can use git or hg to connect to Bitbucket. Shell access is disabled.

  4. Cloned my mercurial repository into /tmp/conferences/conferences:

    hg clone /tmp/conferences/conferences.hg

  5. 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 ..

  6. Edited the users.txt file to map the old users to the new one.
  7. Ran the conversion

    hg convert --authors users.txt conferences.hg conferences.hg.sanitised

  8. Created an empty git repository
  9. Change the directory to /tmp/conferences/conferences.hg.sanitised
  10. Tried to push using hg-git:

    hg push git+ssh://

    Which would barf:

    pushing to git+ssh://
    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.

  11. Same with

    hg push git+ssh://

  12. Created a local git repository:

    git init /tmp/conferences/conferences.git

  13. Added that one to my ~/.hgrc

    gitbare = /tmp/conferences/conferences.git

  14. 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

  15. Searched for “abort: git remote error: refs/heads/master failed to update”
  16. Read about mercurial – hg-git push silently fails – Stack Overflow.
  17. removed the non-bare conferences.git tree:

    rm -rf /tmp/conferences/conferences.git

  18. Recreated a bare git repository:

    git init --bare /tmp/conferences/conferences.git.bare

  19. 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

  20. 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

  21. Pushed that non-bare repository to my new git repository at BitBucket:

    cd conferences.git
    git remote add origin.bitbucket
    git push -u origin.bitbucket --all
    git push -u origin.bitbucket --tags

  22. Pushed that non-bare repository to my new git repository at GitHub:

    git remote add origin.github
    git push -u origin.github --all
    git push -u origin.github --tags

  23. Decommissioned the Linux VM.
  24. Started using the GitHub repository from my regular machines.




Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: