Understanding Mercurial Architecture

Repository Internals

Mercurial tracks changes via a DAG (Directed Acyclic Graph) of changesets. Each changeset records metadata, file diffs, and parent references. Unlike Git, Mercurial commits do not hash file contents directly, which impacts how divergence and merges are handled.

Subrepositories and Extensions

Subrepos allow modular project composition but often introduce sync issues due to version locking, nested histories, or inconsistent state across team members. Enterprise teams may also use extensions like hg largefiles, mq, or evolve, each with its own risks.

Common Symptoms of Version Control Failures

1. Silent Merge Conflicts or Diverging Heads

  • Unnoticed conflicting changes on parallel branches
  • Multiple heads in a branch preventing push

2. Subrepo Desynchronization

  • Subrepos point to different revisions across team members
  • Committing without updating subrepo states leads to misleading history

3. Corrupted or Missing History

  • Missing changesets after pull or push
  • Broken DAG due to interrupted operations or file system issues

Advanced Troubleshooting Techniques

Detect and Resolve Multiple Heads

# List all heads on a branch
hg heads default

# Merge heads explicitly
hg merge --tool :merge
hg commit -m "Resolve multiple heads"

Repair a Corrupted Repository

# Rebuild internal state
hg verify
hg debugrebuildstate

# Re-clone as a last resort
hg clone --pull /path/to/corrupt /path/to/new

Validate Subrepo Consistency

# Inspect subrepo revisions
cat .hgsubstate

# Force sync with parent repo
hg update
hg pull -S
hg commit -S -m "Sync subrepos"

Diagnose Hook Failures

Custom hooks may silently fail if stderr is suppressed. Always log hook outputs:

[hooks]
pretxncommit = python:myhook.py
[ui]
logtemplate = "{date|isodate} {author}: {desc}\n"

Anti-Patterns and Risks in Large Teams

1. Unmanaged Subrepos

Failing to include .hgsub and .hgsubstate in commits can cause missing or outdated dependencies.

2. Force Push Without Bookmark Management

Unlike Git branches, Mercurial bookmarks don't track history. Force pushing without bookmark updates may lead to lost work.

3. Mixing Evolve and Non-Evolve Users

The evolve extension adds changeset rewriting. Mixing workflows can break consistency unless all team members use the same tooling.

Best Practices for Stability and Collaboration

1. Enforce Repository Verification

Use hg verify in CI pipelines to ensure repository integrity after merges or rebases.

2. Standardize Extensions

Pin and document required extensions (e.g., evolve, rebase) in a shared hgrc to ensure uniform tooling across environments.

3. Automate Subrepo Updates

Use pre-push hooks or CI checks to validate subrepo alignment and avoid surprises during deployment.

4. Backup and Audit

Use hg bundle for backup and distributed recovery. Maintain change logs through hg log --template formats for auditing.

Conclusion

Mercurial offers a clean, consistent DVCS experience when used correctly, but subtle design choices can complicate troubleshooting. Recognizing issues like multiple heads, subrepo misalignment, or corruption early ensures better collaboration and fewer deployment risks. Teams adopting consistent hooks, extension policies, and repository validation workflows can prevent most of the pitfalls encountered in advanced use cases.

FAQs

1. How do I fix "abort: push creates new remote head"?

This occurs when your changes diverge from the remote. Run hg pull, hg merge, then push again.

2. Can I recover a deleted changeset?

Use hg log --hidden or hg strip --backup with care. If you used evolve, hg obslog may help revert obsoleted commits.

3. Why do subrepos not update on clone?

Subrepos require -S or explicit sync. Use hg clone -U -S and run hg update afterward.

4. What's the difference between bookmarks and branches?

Branches are permanent markers in history. Bookmarks are movable pointers, like Git branches, but don't retain ancestry by default.

5. Is Mercurial still viable for enterprise use?

Yes, especially for teams valuing performance and simplicity. It remains widely used in large-scale systems like Mozilla and offers solid tooling for controlled environments.