mq: catch attempt to qpush to an earlier patch (issue2587) stable
authorAfuna <afunamatata@gmail.com>
Sat, 12 Feb 2011 16:08:41 +0800
branchstable
changeset 13369 69238d0ca60f
parent 13340 02aa06a021a0
child 13373 900a92862a7b
child 13427 2432b3227303
mq: catch attempt to qpush to an earlier patch (issue2587) We can't assume that all pushable patches early in the series have already been applied. If a hg qselect is done while you already have patches applied, some patches with guards may now be pushable, even though they come earlier in the series. So instead of checking only applied patches, explicitly check where we are in the series against the position of the patch we want to qpush to.
hgext/mq.py
tests/test-mq-qpush-fail.t
--- a/hgext/mq.py	Thu Feb 03 00:27:44 2011 -0600
+++ b/hgext/mq.py	Sat Feb 12 16:08:41 2011 +0800
@@ -1029,15 +1029,17 @@
             # go backwards with qpush)
             if patch:
                 info = self.isapplied(patch)
-                if info:
-                    if info[0] < len(self.applied) - 1:
-                        raise util.Abort(
-                            _("cannot push to a previous patch: %s") % patch)
+                if info and info[0] >= len(self.applied) - 1:
                     self.ui.warn(
                         _('qpush: %s is already at the top\n') % patch)
                     return 0
+
                 pushable, reason = self.pushable(patch)
-                if not pushable:
+                if pushable:
+                    if self.series.index(patch) < self.series_end():
+                        raise util.Abort(
+                            _("cannot push to a previous patch: %s") % patch)
+                else:
                     if reason:
                         reason = _('guarded by %r') % reason
                     else:
--- a/tests/test-mq-qpush-fail.t	Thu Feb 03 00:27:44 2011 -0600
+++ b/tests/test-mq-qpush-fail.t	Sat Feb 12 16:08:41 2011 +0800
@@ -88,3 +88,49 @@
   applying patch1
   unable to read patch1
   [1]
+
+Test qpush to a patch below the currently applied patch.
+
+  $ hg qq -c guardedseriesorder
+  $ hg qnew a
+  $ hg qguard +block
+  $ hg qnew b
+  $ hg qnew c
+
+  $ hg qpop -a
+  popping c
+  popping b
+  popping a
+  patch queue now empty
+
+try to push and pop while a is guarded
+
+  $ hg qpush a
+  cannot push 'a' - guarded by ['+block']
+  [1]
+  $ hg qpush -a
+  applying b
+  patch b is empty
+  applying c
+  patch c is empty
+  now at: c
+
+now try it when a is unguarded, and we're at the top of the queue
+  $ hg qsel block
+  number of guarded, applied patches has changed from 1 to 0
+  $ hg qpush b
+  abort: cannot push to a previous patch: b
+  [255]
+  $ hg qpush a
+  abort: cannot push to a previous patch: a
+  [255]
+
+and now we try it one more time with a unguarded, while we're not at the top of the queue
+
+  $ hg qpop b
+  popping c
+  now at: b
+  $ hg qpush a
+  abort: cannot push to a previous patch: a
+  [255]
+