In Mercurial Is it "safe" to pull when a mq patch is applied?
The go programming language has a page on code reviews using mq and it states: "Since pulling, pushing, updating and committing whi开发者_开发技巧le 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?
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.
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'thg update
). this creates a new branch (hg heads
shows the branch you're on asqtip
and the new branch you just pulled astip
) - 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 neverqfinished
.
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.
精彩评论