Managing Permanent History: When to Use Mercurial Named Branches vs. Bookmarks
Stop cluttering your Mercurial history. Learn the critical difference between permanent Named Branches and ephemeral Bookmarks to keep your repository clean.
20 Jan 2026, 09:15 UTC

The Problem with Ephemeral Branches
Developers moving from Git to Mercurial often treat branches as disposable pointers. In Git, a branch is a lightweight reference that can be deleted once a feature is merged, leaving no trace of the branch name in the commit history. If you apply this same mental model to Mercurial's Named Branches, you will quickly encounter "branch pollution": a repository history cluttered with hundreds of permanent, defunct branch names that cannot be easily erased.
The takeaway is simple: Use Named Branches for structural, long-term organizational streams and Bookmarks for short-lived task tracking.
Named Branches: The Permanent Record
A Named Branch in Mercurial is not a pointer; it is metadata embedded directly into every commit created on that branch. When you run hg branch feature-x, every subsequent commit is stamped with that name. This identity is global and persists across all clones of the repository.
This makes Named Branches ideal for high-level project organization, such as:
- Release Streams: Maintaining a
stable-v1.0branch for security patches while developingv2.0. - Long-lived Feature Sets: Large architectural shifts that require months of parallel development and multiple contributors.
- Environment-specific tracks: Separating
productionandstagingconfigurations that must diverge permanently.
Bookmarks: The Lightweight Alternative
For the "quick fix" or the daily feature task, Mercurial provides Bookmarks. A bookmark is a pointer to a specific commit, behaving almost exactly like a Git branch. When you move a bookmark, you are moving a reference, not stamping the commit metadata.
Because bookmarks are not embedded in the commits, they can be deleted without leaving a permanent mark on the repository's history. This prevents the metadata bloat associated with using named branches for every single Jira ticket or bug fix.
Practical Example: Feature Integration
Consider a scenario where you need to implement a major API overhaul (long-term) and a quick CSS fix (short-term). Here is how to handle both using the Mercurial CLI on a Unix-like terminal with standard user permissions.
1. The Long-term Feature (Named Branch)
# Create the named branch
hg branch api-overhaul
# Make changes and commit
hg commit -m "Implement new REST endpoints"
# Verify the branch name is embedded in the commit
hg log -BThe -B flag in the log command confirms that the commit is permanently associated with api-overhaul. Even after this is merged into the default branch, the history will always show these commits belonged to that specific stream.
2. The Quick Fix (Bookmark)
# Create a bookmark for a quick fix
hg bookmark css-fix
# Make changes and commit
hg commit -m "Fix header alignment"
# Merge back to default and delete the bookmark
hg update default
hg merge css-fix
hg commit -m "Merge CSS fix"
hg bookmark -d css-fixAfter the hg bookmark -d command, the css-fix reference is gone. Unlike the named branch, there is no permanent "css-fix" label attached to those commits in the global history.
The Trade-off: Metadata Persistence
The primary limitation of Named Branches is that they are permanent. Once a commit is made on a named branch and pushed to a shared server, that branch name exists in the repository history forever. You cannot "delete" a named branch in the same way you delete a folder; you can only stop using it or close it via a merge.
If you use named branches for every small task, your hg branches output will eventually become an unreadable list of hundreds of dead branches, making it difficult to identify which streams are actually active.
Verification and Results
To check the current state of your repository and decide if you have "branch pollution," run:
hg branchesIf the list contains dozens of feature names that were merged months ago, you have been using Named Branches where Bookmarks were more appropriate. To verify a specific commit's permanent identity, use hg log -B -r [revision]; if a branch name appears, it is a permanent record.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.