Analysis
Mercurial Queues in 2026: What to Use Instead

Do not start new work with Mercurial Queues. Use amend for one evolving change, shelve for a temporary interruption, histedit for a series, and Evolve when the project needs explicit handling of obsolete history.
Why this page changed
The original version of this article was published in 2011. It described the commands I actually used, but it read as if MQ were still the obvious way to organize unfinished work. That is no longer responsible advice.
The Mercurial project marked MQ deprecated in 2014. The deprecation note pointed to rebase, histedit, and commit --amend as safer tools for the jobs MQ had accumulated. Current Mercurial documentation still describes extensions as optional features that can change or destroy history. That makes MQ relevant when maintaining an old repository, not a workflow I would introduce to a new one.
The old article did get one thing right: unfinished work and published history are different states. I still want small, coherent units, a clean point to switch tasks, and a deliberate moment when history becomes shared. I just would not model those states as a pile of applied and unapplied MQ patches anymore.
The modern replacement depends on the job
| Old MQ job | Current choice | Boundary |
|---|---|---|
| Start and repeatedly refresh the current patch | Make a draft commit, then run hg commit --amend |
Amend only private work with no children. |
| Pop unfinished changes to switch tasks | hg shelve --name task-name |
A shelf is temporary storage, not published history. |
| Bring the task back | hg unshelve --name task-name |
Resolve conflicts before continuing. |
| Reorder, fold, or edit a patch series | Histedit, or rebase for moving commits | Rewriting shared changesets can break other clones. |
| Collaborate on mutable changes | Evolve and topics, if the whole team supports them | Do not quietly impose an extension-based workflow. |
For one unfinished change, amend a draft commit
My old MQ loop was hg qnew, edit, test, and hg qrefresh until the patch was ready. The simpler current version is an ordinary commit that remains draft:
hg commit -m "Start the parser change"
# edit and test again
hg commit --amend
Mercurial’s current commit documentation says --amend combines the parent of the working directory with the current commit and the new working-copy changes. It also states the important limits: a public changeset cannot be amended, and neither can a changeset that has children.
That is the safety model I want. I can improve the most recent private unit without inventing a second patch stack. Once I push or otherwise make the changeset public, I stop treating it as disposable.
Mercurial stores an amend backup under .hg/strip-backup, according to the command documentation. I still would not use that as a normal recovery plan. Before rewriting anything important, I check the phase, the outgoing set, and whether another clone may already depend on the changeset.
For an interruption, shelve the working copy
Sometimes I do not want a commit at all. A production problem arrives while the working directory contains a half-written experiment. This is where hg shelve maps cleanly to the old instinct to pop work out of the way:
hg shelve --name parser-experiment
# handle the interruption and commit it
hg unshelve --name parser-experiment
The official shelve documentation describes the command as saving the dirty working-copy state in a named shelved change and leaving the working directory clean. Unshelve restores that change later. Naming the shelf matters once more than one interruption exists; a meaningful name is cheaper than guessing from dates.
I would not use shelves as a long-term backlog. They are easy to forget, they do not communicate intent like normal history, and they are not a substitute for pushing recoverable work somewhere appropriate. A shelf is a pause button.
For a series, use histedit deliberately
MQ made a stack tangible: apply a patch, pop it, push the next one, fold or reorder the stack, then finish it into permanent changesets. Histedit handles the cleanup part against ordinary commits. It can edit, fold, drop, or reorder a selected series.
Histedit is an extension, so it may need to be enabled in the Mercurial configuration:
[extensions]
histedit =
Then the exact revision range needs to be chosen with care. I would inspect the graph and outgoing changes first, make sure the commits are still draft, and only then start the edit. Rebase belongs in the same caution box: it is useful for moving draft work onto a different parent, but it also rewrites identity.
The rule is not complicated. Clean up private history as much as it helps. Do not rewrite public history just to make it prettier.
Where Evolve fits
The Evolve extension provides a more explicit model for safely sharing mutable history, and topics can give a stack a durable name. That can be a strong fit for a team already committed to Mercurial’s evolution model. It is not the default recommendation I would hand to someone who only needs to amend one local commit or park one interruption.
Extension compatibility also matters. The Evolve project publishes releases against particular Mercurial versions. I would confirm that match on every machine involved before adopting it as a team workflow.
The MQ commands worth recognizing
An old repository may still contain a .hg/patches directory, MQ configuration, or maintenance notes built around these commands:
hg qnew namecreates a new patch at the top of the queue.hg qrefreshupdates the current patch from working-copy changes.hg qpopremoves the current applied patch from the working directory.hg qpushapplies the next patch.hg qserieslists the patch series.hg qfinishconverts applied patches into regular changesets.
I keep this reference because deleting historical context would make the old URL less useful. I would first clone or back up the repository, inspect which patches are applied, and understand its release process before converting anything. A mechanical migration without that context can turn an obscure legacy workflow into lost work.
My working rule now
- Commit a coherent draft early. A small normal commit is easier to inspect and recover than an invisible working-copy state.
- Amend only while it is private. Once another clone may have it, add a new commit instead of rewriting the old one.
- Shelve short interruptions. Name the shelf and bring it back promptly.
- Use histedit or rebase with an explicit range. Check phases and outgoing work first.
- Keep MQ knowledge for legacy repositories. Recognition is useful; adoption is not.
This is the same boundary I use in current infrastructure work: make state visible, separate temporary state from durable state, and avoid a convenient tool silently becoming the only recovery path. The GitLab MCP session article shows that problem at a service boundary, while the Snap-DNS key article applies it to browser and server state. The broader MCP server article explains why I keep ownership boundaries explicit.
What I verified in Mercurial
The current replacement guidance comes from Mercurial’s official documentation for shelve, commit and amend, histedit and changing history, and extensions. The historical deprecation basis is the Mercurial developers’ MQ deprecation change. Evolve compatibility should be checked against the project’s current release material.
I used the original MQ workflow in 2011. I did not rerun these modern commands against a fresh local Mercurial installation for this rewrite, so the command descriptions above are documentation-based rather than a new hands-on benchmark.