Mercurial Phases: Using Draft, Secret and Public to Guard Your Pushes
Mercurial phases label each changeset as draft, secret or public to prevent accidental publication and support safe history rewriting in team workflows.
01 Jan 2026, 00:33 UTC

Pushing a half-finished fixup or a changeset you intended to rewrite is the kind of mistake that creates noise for the whole team. Mercurial phases give each changeset a visibility label — draft, secret or public — and use that label to gate what can be pushed or fetched. The useful takeaway is not that phases prevent rewriting, but that they make publication an explicit decision.
The problem phases solve
A changeset in Mercurial is a commit. By default new commits are created with phase draft. Draft means local and mutable. Secret is a stricter draft that is intentionally hidden from normal pushes and pulls. Public means the changeset is shared and should be treated as immutable by collaborators.
Without a label, the only signal is whether a revision already exists on the remote. Phases add metadata that travels with the changeset, so a client can refuse to push a draft or secret changeset even if the remote would technically accept it.
How phases work in practice
Phase is metadata attached to each changeset. It is stored in the repository and moves with clones. The default flow is draft on creation, then automatic promotion to public when the changeset is pushed to a central repository that enforces phase policy.
You can inspect labels locally before any network operation. Run the command in your local clone with read access to the repository:
hg phase --listThis shows the phase for each changeset in the current working directory. A practical pre-push check is a dry run:
hg push --dry-run <central-repo>The dry run reports which changesets would be transferred and lets you see if phase rules would block a push. Server side policy can be reviewed in the phase section of .hg/hgrc on the server, for example settings that control whether incoming draft changesets are accepted or automatically promoted.
Explicit promotion is done with hg phase. Promotion requires write access to the local repository and changes metadata:
hg phase -r <rev> -f publicUse a specific revision identifier such as a changeset hash or local revision number. The -f flag forces the change. Once a changeset is public, collaborators who have already fetched it will expect it to remain stable.
Worked example: keeping a fixup draft secret
Suppose you create a work-in-progress commit on a feature branch and later create a clean rewrite for review. You want the first commit to stay local.
1. Identify the revisions. In the local clone, list phases to confirm the first commit is draft.
2. Mark the unwanted commit as secret so it is excluded from normal pushes:
hg phase -r <wip-rev> secretSecret changesets are not pushed by default and are hidden from pulls unless explicitly requested.
3. Verify the push set. Run hg push --dry-run <central-repo> and confirm only the intended clean revision is listed.
Risk: secret is a client-side convention. If the server is misconfigured and accepts secret changesets, they can still be published. Team coordination is required when using evolve, which builds on phases to support safe history rewriting. Evolve requires explicit opt-in and should not be used on public changesets.
Trade-offs and limits
Phase enforcement is primarily client side. A misconfigured server may still accept pushes of secret changesets, so phases are a guardrail not a security boundary.
Accidentally labeling a changeset as public after rewriting can expose unintended history to collaborators. Promotion from draft to public is easy to do and hard to undo in a shared context.
Teams must communicate when using evolve or manual phase changes, because rewriting published history violates shared workflow norms even if phases technically allow it.
Check results practically by inspecting phase labels before push and by reviewing server phase policy in .hg/hgrc. If you need to keep history mutable, keep changesets in draft or secret until the team agrees on publication.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.