|
root / skills / mercurial-sync-and-merge / SKILL.md
SKILL.md markdown 160 lines 4.8 KB

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:

  1. 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"
    
  2. 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 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

hg update -r <target>                              # check out the changeset to merge INTO
hg merge -r <source> --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:

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

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:

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:

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 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:

    grep -r '<<<<<<<' .