published on
by
tags: Mercurial

Mercurial at Orus.io

At orus.io, mercurial is our DVCS of predilection.

This post is a practical guide for using mercurial on our repositories.

Installation

Use a recent version

Because we use cutting edge extensions, you need a not too old version of mercurial, preferably >= 4.0.

For Ubuntu LTS users, the Mercurial PPA provides what we need:

$ sudo add-apt-repository ppa:mercurial-ppa/releases
$ sudo apt-get update

If no package source suits your distro, you can install it with pip (be careful, mercurial runs on python 2):

$ pip2 install mercurial

Get the extensions

We use 2 powerful extensions that are not (yet) included in the default package:

These 2 extensions are bundled in the hg-evolve package.

To install it, use pip (make sure to use python 2):

$ pip2 install --user hg-evolve

Then activate them in your ~/.hgrc:

[extensions]
evolve =
topic =

Configure

In your .hgrc, make sure you activate a few builtin extensions:

[extensions]
histedit = 
rebase = 
pager =   # not needed with mercurial >= 4.2
color =   # not needed with mercurial >= 4.2

They are not mandatory but will make your life easier.

Also, to make topics and evolve easier to work with, the following options are recommanded:

[experimental]
graph-group-branches = True
graph-group-branches.firstbranch = .
thg.displaynames = topics
verbose-obsolescence-exchange = 1
enforce-topic = True

[color]
mode = terminfo
log.topic = blue_background white
log.draft = blue_background black

The workflow

Start a feature branch

When working on a new feature, checkout the default head, and start a new topic:

$ hg checkout default
$ hg topic my-topic-name

The topic name should make it easy for others to identify what you are working on.

From this point, all the commits will embed the current topic on the changesets, until you checkout a different topic (or any topic-less branch head).

Rebase a topic

If the default branch grew while you worked on your topic, you simply have to rebase it (which requires the rebase extension):

$ hg checkout my-topic-name
$ hg rebase

Mercurial will automatically rebase the entire topic on the original branch head.

Publish a topic

Once a topic is ready for merge (the readiness depends on the project, but it generally means it has been reviewed, possibly inside a PR), someone will need to publish it.

This operation will make the changesets of the topic public, meaning they cannot be rebased or amended anymore, and that the topic flag will be hidden (note: it is still in the changeset).

We generally do this after rebasing the topic, which removes the need for a merge changeset.

Here is how it generally goes:

$ hg checkout my-topic-name
$ hg rebase
# run the tests
$ hg push
# see if CI is happy
$ hg phase -p .

At some point in my ideally shaped future, I expect the publication to be done by the CI.

Useful commands

Sometimes we need to jump to the previous or next changeset in line. Instead of looking for its id, the ‘evolve’ extension provides the commands:

  • hg prev
  • hg next

Folding

To fold two or more changeset into one, checkout the last changeset of the group and use the ‘hg fold’ command.

For example, to fold the current changeset into its parent:

$ hg fold --from .^

When amending or rebasing some changesets, their descendants end up “instables”. The easiest way to deal with this situation is to use the “hg next –evolve” command, which uses the obsolescence markers to determine what to do.

For example, amending a changeset and rebasing its descendants:

$ hg checkout my-topic
$ hg prev
$ hg prev
# modify something
$ hg amend
$ hg next --evolve
$ hg next --evolve

In this sequence, we checkout a topic, move back to the 3rd cset from the end, and amend it. At this point the 2 last changesets have no parent anymore.

The “hg next –evolve” command will rebase one changeset and switch to it. Running it twice will rebase our 2 remaining changesets and we end up on our topic head.

There is of course much more to it, go read the User Guide which explains it better than I would.

GUI

Bitbucket

Bitbucket does not (yet) display the topics, but it does exchange the obsolescence marker, which makes it evolve friendly. We have to thank Sean Farley for that (see the bitbucket issue).

Warning! the feature is disabled by default and needs to be activated on the bitbucket account that host the repository. To do that on your account (or organization), go to Account / Settings / Integrations and Features / Labs page

Tortoisehg

Tortoisehg, with the configuration above, will display the topics, which makes it comfortable to browse them.

On linux, the easiest way to use their latest version (which is needed for compatibility with the latest mercurial version you installed earlier) is to clone their repo, install the prerequisites, and link the thg command in your PATH.

On Ubuntu:

cd <dir>
hg clone https://bitbucket.org/tortoisehg/thg
sudo apt-get install mercurial pyqt4-dev-tools python-qscintilla2 python-iniparse python-pygments
ln -s <dir>/thg ~/.local/bin  # ! make sure ~/.local/bin is in your PATH !

More instructions in the documentation

SourceTree

I do not know the state of SourceTree for displaying topics (if you do, please tell me about it: christophe dot devienne at orus dot io).

Changelog

[2017-04-19] Update

  • evolve is now released on pypi, and the topic-experiment was merged into it.
  • update obsolete extensions/commands (thanks to Pierre-Yves David)

[2017-09-27] Update

  • Add ‘enforce-topic’ to the recommanded options

[2017-10-02] Update

  • Add a warning about using python2