mercurial/revset.py
changeset 34029 1b28525e6698
parent 33876 457d1ebf151b
child 34034 96f249dce03e
equal deleted inserted replaced
34028:72b5f4d53c58 34029:1b28525e6698
    50 spanset = smartset.spanset
    50 spanset = smartset.spanset
    51 fullreposet = smartset.fullreposet
    51 fullreposet = smartset.fullreposet
    52 
    52 
    53 # helpers
    53 # helpers
    54 
    54 
    55 def getset(repo, subset, x):
    55 def getset(repo, subset, x, order=defineorder):
    56     if not x:
    56     if not x:
    57         raise error.ParseError(_("missing argument"))
    57         raise error.ParseError(_("missing argument"))
    58     return methods[x[0]](repo, subset, *x[1:])
    58     return methods[x[0]](repo, subset, *x[1:], order=order)
    59 
    59 
    60 def _getrevsource(repo, r):
    60 def _getrevsource(repo, r):
    61     extra = repo[r].extra()
    61     extra = repo[r].extra()
    62     for label in ('source', 'transplant_source', 'rebase_source'):
    62     for label in ('source', 'transplant_source', 'rebase_source'):
    63         if label in extra:
    63         if label in extra:
    67                 pass
    67                 pass
    68     return None
    68     return None
    69 
    69 
    70 # operator methods
    70 # operator methods
    71 
    71 
    72 def stringset(repo, subset, x):
    72 def stringset(repo, subset, x, order):
    73     x = scmutil.intrev(repo[x])
    73     x = scmutil.intrev(repo[x])
    74     if (x in subset
    74     if (x in subset
    75         or x == node.nullrev and isinstance(subset, fullreposet)):
    75         or x == node.nullrev and isinstance(subset, fullreposet)):
    76         return baseset([x])
    76         return baseset([x])
    77     return baseset()
    77     return baseset()
   124     xs = dagop.reachableroots(repo, getset(repo, r, x), getset(repo, r, y),
   124     xs = dagop.reachableroots(repo, getset(repo, r, x), getset(repo, r, y),
   125                               includepath=True)
   125                               includepath=True)
   126     return subset & xs
   126     return subset & xs
   127 
   127 
   128 def andset(repo, subset, x, y, order):
   128 def andset(repo, subset, x, y, order):
   129     return getset(repo, getset(repo, subset, x), y)
   129     if order == anyorder:
       
   130         yorder = anyorder
       
   131     else:
       
   132         yorder = followorder
       
   133     return getset(repo, getset(repo, subset, x, order), y, yorder)
       
   134 
       
   135 def flipandset(repo, subset, y, x, order):
       
   136     # 'flipand(y, x)' is equivalent to 'and(x, y)', but faster when y is small
       
   137     if order == anyorder:
       
   138         yorder = anyorder
       
   139     else:
       
   140         yorder = followorder
       
   141     return getset(repo, getset(repo, subset, y, yorder), x, order)
   130 
   142 
   131 def differenceset(repo, subset, x, y, order):
   143 def differenceset(repo, subset, x, y, order):
   132     return getset(repo, subset, x) - getset(repo, subset, y)
   144     return getset(repo, subset, x, order) - getset(repo, subset, y, anyorder)
   133 
   145 
   134 def _orsetlist(repo, subset, xs):
   146 def _orsetlist(repo, subset, xs, order):
   135     assert xs
   147     assert xs
   136     if len(xs) == 1:
   148     if len(xs) == 1:
   137         return getset(repo, subset, xs[0])
   149         return getset(repo, subset, xs[0], order)
   138     p = len(xs) // 2
   150     p = len(xs) // 2
   139     a = _orsetlist(repo, subset, xs[:p])
   151     a = _orsetlist(repo, subset, xs[:p], order)
   140     b = _orsetlist(repo, subset, xs[p:])
   152     b = _orsetlist(repo, subset, xs[p:], order)
   141     return a + b
   153     return a + b
   142 
   154 
   143 def orset(repo, subset, x, order):
   155 def orset(repo, subset, x, order):
   144     xs = getlist(x)
   156     xs = getlist(x)
   145     if order == followorder:
   157     if order == followorder:
   146         # slow path to take the subset order
   158         # slow path to take the subset order
   147         return subset & _orsetlist(repo, fullreposet(repo), xs)
   159         return subset & _orsetlist(repo, fullreposet(repo), xs, anyorder)
   148     else:
   160     else:
   149         return _orsetlist(repo, subset, xs)
   161         return _orsetlist(repo, subset, xs, order)
   150 
   162 
   151 def notset(repo, subset, x, order):
   163 def notset(repo, subset, x, order):
   152     return subset - getset(repo, subset, x)
   164     return subset - getset(repo, subset, x, anyorder)
   153 
   165 
   154 def relationset(repo, subset, x, y, order):
   166 def relationset(repo, subset, x, y, order):
   155     raise error.ParseError(_("can't use a relation in this context"))
   167     raise error.ParseError(_("can't use a relation in this context"))
   156 
   168 
   157 def relsubscriptset(repo, subset, x, y, z, order):
   169 def relsubscriptset(repo, subset, x, y, z, order):
   174     raise error.UnknownIdentifier(rel, ['generations'])
   186     raise error.UnknownIdentifier(rel, ['generations'])
   175 
   187 
   176 def subscriptset(repo, subset, x, y, order):
   188 def subscriptset(repo, subset, x, y, order):
   177     raise error.ParseError(_("can't use a subscript in this context"))
   189     raise error.ParseError(_("can't use a subscript in this context"))
   178 
   190 
   179 def listset(repo, subset, *xs):
   191 def listset(repo, subset, *xs, **opts):
   180     raise error.ParseError(_("can't use a list in this context"),
   192     raise error.ParseError(_("can't use a list in this context"),
   181                            hint=_('see hg help "revsets.x or y"'))
   193                            hint=_('see hg help "revsets.x or y"'))
   182 
   194 
   183 def keyvaluepair(repo, subset, k, v):
   195 def keyvaluepair(repo, subset, k, v, order):
   184     raise error.ParseError(_("can't use a key-value pair in this context"))
   196     raise error.ParseError(_("can't use a key-value pair in this context"))
   185 
   197 
   186 def func(repo, subset, a, b, order):
   198 def func(repo, subset, a, b, order):
   187     f = getsymbol(a)
   199     f = getsymbol(a)
   188     if f in symbols:
   200     if f in symbols:
  1506                 parents = repo[r].parents()
  1518                 parents = repo[r].parents()
  1507                 if len(parents) == 2:
  1519                 if len(parents) == 2:
  1508                     ps.add(parents[1].rev())
  1520                     ps.add(parents[1].rev())
  1509     return subset & ps
  1521     return subset & ps
  1510 
  1522 
  1511 @predicate('present(set)', safe=True)
  1523 @predicate('present(set)', safe=True, takeorder=True)
  1512 def present(repo, subset, x):
  1524 def present(repo, subset, x, order):
  1513     """An empty set, if any revision in set isn't found; otherwise,
  1525     """An empty set, if any revision in set isn't found; otherwise,
  1514     all revisions in set.
  1526     all revisions in set.
  1515 
  1527 
  1516     If any of specified revisions is not present in the local repository,
  1528     If any of specified revisions is not present in the local repository,
  1517     the query is normally aborted. But this predicate allows the query
  1529     the query is normally aborted. But this predicate allows the query
  1518     to continue even in such cases.
  1530     to continue even in such cases.
  1519     """
  1531     """
  1520     try:
  1532     try:
  1521         return getset(repo, subset, x)
  1533         return getset(repo, subset, x, order)
  1522     except error.RepoLookupError:
  1534     except error.RepoLookupError:
  1523         return baseset()
  1535         return baseset()
  1524 
  1536 
  1525 # for internal use
  1537 # for internal use
  1526 @predicate('_notpublic', safe=True)
  1538 @predicate('_notpublic', safe=True)
  1716 
  1728 
  1717 @predicate('reverse(set)', safe=True, takeorder=True)
  1729 @predicate('reverse(set)', safe=True, takeorder=True)
  1718 def reverse(repo, subset, x, order):
  1730 def reverse(repo, subset, x, order):
  1719     """Reverse order of set.
  1731     """Reverse order of set.
  1720     """
  1732     """
  1721     l = getset(repo, subset, x)
  1733     l = getset(repo, subset, x, order)
  1722     if order == defineorder:
  1734     if order == defineorder:
  1723         l.reverse()
  1735         l.reverse()
  1724     return l
  1736     return l
  1725 
  1737 
  1726 @predicate('roots(set)', safe=True)
  1738 @predicate('roots(set)', safe=True)
  1800     takes one optional argument, ``topo.firstbranch``, which takes a revset that
  1812     takes one optional argument, ``topo.firstbranch``, which takes a revset that
  1801     specifies what topographical branches to prioritize in the sort.
  1813     specifies what topographical branches to prioritize in the sort.
  1802 
  1814 
  1803     """
  1815     """
  1804     s, keyflags, opts = _getsortargs(x)
  1816     s, keyflags, opts = _getsortargs(x)
  1805     revs = getset(repo, subset, s)
  1817     revs = getset(repo, subset, s, order)
  1806 
  1818 
  1807     if not keyflags or order != defineorder:
  1819     if not keyflags or order != defineorder:
  1808         return revs
  1820         return revs
  1809     if len(keyflags) == 1 and keyflags[0][0] == "rev":
  1821     if len(keyflags) == 1 and keyflags[0][0] == "rev":
  1810         revs.sort(reverse=keyflags[0][1])
  1822         revs.sort(reverse=keyflags[0][1])
  1986             r = int(t)
  1998             r = int(t)
  1987             if str(r) != t or r not in cl:
  1999             if str(r) != t or r not in cl:
  1988                 raise ValueError
  2000                 raise ValueError
  1989             revs = [r]
  2001             revs = [r]
  1990         except ValueError:
  2002         except ValueError:
  1991             revs = stringset(repo, subset, t)
  2003             revs = stringset(repo, subset, t, defineorder)
  1992 
  2004 
  1993         for r in revs:
  2005         for r in revs:
  1994             if r in seen:
  2006             if r in seen:
  1995                 continue
  2007                 continue
  1996             if (r in subset
  2008             if (r in subset
  2050     "rangepost": rangepost,
  2062     "rangepost": rangepost,
  2051     "dagrange": dagrange,
  2063     "dagrange": dagrange,
  2052     "string": stringset,
  2064     "string": stringset,
  2053     "symbol": stringset,
  2065     "symbol": stringset,
  2054     "and": andset,
  2066     "and": andset,
       
  2067     "flipand": flipandset,
  2055     "or": orset,
  2068     "or": orset,
  2056     "not": notset,
  2069     "not": notset,
  2057     "difference": differenceset,
  2070     "difference": differenceset,
  2058     "relation": relationset,
  2071     "relation": relationset,
  2059     "relsubscript": relsubscriptset,
  2072     "relsubscript": relsubscriptset,
  2111     if localalias:
  2124     if localalias:
  2112         aliases.extend(localalias.items())
  2125         aliases.extend(localalias.items())
  2113     if aliases:
  2126     if aliases:
  2114         tree = revsetlang.expandaliases(tree, aliases, warn=warn)
  2127         tree = revsetlang.expandaliases(tree, aliases, warn=warn)
  2115     tree = revsetlang.foldconcat(tree)
  2128     tree = revsetlang.foldconcat(tree)
  2116     tree = revsetlang.analyze(tree, order)
  2129     tree = revsetlang.analyze(tree)
  2117     tree = revsetlang.optimize(tree)
  2130     tree = revsetlang.optimize(tree)
  2118     posttreebuilthook(tree, repo)
  2131     posttreebuilthook(tree, repo)
  2119     return makematcher(tree)
  2132     return makematcher(tree, order)
  2120 
  2133 
  2121 def makematcher(tree):
  2134 def makematcher(tree, order=defineorder):
  2122     """Create a matcher from an evaluatable tree"""
  2135     """Create a matcher from an evaluatable tree"""
  2123     def mfunc(repo, subset=None):
  2136     def mfunc(repo, subset=None):
  2124         if subset is None:
  2137         if subset is None:
  2125             subset = fullreposet(repo)
  2138             subset = fullreposet(repo)
  2126         return getset(repo, subset, tree)
  2139         return getset(repo, subset, tree, order)
  2127     return mfunc
  2140     return mfunc
  2128 
  2141 
  2129 def loadpredicate(ui, extname, registrarobj):
  2142 def loadpredicate(ui, extname, registrarobj):
  2130     """Load revset predicates from specified registrarobj
  2143     """Load revset predicates from specified registrarobj
  2131     """
  2144     """