Patchwork [6,of,7,V4] revset: optimize out reverse() according to ordering requirement (BC)

login
register
mail settings
Submitter Yuya Nishihara
Date June 23, 2016, 3:59 p.m.
Message ID <b6a2aa2e7f62d6c4c235.1466697598@mimosa>
Download mbox | patch
Permalink /patch/15584/
State Accepted
Headers show

Comments

Yuya Nishihara - June 23, 2016, 3:59 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1462250172 -32400
#      Tue May 03 13:36:12 2016 +0900
# Node ID b6a2aa2e7f62d6c4c2351112556ab92b2be7a3ac
# Parent  7fcfd3c037c8695a510e633c7f92432acda35118
revset: optimize out reverse() according to ordering requirement (BC)

Because smartset.reverse() may modify the underlying subset, it should be
called only if the set can define the ordering.

In the following example, 'a' and 'c' is the same object, so 'b.reverse()'
would reverse 'a' unexpectedly.

  # '0:2 & reverse(all())'
  <filteredset
    <spanset- 0:2>,    # a
    <filteredset       # b
      <spanset- 0:2>,  # c
      <spanset+ 0:9>>>

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2503,6 +2503,8 @@  def _optimize(x, small, order):
         if f == "present":
             d = order
         wa, ta = _optimize(x[2], small, d)
+        if f == 'reverse' and order != defineorder:
+            return wa, ta
         if f in ("author branch closed date desc file grep keyword "
                  "outgoing user"):
             w = 10 # slow
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1325,18 +1325,25 @@  ordering defined by it.
       ('symbol', '2')
       ('string', 'define'))
     (func
-      ('symbol', 'reverse')
-      (func
-        ('symbol', 'all')
-        None)))
+      ('symbol', 'all')
+      None))
   * set:
   <filteredset
-    <spanset- 0:2>,
+    <spanset+ 0:2>,
     <spanset+ 0:9>>
+  0
+  1
   2
-  1
-  0
- BROKEN: should be '0 1 2'
+
+ invalid argument passed to 'reverse()' to be optimized out:
+
+  $ log '0:2 & reverse()'
+  hg: parse error: missing argument
+  [255]
+  $ log '0:2 & reverse(0, 1)'
+  hg: parse error: can't use a list in this context
+  (see hg help "revsets.x or y")
+  [255]
 
  'sort()' should take effect only if it is the outermost expression: