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>>>
--- a/mercurial/revset.py Tue May 03 12:52:50 2016 +0900
+++ b/mercurial/revset.py Tue May 03 13:36:12 2016 +0900
@@ -1833,12 +1833,13 @@
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)
--- a/tests/test-revset.t Tue May 03 12:52:50 2016 +0900
+++ b/tests/test-revset.t Tue May 03 13:36:12 2016 +0900
@@ -1594,12 +1594,11 @@
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: