In Mercurial Is it "safe" to pull when a mq patch is applied?

2k views Asked by At

The go programming language has a page on code reviews using mq and it states: "Since pulling, pushing, updating and committing while mq patches are applied can damage your repository".

I understand why pushing or updating could be an issue, but is pulling an issue?

If you have mq patches applied and you pull will your repository be damaged?

2

There are 2 answers

4
bjlaub On BEST ANSWER

It can certainly be an issue if you accidentally merge with the upstream changesets while you have MQ patches applied in your repository. Here's a scenario I just tried out which seems to exhibit problems:

  • suppose in your clone, you push all of your patches with hg qpush -a
  • then you pull changesets from upstream with hg pull (but don't hg update). this creates a new branch (hg heads shows the branch you're on as qtip and the new branch you just pulled as tip)
  • as you're hacking away, you decide to switch over to the new branch, and run hg update -C tip, but do so without popping your patches.
  • as you hack away some more, you decide to merge the branches with hg merge. Oops! You just merged in an MQ patch that was never qfinished.

Since MQ works by creating and destroying history, the patch changesets look like normal parts of the history. However, since you "leap-frogged" over the applied patches and merged them with a non-patch changeset, you can no longer pop the patches off. In fact, running hg qpop will abort with a message saying:

abort: popping would remove a revision not managed by this patch queue

I generally just try to be careful and conscious about pulling or pushing when I'm working with a patch queue, but the hooks suggested by the go page provide a nice safeguard.

Note that you can always rebase your patches on top of upstream changesets as well. See this page for a description of how to do that.

0
Martin Geisler On

If you have mq patches applied and you pull will your repository be damaged?

The answer is no. When you pull, you add more changesets to your local history. The applied MQ patches also live as changesets in the changeset graph, but that's not dangerous and you will not lose any data.

What may happen is that you have applied some patches:

.... a --- b --- p1 --- p2 --- p3

You then send the patches to the upstream mailinglist for inclusion. Someone reviews the patches, commits them, and pushes the changesets to the main repository. Other changesets are pushed afterwards and next time you pull you end up with:

.... a --- b --- p1 --- p2 --- p3 --- c --- d

Changesets p1 to p3 are still MQ patches in your repository, but they now have non-MQ children! Trying to pop them results in (with Mercurial 2.1.1):

$ hg qpop
abort: popping would remove a revision not managed by this patch queue

This is a bit of a dead-lock. It's annoying but not dangerous. To resolve it you must make MQ understand that p1 to p3 are no longer managed by MQ. You do this by removing the lines for these changesets from .hg/patches/status. MQ should probably eventually remove these lines by itself when this happens — but it happens pretty rarely so nobody has written that patch yet.