Merge Request Quick Start Guide

This guide is meant for end-users of Heptapod, developers.

This is aimed at Mercurial beginners and veterans alike, so bear with the verbose instructions.

This guide will walk you through the creation of your first Merge Request on Heptapod. It will use lightweight "topic" branches to do so. You can read more details about this workflow here. It is also possible to use Mercurial's named branches to create Merge Requests, this is covered at the end.

Visit the to get the "why" behind this guide.

Getting set up

First, you need an account on your Heptapod instance with Developer rights or above on the project you are targeting. Projects can be setup to add a button to request permissions at the top of the page, if not, ask one of the maintainers to grant you that right.

We recommend you update your Mercurial install. Not only will you get a faster and more secure Mercurial, some bugs were fixed in recent versions that will make your experience with Heptapod more enjoyable!

Then, you will need to install the evolve and topic extensions. They both come within the same Python package. (Mercurial veterans used to named branch workflows: there is a section for you at the end)

Traditionally, it is installed via the Python package manager pip:

$ pip install --user hg-evolve

This package has no dependencies (not even Mercurial) and will not pollute your system-wide interpreter.


Be careful to install using the right version of pip. You may have installed Mercurial using Python 2 (pip2) or Python 3 (pip3). You can check with hg debuginstall.

If you already have it installed, please make sure it is also up-to-date. We need to add them to our config:

$ hg config -e  # to open global config, for repo config use -l

Add the following:

evolve =
topic =

You can check that they are installed by running hg version -v.

Basic contribution flow

Client-side work

Heptapod uses a topic-first workflow. We feel like it is the best workflow for Heptapod and that it should fit most projects just fine. You will come to enjoy it: if you don't, please tell us why!

Let's setup our repository:

$ hg clone <insert URL> super-repo  # you can get the URL on the repository homepage
$ cd super-repo

Now let's create a topic and start working:

$ hg topic my-super-topic
$ # ... make changes
$ hg commit -m "foobar"

Congratulations, you now have a topic with one changeset (other name for commit) in it! Let's check it out:

$ hg stack
### topic: my-super-topic
### target: default (branch)
s1@ foobar (current)
s0^ <the changeset from where your topic branch starts> (base)

The stack command gives you a linear view of your active topic and the base changeset (also called s0). If you add multiple changes to your topic, you will see them stack up with this command.

The hg log -G command will also show you the topic information, but within the usual graph.

(If you prefer to use named branch instead of topic, check named branch workflow)

Creating the MR

You need to have Developer rights on the target repository to push to it. Heptapod does not support personal forks for now (see the FAQ workflow section. for more information).

Let us push our changes to the repository:

$ hg push


You can also use hg push -r .. By default Mercurial pushes every head in your repository, and if you have many heads, you may want to be sure to only push your topic head.

You will normally be greeted with a link prompting you to create the MR related to your topic, it will not be created automatically on push. Of course, you can also create it directly from the web interface.

Warning: make sure that the target branch is the right one. It always defaults to... `default` for now.

Updating the MR

You have been asked some changes, the CI broke, or you just thought of something: you need to update your MR.

First, you should pull the latest changes with hg pull (for Git users: Mercurial's pull is like Git's fetch) to make sure your repo is up-to-date.

Make your changes, for example:

$ # Make a new change
$ hg commit

Then simply run hg push -r . to update your MR. The server will respond with a link to the MR, saying that it's been updated.

(If you prefer to update the existing commit instead of adding new ones, check rewriting history)

Merging the MR

From the Web UI

By clicking the "Merge" button on the GitLab web interface, you make all of the changesets in the associated topic public. They become immutable and stay part of their target branch forever.

Now that the changes have been merged in their target branch, they are part of the permanent history of the project. They moved to the "public" phase and Mercurial will prevent any further rewriting of this changeset. Additional changes can be done with new changesets in a new MR.

From Mercurial

You can "merge" your topic from Mercurial as well. At the tip of your topic:

$ hg push -r . --publish

Or in two separate steps if you prefer:

$ hg phase -r . --public
$ hg push -r .

Or, if you are on the target named branch:

$ hg merge my-super-topic  # automatically published on push

Again, be careful, this cannot be undone.

Useful Variants

Rewriting History

Sometimes updating a MR means rewriting parts of it to better reflect the functional changes to the project:

$ # Amend the current change
$ hg amend
$ # Amend and change the description
$ hg amend -e
$ # Fold (squash) part of your topic into a single change
$ hg fold -r s1::s3 --exact

Users from other version control systems might be surprised: there is no need for a --force push. The Changeset Evolution mechanism inside Mercurial and the evolve extension keeps track of the changes made to your history, no matter by whom or when, preventing the issues that arise from history-rewriting.


You might find the histedit, rebase and absorb extensions useful for more history-rewriting. Use hg help -e <name of extension> to get more information.


There was a bug in Mercurial < 5.3.2 that sometimes got local heads confused and refused a push. You can update to a later version to fix this. A workaround for previous versions is, ironically, to use the --force flag in this particular case: this is safe because the Heptapod server-side has strong checks against actually unsafe force-pushes, it is just to bypass the checks of your local Mercurial.

Using existing changes

Say you've already made the changes that will constitute your MR and you want to use those.

Make sure that you have the changesets you want to use:

$ hg log -r <hash1>::<hash2>

This X::Y notation is the (linear) range of changesets between the changesets X and Y.


It is called a "revset". Revsets are sets of revisions (or changesets) that use a Mercurial-specific query language. The most simple revset is ., which denotes the current revision (or current changeset). See hg help revset for more information.

Then set the topic for that range:

$ hg topic -r <hash1>::<hash2> my-super-topic

This command will add the targeted revisions to the topic, creating it if it does not already exist. (Note that only changesets of draft phase may have a topic.)

Then once again check that the topic contains the right changes:

$ hg stack

If you want to clear the topic of one or multiple changes, you can use hg topic -r <revset> --clear.

Named branch workflow

Disclaimer: The "named branch workflow" is not the workflow that we recommend new projects or users use. It is less powerful, flexible and forgiving than a topic-based workflow. We encourage you to at least give the topic-based workflow a try.

Heptapod is compatible with public-only named branches: only topic-less drafts are forbidden. You can even mix the two workflows if you like, maybe as a transition period.


If you feel like something is unclear or missing from this guide, please open an issue on the issue tracker.