[PATCH V2] mq: catch attempt to qpush to an earlier patch in the series (issue2587)

Afuna afunamatata at gmail.com
Sat Feb 12 02:10:57 CST 2011


# HG changeset patch
# User Afuna
# Date 1297498121 -28800
# Node ID 94a5462d970734fb7ff6aadc0964acd3da529d4b
# Parent  d4ab9486e514dd24e21a2ca3b6c439ea13d85cab
mq: catch attempt to qpush to an earlier patch in the series (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.

diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -1061,15 +1061,17 @@ class queue(object):
             # 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:
diff --git a/tests/test-mq-qpush-fail.t b/tests/test-mq-qpush-fail.t
--- a/tests/test-mq-qpush-fail.t
+++ b/tests/test-mq-qpush-fail.t
@@ -88,3 +88,49 @@ qpush should fail the same way as below
   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]
+


More information about the Mercurial-devel mailing list