---
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
```sh
hg pull # fetch new changesets, do not touch the working dir
hg update # update working dir to tip of the active branch/bookmark
```
Combined:
```sh
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:
```sh
hg heads # all heads
hg heads default # heads on the default branch
```
Resolution options:
1. **Merge them** — combine the two lines:
```sh
hg update -r
hg merge
# resolve any conflicts (see below)
hg commit -m "merge: combine parallel work"
```
2. **Rebase your work onto the other head** (preferred for personal feature work):
```sh
# If your work is the new head and the other is upstream:
hg update -r
# then for each of your local commits, replay using rebase or amend
```
Note: vanilla Mercurial without the `rebase` extension can't `hg rebase` directly. Either enable `rebase` in `~/.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
```sh
hg update -r # check out the changeset to merge INTO
hg merge -r --tool internal:merge # bring source into the working dir
# files with conflicts are listed in the output
```
**Always pass `--tool internal:merge`** when running `hg merge` from a Claude Code session. The user's `~/.hgrc` may default to `vimdiff`, `kdiff3`, or another interactive tool, none of which work in a non-TTY context — the merge will hang or error. `internal:merge` writes conflict markers (`<<<<<<<` / `=======` / `>>>>>>>`) into the file and returns control immediately, which is exactly what the resolution flow below assumes.
## Conflict resolution
After `hg merge`, files in conflict are marked. Inspect them:
```sh
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:
```sh
hg resolve --mark path/to/file
```
Or after editing all of them:
```sh
hg resolve --mark --all
```
Verify nothing remains:
```sh
hg resolve --list # should print nothing
```
Re-run a merge tool on a specific file (e.g., to retry):
```sh
hg resolve --tool internal:merge3 path/to/file
```
### Shortcuts when one side wins
If the user explicitly picks one side ("keep ours", "take theirs") rather than wanting a hand-merge, use the appropriate `internal:` resolver — it both resolves and marks in one step, no manual editing needed:
```sh
hg resolve --tool internal:local path/to/file # keep working-dir version
hg resolve --tool internal:other path/to/file # take incoming version
```
Then verify with `hg resolve --list` and proceed to commit.
Once all files are resolved:
```sh
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:
```sh
hg update -C -r
```
`-C` means clean — discard the in-progress merge state. Verify the working dir is clean afterward with `hg status`.
## Common pitfalls
- **`hg pull` without `-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 merge` and then run other commands, the working dir has two parents until you `hg commit`. Until then, `hg parents` shows both.
- **Conflict markers committed:** if you `hg commit` without removing all `<<<<<<<`/`=======`/`>>>>>>>` markers, you commit broken files. Always grep before commit:
```sh
grep -r '<<<<<<<' .
```