mercurial/revset.py
changeset 34011 1b28525e6698
parent 33855 457d1ebf151b
child 34016 96f249dce03e
--- a/mercurial/revset.py	Mon Aug 28 23:44:47 2017 -0700
+++ b/mercurial/revset.py	Sun Aug 20 10:55:11 2017 -0700
@@ -52,10 +52,10 @@
 
 # helpers
 
-def getset(repo, subset, x):
+def getset(repo, subset, x, order=defineorder):
     if not x:
         raise error.ParseError(_("missing argument"))
-    return methods[x[0]](repo, subset, *x[1:])
+    return methods[x[0]](repo, subset, *x[1:], order=order)
 
 def _getrevsource(repo, r):
     extra = repo[r].extra()
@@ -69,7 +69,7 @@
 
 # operator methods
 
-def stringset(repo, subset, x):
+def stringset(repo, subset, x, order):
     x = scmutil.intrev(repo[x])
     if (x in subset
         or x == node.nullrev and isinstance(subset, fullreposet)):
@@ -126,30 +126,42 @@
     return subset & xs
 
 def andset(repo, subset, x, y, order):
-    return getset(repo, getset(repo, subset, x), y)
+    if order == anyorder:
+        yorder = anyorder
+    else:
+        yorder = followorder
+    return getset(repo, getset(repo, subset, x, order), y, yorder)
+
+def flipandset(repo, subset, y, x, order):
+    # 'flipand(y, x)' is equivalent to 'and(x, y)', but faster when y is small
+    if order == anyorder:
+        yorder = anyorder
+    else:
+        yorder = followorder
+    return getset(repo, getset(repo, subset, y, yorder), x, order)
 
 def differenceset(repo, subset, x, y, order):
-    return getset(repo, subset, x) - getset(repo, subset, y)
+    return getset(repo, subset, x, order) - getset(repo, subset, y, anyorder)
 
-def _orsetlist(repo, subset, xs):
+def _orsetlist(repo, subset, xs, order):
     assert xs
     if len(xs) == 1:
-        return getset(repo, subset, xs[0])
+        return getset(repo, subset, xs[0], order)
     p = len(xs) // 2
-    a = _orsetlist(repo, subset, xs[:p])
-    b = _orsetlist(repo, subset, xs[p:])
+    a = _orsetlist(repo, subset, xs[:p], order)
+    b = _orsetlist(repo, subset, xs[p:], order)
     return a + b
 
 def orset(repo, subset, x, order):
     xs = getlist(x)
     if order == followorder:
         # slow path to take the subset order
-        return subset & _orsetlist(repo, fullreposet(repo), xs)
+        return subset & _orsetlist(repo, fullreposet(repo), xs, anyorder)
     else:
-        return _orsetlist(repo, subset, xs)
+        return _orsetlist(repo, subset, xs, order)
 
 def notset(repo, subset, x, order):
-    return subset - getset(repo, subset, x)
+    return subset - getset(repo, subset, x, anyorder)
 
 def relationset(repo, subset, x, y, order):
     raise error.ParseError(_("can't use a relation in this context"))
@@ -176,11 +188,11 @@
 def subscriptset(repo, subset, x, y, order):
     raise error.ParseError(_("can't use a subscript in this context"))
 
-def listset(repo, subset, *xs):
+def listset(repo, subset, *xs, **opts):
     raise error.ParseError(_("can't use a list in this context"),
                            hint=_('see hg help "revsets.x or y"'))
 
-def keyvaluepair(repo, subset, k, v):
+def keyvaluepair(repo, subset, k, v, order):
     raise error.ParseError(_("can't use a key-value pair in this context"))
 
 def func(repo, subset, a, b, order):
@@ -1508,8 +1520,8 @@
                     ps.add(parents[1].rev())
     return subset & ps
 
-@predicate('present(set)', safe=True)
-def present(repo, subset, x):
+@predicate('present(set)', safe=True, takeorder=True)
+def present(repo, subset, x, order):
     """An empty set, if any revision in set isn't found; otherwise,
     all revisions in set.
 
@@ -1518,7 +1530,7 @@
     to continue even in such cases.
     """
     try:
-        return getset(repo, subset, x)
+        return getset(repo, subset, x, order)
     except error.RepoLookupError:
         return baseset()
 
@@ -1718,7 +1730,7 @@
 def reverse(repo, subset, x, order):
     """Reverse order of set.
     """
-    l = getset(repo, subset, x)
+    l = getset(repo, subset, x, order)
     if order == defineorder:
         l.reverse()
     return l
@@ -1802,7 +1814,7 @@
 
     """
     s, keyflags, opts = _getsortargs(x)
-    revs = getset(repo, subset, s)
+    revs = getset(repo, subset, s, order)
 
     if not keyflags or order != defineorder:
         return revs
@@ -1988,7 +2000,7 @@
                 raise ValueError
             revs = [r]
         except ValueError:
-            revs = stringset(repo, subset, t)
+            revs = stringset(repo, subset, t, defineorder)
 
         for r in revs:
             if r in seen:
@@ -2052,6 +2064,7 @@
     "string": stringset,
     "symbol": stringset,
     "and": andset,
+    "flipand": flipandset,
     "or": orset,
     "not": notset,
     "difference": differenceset,
@@ -2113,17 +2126,17 @@
     if aliases:
         tree = revsetlang.expandaliases(tree, aliases, warn=warn)
     tree = revsetlang.foldconcat(tree)
-    tree = revsetlang.analyze(tree, order)
+    tree = revsetlang.analyze(tree)
     tree = revsetlang.optimize(tree)
     posttreebuilthook(tree, repo)
-    return makematcher(tree)
+    return makematcher(tree, order)
 
-def makematcher(tree):
+def makematcher(tree, order=defineorder):
     """Create a matcher from an evaluatable tree"""
     def mfunc(repo, subset=None):
         if subset is None:
             subset = fullreposet(repo)
-        return getset(repo, subset, tree)
+        return getset(repo, subset, tree, order)
     return mfunc
 
 def loadpredicate(ui, extname, registrarobj):