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

   ```sh
   # 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

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

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

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

  ```sh
  grep -r '<<<<<<<' .
  ```
