Cheatsheet - Mercurial (hg)
This cheatsheet provides a quick reference for common Mercurial commands.
Setup & Configuration
- Configure User:
- Edit
~/.hgrc(Unix/macOS) or%USERPROFILE%\mercurial.ini(Windows):[ui] username = Your Name <[email protected]> - Alternatively, use
hg config --editto open the global config file in your editor.
- Edit
- Per-Repository Configuration:
- Edit
.hg/hgrcinside your repository.
- Edit
- Enable Extensions (Example:
shelve):- Edit a config file (
.hg/hgrcor global) and add:[extensions] shelve = ; rebase = ; mq = ; evolve = ; histedit = - Note: Many advanced commands require enabling extensions.
- Edit a config file (
Getting a Repository
- Initialize New Repository:
hg init [<directory>]- Create a new repository in the specified directory (or current one).
- Clone Existing Repository:
hg clone <repo_url> [<destination>]- Copy an existing repository from a URL or path.
Basic Workflow
- Check Status:
hg statusorhg st- Show the status of files in the working directory:M= ModifiedA= AddedR= RemovedC= Clean (No changes)!= Missing (Deleted locally, still tracked)?= Not Tracked (Unknown)I= Ignored
- See Changes:
hg diff [<file>]- Show changes in tracked files since the last commit (parent revision).hg diff --rev <rev1>:<rev2>- Show differences between two specific revisions.
- Add Files (Mark for Tracking):
hg add <file> ...- Tell Mercurial to start tracking a new file. Needed only once per file.hg addremove- Automatically detect and add untracked files and mark missing files as removed.
- Stop Tracking Files:
hg forget <file> ...- Tell Mercurial to stop tracking a file (but leave it in the working dir). Will be removed from the repo on next commit.
- Remove Files (Track & Delete):
hg remove <file> ...orhg rm <file> ...- Tell Mercurial to stop tracking a file and delete it from the working directory.
- Commit Changes:
hg commit -m "Commit message"orhg ci -m "..."- Record tracked changes to the repository.hg commit <file> ... -m "..."- Commit changes only in the specified files.hg commit --amend- Amend the last commit (often requiresevolveextension or changing phase).
Branching & Merging
- Named Branches: (Permanent metadata)
hg branch <branch_name>- Set the name for the next commit. Does not change the working directory.hg branches- List all named branches.hg branch- Show the current named branch (of the working directory's parent commit).
- Bookmarks: (Lightweight, mutable pointers - like Git branches)
hg bookmark <bookmark_name>- Create a bookmark at the current commit.hg bookmarks- List all bookmarks.hg bookmark -d <bookmark_name>- Delete a bookmark.
- Heads: (Tips of lines of development)
hg heads- List all heads (commits with no children in the repo). Crucial for understanding merge situations. Multiple heads can exist on the same named branch.
- Switch Working Directory Revision:
hg update <target>orhg up <target>- Update working directory to a specific revision (changeset hash, revision number, tag, bookmark, or branch name).hg update -C <target>orhg up -C <target>- Update working directory, discarding any uncommitted local changes.hg update default- Switch to the tip of thedefaultbranch.hg update null- Update to the "empty" state before the first commit (useful for clean builds).
- Merging:
hg merge [<rev>]- Merge another head (specified by<rev>, or the single other head if obvious) into the current working directory revision. Creates a merge changeset upon commit.- Tip: Run
hg headsbeforehg mergeto see what needs merging.
- Resolving Conflicts:
hg resolve --listorhg resolve -l- Show files with unresolved merge conflicts.hg resolve <file>- Re-run the merge tool for a specific conflicted file.hg resolve -m <file>- Mark a file as resolved after manually editing it.- After resolving all conflicts,
hg commit.
Working with Remotes
- Configure Remote Paths:
- Edit
.hg/hgrc(repo-specific) or global config (~/.hgrc, etc.):[paths] default = <url_for_pull_push> upstream = <another_remote_url> hg paths- List configured remote repository paths.
- Edit
- Fetch Changes:
hg incoming [<remote>]orhg in [<remote>]- Show changesets that would be pulled from the remote.hg pull [<remote>]- Fetch changesets from a remote repository into the local one. Does not update the working directory.
- Fetch & Update:
hg pull -u [<remote>]- Fetch changesets and update the working directory to the new tip (if no merge is required).
- Push Changes:
hg outgoing [<remote>]orhg out [<remote>]- Show changesets that would be pushed to the remote.hg push [<remote>]- Send local changesets to the remote repository.hg push --new-branch- Required if pushing commits that introduce a new named branch.hg push -B <bookmark_name>- Push a specific bookmark and its associated commits.
History & Inspection
- View History:
hg log [<file>]orhg history [<file>]- Show commit history.hg glog- Show history graphically in the terminal (simple TUI).hg log -r <revspec>- Show history for specific revisions (e.g.,hg log -r 10:20,hg log -r tip,hg log -r 'ancestors(.)').hg log -k "keyword"- Search commit messages.hg log -p- Show history with patches (diffs).
- View Specific Commit:
hg log -r <rev>- Show details for a specific revision.hg export <rev>- Show commit details and diff in raw patch format.hg cat -r <rev> <file>- Show the content of a file at a specific revision.
- Tagging:
hg tag <tag_name> [-r <rev>]- Create a tag at the specified revision (or current parent revision). Tags are permanent.hg tags- List all tags.
- Annotate Lines (Blame):
hg annotate <file>orhg blame <file>- Show who last modified each line of a file.
Undoing Changes
- Discard Working Directory Changes:
hg revert <file> ...- Revert specified files (or directories) back to the state of the parent revision (.). Discards uncommitted changes.hg revert --allorhg revert -a- Revert all changes in the working directory.
- Undo a Commit (Safely):
hg backout <rev>- Create a new commit that reverses the changes introduced by<rev>. This is the safe way to undo changes that might have been shared.
- Remove Commits (Destructive - Use with Caution):
hg strip <rev>- Remove a changeset and all its descendants. Requiresmqorevolveextension enabled. This rewrites history and should generally NOT be used on changesets already pushed/shared.
- Temporarily Stash Changes:
hg shelve [<file> ...]- Store uncommitted changes temporarily. Requiresshelveextension.hg unshelve- Restore the most recently shelved changes.hg shelve --list- List shelved changes.
Advanced (Often Require Extensions)
- Cherry-Picking:
hg graft <rev>- Copy the changes from<rev>onto the current working directory parent revision, creating a new commit. Often requires enabling.
- Rebasing:
hg rebase -s <source> -d <destination>- Re-write commits starting from<source>onto<destination>. Requiresrebaseextension. Used to linearize history.
Revision Specifiers
You can refer to revisions using:
- Revision Number:
0,1,42(Local to the repo) - Changeset Hash:
abcdef123456(Globally unique, usually abbreviated) - Tags:
hg update v1.0 - Bookmarks:
hg update feature-x - Branch Names:
hg update stable - Relative:
.(parent of working dir),tip(newest head overall),^(parent),+(child),~N(N'th ancestor) - Sets:
ancestors(X),descendants(X),X:Y(range),max(set),min(set),head()
FAQ
How to change hg editor to vim
add editor=vim to .hgrc
[ui]
username=...
editor=vim
How to Show Changes
$ hg diff -c <bookmark>
How to Show hg diff
Show changes in current commit:
$ hg diff -c <bookmark>
Add diff alias
function diff_fn() {
if [ -z $1 ]
then
hg diff -r .^
else
x=$(hg book | grep -e "$1 ")
hg diff -c ${x: -12}
fi
}
alias diff=diff_fn
hg vs git
Core Concepts & Differences Summary
| Concept | Mercurial (hg) Approach | Git Approach | Key Difference Highlight |
|---|---|---|---|
| Branching | Named branches are permanent metadata. Anonymous branches create multiple 'heads'. Bookmarks are lightweight/mutable. | Branches are lightweight, movable pointers. | Hg branches permanent vs Git branches ephemeral. Hg bookmarks ≈ Git branches. Hg has concept of multiple 'heads' per branch. |
| Staging Area | No direct equivalent by default. hg commit takes all tracked changes. hg add marks for tracking once. |
Explicit staging area (index). git add stages specific content snapshot for commit. |
Git requires explicit staging (git add) before each commit; Hg typically commits all modified tracked files. |
| History Mod | Discouraged on published changesets. Requires extensions (rebase, histedit, evolve) for rewriting. hg backout ≈ git revert. |
Built-in tools (rebase, commit --amend, reset) common for local history rewrite. |
Git has built-in, commonly used history rewriting tools; Hg keeps history more immutable by default/design. |
| Commit IDs | SHA-1 hash + Local sequential revision number (e.g., 42:abcdef). |
SHA-1 (or SHA-256) hash only. | Hg includes local, non-globally-unique revision numbers for convenience. |
| Tracking Files | hg add marks for tracking once. Modifications auto-included later. hg addremove useful. |
git add stages current content for commit. Needs re-adding after modifications. |
hg add = "start tracking"; git add = "stage this version for commit". |
Commands Comparison Table
| Feature / Action | Mercurial (hg) Command | Git Command (Equivalent/Related) | Difference / Note |
|---|---|---|---|
| Setup User | hg config --edit or edit ~/.hgrc / mercurial.ini |
git config --global user.name "..."git config --global user.email "..." |
Hg uses INI format config files. Git uses git config. |
| Enable Extensions | Edit .hg/hgrc or ~/.hgrc, add [extensions] section (e.g., rebase =) |
N/A (Features often built-in) | Difference: Many advanced Hg features require enabling extensions. Git features are generally built-in. |
| Initialize Repo | hg init [<dir>] |
git init [<dir>] |
Similar function. |
| Clone Repo | hg clone <url> [<dest>] |
git clone <url> [<dest>] |
Similar function. |
| Check Status | hg status or hg st |
git status |
Difference: hg status shows working dir vs last commit. git status shows working dir vs staging area & staging area vs last commit. |
| See Changes (Working Dir) | hg diff [<file>] |
git diff HEAD [<file>] (closest equivalent) git diff (vs staging area) |
hg diff compares to parent commit; git diff (no args) compares to staging area. |
| See Changes (Staged) | N/A (No staging area) | git diff --staged or git diff --cached |
Difference: Git's staging area allows comparing staged vs committed changes. |
| Add File (Track/Stage) | hg add <file> (Track file once) hg addremove (Detect new/missing) |
git add <file> (Stage current content for next commit) |
Difference: hg add = "start tracking". git add = "stage this version". git add needed repeatedly if file changes before commit. |
| Commit | hg commit -m "..." or hg ci -m "..."hg commit <file> ... -m "..." |
git commit -m "..."git commit <file> ... -m "..." (commits staged versions) |
Difference: hg commit usually commits all tracked changes. git commit commits only staged changes. |
| Amend Last Commit | hg commit --amend (Often needs evolve extension or phase change) |
git commit --amend (Built-in) |
Easier and built-in with Git. |
| Remove File (from disk) | hg remove <file> or hg rm <file> |
git rm <file> |
Both remove from disk and schedule for removal from tracking on commit/staging. |
| Stop Tracking File (keep) | hg forget <file> |
git rm --cached <file> |
Both stop tracking but leave file in working directory. |
| List Branches (Named) | hg branches |
git branch |
Hg named branches are permanent metadata. |
| List Heads (All commits) | hg heads |
git log --all --graph --oneline --decorate (Visualizes tips of all refs) |
Difference: hg heads shows tips of divergent lines of development, even within the same named branch (critical concept). |
| List Bookmarks (Like Git) | hg bookmarks |
git branch |
Difference: Hg bookmarks are mutable pointers, most similar to Git branches. |
| Create Branch (Named) | hg branch <name> (Marks next commit, doesn't switch) |
git branch <name> (Creates pointer, doesn't switch) |
Difference: Hg named branch creation affects the next commit and is permanent metadata. |
| Create Bookmark (Like Git) | hg bookmark <name> |
git branch <name> |
Closest Hg equivalent to creating a Git branch. |
| Switch Branch/Rev/Bookmark | hg update <target> or hg up <target>hg update -C <target> (discard changes) |
git checkout <target> or git switch <branch>git checkout -f <target> (discard changes) |
hg update or hg up is the primary command for changing the working directory revision. |
| Merge | hg merge <rev/branch/bookmark> (Merges specified head into current) |
git merge <branch/commit> |
Difference: In Hg, often merging unnamed heads within the same named branch (hg heads is key). Git usually merges distinct branches. |
| Resolve Conflicts | hg resolve -l (list), hg resolve -m <file> (mark resolved), edit file |
Edit file, git add <file>, git commit |
Workflow differs slightly: Hg has resolve -m, Git uses add to mark resolved. |
| Tagging | hg tag <name> [-r <rev>] |
git tag <name> [<commit>]git tag -a <name> -m "..." (annotated) |
Git distinguishes between lightweight and annotated tags. |
| List Remotes | hg paths |
git remote -v |
Hg configures remote paths in .hg/hgrc. |
| Add Remote | Edit .hg/hgrc -> [paths] section |
git remote add <name> <url> |
Hg typically involves editing config file; Git uses a command. |
| Fetch Changes | hg pull [<remote>] (Fetches only) hg incoming [<remote>] (Preview fetch) |
git fetch [<remote>] (Fetches only) |
Difference: hg pull only fetches. git pull fetches + merges/rebases. |
| Fetch & Update Working Dir | hg pull -u [<remote>] |
git pull [<remote>] (Default: fetch + merge) |
hg pull -u is the closest equivalent to the default git pull. |
| Integrate After Fetch | hg update (move working dir) or hg merge (if new head created) |
git merge <remote>/<branch> or git rebase <remote>/<branch> |
Hg requires separate steps (pull then update or merge) unless using -u. |
| Push Changes | hg push [<remote>]hg push --new-branch (for new named branch)hg push -B <bm> |
git push [<remote>] [<branch>]git push -u <remote> <branch> (set upstream) |
Difference: Need --new-branch for Hg named branches. Pushing bookmarks (-B) common for Git-like branch workflow. |
| Preview Push | hg outgoing [<remote>] or hg out [<remote>] |
git log <remote>/<branch>..HEAD or git diff <remote>/<branch>...HEAD --stat |
hg outgoing directly shows changesets to be pushed. |
| View History | hg log [<file>] or hg history [<file>]hg log -G or hg glog (TUI graph) |
git log [<file>]git log --graph --oneline --decorate |
Both offer powerful logging. hg glog provides a basic built-in TUI graph. |
| View Specific Commit | hg log -r <rev>hg export <rev> (Show patch) |
git show <commit> |
hg export is good for seeing the raw patch. git show combines diff and commit info. |
| Annotate Lines (Blame) | hg blame <file> or hg annotate <file> |
git blame <file> |
Similar function, different command names. |
| Discard Working Dir Changes | hg revert <file> or hg revert --all |
git checkout -- <file> (old) or git restore <file> (new)git restore . (all) |
Difference: Command name clash! hg revert discards uncommitted changes. git revert creates an undo commit. |
| Undo Last Commit (Keep Chgs) | hg uncommit (needs evolve) or hg strip tip (destructive, needs mq) or hg update .^ |
git reset HEAD~ or git reset --soft HEAD~ |
Often requires extensions or is destructive in Hg core. Built-in with Git. |
| Undo Last Commit (Drop Chgs) | hg strip tip (destructive, needs mq/evolve) |
git reset --hard HEAD~ (destructive) |
Both are destructive; often needs extensions in Hg. |
| Undo Published Commit Safely | hg backout <rev> (Creates reversing commit) |
git revert <commit> (Creates reversing commit) |
Difference: Naming. hg backout == git revert. This is the safe way to undo shared history. |
| Temporarily Stash Changes | hg shelve (needs shelve extension)hg unshelve |
git stashgit stash pop or git stash apply |
Needs extension in Hg; built-in in Git. |
| Cherry-Pick Commit | hg graft <rev> (Often needs enabling/extension) |
git cherry-pick <commit> |
Copies a commit from one branch/point to another. |
| Rebase (Replay Commits) | hg rebase -s <src> -d <dest> (needs rebase extension) |
git rebase <base> |
Needs extension in Hg; built-in in Git. Used for linearizing history. |
| Search History (Message) | hg log -k "keyword" |
git log --grep="keyword" |
Similar search functionality. |
| Search History (Content) | hg log --patch -S"content string" (Less direct than Git's pickaxe) |
git log -S"content string" (Pickaxe - finds commits adding/removing string) |
Git's -S (pickaxe) is specifically optimized for finding code introduction/removal. |