By admin , 29 April 2026

Two design lineages

Git's CLI emerged organically. Linus Torvalds and the early team valued power and speed; commands accumulated over years, often by different contributors with different sensibilities. Mercurial's CLI was designed top-down by Matt Mackall with a deliberate focus on consistency and discoverability.

Command consistency

Mercurial uses verb-noun consistently: hg commit, hg branch, hg merge. Options are consistent: -r always means revision, -m always message. Git's verbs overlap (checkout does several different things) and option meanings shift across subcommands. The 2019 introduction of git switch and git restore is a partial cleanup, but checkout remains for compatibility.

Help text

hg help commit         # focused, short, relevant
git help commit         # exhaustive man page

Mercurial's help is task-shaped; Git's is reference-shaped. Both have value; Mercurial's is more useful when learning, Git's more useful when scripting.

Error messages

Mercurial famously has friendlier errors. A failed merge in Mercurial says what to do next; in Git, you may get a cryptic line about object refs. Recent Git versions have improved noticeably, but the gap persists.

Safe defaults

Mercurial's commands rarely destroy data without an explicit extension. hg revert moves your changes to .orig files; hg strip requires the strip extension; hg histedit requires enabling histedit. Git's defaults are sharper: git reset --hard destroys uncommitted work without warning.

Status output

# Mercurial: minimal, comprehensible
hg status
M src/checkout.js
A src/payment.js
? notes.txt

# Git: more states, busier
git status
On branch feature/login
Your branch is ahead of 'origin/feature/login' by 2 commits.
  (use "git push" to publish your local commits)
Changes to be committed:
  ...
Changes not staged for commit:
  ...
Untracked files:
  ...

Git's status is denser but more informative once you internalise it. Mercurial's is faster to scan.

Branching commands

# Mercurial: branches are conceptually heavyweight
hg branch feature/login
hg commit -m "Start"

# Mercurial: bookmarks for Git-like branching
hg bookmark feature
hg commit -m "Start"

# Git
git checkout -b feature/login
git commit -m "Start"

Mercurial's named-branch / bookmark distinction is a frequent newcomer pitfall.

History rewriting

Git: git rebase -i, built in, no opt-in. Mercurial: hg histedit, requires enabling the extension. Both work; Mercurial's gate signals "be careful".

Hooks and extensions

Mercurial extensions plug in cleanly via Python; the API is documented and stable. Git hooks are shell scripts; the core.hooksPath setting allows sharing. Mercurial's API is more programmer-friendly; Git's hooks are more interoperable across systems.

Tab completion

Both ship completions for major shells. Git's completion is more thoroughly maintained, especially for unusual subcommands. Mercurial's is reliable for the common subset.

The cost of unfamiliarity

For someone fluent in Git, Mercurial's renamed commands and gated extensions feel restrictive. For someone new to both, Mercurial is easier on day one. Migration in either direction takes about a week of conscious effort to retrain reflexes.

Modern improvements

Git has narrowed the UX gap with better error messages, switch and restore, partial clone, and porcelain-friendly defaults. Mercurial continues to refine, with Sapling (Meta's fork) showing what a Mercurial-derived UX could look like with monorepo scale in mind.

If you are starting fresh and ecosystem does not constrain you, Mercurial's UX merits real consideration. If you are joining an existing Git project, the lesson is to invest deliberately in aliases, prompts, and tooling that smooth the rough edges.