|
root / skills / mercurial-sync-and-merge / SKILL.md
SKILL.md markdown 147 lines 3.9 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>           # 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 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 '<<<<<<<' .