name: mercurial-sync-and-merge
description: Use when pulling changes from a remote, updating to a different revision, dealing with multiple heads, or resolving merge conflicts in a Mercurial repo.
Mercurial sync and merge
When this applies
Use when:
- Pulling changes from a remote.
- Updating the working directory to a different revision.
- The repo has multiple heads on the same branch.
- Resolving merge conflicts.
Do not use for:
- Local commit hygiene → see
mercurial-basics. - Moving or deleting bookmarks → see
mercurial-bookmarks-and-prs. - Amending after a merge → see
mercurial-history-rewriting.
Pull then update
hg pull # fetch new changesets, do not touch the working dir
hg update # update working dir to tip of the active branch/bookmark
Combined:
hg pull -u # pull then update in one step (most common)
If a pull brings in changesets that create a new head on the same branch (someone else committed in parallel), hg update will move to the new tip only if the working dir is at the previous tip. Otherwise it warns about multiple heads.
Multiple heads
A "head" is a changeset with no children on the same branch. Normal repos have one head per branch. Two parallel commits → two heads.
See them:
hg heads # all heads
hg heads default # heads on the default branch
Resolution options:
-
Merge them — combine the two lines:
hg update -r <head A> hg merge <head B> # resolve any conflicts (see below) hg commit -m "merge: combine parallel work" -
Rebase your work onto the other head (preferred for personal feature work):
# If your work is the new head and the other is upstream: hg update -r <upstream head> # then for each of your local commits, replay using rebase or amendNote: vanilla Mercurial without the
rebaseextension can'thg rebasedirectly. Either enablerebasein~/.hgrc([extensions] rebase =) or fall back to merge.
For Isurus today: merge is the safe default; rebase is not part of the v1 workflow.
Merging two heads
hg update -r <target> # check out the changeset to merge INTO
hg merge -r <source> # bring source into the working dir
# files with conflicts are listed in the output
Conflict resolution
After hg merge, files in conflict are marked. Inspect them:
hg resolve --list # 'U' = unresolved, 'R' = resolved
Edit each unresolved file. Conflict markers look like:
<<<<<<< local
your version
=======
their version
>>>>>>> other
Remove the markers, keep the correct content, save. Then mark resolved:
hg resolve --mark path/to/file
Or after editing all of them:
hg resolve --mark --all
Verify nothing remains:
hg resolve --list # should print nothing
Re-run a merge tool on a specific file (e.g., to retry):
hg resolve --tool internal:merge3 path/to/file
Once all files are resolved:
hg commit -m "merge: combine X and Y"
A merge commit has two parents. hg log --graph (or hg log -G) shows the merge visually.
Aborting a merge
If you started a merge and want to back out:
hg update -C -r <pre-merge revision>
-C means clean — discard the in-progress merge state. Verify the working dir is clean afterward with hg status.
Common pitfalls
-
hg pullwithout-u: changesets are in the repo but the working dir is unchanged. You're working against stale code without realizing. -
Two parents after merge with no commit: if you
hg mergeand then run other commands, the working dir has two parents until youhg commit. Until then,hg parentsshows both. -
Conflict markers committed: if you
hg commitwithout removing all<<<<<<</=======/>>>>>>>markers, you commit broken files. Always grep before commit:grep -r '<<<<<<<' .