mq: pop/refresh: avoid losing revisions not managed by mq
We already disallow committing on top of an mq revision exactly
to avoid losing this new revision during a qpop/qrefresh, so this
can be seen as an additional safety check.
If this is not enough to fix
issue844, it should at least prevent
it from happening.
--- a/hgext/mq.py Sun Feb 03 21:03:46 2008 -0200
+++ b/hgext/mq.py Sun Feb 03 21:03:46 2008 -0200
@@ -861,10 +861,16 @@
start = info[0]
rev = revlog.bin(info[1])
+ if update:
+ top = self.check_toppatch(repo)
+
+ if repo.changelog.heads(rev) != [revlog.bin(self.applied[-1].rev)]:
+ raise util.Abort("popping would remove a revision not "
+ "managed by this patch queue")
+
# we know there are no local changes, so we can make a simplified
# form of hg.update.
if update:
- top = self.check_toppatch(repo)
qp = self.qparents(repo, rev)
changes = repo.changelog.read(qp)
mmap = repo.manifest.read(changes[0])
@@ -915,6 +921,8 @@
self.check_toppatch(repo)
(top, patchfn) = (self.applied[-1].rev, self.applied[-1].name)
top = revlog.bin(top)
+ if repo.changelog.heads(top) != [top]:
+ raise util.Abort("cannot refresh a revision with children")
cparents = repo.changelog.parents(top)
patchparent = self.qparents(repo, top)
message, comments, user, date, patchfound = self.readheaders(patchfn)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-safety Sun Feb 03 21:03:46 2008 -0200
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+echo '[extensions]' >> $HGRCPATH
+echo 'hgext.mq =' >> $HGRCPATH
+
+hg init repo
+cd repo
+
+echo foo > foo
+hg ci -qAm 'add a file'
+
+hg qinit
+
+hg qnew foo
+echo foo >> foo
+hg qrefresh -m 'append foo'
+
+hg qnew bar
+echo bar >> foo
+hg qrefresh -m 'append bar'
+
+echo '% try to commit on top of a patch'
+echo quux >> foo
+hg ci -m 'append quux'
+
+# cheat a bit...
+mv .hg/patches .hg/patches2
+hg ci -m 'append quux'
+mv .hg/patches2 .hg/patches
+
+echo '% qpop/qrefresh on the wrong revision'
+hg qpop
+hg qpop -n patches 2>&1 | sed -e 's/\(using patch queue:\).*/\1/'
+hg qrefresh
+
+hg up -C qtip
+echo '% qpop'
+hg qpop
+
+echo '% qrefresh'
+hg qrefresh
+
+echo '% tip:'
+hg tip --template '#rev# #desc#\n'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-safety.out Sun Feb 03 21:03:46 2008 -0200
@@ -0,0 +1,14 @@
+% try to commit on top of a patch
+abort: cannot commit over an applied mq patch
+% qpop/qrefresh on the wrong revision
+abort: working directory revision is not qtip
+using patch queue:
+abort: popping would remove a revision not managed by this patch queue
+abort: working directory revision is not qtip
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% qpop
+abort: popping would remove a revision not managed by this patch queue
+% qrefresh
+abort: cannot refresh a revision with children
+% tip:
+3 append quux