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.