Mercurial Merge Tracking: A Diagnostic Guide for Complex Branch Topologies
When working with Mercurial's named branches and frequent merges, unexpected merge conflicts can appear. This diagnostic guide helps identify and fix merge tracking issues using Mercurial's built-in tools like hg debugmergestate and hg debugstatecheck.
08 Feb 2026, 13:51 UTC

The Problem: Merge Conflicts in Complex Mercurial Histories
When working with Mercurial's named branches and frequent merges, you may encounter unexpected merge conflicts, duplicate changesets, or difficulty determining which changes are truly new. These issues often stem from misunderstanding Mercurial's merge tracking algorithm.
How Mercurial Tracks Merges
Mercurial uses an ancestors algorithm that tracks the entire directed acyclic graph (DAG) of changesets, not just parent pointers. This means it can correctly identify when two changesets share a common ancestor, even in complex branching scenarios. However, this also means that merge tracking state is stored per-branch and can become inconsistent if not managed properly.
Common Merge Tracking Symptoms
| Symptom | Potential Cause |
|---|---|
| Duplicate merge conflicts on same files | Merge tracking metadata lost or inconsistent |
| Mercurial claims changes are new when they're not | Repository corruption or manual history manipulation |
| 'hg merge' always shows conflicts | Working directory state inconsistent with repository |
| Unexpected 'abort: repository is unrelated' errors | Branches diverged without proper merge relationship |
Diagnostic Checklist
- Verify current branch state - Run
hg branchandhg parentsto confirm you're on the expected branch with correct parent changesets - Check branch relationships - Run
hg log --graph --branch BRANCHNAMEto visualize the branch's merge history - Validate merge tracking - Run
hg debugmergestateto inspect Mercurial's internal merge tracking state - Compare with other branches - Run
hg log --follow --branch BRANCHNAME FILENAMEto trace file history across merges - Check for evolve extension interference - If evolve is enabled, run
hg debugstatecheckto verify commit rewriting didn't corrupt merge metadata
Specific Fixes by Finding
Merge State Corruption
If hg debugmergestate shows inconsistent state:
# Clear corrupted merge state hg merge --abort # If that fails, manually clear the merge state rm .hg/merge-state
Run from the repository root. Requires write permissions to .hg directory. Risk: Only use if you're certain no actual merge is in progress.
Broken Merge History
If branches show incorrect ancestry:
# Identify the problematic changeset hg log --graph --branch BRANCHNAME # If a merge changeset is missing or corrupted, you may need to recreate it hg merge CHANGSETID
CHANGSETID is the identifier of the changeset you're trying to merge.
Evolve Extension Conflicts
If commit rewriting broke merge tracking:
# Check evolve state hg debugstatecheck # If issues found, rebuild merge metadata hg debugrebuildmergestate
This command rebuilds merge tracking metadata from the DAG. May take time on large repositories.
Escalation Criteria
Proceed to repository recovery procedures if:
hg debugmergestatereports unrecoverable state- Multiple branches show incorrect ancestry after multiple diagnostic attempts
- The repository fails basic operations like
hg statusorhg log - You're working with a production repository and cannot afford any risk of data loss
Preventive Configuration
Add to your .hgrc or hgrc to improve merge tracking reliability:
[merge-tools] default = internal:merge3 [ui] merge = internal:merge3 [evolve] enabled = True
Verification Steps
After applying fixes, verify resolution:
- Run
hg debugmergestate- should show clean state - Perform a test merge to a new branch - should complete without unexpected conflicts
- Run
hg verify- should report no integrity issues
Limitations and Considerations
This guide assumes standard Mercurial 5.0+ with default merge tracking. Named branches persist permanently and cannot be deleted, which can cause repository bloat if many experimental branches are created. The evolve extension is experimental and may introduce compatibility issues across versions. Always test merge tracking fixes on non-production repositories first.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.