Heptapod's default workflow

Pierre-Yves David
2019-09-04

Why having a clear default workflow is important?

When we started working on Heptapod, our version of Gitlab with support for the Mercurial version control, an important question arose: What should be the recommended workflow?

Great versatility and extensibility are two of Mercurial strengths. Howerever these properties also have their drawbacks, as different groups of users might end up using the tool in quite different ways, hence forcing collaboration platforms to deal with many variants.

Selecting one standard workflow for Heptapod is important to avoid these traps. Having one, unified and smooth, way to interact with Heptapod makes such platform much more powerful and is much more comfortable to users.

Furthermore, selecting one default workflow means we can optimize the default user experience towards it. This helps us to offer the best to people sticking to that workflow.

However, selecting a default workflow and optimizing for it does not mean blocking all other alternatives. It is possible to configure Heptapod to unlock other behaviors if users want to.

What needs should this workflow meet?

We want a workflow that:

  • stick to Mercurial core concepts and empower them as much as possible,
  • fit the popular Merge Request system of GitLab,
  • keep changesets as first class citizens,
  • accomodate both simple usecase and more advanced usage in a smooth way,
  • in particular, smoothly compatible with Mercurial history editing capability.

What choices did we make ?

To accommodate these goals, we made a handful of choices in the default Heptapod configuration and user experience:

  • Server side, Each name (eg: named branches) cannot have multiple heads.

  • The branching model uses named branches and topics. Long lived branches are based on named branches, feature branches are based on topic-branches,

  • Phase movements use a simple scheme based on the branching model: changesets get published upon pushes unless they have a topic

  • Support for changeset evolution is enabled by default.

  • Bookmarks aren't allowed by default.

What do these choices means

Using a single head per name

While having multiple heads locally offers a great flexibility, it gets confusing for users and tooling when a name points to ambiguous content. Users might learn to work around it but tooling usually can't. To address this, Heptapod server will only accept a single head per named branch. This also applies to topics too, each topic will need to have a single head server side.

To give an example: Having one single head for each branches and topics means the Merge Request logic can be driven by these names without fear of ambiguity or sudden/drastic changes in their meaning.

To accommodate older repositories or different workflow, this constraint can be lifted through configuration. However this might prevent the use of some features of Heptapod on those branches.

More details in our FAQ

Branching model and mutability

We decided to use named branches and topics for our branching model as both fit well in the general philosophy of Mercurial.

In Heptapod, named branches are meant to be used for long term branches, their content is immutable and they come with all the clarity and advantage of what they usually provide. However, named branch are not ideal for short lived feature branches, so we decided to use topics for that. Topics are very similar to named branches but are designed for a shorter and automatic life cycle.

Each changeset can be assigned a topic in addition to its named branch. All changesets within this topic will make a small feature branch that Heptapod will use for Merge Request. However, once the Merge Request gets merged, the changesets move to the public phase, the topic "fades away" and gets fully integrated to its target named branch. This lightweight life cycle is appealing: opening and closing Merge Requests comes at a very low overhead and won't leave unwelcome long term marks in the history.

In addition, since all changesets are explicitly in a topic, the content of each feature branches is clearly defined for both Heptapod, server side and the user locally. This was an important criteria for us.

The strong link between Heptapod Merge Request workflow and Mercurial concept works both way. Users can decide to locally publish a feature branch and Heptapod will be able to acknowledge the operation once pushed.

Users can also decide to use named branches only. The Merge Request system fully supports a branch to branch workflow.

Mutability and evolution

An important choice we made was to enforce everything outside of topics to be public. This comes with various advantages.

First, it provides backward compatibility with how Mercurial has been working for many years. People using default Mercurial configuration before going to Heptapod, without topic, will keep the same behavior. Whatever they push will move to the public space. However it makes it easy for them (even a subset of them) to exchange draft feature branches, by simply start using topic for it. This way, instead of having to deal with the combination of multiple dimensions (branch type + mutability), the different concepts align to expose a clear boundary and behavior: feature branch are mutable, long term branch are not.

Second, having the phase movements deeply integrated with the general workflow comes with an additional benefit. The amount of draft changesets gets naturally controled since they need to get public to reach the main branches. In such context, enabling changesets evolution for everybody seems like a sane default. The topic space keeps on being mutable and can be amended and rebased, while the named branch space provides strong immutability guarantees and will need explicit merge changesets to integrate content from one branch to another.

(Of course, users can also change their instance configuration to whatever publication mode they want to)

No bookmark by default

The branching model and its integration to GitLab Merge Request is based exclusively on branches and topic, we do not support bookmarks yet. Bookmarks have a long history of being less well integrated with other Mercurial concepts and still have some issues. We believe that branches and topics cover enough use cases to avoid dealing with an extra concept here, especially since it could be a source of technical issues.

Still, we might gradually improve bookmarks support in Heptapod as time passes, depending on what kind of needs people express. The most probable first step would be limited support for bookmarks whilst providing a mirror of an external Git source repository.