git remote helper to interact with mercurial repositories
Python C Makefile
Latest commit 193455f Feb 18, 2017 @glandium Add refspec for hg/* refs used by `git cinnabar fetch`
This fixes a regression from 990458d.
Failed to load latest commit information.
cinnabar Add refspec for hg/* refs used by `git cinnabar fetch` Feb 18, 2017
git-core @ 3b9e3c2 Update git-core to v2.11.1 Feb 9, 2017
.appveyor.yml Add a git cinnabar command to download the helper, and use it on CI Nov 25, 2016
.gitignore move and ignore git-cinnabar-helper, so it doesn't appear to be untra… Oct 31, 2016
.gitmodules Add a submodule for the git repository Feb 12, 2015
.travis.yml Allow graft to work with git version < 1.9 Dec 30, 2016 CI: Make compatible with old versions of mercurial Jun 30, 2016 [CI] Fixup the changes from d461491 to actually check something real Jan 1, 2017
COPYING Initial prototype Dec 5, 2014 Update git-core to v2.11.1 Feb 9, 2017
Makefile Automatically initialize the submodule when running `make` Nov 25, 2016 Update helper build instructions in README Nov 25, 2016
cinnabar-fast-import.c Update git-core to v2.11.1 Feb 9, 2017
cinnabar-helper.c Allow more fine-grained versioning of the helper Dec 20, 2016
configure Run autoconf before running configure Nov 9, 2016
connect.c helper: Initial (experimental and incomplete) support for mercurial w… May 8, 2016
git-cinnabar Fixup badly placed import Dec 31, 2016
git-remote-hg Use LazyCall instead of the last uses of LazyString for logging Apr 18, 2016
hg-bundle.c helper: Support bundle2 responses to bundle2 pushes Aug 5, 2016
hg-bundle.h helper: Support bundle2 responses to bundle2 pushes Aug 5, 2016
hg-connect-http.c helper: Use HTTP headers for wire protocol command arguments when all… Jul 24, 2016
hg-connect-internal.h helper: Initial (experimental and incomplete) support for mercurial w… May 8, 2016
hg-connect-stdio.c helper: Support bundle2 responses to bundle2 pushes Aug 5, 2016
hg-connect.c Update git-core to v2.11.0 Nov 30, 2016
hg-connect.h helper: Add support for the lookup command Jul 25, 2016

git-cinnabar 0.4

When you update, please read this file again, it may contain important notes.

cinnabar is the common natural form in which mercury can be found on Earth. It contains mercury sulfide and its powder is used to make the vermillion pigment.

git-cinnabar is a git remote helper to interact with mercurial repositories. Contrary to other such helpers*, it doesn't use a local mercurial clone under the hood, although it currently does require mercurial to be installed for some of its libraries.

* This applies to the following tools:

The main focus at the moment is to make it work with mozilla-central and related mercurial repositories and support Mozilla workflows (try server, etc.).

Repositories last used with versions lower than 0.3.0 are not supported. Please run git cinnabar fsck with version 0.3.0 first.


  • Git version 1.8.5 or newer
  • Mercurial version 1.9 or newer


  • Add this directory to your PATH. If you have another git-remote-hg project in your PATH already, make sure the git-cinnabar path comes before.

A native helper can be used for faster operations. You can download a prebuilt binary with the following command (assuming one is available for your system):

  $ git cinnabar download

Alternatively, you can do the following to build it:

  $ make helper

Or see git-core/INSTALL after initializing the submodule, for build/install instructions, but run the commands in this directory. This will build/install git as well as the tools from this directory. Note that if you have a non-standard Python installation location (for example if you are on macOS and have installed it using homebrew) you need to pass --with-python=/path/to/python to the configure script or set the PYTHON_PATH environment variable to your Python installation path when using make to build this tool.


$ git clone hg::<mercurial repo>

where <mercurial repo> can be a path to a local directory containing a mercurial repository, or a http, https or ssh url.

Essentially, use git like you would for a git repository, but use a hg:: url where you would use a git:// url.

Mercurial bookmarks are exposed as refs/heads/bookmarks/$bookmark remote refs. If you want to interact exclusively with mercurial with bookmarks, you can use a refspec like refs/heads/bookmarks/*:refs/remotes/$remote/*.

Mercurial branches are exposed as namespaces under refs/heads/branches/. As mercurial branches can have multiple heads, each head is exposed as refs/heads/branches/$branch/$head, where $head is the mercurial sha1 of the head changeset. There is however an exception to that pattern, for the tip changeset of the branch, which is exposed as refs/heads/branches/$branch/tip. If you only care about the tip changeset of each branch, you can use a refspec like refs/heads/branches/*/tip:ref/remotes/$remote/*.

See for an example workflow for Mozilla repositories.

Translating git commits to mercurial changesets and vice-versa:

When dealing with a remote repository that doesn't use the same identifiers, things can easily get complicated. Git-cinnabar comes with commands to know the mercurial changeset a git commit represents and the other way around.

The following command will give you the git commit corresponding to the given mercurial changeset sha1:

$ git cinnabar hg2git <changeset>

The following command will give you the mercurial changeset corresponding to the given git commit sha1:

$ git cinnabar git2hg <commit>

Both commands allow abbreviated forms, as long as they are unambiguous (no need for all the 40 hex digits of the sha1).

Avoiding metadata:

In some cases, it is not desirable to have git-cinnabar create metadata for all pushed commits. Notably, for volatile commits such as those used on the Mozilla try repository.

By default, git-cinnabar doesn't store metadata when pushing to non-publishing repositories. It does otherwise.

This behavior can be changed per-remote with a remote.$remote.cinnabar-data preference with one of the following values:

  • always
  • never
  • phase

phase is the default described above. always and never are self-explanatory.


At the moment, push is limited to non-merge commits.

There is no support for the following mercurial features:

  • obsolescence markers
  • phases
  • namespaces

Checking corruptions:

Git-cinnabar is still in early infancy, and its metadata might get corrupted for some reason.

The following command allows to detect various types of metadata corruption:

git cinnabar fsck

This command will fix the corruptions it can, as well as adjust some of the metadata that contains items that became unnecessary in newer versions.

The --manifests and --files options may be added for additional validation on manifests and files. Using either or both adds a significant amount of work, and the command can take more than half an hour on repositories the size of mozilla-central.

hg:// urls:

The msys shell (not msys2) doesn't keep hg::url intact when crossing the msys/native boundary, so when running cinnabar in a msys shell with a native git, the url is munged as hg;;proto;\host\path\, which git doesn't understand and doesn't even start redirecting to git-remote-hg.

To allow such setups to still work, hg:// urls are supported. But since mercurial can be either on many different protocols, we abuse the port in the given url to pass the protocol.

A hg:// url thus looks like:


The default protocol is https, and the port can be omitted.

  • hg::



  • hg::



  • hg::ssh://



  • hg::file:///some/path

    becomes (awkward)


  • hg::http://localhost:8080/foo