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:
rebaseand 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
rhgfor the commandsrhgsupports, andrhghas 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 →jj, where the working copy is itself a commit, every operation can be undone, and conflicts are stored in commits instead of stopping you.sl client that works with Git repositories and makes stacks of commits and undo easy, plus a server and virtual filesystem that scale it to Meta’s monorepo.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 publicSee 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
rsyncand 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
- 2005
Matt Mackall announces Mercurial v0.1 on the kernel mailing list (April 19)
- 2008
Mercurial 1.0 (March 24)
- 2012
Mercurial 2.1 adds phases (February 1)
- 2014
Facebook explains how it scaled Mercurial for its monorepo (January 7)
- 2020
Bitbucket removes Mercurial support; all hg repositories disabled by August 26
- 2022
Mercurial 6.2 drops Python 2 (July 11)
- 2025
Mozilla moves Firefox’s source of truth from Mercurial to Git (April 30)
- Matt Mackall on LKML: Mercurial v0.1, a minimal scalable distributed SCM (Apr 2005)
- Linus Torvalds on LKML: Kernel SCM saga.. (Apr 6, 2005)
- Mercurial: Release notes (1.0 on 2008-03-24, 2.1 on 2012-02-01)
- Mercurial wiki: Phases (introduced in Mercurial 2.1)
- Mercurial: The Definitive Guide, Behind the scenes (revlogs, snapshots, append-only)
- Mercurial help: hg branch (branch names are permanent and global)
- Engineering at Meta: Scaling Mercurial at Facebook (Jan 7, 2014)
- PEP 512: Migrating from hg.python.org to GitHub (moved 2017-02-10)
- Atlassian blog: Sunsetting Mercurial support in Bitbucket (Apr 2020, updated Aug 2020)
- Mercurial 6.2 release notes: removed Python 2 support (Jul 11, 2022)
- Mozilla dev-platform: Engineering Effectiveness Newsletter, Q2 2025 (Firefox moved to Git on April 30, 2025)
- Engineering at Meta: Sapling, source control that’s user-friendly and scalable (Nov 15, 2022; began as a Mercurial extension)
- Mercurial 7.2 release notes (Jan 29, 2026)
Sources19 · facts checked 20 October 2026
- Mercurial: The Definitive Guide, Behind the scenes (revlogs, changelog, manifest, append-only transactions)
- Mercurial help: phases (public, draft, secret)
- Mercurial help: hg branch (branch names are permanent and global; use bookmarks)
- Mercurial help: hg bookmarks
- Mercurial help: hg push (-B pushes a bookmark and its ancestors)
- Mercurial help: hg phase (with no argument, shows the current phase)
- Mercurial help: hg log (-G graph, -l limit)
- Mercurial wiki: Changeset Evolution (obsolescence markers, evolve extension outside core)
- Mercurial help: rust (Rust extensions and rhg)
- Mercurial: Quick start
- Mercurial: COPYING (GNU GPL version 2)
- PyPI: mercurial (GPL-2.0-or-later)
- Software Freedom Conservancy: Current member projects (Mercurial)
- Mercurial 7.2 release notes (7.2.4 on 2026-08-11; Rust extensions, dirstate-v2)
- Mercurial: release tarballs (mercurial-7.2.4, Aug 11, 2026)
- Engineering at Meta: Scaling Mercurial at Facebook (Jan 7, 2014)
- Atlassian blog: Sunsetting Mercurial support in Bitbucket (2020)
- PEP 512: Migrating from hg.python.org to GitHub
- Mozilla dev-platform: Engineering Effectiveness Newsletter, Q2 2025 (Firefox moved to Git)