Getting started with Mercurial for version control

Getting started with Mercurial for version control

Learn the basics of Mercurial, a distributed version control system written in Python.

Blue folders flying in the clouds above a city skyline
Image by :

Subscribe now

Get the highlights in your inbox every week.

Mercurial is a distributed version control system written in Python. Because it's written in a high-level language, you can write a Mercurial extension with a few Python functions.

There are several ways to install Mercurial, which are explained in the official documentation. My favorite one is not there: using pip. This is the most amenable way to develop local extensions!

For now, Mercurial only supports Python 2.7, so you will need to create a Python 2.7 virtual environment:

python2 -m virtualenv mercurial-env
./mercurial-env/bin/pip install mercurial

To have a short command, and to satisfy everyone's insatiable need for chemistry-based humor, the command is called hg.

$ source mercurial-env/bin/activate
(mercurial-env)$ mkdir test-dir
(mercurial-env)$ cd test-dir
(mercurial-env)$ hg init
(mercurial-env)$ hg status

The status is empty since you do not have any files. Add a couple of files:

(mercurial-env)$ echo 1 > one
(mercurial-env)$ echo 2 > two
(mercurial-env)$ hg status
? one
? two
(mercurial-env)$ hg addremove
adding one
adding two
(mercurial-env)$ hg commit -m 'Adding stuff'
(mercurial-env)$ hg log
changeset:   0:1f1befb5d1e9
tag:         tip
user:        Moshe Zadka <>
date:        Fri Mar 29 12:42:43 2019 -0700
summary:     Adding stuff

The addremove command is useful: it adds any new files that are not ignored to the list of managed files and removes any files that have been removed.

As I mentioned, Mercurial extensions are written in Python—they are just regular Python modules.

This is an example of a short Mercurial extension:

from mercurial import registrar
from mercurial.i18n import _

cmdtable = {}
command = registrar.command(cmdtable)

    [('w', 'whom', '', _('Whom to greet'))])
def say_hello(ui, repo, **opts):
    ui.write("hello ", opts['whom'], "\n")

A simple way to test it is to put it in a file in the virtual environment manually:

$ vi ../mercurial-env/lib/python2.7/site-packages/

Then you need to enable the extension. You can start by enabling it only in the current repository:

$ cat >> .hg/hgrc
hello_ext =

Now, a greeting is possible:

(mercurial-env)$ hg say-hello --whom world
hello world

Most extensions will do more useful stuff—possibly even things to do with Mercurial. The repo object is a mercurial.hg.repository object.

Refer to the official documentation for more about Mercurial's API. And visit the official repo for more examples and inspiration.


About the author

Moshe sitting down, head slightly to the side. His t-shirt has Guardians of the Galaxy silhoutes against a background of sound visualization bars.
Moshe Zadka - Moshe has been involved in the Linux community since 1998, helping in Linux "installation parties". He has been programming Python since 1999, and has contributed to the core Python interpreter. Moshe has been a DevOps/SRE since before those terms existed, caring deeply about software reliability, build reproducibility and other such things. He has worked in companies as small as three people and as big as tens of thousands -- usually some place around where software meets system administration...