name: mercurial-bookmarks-and-prs
description: Use when starting feature work, switching between in-progress work, or pushing a feature for review in a Mercurial repo. Bookmarks are the unit of feature work and the unit of pull requests in this workflow.
Mercurial bookmarks and pull requests
When this applies
Use when:
- Starting a new feature or fix that will become a pull request.
- Switching between multiple in-progress features.
- About to push work for review.
- A bookmark is in the wrong place and needs fixing.
Do not use for:
- Long-lived branches like
default,stable— those are named branches, see "Bookmark vs named branch" below for the distinction. - Pulling/merging upstream changes → see
mercurial-sync-and-merge. - Amending commits before push → see
mercurial-history-rewriting.
Bookmark vs named branch
| Bookmark | Named branch | |
|---|---|---|
| Purpose | Feature/PR pointer | Long-lived line of development |
| Lifetime | Days to weeks; deleted after merge | Months to years |
| Examples | add-language-stats, fix-nil-reviewer |
default, stable, release-2.0 |
| Moves on commit? | Yes (the active one moves) | The new commit stays on the branch |
| Can be deleted? | Yes (hg bookmark -d) |
Effectively no |
Rule of thumb: if you'd open a PR for it, it's a bookmark. If it's a maintained release line, it's a named branch.
Starting a feature
hg pull -u # sync to latest default
hg bookmark my-feature # create bookmark at current rev
# ... edit files ...
hg add new-file.go
hg commit -m "feat: add new thing"
hg push -B my-feature # push the bookmark to the remote
After hg commit, the bookmark my-feature advances to the new changeset automatically (it's the active bookmark).
Listing bookmarks
hg bookmarks
Output marks the active bookmark with *:
add-language-stats 42:a1b2c3d4e5f6
* my-feature 47:b9c8d7e6f5a4
work-in-progress 39:c5d4e3f2a1b0
Switching bookmarks
hg update my-feature # switch to the bookmark and make it active
hg update checks out the changeset the bookmark points to AND activates the bookmark (so future commits move it forward).
If you only want to look at a revision without activating any bookmark there:
hg update -r <revision>
Pushing for review
The Isurus convention (non-publishing repo + bookmarks = PRs):
hg push -B my-feature
-B my-feature pushes the bookmark by name. Without -B, hg push pushes the current head's changesets but does not push the bookmark itself, which means the remote won't know to associate them with a PR.
After pushing, open the PR in the Isurus web UI (or the equivalent forge UI). See isurus-conventions for Isurus specifics.
Updating a PR after review feedback
In a non-publishing repo, pushed changesets stay draft until the PR is merged. That means amending after a push is safe:
# ... make the requested changes ...
hg amend # rewrites the tip changeset in place
hg push -B my-feature -f # -f because the rewrite changed the hash
The -f is required because the new amended changeset has a different hash than what's on the remote; without -f the push is rejected. This is the intended workflow — not a sign you're doing something dangerous, because the changesets are still draft.
Deleting a bookmark after merge
Once the PR is merged into default:
hg pull -u # pull in the merged changes
hg bookmark -d my-feature # delete locally
hg push --delete my-feature # delete on the remote (if not already gone)
Recovering a misplaced bookmark
If the bookmark is on the wrong changeset (e.g., you forgot it was active and committed something unrelated):
hg bookmarks # see where it is
hg bookmark my-feature -r <correct> # move it
The -r flag moves an existing bookmark to a specific revision without checking out anything.
Common pitfalls
- Forgetting
-Bon push: the changesets land but no bookmark = no PR association. Re-push withhg push -B <name>. - Forgetting
-fafter amend: push is rejected with "remote has changesets you don't have." Verify it's your own amended changeset (not a real upstream change), then-f. - Active bookmark surprise:
hg update -r <rev>without a bookmark name leaves no bookmark active; subsequent commits create anonymous heads. Always activate a bookmark you intend to commit to.