Git interoperability with a Mercurial Repository

GitVersion ControlMercurialInteropDvcs

Git Problem Overview


I use GIT on a Mac. Enough said. I have the tools, I have the experience. And I want to continue to use it. No wars here...

The problem is always with interoperability. Most people use SVN, which is great for me. Git SVN works out of the box, and is a no frills solution. People can continue happily use SVN and I don't lose my workflow and neither my tools.

Now... Some guys come along with Mercurial. Fine for them: they have their reasons. But I can't find any GIT HG out-of-the-box. I don't want to switch to HG, but I still need to interoperate with their repository.

Any of you guys know a simple solution for this?

Git Solutions


Solution 1 - Git

There's a new git-remote-hg that provides native support:

Bridge support in Git for Mercurial and Bazaar

Just copy git-remote-hg to your $PATH, make it executable, and that's it, no dependencies (other than Mercurial):

git clone hg::https://www.mercurial-scm.org/repo/hg/

You should be able to push and pull from it as if it was a native Git repository.

When you push new Git branches, Mercurial bookmarks will be created for them.

See the git-remote-hg wiki for more information.

Solution 2 - Git

You should be able to use hg-git.

hg clone <hg repository>

edit ~/.hgrc and add :

[extensions]
hgext.bookmarks =
hggit =

create a bookmark so you will have a master in git :

cd <repository>
hg bookmark -r default master

edit .hg/hgrc in the repository and add :

[git]
intree = true

now you can create the git repository :

hg gexport

and you can use the resulting directory as a git clone. pulling from mercurial would be :

hg pull
hg gexport

and pushing to mercurial :

hg gimport
hg push

(Yes, you need to use hg with this workflow but your hacking will be all in git)

P.S. If you have a problem with this workflow, please file a bug.

Solution 3 - Git

Update from June 2012. Currently there seem to be the following methods for Git/Hg interoperability when the developer wants to work from the git side:

  1. Install Mercurial and the hg-git extension. You can do the latter using your package manager, or with easy_install hg-git. Then make sure the following is in your ~/.hgrc:

    [extensions]
    hggit = 
    

You may see some references that talk about specifying the bookmarks extension here too, but that has been built into Mercurial since v 1.8. Here are some tips about installing hg-git on Windows.

Once you have hg-git, you can use commands roughly like Abderrahim Kitouni posted above. This method has been refined and tweaked since 2009 though, and there is a friendly wrapper: git-hg-again. This uses the toplevel directory as a working directory for both Mercurial and Git at the same time. It creates a Mercurial bookmark that it keeps in synch with the tip of the default (unnamed) branch in the Mercurial repository, and it updates a local Git branch from that bookmark.

  1. git-remote-hg is a different wrapper, also based on the Mercurial hg-git extension. This additionally makes use of the git-remote-helpers protocols (hence its name). It uses the toplevel directory only for a Git working directory; it keeps its Mercurial repository bare. It also maintains a second bare Git repository to make synching between Git and Mercurial safer and more idiomatically gitlike.

  2. The git-hg script (formerly maintained here) uses a different method, based on hg-fast-export from the fast-export project. Like method 2, this also keeps a bare Mercurial repository and an additional bare Git repository.

For pulling, this tool ignores Mercurial bookmarks and instead imports every named Mercurial branch into a Git branch, and the default (unnamed) Mercurial branch into master.

Some commentary discusses this tool as being hg->git only, but it claims to have merged in git->hg push support on 7 Dec 2011. As I explain in a review of these tools, though, the way this tool tries to implement push support doesn't seem to be workable.

  1. There's also another project called git-remote-hg. Unlike the version listed above, this one doesn't rely on hg-git, but instead directly accesses the Mercurial Python API. At the moment, using it also requires a patched version of git. I haven't tried this yet.

  2. Finally, Tailor is a project that incrementally converts between a variety of different VCSs. It sounds like development of this won't be aggressively continued.

The first three of these approaches looked lightweight enough to persuade me to investigate. I needed to tweak them in some ways to get them to run on my setup, and I saw some ways to tweak them further to improve them, and then I tweaked them still further to make them behave more like each other so that I could evaluate them more effectively. Then I thought others might like to have these tweaks too, to do the same evaluation. So I've made a source package that will enable you to install my versions of any of the first three tools. It should also take care of installing the needed hg-fast-export pieces. (You need to install hg-git on your own.)

I encourage you to try them out and decide for yourself what works best. I'll be glad to hear about cases where these tools break. I'll try to keep them in synch with upstream changes, and to make sure the upstream authors are aware of the tweaks I think are useful.

As I mentioned above, in evaluating these tools, I came to the conclusion that git-hg is only usable for pulling from Mercurial, not for pushing.

Relatedly, here are some useful comparisons/translation manuals between Git and Mercurial, in some cases targetted at users who already know Git:

Solution 4 - Git

You can try hg2git, which is python script and is part of fast-export, which you can find at http://repo.or.cz/w/fast-export.git .

You'll need to have mercurial installed though.

Solution 5 - Git

Since hg-git is a two-way bridge, it will also allow you to push changesets from Git to Mercurial.

Solution 6 - Git

Hg-Git Mercurial Plugin. Haven't tried it myself, but might be worth checking out.

Solution 7 - Git

I have had great success with git-hg from https://github.com/cosmin/git-hg (requires working install of hg, too). It supports fetch, pull and push and is more stable for me than hg-git (similar features from hg to git).

See https://github.com/cosmin/git-hg#usage for usage examples. The user interface is very similar to git-svn.

The git-hg requires extra disk space for each cloned hg repo. The implementation uses full mercurial clone, an extra git bare clone and the actual git repo. The required disk space is roughly 3 times the normal git only usage. The extra copies are stored below the .git directory of your working directory (or location pointed by GIT_DIR as usual).

Notice: The basic problem that git-hg tries to solve is that there is no 1:1 mapping between git and hg features. The biggest problem is the impedance mismatch between git branches and hg unnamed branches and hg named branches and hg bookmarks (all of those look a lot like branches to git users). A related problem is that hg tries to save original named branch name in the version history as opposed to git where the branch name is only added to template commit message by default.

Any tool that claims to create interoperable bridge between git and hg should explain how it's going to deal with this impedance match. You can then decide if the selected solution fits your needs.

The solution that git-hg uses is to discard all hg bookmarks and convert named branches to git branches. In addition it sets the git master branch to default unnamed hg branch.

Solution 8 - Git

Have tried hggit. Works for me, since I have to cope the work of git'ers and hg'ers. Especially for reviews this is great.

A minor issue/warning on that topic:

I have tried to clone a stable linux kernel repository with hg. These repositories are maintained in git and typically have a large number of files in it.

It was very slow. Took me 2 days to fully clone and update a working copy.

Solution 9 - Git

I have tried cosmin's git-hg and abourget's git-hg-again both on mutt's hg repo, it seems that the later respects the order of a merge well, the former is a bit random. You can see from the screenshots below.

A merge history graph of mutt imported by cosmin's git-hg:

enter image description here

A merge history graph of mutt imported by abourget's git-hg-again:

enter image description here

The actuall history graph plotted by hgk on mutt's hg repository:

enter image description here

As you can see from the above, the second graph by abourget's git-hg-again is very close to the original hgk graph and is actually reflecting the real workflow of the mutt.

One drawback of git-hg-again I found is that it does not add a 'hg' remote, rather imports all its refs as local tags, git-hg has a wonderful 'hg' remote represents the upstream hg repo.

Solution 10 - Git

The up-to-date answer in 2021 seems to be git cinnabar, which is used e.g. by Firefox.

Other scripts suggested on this page are either unmaintained or require outdated software to run (typically python 2.7). By contrast, cinnabar works with python 3.5+ and is maintained until the date of writing at least.

Once cinnabar installed, you can either clone mercurial repositories directly by prefixing with hg:::

git clone hg::https://hg.mozilla.org/mozilla-unified

Or add or set a remote to

git remote set-url origin hg::https://hg.mozilla.org/mozilla-unified
git fetch origin

You can push to mercurial remotes.

Using hg2git and git2hg commands allow to translate git commit sha1s to mercurial changeset and back. More docs available on the github page.

Solution 11 - Git

Two-way hg-git (and git-git, hg-hg) sync is also possible with the service Git-hg Mirror. It uses hg-git (among others) behind the scenes and its code is also open source.


Disclaimer: I'm from the company behind it.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHugo Sereno FerreiraView Question on Stackoverflow
Solution 1 - GitFelipeCView Answer on Stackoverflow
Solution 2 - GitAbderrahim KitouniView Answer on Stackoverflow
Solution 3 - GitdubiousjimView Answer on Stackoverflow
Solution 4 - GitsykoraView Answer on Stackoverflow
Solution 5 - GitMartin GeislerView Answer on Stackoverflow
Solution 6 - GitralphtheninjaView Answer on Stackoverflow
Solution 7 - GitMikko RantalainenView Answer on Stackoverflow
Solution 8 - GitWizzView Answer on Stackoverflow
Solution 9 - GitweynhamzView Answer on Stackoverflow
Solution 10 - GitCimbaliView Answer on Stackoverflow
Solution 11 - GitPiedoneView Answer on Stackoverflow