Frequently Asked Questions

What is Heptapod license?

Same as GitLab Community Edition, for simplicity and to preserve the possibility to merge back.

Are you planning on contributing Heptapod features back to GitLab?

We (Octobus) would even be happy if GitLab would simply provide the Mercurial option in some future, as this is in line with our primary business being professional services around Mercurial.

That being said, this question in practice depends on where the Heptapod community wants to go once it's mature enough, and if there are clear benefits for GitLab upstream.

For the time being, our "friendly fork" status with respect to upstream GitLab is comfortable enough for us and GitLab upstream.

Is there an Enterprise Edition for Heptapod?

Currently no, but if you're interested, tell us, and we'll reach out to GitLab about that.

Does Heptapod support both Git and Mercurial?

No, but we'd love it to. If you want it sooner than later, vote for it via the general interest and support form.

Does Heptapod support evolve and topics?

Yes, one of the primary goals in launching the Heptapod project was to provide full native support for changeset evolution and topics-based workflows.

On the GitLab side of things (Web user interface, RESTful API), topics are exposed as "GitLab branches" with the following naming convention:


Here is an example from Heptapod's own development repository:

screenshot of Heptapod branch selector, showing some topics

Thanks to this, most GitLab features meant for Git branches translate transparently to topics. It is in particular perfectly standard to file Merge Requests for topics.

Does Heptapod support bookmarks?

By default, no.

With topics being the prominent way to provide short-lived feature branches with perceived mutability, we believe that it would be redundant and very error prone to simultaneously support bookmarks.

Also, supporting bookmarks alongside topics is a source of potential technical problems that we can't afford for the time being.

That being said, as of version 0.6.0, Heptapod will have some optional limited support for bookmarks, intended for cases where a whole Mercurial named branch is dedicated to tracking an external Git upstream with hg-git. In that case, upstream Git branches are translated to Mercurial bookmarks, and are readily visible under the same name in the GitLab interface.

To enable bookmarks on non-topic changesets, use the following HGRC server-side snippet:

hg-git.bookmarks-on-named-branches = yes
single-head-per-branch = no


Bookmarks on topics are forbidden in all cases. Pushing several bookmarks on a given branch has to be done with --force.

What are Heptapod's workflows and Mercurial flavour?

The short answer would be that it's adapted to the Merge Request process of GitLab, but let's elaborate a bit on top of that.

Mercurial is highly configurable and even customizable through extensions. This means that there are different ways of using it. Furthermore, because of its strong backwards compatibility promise over more that 10 years of development, the default settings aren't aligned with MR-centric workflows.

We especially want the picture to be simple for newcomers with little or even no prior Mercurial experience. This is effectively a subset of what's possible with Mercurial, that amounts to say that by default in Heptapod, starting from version 0.6.0:

  • named branches have public changesets only and are writeable only by the Master role members.
  • topics are writeable by all members of the Developer role and of course can be fully amended, rebased, etc.

More high-level explanations and motivations for this are given in the Octobus blog post

For experienced Mercurial users, we provide below detailed explanations for all settings that enforce these rules, with the relevant Heptapod version information.

One head per branch or topic

This has been true from Heptapod's inception.

Even if you force push, multiple heads on a given branch or branch/topic combination will be rejected by the server.

Multiple draft heads aren't needed when topics are available: just label them with topics, and you're set, you can do anything that you would have done with anonymous heads.

Functionally, multiple heads and especially multiple public heads have been a major source of confusion among users and have tremendous drawbacks for automatic processing, causing continuous integration systems to be stuck at the point before the ramification or building the wrong revision.

From Heptapod 0.6.0 onwards, there won't be any technical limitation to accept multiple heads. We still advise strongly against them, and it should be done in special cases only. The only valid use-case we can think of are related to importing repositories from other hostings systems:

  • older repositories often have some old multiple heads lurking around, especially in closed branches, and it can be cumbersome or hard to understand why they should be merged and closed. Heptapod's import features will therefore lift that restriction temporarily.
  • if an import has to be done by direct pushes because other means can't work in that precise case, an incremental approach is usually necessary because of various timeouts (see issue heptapod#25 for more details). Arbitrary selection of successive points in history tends to produce multiple heads even if the whole repository hasn't any.

To allow multiple heads, use the following HGRC server-side snippet:

single-head-per-branch = no

Publishing is restricted to project masters

Starting with Heptapod 0.6.0, only project Masters are permitted to push a public changeset or the promotion a changeset to the public phase.

This is an important design choice, and it is related to the fact that we don't support personal forks yet. Indeed, without personal forks, one must assign Developer roles to all contributors on the main project, so that they can push their changes for review. Without the publishing permission, this would mean that all contributors would gain inconditional rights to push anything with their Mercurial client.


For consistency between the Web UI (or RESTful API) and what is allowed with a hg push, at the time of this writing, it is necessary to use GitLab's protected branch feature, and to declare explicitely that branch/* is protected on all projects. We hope to make it automatic for the 0.6.0 release.

If you still want to lift this permission restriction, you may disable the check_publish hook, with the following HGRC server-side snippet:


Heptapod is auto-publishing except for topics

Also starting with Heptapod 0.6.0, this goes with the restriction of the publication permission: all non-topic changesets are published automatically by Heptapod.

This means in particular that only repository Masters can actually push a non topic changeset.

To switch to a full non publishing behaviour, use the following HGRC server-side snippet:

publish-bare-branch = no

Before Heptapod 0.6.0, all repos were non publishing: all draft changesets pushed to Heptapod would have stayed drafts.

This finishes the set of features that leave us in a quite simple state with respect to named branches, topics and phases.

Does Heptapod have personal forks ?

Not for the time being, but we need them less than in regular GitLab.

In practice, not having forks means that all contributors to a project have to be granted the right to push topics to its main repository. In Heptapod, this is the Developer role, which does not have the right to push to named branches by default.

We are thinking about supporting personal forks, but we want to do it the right way, so that the chosen solution is transparent for users, and robust enough to serve us in the long run.

How can one change the settings of a server-side repository ?

As of this writing we don't have a proper Web User Interface for that, but Heptapod systems administrators can do it in the container directly.

Needed actions

  1. Edit the appropriate HGRC files in the instance (see Mercurial configuration files below). Currently, that means either using vi under docker exec or directly within the Docker volume if that makes sense to you.

  2. Reload the configuration of the hgserve service:

    docker exec -t CONTAINER_NAME gitlab-ctl hup hgserve

    If in doubt whether the changes have been applied, you may also restart the whole container, but that causes a few minutes of downtime.

    You can watch the hgserve workers restarting in /var/log/gitlab/hgserve/gunicorn.log.

Mercurial configuration files


all paths below are within the Docker container, and directly usable through docker exec.

The settings of Heptapod Mercurial repositories rely on the standard HGRC system, and have been cut in several parts by a cascade of %include directives.

  • /etc/gitlab/heptapod.hgrc: these are the global settings that apply to all Heptapod repositories. This is where you would, e.g., fine tune the Mercurial logging, and in particular set the Sentry DSN. This file is initialized with instructions on how to safely edit it.
  • /var/opt/gitlab/git-data/repositories/GROUP[/SUBGROUP]/PROJECT.hg/.hg/hgrc: specific settings for the given project. If you want to change them, be extra careful not to interfere with the necessary inclusion of the global settings and mirror-path in the heptapod section.

Does Heptapod use Git under the hood?

Yes, as a temporary implementation detail, going only from the server-side Mercurial repository to an inner Git repository; there is no back conversion to Mercurial.

The Mercurial client interacts with a regular Mercurial repository on the server side, which itself pushes under the hood to a Git repository through a customized version of hg-git.

The only purpose of the Git repository is to be a read-only convenience mirror for other GitLab components, including the Git hooks that GitLab uses internally to get notified of new commits and perform subsequent actions (closing a Merge Request, launching the CI…).

Because there is no back conversion, all writes initiated from GitLab (e.g. merging a Merge Request from the web user interface) actually perform regular Mercurial commands on the server-side Mercurial repository. This guarantees that Heptapod behaves like a regular Mercurial server.

This mirror Git repository trick helped keeping the size of our diff from regular GitLab to a minimum and get to a working prototype very quickly, but it has many drawbacks, including performance and scalability.

During the current post-prototype, yet experimental phase, we intend to gradually get rid of it.