Mercurial > public > mercurial-scm > hg
diff mercurial/revset.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 911e25dc9d8c |
children | 687b865b95ad |
line wrap: on
line diff
--- a/mercurial/revset.py Sat Oct 05 10:29:34 2019 -0400 +++ b/mercurial/revset.py Sun Oct 06 09:45:02 2019 -0400 @@ -93,17 +93,19 @@ # # There are a few revsets that always redefine the order if 'define' is # specified: 'sort(X)', 'reverse(X)', 'x:y'. -anyorder = 'any' # don't care the order, could be even random-shuffled +anyorder = 'any' # don't care the order, could be even random-shuffled defineorder = 'define' # ALWAYS redefine, or ALWAYS follow the current order followorder = 'follow' # MUST follow the current order # helpers + def getset(repo, subset, x, order=defineorder): if not x: raise error.ParseError(_("missing argument")) return methods[x[0]](repo, subset, *x[1:], order=order) + def _getrevsource(repo, r): extra = repo[r].extra() for label in ('source', 'transplant_source', 'rebase_source'): @@ -114,11 +116,14 @@ pass return None + def _sortedb(xs): return sorted(pycompat.rapply(pycompat.maybebytestr, xs)) + # operator methods + def stringset(repo, subset, x, order): if not x: raise error.ParseError(_("empty string is not a valid revision")) @@ -127,6 +132,7 @@ return baseset([x]) return baseset() + def rawsmartset(repo, subset, x, order): """argument is already a smartset, use that directly""" if order == followorder: @@ -134,6 +140,7 @@ else: return x & subset + def rangeset(repo, subset, x, y, order): m = getset(repo, fullreposet(repo), x) n = getset(repo, fullreposet(repo), y) @@ -142,10 +149,12 @@ return baseset() return _makerangeset(repo, subset, m.first(), n.last(), order) + def rangeall(repo, subset, x, order): assert x is None return _makerangeset(repo, subset, 0, repo.changelog.tiprev(), order) + def rangepre(repo, subset, y, order): # ':y' can't be rewritten to '0:y' since '0' may be hidden n = getset(repo, fullreposet(repo), y) @@ -153,12 +162,15 @@ return baseset() return _makerangeset(repo, subset, 0, n.last(), order) + def rangepost(repo, subset, x, order): m = getset(repo, fullreposet(repo), x) if not m: return baseset() - return _makerangeset(repo, subset, m.first(), repo.changelog.tiprev(), - order) + return _makerangeset( + repo, subset, m.first(), repo.changelog.tiprev(), order + ) + def _makerangeset(repo, subset, m, n, order): if m == n: @@ -178,12 +190,15 @@ # carrying the sorting over when possible would be more efficient return subset & r + def dagrange(repo, subset, x, y, order): r = fullreposet(repo) - xs = dagop.reachableroots(repo, getset(repo, r, x), getset(repo, r, y), - includepath=True) + xs = dagop.reachableroots( + repo, getset(repo, r, x), getset(repo, r, y), includepath=True + ) return subset & xs + def andset(repo, subset, x, y, order): if order == anyorder: yorder = anyorder @@ -191,6 +206,7 @@ yorder = followorder return getset(repo, getset(repo, subset, x, order), y, yorder) + def andsmallyset(repo, subset, x, y, order): # 'andsmally(x, y)' is equivalent to 'and(x, y)', but faster when y is small if order == anyorder: @@ -199,9 +215,11 @@ yorder = followorder return getset(repo, getset(repo, subset, y, yorder), x, order) + def differenceset(repo, subset, x, y, order): return getset(repo, subset, x, order) - getset(repo, subset, y, anyorder) + def _orsetlist(repo, subset, xs, order): assert xs if len(xs) == 1: @@ -211,6 +229,7 @@ b = _orsetlist(repo, subset, xs[p:], order) return a + b + def orset(repo, subset, x, order): xs = getlist(x) if not xs: @@ -221,12 +240,15 @@ else: return _orsetlist(repo, subset, xs, order) + def notset(repo, subset, x, order): 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")) + def _splitrange(a, b): """Split range with bounds a and b into two ranges at 0 and return two tuples of numbers for use as startdepth and stopdepth arguments of @@ -257,14 +279,17 @@ descdepths = (max(a, 0), b + 1) return ancdepths, descdepths + def generationsrel(repo, subset, x, rel, z, order): # TODO: rewrite tests, and drop startdepth argument from ancestors() and # descendants() predicates - a, b = getintrange(z, - _('relation subscript must be an integer or a range'), - _('relation subscript bounds must be integers'), - deffirst=-(dagop.maxlogdepth - 1), - deflast=+(dagop.maxlogdepth - 1)) + a, b = getintrange( + z, + _('relation subscript must be an integer or a range'), + _('relation subscript bounds must be integers'), + deffirst=-(dagop.maxlogdepth - 1), + deflast=+(dagop.maxlogdepth - 1), + ) (ancstart, ancstop), (descstart, descstop) = _splitrange(a, b) if ancstart is None and descstart is None: @@ -284,6 +309,7 @@ return subset & s + def relsubscriptset(repo, subset, x, y, z, order): # this is pretty basic implementation of 'x#y[z]' operator, still # experimental so undocumented. see the wiki for further ideas. @@ -295,16 +321,22 @@ relnames = [r for r in subscriptrelations.keys() if len(r) > 1] raise error.UnknownIdentifier(rel, relnames) + def subscriptset(repo, subset, x, y, order): raise error.ParseError(_("can't use a subscript in this context")) + 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"\'')) + 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, order): raise error.ParseError(_("can't use a key-value pair in this context")) + def func(repo, subset, a, b, order): f = getsymbol(a) if f in symbols: @@ -318,6 +350,7 @@ syms = [s for (s, fn) in symbols.items() if keep(fn)] raise error.UnknownIdentifier(f, syms) + # functions # symbols are callables like: @@ -335,12 +368,15 @@ predicate = registrar.revsetpredicate() + @predicate('_destupdate') def _destupdate(repo, subset, x): # experimental revset for update destination args = getargsdict(x, 'limit', 'clean') - return subset & baseset([destutil.destupdate(repo, - **pycompat.strkwargs(args))[0]]) + return subset & baseset( + [destutil.destupdate(repo, **pycompat.strkwargs(args))[0]] + ) + @predicate('_destmerge') def _destmerge(repo, subset, x): @@ -350,6 +386,7 @@ sourceset = getset(repo, fullreposet(repo), x) return subset & baseset([destutil.destmerge(repo, sourceset=sourceset)]) + @predicate('adds(pattern)', safe=True, weight=30) def adds(repo, subset, x): """Changesets that add a file matching pattern. @@ -362,6 +399,7 @@ pat = getstring(x, _("adds requires a pattern")) return checkstatus(repo, subset, pat, 1) + @predicate('ancestor(*changeset)', safe=True, weight=0.5) def ancestor(repo, subset, x): """A greatest common ancestor of the changesets. @@ -383,14 +421,17 @@ return baseset([r]) return baseset() -def _ancestors(repo, subset, x, followfirst=False, startdepth=None, - stopdepth=None): + +def _ancestors( + repo, subset, x, followfirst=False, startdepth=None, stopdepth=None +): heads = getset(repo, fullreposet(repo), x) if not heads: return baseset() s = dagop.revancestors(repo, heads, followfirst, startdepth, stopdepth) return subset & s + @predicate('ancestors(set[, depth])', safe=True) def ancestors(repo, subset, x): """Changesets that are ancestors of changesets in set, including the @@ -406,8 +447,9 @@ raise error.ParseError(_('ancestors takes at least 1 argument')) startdepth = stopdepth = None if 'startdepth' in args: - n = getinteger(args['startdepth'], - "ancestors expects an integer startdepth") + n = getinteger( + args['startdepth'], "ancestors expects an integer startdepth" + ) if n < 0: raise error.ParseError("negative startdepth") startdepth = n @@ -417,8 +459,10 @@ if n < 0: raise error.ParseError(_("negative depth")) stopdepth = n + 1 - return _ancestors(repo, subset, args['set'], - startdepth=startdepth, stopdepth=stopdepth) + return _ancestors( + repo, subset, args['set'], startdepth=startdepth, stopdepth=stopdepth + ) + @predicate('_firstancestors', safe=True) def _firstancestors(repo, subset, x): @@ -426,6 +470,7 @@ # Like ``ancestors(set)`` but follows only the first parents. return _ancestors(repo, subset, x, followfirst=True) + def _childrenspec(repo, subset, x, n, order): """Changesets that are the Nth child of a changeset in set. @@ -438,12 +483,14 @@ break if len(c) > 1: raise error.RepoLookupError( - _("revision in set has more than one child")) + _("revision in set has more than one child") + ) r = c[0].rev() else: cs.add(r) return subset & cs + def ancestorspec(repo, subset, x, n, order): """``set~n`` Changesets that are the Nth ancestor (first parents only) of a changeset @@ -464,6 +511,7 @@ ps.add(r) return subset & ps + @predicate('author(string)', safe=True, weight=10) def author(repo, subset, x): """Alias for ``user(string)``. @@ -471,8 +519,10 @@ # i18n: "author" is a keyword n = getstring(x, _("author requires a string")) kind, pattern, matcher = _substringmatcher(n, casesensitive=False) - return subset.filter(lambda x: matcher(repo[x].user()), - condrepr=('<user %r>', n)) + return subset.filter( + lambda x: matcher(repo[x].user()), condrepr=('<user %r>', n) + ) + @predicate('bisect(string)', safe=True) def bisect(repo, subset, x): @@ -491,12 +541,14 @@ state = set(hbisect.get(repo, status)) return subset & state + # Backward-compatibility # - no help entry so that we do not advertise it any more @predicate('bisected', safe=True) def bisected(repo, subset, x): return bisect(repo, subset, x) + @predicate('bookmark([name])', safe=True) def bookmark(repo, subset, x): """The named bookmark or all bookmarks. @@ -506,9 +558,11 @@ # i18n: "bookmark" is a keyword args = getargs(x, 0, 1, _('bookmark takes one or no arguments')) if args: - bm = getstring(args[0], - # i18n: "bookmark" is a keyword - _('the argument to bookmark must be a string')) + bm = getstring( + args[0], + # i18n: "bookmark" is a keyword + _('the argument to bookmark must be a string'), + ) kind, pattern, matcher = stringutil.stringmatcher(bm) bms = set() if kind == 'literal': @@ -516,8 +570,9 @@ pattern = repo._bookmarks.expandname(pattern) bmrev = repo._bookmarks.get(pattern, None) if not bmrev: - raise error.RepoLookupError(_("bookmark '%s' does not exist") - % pattern) + raise error.RepoLookupError( + _("bookmark '%s' does not exist") % pattern + ) bms.add(repo[bmrev].rev()) else: matchrevs = set() @@ -531,6 +586,7 @@ bms -= {node.nullrev} return subset & bms + @predicate('branch(string or set)', safe=True, weight=10) def branch(repo, subset, x): """ @@ -541,6 +597,7 @@ :hg:`help revisions.patterns`. """ getbi = repo.revbranchcache().branchinfo + def getbranch(r): try: return getbi(r)[0] @@ -558,22 +615,28 @@ # note: falls through to the revspec case if no branch with # this name exists and pattern kind is not specified explicitly if repo.branchmap().hasbranch(pattern): - return subset.filter(lambda r: matcher(getbranch(r)), - condrepr=('<branch %r>', b)) + return subset.filter( + lambda r: matcher(getbranch(r)), condrepr=('<branch %r>', b) + ) if b.startswith('literal:'): - raise error.RepoLookupError(_("branch '%s' does not exist") - % pattern) + raise error.RepoLookupError( + _("branch '%s' does not exist") % pattern + ) else: - return subset.filter(lambda r: matcher(getbranch(r)), - condrepr=('<branch %r>', b)) + return subset.filter( + lambda r: matcher(getbranch(r)), condrepr=('<branch %r>', b) + ) s = getset(repo, fullreposet(repo), x) b = set() for r in s: b.add(getbranch(r)) c = s.__contains__ - return subset.filter(lambda r: c(r) or getbranch(r) in b, - condrepr=lambda: '<branch %r>' % _sortedb(b)) + return subset.filter( + lambda r: c(r) or getbranch(r) in b, + condrepr=lambda: '<branch %r>' % _sortedb(b), + ) + @predicate('phasedivergent()', safe=True) def phasedivergent(repo, subset, x): @@ -587,6 +650,7 @@ phasedivergent = obsmod.getrevs(repo, 'phasedivergent') return subset & phasedivergent + @predicate('bundle()', safe=True) def bundle(repo, subset, x): """Changesets in the bundle. @@ -599,6 +663,7 @@ raise error.Abort(_("no bundle provided - specify with -R")) return subset & bundlerevs + def checkstatus(repo, subset, pat, field): """Helper for status-related revsets (adds, removes, modifies). The field parameter says which kind is desired: @@ -609,6 +674,7 @@ hasset = matchmod.patkind(pat) == 'set' mcache = [None] + def matches(x): c = repo[x] if not mcache[0] or hasset: @@ -637,6 +703,7 @@ return subset.filter(matches, condrepr=('<status[%r] %r>', field, pat)) + def _children(repo, subset, parentset): if not parentset: return baseset() @@ -654,6 +721,7 @@ cs.add(r) return baseset(cs) + @predicate('children(set)', safe=True) def children(repo, subset, x): """Child changesets of changesets in set. @@ -662,14 +730,17 @@ cs = _children(repo, subset, s) return subset & cs + @predicate('closed()', safe=True, weight=10) def closed(repo, subset, x): """Changeset is closed. """ # i18n: "closed" is a keyword getargs(x, 0, 0, _("closed takes no arguments")) - return subset.filter(lambda r: repo[r].closesbranch(), - condrepr='<branch closed>') + return subset.filter( + lambda r: repo[r].closesbranch(), condrepr='<branch closed>' + ) + # for internal use @predicate('_commonancestorheads(set)', safe=True) @@ -684,6 +755,7 @@ ancs = repo.changelog._commonancestorsheads(*list(startrevs)) return subset & baseset(ancs) + @predicate('commonancestors(set)', safe=True) def commonancestors(repo, subset, x): """Changesets that are ancestors of every changeset in set. @@ -695,6 +767,7 @@ subset &= dagop.revancestors(repo, baseset([r])) return subset + @predicate('contains(pattern)', weight=100) def contains(repo, subset, x): """The revision's manifest contains a file matching pattern (but might not @@ -722,6 +795,7 @@ return subset.filter(matches, condrepr=('<contains %r>', pat)) + @predicate('converted([id])', safe=True) def converted(repo, subset, x): """Changesets converted from the given identifier in the old repository if @@ -742,8 +816,10 @@ source = repo[r].extra().get('convert_revision', None) return source is not None and (rev is None or source.startswith(rev)) - return subset.filter(lambda r: _matchvalue(r), - condrepr=('<converted %r>', rev)) + return subset.filter( + lambda r: _matchvalue(r), condrepr=('<converted %r>', rev) + ) + @predicate('date(interval)', safe=True, weight=10) def date(repo, subset, x): @@ -752,8 +828,10 @@ # i18n: "date" is a keyword ds = getstring(x, _("date requires a string")) dm = dateutil.matchdate(ds) - return subset.filter(lambda x: dm(repo[x].date()[0]), - condrepr=('<date %r>', ds)) + return subset.filter( + lambda x: dm(repo[x].date()[0]), condrepr=('<date %r>', ds) + ) + @predicate('desc(string)', safe=True, weight=10) def desc(repo, subset, x): @@ -767,17 +845,21 @@ kind, pattern, matcher = _substringmatcher(ds, casesensitive=False) - return subset.filter(lambda r: matcher(repo[r].description()), - condrepr=('<desc %r>', ds)) - -def _descendants(repo, subset, x, followfirst=False, startdepth=None, - stopdepth=None): + return subset.filter( + lambda r: matcher(repo[r].description()), condrepr=('<desc %r>', ds) + ) + + +def _descendants( + repo, subset, x, followfirst=False, startdepth=None, stopdepth=None +): roots = getset(repo, fullreposet(repo), x) if not roots: return baseset() s = dagop.revdescendants(repo, roots, followfirst, startdepth, stopdepth) return subset & s + @predicate('descendants(set[, depth])', safe=True) def descendants(repo, subset, x): """Changesets which are descendants of changesets in set, including the @@ -793,8 +875,9 @@ raise error.ParseError(_('descendants takes at least 1 argument')) startdepth = stopdepth = None if 'startdepth' in args: - n = getinteger(args['startdepth'], - "descendants expects an integer startdepth") + n = getinteger( + args['startdepth'], "descendants expects an integer startdepth" + ) if n < 0: raise error.ParseError("negative startdepth") startdepth = n @@ -804,8 +887,10 @@ if n < 0: raise error.ParseError(_("negative depth")) stopdepth = n + 1 - return _descendants(repo, subset, args['set'], - startdepth=startdepth, stopdepth=stopdepth) + return _descendants( + repo, subset, args['set'], startdepth=startdepth, stopdepth=stopdepth + ) + @predicate('_firstdescendants', safe=True) def _firstdescendants(repo, subset, x): @@ -813,6 +898,7 @@ # Like ``descendants(set)`` but follows only the first parents. return _descendants(repo, subset, x, followfirst=True) + @predicate('destination([set])', safe=True, weight=10) def destination(repo, subset, x): """Changesets that were created by a graft, transplant or rebase operation, @@ -855,8 +941,11 @@ r = src src = _getrevsource(repo, r) - return subset.filter(dests.__contains__, - condrepr=lambda: '<destination %r>' % _sortedb(dests)) + return subset.filter( + dests.__contains__, + condrepr=lambda: '<destination %r>' % _sortedb(dests), + ) + @predicate('contentdivergent()', safe=True) def contentdivergent(repo, subset, x): @@ -869,6 +958,7 @@ contentdivergent = obsmod.getrevs(repo, 'contentdivergent') return subset & contentdivergent + @predicate('expectsize(set[, size])', safe=True, takeorder=True) def expectsize(repo, subset, x, order): """Return the given revset if size matches the revset size. @@ -884,21 +974,25 @@ err = '' if 'size' not in args or 'set' not in args: raise error.ParseError(_('invalid set of arguments')) - minsize, maxsize = getintrange(args['size'], - _('expectsize requires a size range' - ' or a positive integer'), - _('size range bounds must be integers'), - minsize, maxsize) + minsize, maxsize = getintrange( + args['size'], + _('expectsize requires a size range' ' or a positive integer'), + _('size range bounds must be integers'), + minsize, + maxsize, + ) if minsize < 0 or maxsize < 0: raise error.ParseError(_('negative size')) rev = getset(repo, fullreposet(repo), args['set'], order=order) if minsize != maxsize and (len(rev) < minsize or len(rev) > maxsize): - err = _('revset size mismatch.' - ' expected between %d and %d, got %d') % (minsize, maxsize, - len(rev)) + err = _( + 'revset size mismatch.' ' expected between %d and %d, got %d' + ) % (minsize, maxsize, len(rev)) elif minsize == maxsize and len(rev) != minsize: - err = _('revset size mismatch.' - ' expected %d, got %d') % (minsize, len(rev)) + err = _('revset size mismatch.' ' expected %d, got %d') % ( + minsize, + len(rev), + ) if err: raise error.RepoLookupError(err) if order == followorder: @@ -906,17 +1000,21 @@ else: return rev & subset + @predicate('extdata(source)', safe=False, weight=100) def extdata(repo, subset, x): """Changesets in the specified extdata source. (EXPERIMENTAL)""" # i18n: "extdata" is a keyword args = getargsdict(x, 'extdata', 'source') - source = getstring(args.get('source'), - # i18n: "extdata" is a keyword - _('extdata takes at least 1 string argument')) + source = getstring( + args.get('source'), + # i18n: "extdata" is a keyword + _('extdata takes at least 1 string argument'), + ) data = scmutil.extdatasource(repo, source) return subset & baseset(data) + @predicate('extinct()', safe=True) def extinct(repo, subset, x): """Obsolete changesets with obsolete descendants only. @@ -926,6 +1024,7 @@ extincts = obsmod.getrevs(repo, 'extinct') return subset & extincts + @predicate('extra(label, [value])', safe=True) def extra(repo, subset, x): """Changesets with the given label in the extra metadata, with the given @@ -939,22 +1038,26 @@ # i18n: "extra" is a keyword raise error.ParseError(_('extra takes at least 1 argument')) # i18n: "extra" is a keyword - label = getstring(args['label'], _('first argument to extra must be ' - 'a string')) + label = getstring( + args['label'], _('first argument to extra must be ' 'a string') + ) value = None if 'value' in args: # i18n: "extra" is a keyword - value = getstring(args['value'], _('second argument to extra must be ' - 'a string')) + value = getstring( + args['value'], _('second argument to extra must be ' 'a string') + ) kind, value, matcher = stringutil.stringmatcher(value) def _matchvalue(r): extra = repo[r].extra() return label in extra and (value is None or matcher(extra[label])) - return subset.filter(lambda r: _matchvalue(r), - condrepr=('<extra[%r] %r>', label, value)) + return subset.filter( + lambda r: _matchvalue(r), condrepr=('<extra[%r] %r>', label, value) + ) + @predicate('filelog(pattern)', safe=True) def filelog(repo, subset, x): @@ -1019,12 +1122,14 @@ return subset & s + @predicate('first(set, [n])', safe=True, takeorder=True, weight=0) def first(repo, subset, x, order): """An alias for limit(). """ return limit(repo, subset, x, order) + def _follow(repo, subset, x, name, followfirst=False): args = getargsdict(x, name, 'file startrev') revs = None @@ -1039,8 +1144,9 @@ ctx = mctx = repo[r] if r is None: ctx = repo['.'] - m = matchmod.match(repo.root, repo.getcwd(), [x], - ctx=mctx, default='path') + m = matchmod.match( + repo.root, repo.getcwd(), [x], ctx=mctx, default='path' + ) fctxs.extend(ctx[f].introfilectx() for f in ctx.manifest().walk(m)) s = dagop.filerevancestors(fctxs, followfirst) else: @@ -1050,6 +1156,7 @@ return subset & s + @predicate('follow([file[, startrev]])', safe=True) def follow(repo, subset, x): """ @@ -1059,6 +1166,7 @@ """ return _follow(repo, subset, x, 'follow') + @predicate('_followfirst', safe=True) def _followfirst(repo, subset, x): # ``followfirst([file[, startrev]])`` @@ -1066,8 +1174,10 @@ # of every revisions or files revisions. return _follow(repo, subset, x, '_followfirst', followfirst=True) -@predicate('followlines(file, fromline:toline[, startrev=., descend=False])', - safe=True) + +@predicate( + 'followlines(file, fromline:toline[, startrev=., descend=False])', safe=True +) def followlines(repo, subset, x): """Changesets modifying `file` in line range ('fromline', 'toline'). @@ -1089,7 +1199,8 @@ if len(revs) != 1: raise error.ParseError( # i18n: "followlines" is a keyword - _("followlines expects exactly one revision")) + _("followlines expects exactly one revision") + ) rev = revs.last() pat = getstring(args['file'], _("followlines requires a pattern")) @@ -1097,29 +1208,45 @@ msg = _("followlines expects exactly one file") fname = scmutil.parsefollowlinespattern(repo, rev, pat, msg) fromline, toline = util.processlinerange( - *getintrange(args['lines'][0], - # i18n: "followlines" is a keyword - _("followlines expects a line number or a range"), - _("line range bounds must be integers"))) + *getintrange( + args['lines'][0], + # i18n: "followlines" is a keyword + _("followlines expects a line number or a range"), + _("line range bounds must be integers"), + ) + ) fctx = repo[rev].filectx(fname) descend = False if 'descend' in args: - descend = getboolean(args['descend'], - # i18n: "descend" is a keyword - _("descend argument must be a boolean")) + descend = getboolean( + args['descend'], + # i18n: "descend" is a keyword + _("descend argument must be a boolean"), + ) if descend: rs = generatorset( - (c.rev() for c, _linerange - in dagop.blockdescendants(fctx, fromline, toline)), - iterasc=True) + ( + c.rev() + for c, _linerange in dagop.blockdescendants( + fctx, fromline, toline + ) + ), + iterasc=True, + ) else: rs = generatorset( - (c.rev() for c, _linerange - in dagop.blockancestors(fctx, fromline, toline)), - iterasc=False) + ( + c.rev() + for c, _linerange in dagop.blockancestors( + fctx, fromline, toline + ) + ), + iterasc=False, + ) return subset & rs + @predicate('all()', safe=True) def getall(repo, subset, x): """All changesets, the same as ``0:tip``. @@ -1128,6 +1255,7 @@ getargs(x, 0, 0, _("all takes no arguments")) return subset & spanset(repo) # drop "null" if any + @predicate('grep(regex)', weight=10) def grep(repo, subset, x): """Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')`` @@ -1139,7 +1267,8 @@ gr = re.compile(getstring(x, _("grep requires a string"))) except re.error as e: raise error.ParseError( - _('invalid match pattern: %s') % stringutil.forcebytestr(e)) + _('invalid match pattern: %s') % stringutil.forcebytestr(e) + ) def matches(x): c = repo[x] @@ -1150,6 +1279,7 @@ return subset.filter(matches, condrepr=('<grep %r>', gr.pattern)) + @predicate('_matchfiles', safe=True) def _matchfiles(repo, subset, x): # _matchfiles takes a revset list of prefixed arguments: @@ -1178,16 +1308,18 @@ exc.append(value) elif prefix == 'r:': if rev is not None: - raise error.ParseError('_matchfiles expected at most one ' - 'revision') - if value == '': # empty means working directory + raise error.ParseError( + '_matchfiles expected at most one ' 'revision' + ) + if value == '': # empty means working directory rev = node.wdirrev else: rev = value elif prefix == 'd:': if default is not None: - raise error.ParseError('_matchfiles expected at most one ' - 'default mode') + raise error.ParseError( + '_matchfiles expected at most one ' 'default mode' + ) default = value else: raise error.ParseError('invalid _matchfiles prefix: %s' % prefix) @@ -1201,6 +1333,7 @@ # revisions is quite expensive. getfiles = repo.changelog.readfiles wdirrev = node.wdirrev + def matches(x): if x == wdirrev: files = repo[x].files() @@ -1209,9 +1342,15 @@ if not mcache[0] or (hasset and rev is None): r = x if rev is None else rev - mcache[0] = matchmod.match(repo.root, repo.getcwd(), pats, - include=inc, exclude=exc, ctx=repo[r], - default=default) + mcache[0] = matchmod.match( + repo.root, + repo.getcwd(), + pats, + include=inc, + exclude=exc, + ctx=repo[r], + default=default, + ) m = mcache[0] for f in files: @@ -1219,10 +1358,19 @@ return True return False - return subset.filter(matches, - condrepr=('<matchfiles patterns=%r, include=%r ' - 'exclude=%r, default=%r, rev=%r>', - pats, inc, exc, default, rev)) + return subset.filter( + matches, + condrepr=( + '<matchfiles patterns=%r, include=%r ' + 'exclude=%r, default=%r, rev=%r>', + pats, + inc, + exc, + default, + rev, + ), + ) + @predicate('file(pattern)', safe=True, weight=10) def hasfile(repo, subset, x): @@ -1237,6 +1385,7 @@ pat = getstring(x, _("file requires a pattern")) return _matchfiles(repo, subset, ('string', 'p:' + pat)) + @predicate('head()', safe=True) def head(repo, subset, x): """Changeset is a named branch head. @@ -1249,6 +1398,7 @@ hs.update(cl.rev(h) for h in ls) return subset & baseset(hs) + @predicate('heads(set)', safe=True, takeorder=True) def heads(repo, subset, x, order): """Members of set with no children in set. @@ -1270,6 +1420,7 @@ heads = baseset(heads) return subset & heads + @predicate('hidden()', safe=True) def hidden(repo, subset, x): """Hidden changesets. @@ -1279,6 +1430,7 @@ hiddenrevs = repoview.filterrevs(repo, 'visible') return subset & hiddenrevs + @predicate('keyword(string)', safe=True, weight=10) def keyword(repo, subset, x): """Search commit message, user name, and names of changed files for @@ -1292,11 +1444,14 @@ def matches(r): c = repo[r] - return any(kw in encoding.lower(t) - for t in c.files() + [c.user(), c.description()]) + return any( + kw in encoding.lower(t) + for t in c.files() + [c.user(), c.description()] + ) return subset.filter(matches, condrepr=('<keyword %r>', kw)) + @predicate('limit(set[, n[, offset]])', safe=True, takeorder=True, weight=0) def limit(repo, subset, x, order): """First n members of set, defaulting to 1, starting from offset. @@ -1319,6 +1474,7 @@ return subset & ls return ls & subset + @predicate('last(set, [n])', safe=True, takeorder=True) def last(repo, subset, x, order): """Last n members of set, defaulting to 1. @@ -1339,6 +1495,7 @@ ls.reverse() return ls & subset + @predicate('max(set)', safe=True) def maxrev(repo, subset, x): """Changeset with highest revision number in set. @@ -1354,6 +1511,7 @@ pass return baseset(datarepr=('<max %r, %r>', subset, os)) + @predicate('merge()', safe=True) def merge(repo, subset, x): """Changeset is a merge changeset. @@ -1362,13 +1520,16 @@ getargs(x, 0, 0, _("merge takes no arguments")) cl = repo.changelog nullrev = node.nullrev + def ismerge(r): try: return cl.parentrevs(r)[1] != nullrev except error.WdirUnsupported: return bool(repo[r].p2()) + return subset.filter(ismerge, condrepr='<merge>') + @predicate('branchpoint()', safe=True) def branchpoint(repo, subset, x): """Changesets with more than one child. @@ -1381,13 +1542,15 @@ # XXX this should be 'parentset.min()' assuming 'parentset' is a smartset # (and if it is not, it should.) baserev = min(subset) - parentscount = [0]*(len(repo) - baserev) + parentscount = [0] * (len(repo) - baserev) for r in cl.revs(start=baserev + 1): for p in cl.parentrevs(r): if p >= baserev: parentscount[p - baserev] += 1 - return subset.filter(lambda r: parentscount[r - baserev] > 1, - condrepr='<branchpoint>') + return subset.filter( + lambda r: parentscount[r - baserev] > 1, condrepr='<branchpoint>' + ) + @predicate('min(set)', safe=True) def minrev(repo, subset, x): @@ -1404,6 +1567,7 @@ pass return baseset(datarepr=('<min %r, %r>', subset, os)) + @predicate('modifies(pattern)', safe=True, weight=30) def modifies(repo, subset, x): """Changesets modifying files matched by pattern. @@ -1416,6 +1580,7 @@ pat = getstring(x, _("modifies requires a pattern")) return checkstatus(repo, subset, pat, 0) + @predicate('named(namespace)') def named(repo, subset, x): """The changesets in a given namespace. @@ -1426,15 +1591,16 @@ # i18n: "named" is a keyword args = getargs(x, 1, 1, _('named requires a namespace argument')) - ns = getstring(args[0], - # i18n: "named" is a keyword - _('the argument to named must be a string')) + ns = getstring( + args[0], + # i18n: "named" is a keyword + _('the argument to named must be a string'), + ) kind, pattern, matcher = stringutil.stringmatcher(ns) namespaces = set() if kind == 'literal': if pattern not in repo.names: - raise error.RepoLookupError(_("namespace '%s' does not exist") - % ns) + raise error.RepoLookupError(_("namespace '%s' does not exist") % ns) namespaces.add(repo.names[pattern]) else: for name, ns in repo.names.iteritems(): @@ -1450,6 +1616,7 @@ names -= {node.nullrev} return subset & names + @predicate('id(string)', safe=True) def node_(repo, subset, x): """Revision non-ambiguously specified by the given hex string prefix. @@ -1481,6 +1648,7 @@ result = baseset([rn]) return result & subset + @predicate('none()', safe=True) def none(repo, subset, x): """No changesets. @@ -1489,6 +1657,7 @@ getargs(x, 0, 0, _("none takes no arguments")) return baseset() + @predicate('obsolete()', safe=True) def obsolete(repo, subset, x): """Mutable changeset with a newer version.""" @@ -1497,6 +1666,7 @@ obsoletes = obsmod.getrevs(repo, 'obsolete') return subset & obsoletes + @predicate('only(set, [set])', safe=True) def only(repo, subset, x): """Changesets that are ancestors of the first set that are not ancestors @@ -1513,8 +1683,11 @@ return baseset() descendants = set(dagop.revdescendants(repo, include, False)) - exclude = [rev for rev in cl.headrevs() - if not rev in descendants and not rev in include] + exclude = [ + rev + for rev in cl.headrevs() + if not rev in descendants and not rev in include + ] else: exclude = getset(repo, fullreposet(repo), args[1]) @@ -1523,6 +1696,7 @@ # some optimizations from the fact this is a baseset. return subset & results + @predicate('origin([set])', safe=True) def origin(repo, subset, x): """ @@ -1555,6 +1729,7 @@ # some optimizations from the fact this is a baseset. return subset & o + @predicate('outgoing([path])', safe=False, weight=10) def outgoing(repo, subset, x): """Changesets not found in the specified destination repository, or the @@ -1565,6 +1740,7 @@ discovery, hg, ) + # i18n: "outgoing" is a keyword l = getargs(x, 0, 1, _("outgoing takes one or no arguments")) # i18n: "outgoing" is a keyword @@ -1574,8 +1750,10 @@ dest = None path = repo.ui.paths.getpath(dest, default=('default-push', 'default')) if not path: - raise error.Abort(_('default repository not configured!'), - hint=_("see 'hg help config.paths'")) + raise error.Abort( + _('default repository not configured!'), + hint=_("see 'hg help config.paths'"), + ) dest = path.pushloc or path.loc branches = path.branch, [] @@ -1590,6 +1768,7 @@ o = {cl.rev(r) for r in outgoing.missing} return subset & o + @predicate('p1([set])', safe=True) def p1(repo, subset, x): """First parent of changesets in set, or the working directory. @@ -1612,6 +1791,7 @@ # some optimizations from the fact this is a baseset. return subset & ps + @predicate('p2([set])', safe=True) def p2(repo, subset, x): """Second parent of changesets in set, or the working directory. @@ -1640,9 +1820,11 @@ # some optimizations from the fact this is a baseset. return subset & ps + def parentpost(repo, subset, x, order): return p1(repo, subset, x) + @predicate('parents([set])', safe=True) def parents(repo, subset, x): """ @@ -1663,16 +1845,19 @@ ps -= {node.nullrev} return subset & ps + def _phase(repo, subset, *targets): """helper to select all rev in <targets> phases""" return repo._phasecache.getrevset(repo, targets, subset) + @predicate('_phase(idx)', safe=True) def phase(repo, subset, x): - l = getargs(x, 1, 1, ("_phase requires one argument")) - target = getinteger(l[0], ("_phase expects a number")) + l = getargs(x, 1, 1, "_phase requires one argument") + target = getinteger(l[0], "_phase expects a number") return _phase(repo, subset, target) + @predicate('draft()', safe=True) def draft(repo, subset, x): """Changeset in draft phase.""" @@ -1681,6 +1866,7 @@ target = phases.draft return _phase(repo, subset, target) + @predicate('secret()', safe=True) def secret(repo, subset, x): """Changeset in secret phase.""" @@ -1689,6 +1875,7 @@ target = phases.secret return _phase(repo, subset, target) + @predicate('stack([revs])', safe=True) def stack(repo, subset, x): """Experimental revset for the stack of changesets or working directory @@ -1704,6 +1891,7 @@ return subset & stacks + def parentspec(repo, subset, x, n, order): """``set^0`` The set. @@ -1737,6 +1925,7 @@ ps.add(parents[1].rev()) return subset & ps + @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, @@ -1751,12 +1940,14 @@ except error.RepoLookupError: return baseset() + # for internal use @predicate('_notpublic', safe=True) def _notpublic(repo, subset, x): getargs(x, 0, 0, "_notpublic takes no arguments") return _phase(repo, subset, phases.draft, phases.secret) + # for internal use @predicate('_phaseandancestors(phasename, set)', safe=True) def _phaseandancestors(repo, subset, x): @@ -1770,7 +1961,7 @@ secret = phases.secret phasenamemap = { '_notpublic': draft, - 'draft': draft, # follow secret's ancestors + 'draft': draft, # follow secret's ancestors 'secret': secret, } if phasename not in phasenamemap: @@ -1784,10 +1975,11 @@ revs = dagop.revancestors(repo, s, cutfunc=cutfunc) - if phasename == 'draft': # need to remove secret changesets + if phasename == 'draft': # need to remove secret changesets revs = revs.filter(lambda r: getphase(repo, r) == draft) return subset & revs + @predicate('public()', safe=True) def public(repo, subset, x): """Changeset in public phase.""" @@ -1795,6 +1987,7 @@ getargs(x, 0, 0, _("public takes no arguments")) return _phase(repo, subset, phases.public) + @predicate('remote([id [,path]])', safe=False) def remote(repo, subset, x): """Local revision that corresponds to the given identifier in a @@ -1802,13 +1995,14 @@ synonym for the current local branch. """ - from . import hg # avoid start-up nasties + from . import hg # avoid start-up nasties + # i18n: "remote" is a keyword l = getargs(x, 0, 2, _("remote takes zero, one, or two arguments")) q = '.' if len(l) > 0: - # i18n: "remote" is a keyword + # i18n: "remote" is a keyword q = getstring(l[0], _("remote requires a string id")) if q == '.': q = repo['.'].branch() @@ -1830,6 +2024,7 @@ return baseset([r]) return baseset() + @predicate('removes(pattern)', safe=True, weight=30) def removes(repo, subset, x): """Changesets which remove files matching pattern. @@ -1842,6 +2037,7 @@ pat = getstring(x, _("removes requires a pattern")) return checkstatus(repo, subset, pat, 2) + @predicate('rev(number)', safe=True) def rev(repo, subset, x): """Revision with the given numeric identifier. @@ -1858,6 +2054,7 @@ return baseset() return subset & baseset([l]) + @predicate('_rev(number)', safe=True) def _rev(repo, subset, x): # internal version of "rev(x)" that raise error if "x" is invalid @@ -1869,9 +2066,10 @@ except (TypeError, ValueError): # i18n: "rev" is a keyword raise error.ParseError(_("rev expects a number")) - repo.changelog.node(l) # check that the rev exists + repo.changelog.node(l) # check that the rev exists return subset & baseset([l]) + @predicate('revset(set)', safe=True, takeorder=True) def revsetpredicate(repo, subset, x, order): """Strictly interpret the content as a revset. @@ -1882,6 +2080,7 @@ """ return getset(repo, subset, x, order) + @predicate('matching(revision [, field])', safe=True) def matching(repo, subset, x): """Changesets in which a given set of fields match the set of fields in the @@ -1914,10 +2113,11 @@ fieldlist = ['metadata'] if len(l) > 1: - fieldlist = getstring(l[1], - # i18n: "matching" is a keyword - _("matching requires a string " - "as its second argument")).split() + fieldlist = getstring( + l[1], + # i18n: "matching" is a keyword + _("matching requires a string " "as its second argument"), + ).split() # Make sure that there are no repeated fields, # expand the 'special' 'metadata' field type @@ -1943,14 +2143,26 @@ # We may want to match more than one field # Not all fields take the same amount of time to be matched # Sort the selected fields in order of increasing matching cost - fieldorder = ['phase', 'parents', 'user', 'date', 'branch', 'summary', - 'files', 'description', 'substate', 'diff'] + fieldorder = [ + 'phase', + 'parents', + 'user', + 'date', + 'branch', + 'summary', + 'files', + 'description', + 'substate', + 'diff', + ] + def fieldkeyfunc(f): try: return fieldorder.index(f) except ValueError: # assume an unknown field is very costly return len(fieldorder) + fields = list(fields) fields.sort(key=fieldkeyfunc) @@ -1967,15 +2179,18 @@ 'phase': lambda r: repo[r].phase(), 'substate': lambda r: repo[r].substate, 'summary': lambda r: repo[r].description().splitlines()[0], - 'diff': lambda r: list(repo[r].diff( - opts=diffutil.diffallopts(repo.ui, {'git': True}))), + 'diff': lambda r: list( + repo[r].diff(opts=diffutil.diffallopts(repo.ui, {'git': True})) + ), } for info in fields: getfield = _funcs.get(info, None) if getfield is None: raise error.ParseError( # i18n: "matching" is a keyword - _("unexpected field name passed to matching: %s") % info) + _("unexpected field name passed to matching: %s") + % info + ) getfieldfuncs.append(getfield) # convert the getfield array of functions into a "getinfo" function # which returns an array of field values (or a single value if there @@ -1995,6 +2210,7 @@ return subset.filter(matches, condrepr=('<matching%r %r>', fields, revs)) + @predicate('reverse(set)', safe=True, takeorder=True, weight=0) def reverse(repo, subset, x, order): """Reverse order of set. @@ -2004,19 +2220,23 @@ l.reverse() return l + @predicate('roots(set)', safe=True) def roots(repo, subset, x): """Changesets in set with no parent changeset in set. """ s = getset(repo, fullreposet(repo), x) parents = repo.changelog.parentrevs + def filter(r): for p in parents(r): if 0 <= p and p in s: return False return True + return subset & s.filter(filter, condrepr='<roots>') + _sortkeyfuncs = { 'rev': lambda c: c.rev(), 'branch': lambda c: c.branch(), @@ -2026,6 +2246,7 @@ 'date': lambda c: c.date()[0], } + def _getsortargs(x): """Parse sort options into (set, [(key, reverse)], opts)""" args = getargsdict(x, 'sort', 'set keys topo.firstbranch') @@ -2040,18 +2261,20 @@ keyflags = [] for k in keys.split(): fk = k - reverse = (k.startswith('-')) + reverse = k.startswith('-') if reverse: k = k[1:] if k not in _sortkeyfuncs and k != 'topo': raise error.ParseError( - _("unknown sort key %r") % pycompat.bytestr(fk)) + _("unknown sort key %r") % pycompat.bytestr(fk) + ) keyflags.append((k, reverse)) if len(keyflags) > 1 and any(k == 'topo' for k, reverse in keyflags): # i18n: "topo" is a keyword - raise error.ParseError(_('topo sort order cannot be combined ' - 'with other sort keys')) + raise error.ParseError( + _('topo sort order cannot be combined ' 'with other sort keys') + ) opts = {} if 'topo.firstbranch' in args: @@ -2059,13 +2282,19 @@ opts['topo.firstbranch'] = args['topo.firstbranch'] else: # i18n: "topo" and "topo.firstbranch" are keywords - raise error.ParseError(_('topo.firstbranch can only be used ' - 'when using the topo sort key')) + raise error.ParseError( + _( + 'topo.firstbranch can only be used ' + 'when using the topo sort key' + ) + ) return args['set'], keyflags, opts -@predicate('sort(set[, [-]key... [, ...]])', safe=True, takeorder=True, - weight=10) + +@predicate( + 'sort(set[, [-]key... [, ...]])', safe=True, takeorder=True, weight=10 +) def sort(repo, subset, x, order): """Sort set by keys. The default sort order is ascending, specify a key as ``-key`` to sort in descending order. @@ -2096,9 +2325,10 @@ firstbranch = () if 'topo.firstbranch' in opts: firstbranch = getset(repo, subset, opts['topo.firstbranch']) - revs = baseset(dagop.toposort(revs, repo.changelog.parentrevs, - firstbranch), - istopo=True) + revs = baseset( + dagop.toposort(revs, repo.changelog.parentrevs, firstbranch), + istopo=True, + ) if keyflags[0][1]: revs.reverse() return revs @@ -2109,6 +2339,7 @@ ctxs.sort(key=_sortkeyfuncs[k], reverse=reverse) return baseset([c.rev() for c in ctxs]) + @predicate('subrepo([pattern])') def subrepo(repo, subset, x): """Changesets that add, modify or remove the given subrepo. If no subrepo @@ -2153,6 +2384,7 @@ return subset.filter(matches, condrepr=('<subrepo %r>', pat)) + def _mapbynodefunc(repo, s, f): """(repo, smartset, [node] -> [node]) -> smartset @@ -2167,6 +2399,7 @@ result = set(torev(n) for n in f(tonode(r) for r in s) if n in nodemap) return smartset.baseset(result - repo.changelog.filteredrevs) + @predicate('successors(set)', safe=True) def successors(repo, subset, x): """All successors for set, including the given set themselves""" @@ -2175,9 +2408,11 @@ d = _mapbynodefunc(repo, s, f) return subset & d + def _substringmatcher(pattern, casesensitive=True): kind, pattern, matcher = stringutil.stringmatcher( - pattern, casesensitive=casesensitive) + pattern, casesensitive=casesensitive + ) if kind == 'literal': if not casesensitive: pattern = encoding.lower(pattern) @@ -2186,6 +2421,7 @@ matcher = lambda s: pattern in s return kind, pattern, matcher + @predicate('tag([name])', safe=True) def tag(repo, subset, x): """The specified tag by name, or all tagged revisions if no name is given. @@ -2197,16 +2433,19 @@ args = getargs(x, 0, 1, _("tag takes one or no arguments")) cl = repo.changelog if args: - pattern = getstring(args[0], - # i18n: "tag" is a keyword - _('the argument to tag must be a string')) + pattern = getstring( + args[0], + # i18n: "tag" is a keyword + _('the argument to tag must be a string'), + ) kind, pattern, matcher = stringutil.stringmatcher(pattern) if kind == 'literal': # avoid resolving all tags tn = repo._tagscache.tags.get(pattern, None) if tn is None: - raise error.RepoLookupError(_("tag '%s' does not exist") - % pattern) + raise error.RepoLookupError( + _("tag '%s' does not exist") % pattern + ) s = {repo[tn].rev()} else: s = {cl.rev(n) for t, n in repo.tagslist() if matcher(t)} @@ -2214,10 +2453,12 @@ s = {cl.rev(n) for t, n in repo.tagslist() if t != 'tip'} return subset & s + @predicate('tagged', safe=True) def tagged(repo, subset, x): return tag(repo, subset, x) + @predicate('orphan()', safe=True) def orphan(repo, subset, x): """Non-obsolete changesets with obsolete ancestors. (EXPERIMENTAL) @@ -2237,6 +2478,7 @@ """ return author(repo, subset, x) + @predicate('wdir()', safe=True, weight=0) def wdir(repo, subset, x): """Working directory. (EXPERIMENTAL)""" @@ -2246,6 +2488,7 @@ return baseset([node.wdirrev]) return baseset() + def _orderedlist(repo, subset, x): s = getstring(x, "internal error") if not s: @@ -2268,12 +2511,16 @@ for r in revs: if r in seen: continue - if (r in subset - or r in _virtualrevs and isinstance(subset, fullreposet)): + if ( + r in subset + or r in _virtualrevs + and isinstance(subset, fullreposet) + ): ls.append(r) seen.add(r) return baseset(ls) + # for internal use @predicate('_list', safe=True, takeorder=True) def _list(repo, subset, x, order): @@ -2283,6 +2530,7 @@ else: return _orderedlist(repo, subset, x) + def _orderedintlist(repo, subset, x): s = getstring(x, "internal error") if not s: @@ -2291,6 +2539,7 @@ s = subset return baseset([r for r in ls if r in s]) + # for internal use @predicate('_intlist', safe=True, takeorder=True, weight=0) def _intlist(repo, subset, x, order): @@ -2300,6 +2549,7 @@ else: return _orderedintlist(repo, subset, x) + def _orderedhexlist(repo, subset, x): s = getstring(x, "internal error") if not s: @@ -2309,6 +2559,7 @@ s = subset return baseset([r for r in ls if r in s]) + # for internal use @predicate('_hexlist', safe=True, takeorder=True) def _hexlist(repo, subset, x, order): @@ -2318,6 +2569,7 @@ else: return _orderedhexlist(repo, subset, x) + methods = { "range": rangeset, "rangeall": rangeall, @@ -2348,13 +2600,16 @@ "generations": generationsrel, } + def lookupfn(repo): return lambda symbol: scmutil.isrevsymbol(repo, symbol) + def match(ui, spec, lookup=None): """Create a matcher for a single revision spec""" return matchany(ui, [spec], lookup=lookup) + def matchany(ui, specs, lookup=None, localalias=None): """Create a matcher that will include any revisions matching one of the given specs @@ -2366,16 +2621,20 @@ precedence over [revsetalias] config section. """ if not specs: + def mfunc(repo, subset=None): return baseset() + return mfunc if not all(specs): raise error.ParseError(_("empty query")) if len(specs) == 1: tree = revsetlang.parse(specs[0], lookup) else: - tree = ('or', - ('list',) + tuple(revsetlang.parse(s, lookup) for s in specs)) + tree = ( + 'or', + ('list',) + tuple(revsetlang.parse(s, lookup) for s in specs), + ) aliases = [] warn = None @@ -2391,8 +2650,10 @@ tree = revsetlang.optimize(tree) return makematcher(tree) + def makematcher(tree): """Create a matcher from an evaluatable tree""" + def mfunc(repo, subset=None, order=None): if order is None: if subset is None: @@ -2402,8 +2663,10 @@ if subset is None: subset = fullreposet(repo) return getset(repo, subset, tree, order) + return mfunc + def loadpredicate(ui, extname, registrarobj): """Load revset predicates from specified registrarobj """ @@ -2412,6 +2675,7 @@ if func._safe: safesymbols.add(name) + # load built-in predicates explicitly to setup safesymbols loadpredicate(None, None, predicate)