Overview. This extension adds the ability to work on a Git repository from Mercurial. It also allows using a Git server as a collaboration point for a team with developers using both Git and Mercurial. At the same time, it can also be used to interact with a Mercurial repository using Git.
Most Subversion users are used to having to figure that out manually, which is an error prone and time consuming process – Git makes it trivial. Furthermore, you can merge from the same branch multiple times and not have to resolve the same conflicts over and over again.
There are many tools such as svn2git available to perform the migration, in this tutorial we will focus on git-svn utility: a Git extension , which can be used to check out a Subversion repository to a local Git repository and then push changes from the local Git repository back to the Subversion repository.
You can try using fast-export:
cd ~
git clone https://github.com/frej/fast-export.git
git init git_repo
cd git_repo
~/fast-export/hg-fast-export.sh -r /path/to/old/mercurial_repo
git checkout HEAD
Also have a look at this SO question.
If you're using Mercurial version below 4.6, adrihanu got your back:
As he stated in his comment: "In case you use Mercurial < 4.6 and you got "revsymbol not found" error. You need to update your Mercurial or downgrade fast-export by running git checkout tags/v180317 inside ~/fast-export directory.".
Ok I finally worked this out. This is using TortoiseHg on Windows. If you're not using that you can do it on the command line.
hggit
:Open a command line, enter an empty directory.
git init --bare .git
(If you don't use a bare repo you'll get an error like abort: git remote error: refs/heads/master failed to update
cd
to your Mercurial repository.
hg bookmarks hg
hg push c:/path/to/your/git/repo
In the Git directory: git config --bool core.bare false
(Don't ask me why. Something about "work trees". Git is seriously unfriendly. I swear writing the actual code is easier than using Git.)
Hopefully it will work and then you can push from that new git repo to a non-bare one.
If you want to import your existing mercurial repository into a 'GitHub' repository, you can now simply use GitHub Importer available here [Login required]. No more messing around with fast-export etc. (although its a very good tool)
You will get all your commits, branches and tags intact. One more cool thing is that you can change the author's email-id as well. Check out below screenshots:
Some notes of my experience converting Mercurial to Git.
Using hg-fast-export failed and I needed --force as noted above. Next I got this error:
error: cannot lock ref 'refs/heads/stable': 'refs/heads/stable/sub-branch-name' exists; cannot create 'refs/heads/stable'
Upon completion of the hg-fast-export I ended up with an amputated repo. I think that this repo had a good few orphaned branches and that hg-fast-export needs a somewhat idealised repo. This all seemed a bit rough around the edges, so I moved on to Kiln Harmony (http://blog.fogcreek.com/announcing-kiln-harmony-the-future-of-dvcs/)
Kiln Harmony does not appear to exist on a free tier account as suggested above. I could choose between Git-only and Mercurial-only repos and there is no option to switch. I raised a support ticket and will share the result if they reply.
The Hg-Git mercurial plugin (http://hg-git.github.io/) did work for me. FYI on Mac OSX I installed hg-git via macports as follows:
.hgrc needs these lines:
[ui]
username = Name Surname <[email protected]>
[extensions]
hgext.bookmarks =
hggit =
I then had success with:
hg push git+ssh://[email protected]:myaccount/myrepo.git
All the above are blunt instruments and I only pushed ahead because it took enough time to get the team to use git properly.
Upon first pushing the project per (3) I ended up with all new changes missing. This is because this line of code must be viewed as a guide only:
$ hg bookmark -r default master # make a bookmark of master for default, so a ref gets created
The theory is that the default branch can be deemed to be master when pushing to git, and in my case I inherited a repo where they used 'stable' as the equivalent of master. Moreover, I also discovered that the tip of the repo was a hotfix not yet merged with the 'stable' branch.
Without properly understanding both Mercurial and the repo to be converted, you are probably better off not doing the conversion.
I did the following in order to get the repo ready for a second conversion attempt:
hg update -C stable
hg merge stable/hotfix-feature
hg ci -m "Merge with stable branch"
hg push git+ssh://[email protected]:myaccount/myrepo.git
After this I had a verifiably equivalent project in git, however all the orphaned branches I mentioned earlier are gone. I don't think that is too serious, but I may well live to regret this as an oversight. Therefore my final thought is to keep the original anyway.
Edit: If you just want the latest commit in git, this is simpler than the above merge:
hg book -r tip master
hg push git+ssh://[email protected]:myaccount/myrepo.git
I had a similar task to do, but it contained some aspects that were not sufficiently covered by the other answers here:
I did not try fast-export and hg-fast-export, since they require that you have Python and some Mercurial Python modules on your machine, which I didn't have.
I did try hg-init with TortoiseHG, and this answer gave me a good start. But it looked like it only converts the current branch, not all at once (*). So I read the hg-init docs and this blog post and added
[git]
branch_bookmark_suffix=_bookmark
to my mercurial.ini, and did
hg bookmarks -r default master
hg bookmarks -r my_branch my_branch_bookmark
hg gexport
(Repeat the 2nd line for every branch you want to convert, and repeat it again if you should happen to do another commit before executing the 3rd line). This creates a folder git
within .hg
, which turns out to be a bare Git repo with all the exported branches. I could clone this repo and had a working copy as desired.
Or almost...
Running
git status
on my working copy showed all files with non-ASCII characters in their names as untracked files. So I continued researching and followed this advice:
git rm -rf --cached \*
git add --all
git commit
And finally the repo was ready to be pushed up to Bitbucket :-)
I also tried the Github importer as mentioned in this answer. I used Bitbucket as the source system, and Github did quite a good job, i.e. it converted all branches automatically. However, it showed '?'-characters for all non-ASCII characters in my commit messages (Web-UI and locally) and filenames (Web-UI only), and while I could fix the filenames as described above, I had no idea what to do with the commit messages, and so I'd prefer the hg-init approach. Without the encoding issue the Github importer would have been a perfect and fast solution (as long as you have a paid Github account or can tolerate that your repo is public for as long as it takes to pull it from Github to your local machine).
(*) So it looked like before I discovered that I have to bookmark all the branches I want to export. If you do and push to a bare (!) repo, like the linked answer says, you get all the branches.
From:
http://hivelogic.com/articles/converting-from-mercurial-to-git
Migrating
It’s a relatively simple process. First we download fast-export (the best way is via its Git repository, which I’ll clone right to the desktop), then we create a new git repository, perform the migration, and check out the HEAD. On the command line, it goes like this:
cd ~/Desktop
git clone git://repo.or.cz/fast-export.git
git init git_repo
cd git_repo
~/Desktop/fast-export/hg-fast-export.sh -r /path/to/old/mercurial_repo
git checkout HEAD
You should see a long listing of commits fly by as your project is migrated after running fast-export. If you see errors, they are likely related to an improperly specified Python path (see the note above and customize for your system).
That’s it, you’re done.
Another option is to create a free Kiln account -- kiln round trips between git and hg with 100% metadata retention, so you can use it for a one time convert or use it to access a repository using whichever client you prefer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With