Managing Project Lineage with Mercurial Named Branches
Learn how Mercurial Named Branches provide permanent metadata for project lineage, contrasting them with bookmarks to avoid the problem of anonymous heads.
29 Jul 2025, 20:19 UTC

The Problem with Anonymous Heads
In many version control systems, a branch is simply a pointer to a specific commit. When that pointer is deleted, the identity of the work performed on that branch often vanishes, leaving behind a series of commits that are technically part of the history but lack a clear label. In Mercurial, this can lead to "anonymous heads"—divergent paths in the commit graph that have no name, making it difficult for other developers to understand why a specific set of changes was introduced or where they originated.
The solution for long-term project traceability is Named Branches. Unlike lightweight pointers, a named branch in Mercurial is permanent metadata embedded directly into every commit. This ensures that the lineage of a feature or release is preserved forever, regardless of which clone is viewing the repository.
How Named Branches Differ from Bookmarks
It is common to confuse named branches with bookmarks (which behave similarly to Git branches). The distinction is critical for repository hygiene:
- Bookmarks are lightweight, movable pointers. They are ideal for short-lived feature work or marking a specific point in time. They are not embedded in the commit history.
- Named Branches are permanent labels. Once a commit is created on a named branch, that commit is forever associated with that branch name. This creates a global namespace that persists across all clones of the repository.
Use named branches for structural project milestones (like stable-2.0 or legacy-support) and bookmarks for transient tasks.
Implementing a Named Branch Workflow
Creating a named branch involves explicitly labeling the divergence. Because the branch name is stored in the commit itself, the identity follows the code.
Worked Example: Creating a Stable Release Branch
Assume you are working on the default branch and need to carve out a stable release for a client while continuing development on the main line.
1. Initialize the named branch
Run this command from your local working directory. You must have write permissions to the repository.
hg branch stable-1.02. Commit the changes
The next commit will now be permanently tagged as part of stable-1.0.
hg commit -m "Freeze version 1.0 for production deployment"3. Verify the active branch
To ensure you are not accidentally committing to the default branch, run:
hg branchExpected Result: The command should return stable-1.0.
Integrating Changes Back to Main
When a bug fix is applied to the stable branch and needs to be ported back to the main development line, use the merge command:
hg update default
hg merge stable-1.0After resolving any conflicts, commit the merge. The history will now show a clear path from the stable-1.0 branch back into the default branch.
The Trade-off: Metadata Permanence
The primary limitation of named branches is their permanence. Because the branch name is embedded in the commit metadata, you cannot "delete" a named branch in the same way you delete a folder or a pointer. Even after a branch is merged, it remains visible in the repository's history.
To manage this clutter, Mercurial provides a way to mark a branch as closed. This tells the system that the branch is no longer active, though the history remains intact:
hg commit --close-branch -m "Closing stable-1.0 after final merge"If you frequently create dozens of small feature branches, using named branches will lead to a bloated list of closed branches. In those scenarios, bookmarks are the technically superior choice.
Verification and Diagnostics
To audit the current state of your project's lineage, use these diagnostic commands:
- List all branches: Run
hg branchesto see all active and closed named branches in the repository. - Isolate history: Use
hg log -b stable-1.0to view only the commits associated with that specific named branch. - Check for anonymous heads: Run
hg heads. If you see multiple heads without associated branch names, you have anonymous heads that may need to be merged or named.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.