Patchwork [3,of,4] revset: make reverse() noop depending on ordering requirement (BC)

login
register
mail settings
Submitter Yuya Nishihara
Date Sept. 14, 2016, 4:40 p.m.
Message ID <849cc143ef7a4a95813f.1473871239@mimosa>
Download mbox | patch
Permalink /patch/16625/
State Accepted
Headers show

Comments

Yuya Nishihara - Sept. 14, 2016, 4:40 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1462250172 -32400
#      Tue May 03 13:36:12 2016 +0900
# Node ID 849cc143ef7a4a95813f91618db6353018939c46
# Parent  7054518fb85e9ec814c5946528bcc8ceacae7460
revset: make reverse() noop depending on 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
@@ -1833,12 +1833,13 @@  def matching(repo, subset, x):
 
     return subset.filter(matches, condrepr=('<matching%r %r>', fields, revs))
 
-@predicate('reverse(set)', safe=True)
-def reverse(repo, subset, x):
+@predicate('reverse(set)', safe=True, takeorder=True)
+def reverse(repo, subset, x, order):
     """Reverse order of set.
     """
     l = getset(repo, subset, x)
-    l.reverse()
+    if order == defineorder:
+        l.reverse()
     return l
 
 @predicate('roots(set)', safe=True)
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1594,12 +1594,11 @@  ordering defined by it.
     define)
   * set:
   <filteredset
-    <spanset- 0:2>,
+    <spanset+ 0:2>,
     <spanset+ 0:9>>
+  0
+  1
   2
-  1
-  0
- BROKEN: should be '0 1 2'
 
  'sort()' should take effect only if it is the outermost expression: