cloudparts

Mercurial

A distributed version control system from the same month as Git, written mostly in Python, with a smaller command set, append-only storage and “phases” that stop you rewriting history others already have.

What it is
Version control
Type
Open source
Made by
The Mercurial project (Software Freedom Conservancy)
License
GPL-2.0-or-later
Facts checked
20 October 2026

What it is

Like Git, every Mercurial clone (hg clone) holds the full history, so commit, log, diff and merge run locally and hg push and hg pull exchange only what the other side lacks. Storage is different. Each file’s history is a revlog, which stores compressed deltas between revisions, with a full snapshot written whenever the deltas since the last one pass a threshold, so any revision is rebuilt from at most one snapshot and a short chain of deltas. Mercurial only ever appends to revlogs and never rewrites what it has written, which makes its transactions atomic: readers see a whole commit or none of it. A changeset points to a manifest (the list of files and their revisions), which points into each file’s revlog, and every entry is named by a cryptographic hash of its content.

Two features set its workflow apart. Phases record which changesets have been shared: new commits are draft, pushing them to a publishing server makes them public, and history-editing commands such as rebase refuse to touch public changesets, so you can’t accidentally rewrite what others have pulled; secret changesets are never pushed at all. And it has two kinds of branch: a named branch is stored in each commit and is permanent and global, while a bookmark is a movable label, closer to a Git branch. The separate evolve extension goes further, recording which changesets replaced which (obsolescence markers) so rewritten history can be shared safely.

Matt Mackall announced Mercurial in April 2005; it is licensed GPLv2 or later and is a member project of the Software Freedom Conservancy. The command-line tool hg is Python, with C and Rust for hot paths: optional Rust extensions speed up status, commit, diff and push and pull discovery, and rhg is an experimental pure-Rust front end that falls back for anything it doesn’t support. Several of its biggest users have moved on: Bitbucket dropped Mercurial in 2020, and Mozilla moved Firefox from Mercurial to Git in April 2025. The latest release is 7.2.4 (August 11, 2026).

Why teams pick it

  • Phases make history editing safe by default: rebase and friends refuse to rewrite changesets that are already public
  • Append-only revlogs with periodic snapshots keep any revision quick to rebuild and make interrupted writes harmless
  • A smaller, consistent command set and built-in help (hg help), with Python extensions to add commands
  • Scaled to very large monorepos: Facebook chose it over Git because its modular Python code was easier to extend

Watch out for

  • A small ecosystem: Bitbucket removed Mercurial in 2020, and Python and Firefox have both moved to Git, so few hosts and tools support it
  • Named branches are written into every commit and can’t be deleted; short-lived work needs bookmarks instead
  • The Python implementation is slower than the experimental Rust rhg for the commands rhg supports, and rhg has to be built from source
  • Changeset evolution, the safe way to share rewritten history, still lives in a separate extension and is off by default

Alternatives

What all version control have in common →Compare side by side →

How it fits with other technologies

Clone, commit, and see phases and bookmarks · bash

hg clone https://www.mercurial-scm.org/repo/hello && cd hello

hg bookmark fix-greeting          # a movable label, like a Git branch
# edit files, then
hg commit -m 'Fix the greeting'

hg phase                          # draft: not shared yet, safe to rewrite
hg log -G -l 3                    # history as a graph, newest first
hg push -B fix-greeting           # share it; the changeset becomes public

See it in a real stack

No architecture uses Mercurial yet. Drop it into the playground and wire it up yourself.Open playground →
Where it came from2005–2025

In April 2005 the Linux kernel lost its free use of BitKeeper, and several people set out to write a replacement. Linus Torvalds started Git; Matt Mackall posted “Mercurial v0.1, a minimal scalable distributed SCM” to the kernel mailing list on April 19. His goals were to be as simple, and so as hackable, as possible, as scalable as possible, and efficient in memory, disk and bandwidth. The first version was under 600 lines of Python, and committing the 2.6.10 kernel took 27 seconds on his laptop. The kernel chose Git, but Mercurial found its own users.

Mercurial 1.0 shipped in March 2008, and projects such as Python and Mozilla’s Firefox ran on it for years. In January 2014 Facebook explained why it had picked Mercurial over Git for its huge monorepo: Git’s internals would be hard to change, while Mercurial was clean, modular Python. It added file-system watching and on-demand file fetching, and that extension work later grew into a separate system, Meta’s Sapling.

Then the field consolidated around Git and GitHub. CPython moved to GitHub in February 2017, partly because contributors already knew it. Bitbucket removed Mercurial support in 2020, saying under 1% of its new users chose it. Mozilla moved Firefox to Git on April 30, 2025. Mercurial itself keeps shipping: Python 3 only since 6.2 in 2022, more Rust in each release, and 7.2 in January 2026.

Why it’s built this way

Write it in Python
Mackall’s first goal was to stay simple and hackable, so the core was a few hundred lines of Python, with C added later for hot paths. That is also why Facebook chose it: extensions could change almost anything without forking the tool.
Append-only revlogs with periodic snapshots
Storing deltas saves space, but long delta chains make old revisions slow to rebuild. Writing a full snapshot whenever the deltas since the last one grow too large bounds the work, and only ever appending made writes safe to interrupt and friendly to rsync and HTTP range requests.
Track whether a changeset has been shared
Rewriting history someone else has pulled creates duplicate changesets. Phases, added in Mercurial 2.1 (2012), mark changesets public once pushed, and history-editing commands refuse to modify them.
Permanent named branches, plus bookmarks
A named branch is stored in each commit, so the branch a change was made on stays part of its permanent, global record. For short-lived work Mercurial points to bookmarks instead: movable labels that advance with each commit and can be renamed or deleted without touching history.

Timeline

  1. 2005

    Matt Mackall announces Mercurial v0.1 on the kernel mailing list (April 19)

  2. 2008

    Mercurial 1.0 (March 24)

  3. 2012

    Mercurial 2.1 adds phases (February 1)

  4. 2014

    Facebook explains how it scaled Mercurial for its monorepo (January 7)

  5. 2020

    Bitbucket removes Mercurial support; all hg repositories disabled by August 26

  6. 2022

    Mercurial 6.2 drops Python 2 (July 11)

  7. 2025

    Mozilla moves Firefox’s source of truth from Mercurial to Git (April 30)

Sources19 · facts checked 20 October 2026

Improve this page on GitHub