--- 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 '<<<<<<<' . ```