##// END OF EJS Templates
diff: recurse into subrepositories with --subrepos/-S flag
diff: recurse into subrepositories with --subrepos/-S flag

File last commit:

r12085:6f833fc3 default
r12167:d2c5b092 default
Show More
revset.py
588 lines | 16.7 KiB | text/x-python | PythonLexer
Matt Mackall
revset: introduce revset core
r11275 # revset.py - revision set queries for mercurial
#
# Copyright 2010 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
import re
Dirkjan Ochtman
move discovery methods from localrepo into new discovery module
r11301 import parser, util, error, discovery
Martin Geisler
Consistently import foo as foomod when foo to avoid shadowing...
r12085 import match as matchmod
Martin Geisler
revset: all your error messages are belong to _
r11383 from i18n import _
Matt Mackall
revset: introduce revset core
r11275
elements = {
"(": (20, ("group", 1, ")"), ("func", 1, ")")),
"-": (19, ("negate", 19), ("minus", 19)),
Matt Mackall
revset: add support for prefix and suffix versions of : and ::
r11278 "::": (17, ("dagrangepre", 17), ("dagrange", 17),
("dagrangepost", 17)),
"..": (17, ("dagrangepre", 17), ("dagrange", 17),
("dagrangepost", 17)),
":": (15, ("rangepre", 15), ("range", 15), ("rangepost", 15)),
Matt Mackall
revset: introduce revset core
r11275 "not": (10, ("not", 10)),
"!": (10, ("not", 10)),
"and": (5, None, ("and", 5)),
"&": (5, None, ("and", 5)),
"or": (4, None, ("or", 4)),
"|": (4, None, ("or", 4)),
"+": (4, None, ("or", 4)),
",": (2, None, ("list", 2)),
")": (0, None, None),
"symbol": (0, ("symbol",), None),
"string": (0, ("string",), None),
"end": (0, None, None),
}
keywords = set(['and', 'or', 'not'])
def tokenize(program):
pos, l = 0, len(program)
while pos < l:
c = program[pos]
if c.isspace(): # skip inter-token whitespace
pass
Matt Mackall
revset: add support for prefix and suffix versions of : and ::
r11278 elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
Matt Mackall
revset: raise ParseError exceptions
r11289 yield ('::', None, pos)
Matt Mackall
revset: add support for prefix and suffix versions of : and ::
r11278 pos += 1 # skip ahead
Matt Mackall
revset: introduce revset core
r11275 elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
Matt Mackall
revset: raise ParseError exceptions
r11289 yield ('..', None, pos)
Matt Mackall
revset: introduce revset core
r11275 pos += 1 # skip ahead
Matt Mackall
revset: add support for prefix and suffix versions of : and ::
r11278 elif c in "():,-|&+!": # handle simple operators
Matt Mackall
revset: raise ParseError exceptions
r11289 yield (c, None, pos)
Matt Mackall
revset: introduce revset core
r11275 elif c in '"\'': # handle quoted strings
pos += 1
s = pos
while pos < l: # find closing quote
d = program[pos]
if d == '\\': # skip over escaped characters
pos += 2
continue
if d == c:
Matt Mackall
revset: raise ParseError exceptions
r11289 yield ('string', program[s:pos].decode('string-escape'), s)
Matt Mackall
revset: introduce revset core
r11275 break
pos += 1
else:
Martin Geisler
revset: all your error messages are belong to _
r11383 raise error.ParseError(_("unterminated string"), s)
Matt Mackall
revset: allow extended characters in symbols
r11404 elif c.isalnum() or c in '._' or ord(c) > 127: # gather up a symbol/keyword
Matt Mackall
revset: introduce revset core
r11275 s = pos
pos += 1
while pos < l: # find end of symbol
d = program[pos]
Matt Mackall
revset: allow extended characters in symbols
r11404 if not (d.isalnum() or d in "._" or ord(d) > 127):
Matt Mackall
revset: introduce revset core
r11275 break
if d == '.' and program[pos - 1] == '.': # special case for ..
pos -= 1
break
pos += 1
sym = program[s:pos]
if sym in keywords: # operator keywords
Matt Mackall
revset: raise ParseError exceptions
r11289 yield (sym, None, s)
Matt Mackall
revset: introduce revset core
r11275 else:
Matt Mackall
revset: raise ParseError exceptions
r11289 yield ('symbol', sym, s)
Matt Mackall
revset: introduce revset core
r11275 pos -= 1
else:
Martin Geisler
revset: all your error messages are belong to _
r11383 raise error.ParseError(_("syntax error"), pos)
Matt Mackall
revset: introduce revset core
r11275 pos += 1
Matt Mackall
revset: raise ParseError exceptions
r11289 yield ('end', None, pos)
Matt Mackall
revset: introduce revset core
r11275
# helpers
def getstring(x, err):
Matt Mackall
revset: fix up contains/getstring when no args passed
r11406 if x and (x[0] == 'string' or x[0] == 'symbol'):
Matt Mackall
revset: introduce revset core
r11275 return x[1]
Matt Mackall
revset: raise ParseError exceptions
r11289 raise error.ParseError(err)
Matt Mackall
revset: introduce revset core
r11275
def getlist(x):
if not x:
return []
if x[0] == 'list':
return getlist(x[1]) + [x[2]]
return [x]
Matt Mackall
revset: improve filter argument handling
r11339 def getargs(x, min, max, err):
Matt Mackall
revset: introduce revset core
r11275 l = getlist(x)
Matt Mackall
revset: improve filter argument handling
r11339 if len(l) < min or len(l) > max:
Matt Mackall
revset: raise ParseError exceptions
r11289 raise error.ParseError(err)
Matt Mackall
revset: introduce revset core
r11275 return l
def getset(repo, subset, x):
if not x:
Martin Geisler
revset: all your error messages are belong to _
r11383 raise error.ParseError(_("missing argument"))
Matt Mackall
revset: introduce revset core
r11275 return methods[x[0]](repo, subset, *x[1:])
# operator methods
def stringset(repo, subset, x):
x = repo[x].rev()
Matt Mackall
revset: fix up tests
r11282 if x == -1 and len(subset) == len(repo):
return [-1]
Matt Mackall
revset: introduce revset core
r11275 if x in subset:
return [x]
return []
def symbolset(repo, subset, x):
if x in symbols:
Martin Geisler
revset: all your error messages are belong to _
r11383 raise error.ParseError(_("can't use %s here") % x)
Matt Mackall
revset: introduce revset core
r11275 return stringset(repo, subset, x)
def rangeset(repo, subset, x, y):
Matt Mackall
revset: deal with empty sets in range endpoints...
r11456 m = getset(repo, subset, x)
if not m:
m = getset(repo, range(len(repo)), x)
n = getset(repo, subset, y)
if not n:
n = getset(repo, range(len(repo)), y)
if not m or not n:
return []
m, n = m[0], n[-1]
Matt Mackall
revset: introduce revset core
r11275 if m < n:
Matt Mackall
revset: deal with empty sets in range endpoints...
r11456 r = range(m, n + 1)
else:
r = range(m, n - 1, -1)
s = set(subset)
return [x for x in r if x in s]
Matt Mackall
revset: introduce revset core
r11275
def andset(repo, subset, x, y):
return getset(repo, getset(repo, subset, x), y)
def orset(repo, subset, x, y):
s = set(getset(repo, subset, x))
s |= set(getset(repo, [r for r in subset if r not in s], y))
return [r for r in subset if r in s]
def notset(repo, subset, x):
s = set(getset(repo, subset, x))
return [r for r in subset if r not in s]
def listset(repo, subset, a, b):
Martin Geisler
revset: all your error messages are belong to _
r11383 raise error.ParseError(_("can't use a list in this context"))
Matt Mackall
revset: introduce revset core
r11275
def func(repo, subset, a, b):
if a[0] == 'symbol' and a[1] in symbols:
return symbols[a[1]](repo, subset, b)
Martin Geisler
revset: all your error messages are belong to _
r11383 raise error.ParseError(_("not a function: %s") % a[1])
Matt Mackall
revset: introduce revset core
r11275
# functions
def p1(repo, subset, x):
ps = set()
cl = repo.changelog
for r in getset(repo, subset, x):
ps.add(cl.parentrevs(r)[0])
return [r for r in subset if r in ps]
def p2(repo, subset, x):
ps = set()
cl = repo.changelog
for r in getset(repo, subset, x):
ps.add(cl.parentrevs(r)[1])
return [r for r in subset if r in ps]
def parents(repo, subset, x):
ps = set()
cl = repo.changelog
for r in getset(repo, subset, x):
ps.update(cl.parentrevs(r))
return [r for r in subset if r in ps]
def maxrev(repo, subset, x):
s = getset(repo, subset, x)
if s:
m = max(s)
if m in subset:
return [m]
return []
Nicolas Dumazet
revset: add min function
r11708 def minrev(repo, subset, x):
s = getset(repo, subset, x)
if s:
m = min(s)
if m in subset:
return [m]
return []
Matt Mackall
revset: introduce revset core
r11275 def limit(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 l = getargs(x, 2, 2, _("limit wants two arguments"))
Matt Mackall
revset: introduce revset core
r11275 try:
Martin Geisler
revset: all your error messages are belong to _
r11383 lim = int(getstring(l[1], _("limit wants a number")))
Matt Mackall
revset: introduce revset core
r11275 except ValueError:
Martin Geisler
revset: all your error messages are belong to _
r11383 raise error.ParseError(_("limit expects a number"))
Matt Mackall
revset: introduce revset core
r11275 return getset(repo, subset, l[0])[:lim]
def children(repo, subset, x):
cs = set()
cl = repo.changelog
s = set(getset(repo, subset, x))
for r in xrange(0, len(repo)):
for p in cl.parentrevs(r):
if p in s:
cs.add(r)
return [r for r in subset if r in cs]
def branch(repo, subset, x):
s = getset(repo, range(len(repo)), x)
b = set()
for r in s:
b.add(repo[r].branch())
s = set(s)
return [r for r in subset if r in s or repo[r].branch() in b]
def ancestor(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 l = getargs(x, 2, 2, _("ancestor wants two arguments"))
Matt Mackall
revset: fix ancestor subset handling (issue2298)
r11650 r = range(len(repo))
a = getset(repo, r, l[0])
b = getset(repo, r, l[1])
if len(a) != 1 or len(b) != 1:
Martin Geisler
revset: all your error messages are belong to _
r11383 raise error.ParseError(_("ancestor arguments must be single revisions"))
Matt Mackall
revset: fix ancestor subset handling (issue2298)
r11650 an = [repo[a[0]].ancestor(repo[b[0]]).rev()]
return [r for r in an if r in subset]
Matt Mackall
revset: introduce revset core
r11275
def ancestors(repo, subset, x):
args = getset(repo, range(len(repo)), x)
Matt Mackall
revset: deal with empty sets in range endpoints...
r11456 if not args:
return []
Matt Mackall
revset: introduce revset core
r11275 s = set(repo.changelog.ancestors(*args)) | set(args)
return [r for r in subset if r in s]
def descendants(repo, subset, x):
args = getset(repo, range(len(repo)), x)
Matt Mackall
revset: deal with empty sets in range endpoints...
r11456 if not args:
return []
Matt Mackall
revset: introduce revset core
r11275 s = set(repo.changelog.descendants(*args)) | set(args)
return [r for r in subset if r in s]
def follow(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 getargs(x, 0, 0, _("follow takes no arguments"))
Matt Mackall
revset: introduce revset core
r11275 p = repo['.'].rev()
s = set(repo.changelog.ancestors(p)) | set([p])
return [r for r in subset if r in s]
def date(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 ds = getstring(x, _("date wants a string"))
Matt Mackall
revset: introduce revset core
r11275 dm = util.matchdate(ds)
return [r for r in subset if dm(repo[r].date()[0])]
def keyword(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 kw = getstring(x, _("keyword wants a string")).lower()
Matt Mackall
revset: introduce revset core
r11275 l = []
for r in subset:
c = repo[r]
t = " ".join(c.files() + [c.user(), c.description()])
if kw in t.lower():
l.append(r)
return l
def grep(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 gr = re.compile(getstring(x, _("grep wants a string")))
Matt Mackall
revset: introduce revset core
r11275 l = []
for r in subset:
c = repo[r]
for e in c.files() + [c.user(), c.description()]:
if gr.search(e):
l.append(r)
continue
return l
def author(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 n = getstring(x, _("author wants a string")).lower()
Matt Mackall
revset: introduce revset core
r11275 return [r for r in subset if n in repo[r].user().lower()]
def hasfile(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 pat = getstring(x, _("file wants a pattern"))
Martin Geisler
Consistently import foo as foomod when foo to avoid shadowing...
r12085 m = matchmod.match(repo.root, repo.getcwd(), [pat])
Matt Mackall
revset: introduce revset core
r11275 s = []
for r in subset:
for f in repo[r].files():
if m(f):
s.append(r)
continue
return s
def contains(repo, subset, x):
Matt Mackall
revset: fix up contains/getstring when no args passed
r11406 pat = getstring(x, _("contains wants a pattern"))
Martin Geisler
Consistently import foo as foomod when foo to avoid shadowing...
r12085 m = matchmod.match(repo.root, repo.getcwd(), [pat])
Matt Mackall
revset: introduce revset core
r11275 s = []
if m.files() == [pat]:
for r in subset:
if pat in repo[r]:
s.append(r)
continue
else:
for r in subset:
for f in repo[r].manifest():
if m(f):
s.append(r)
continue
return s
def checkstatus(repo, subset, pat, field):
Martin Geisler
Consistently import foo as foomod when foo to avoid shadowing...
r12085 m = matchmod.match(repo.root, repo.getcwd(), [pat])
Matt Mackall
revset: introduce revset core
r11275 s = []
fast = (m.files() == [pat])
for r in subset:
c = repo[r]
if fast:
if pat not in c.files():
continue
else:
for f in c.files():
if m(f):
break
else:
continue
files = repo.status(c.p1().node(), c.node())[field]
if fast:
if pat in files:
s.append(r)
continue
else:
for f in files:
if m(f):
s.append(r)
continue
return s
def modifies(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 pat = getstring(x, _("modifies wants a pattern"))
Matt Mackall
revset: introduce revset core
r11275 return checkstatus(repo, subset, pat, 0)
def adds(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 pat = getstring(x, _("adds wants a pattern"))
Matt Mackall
revset: introduce revset core
r11275 return checkstatus(repo, subset, pat, 1)
def removes(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 pat = getstring(x, _("removes wants a pattern"))
Matt Mackall
revset: introduce revset core
r11275 return checkstatus(repo, subset, pat, 2)
def merge(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 getargs(x, 0, 0, _("merge takes no arguments"))
Matt Mackall
revset: introduce revset core
r11275 cl = repo.changelog
return [r for r in subset if cl.parentrevs(r)[1] != -1]
def closed(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 getargs(x, 0, 0, _("closed takes no arguments"))
Georg Brandl
revset: fix call to ctx.extra() in closed()
r11349 return [r for r in subset if repo[r].extra().get('close')]
Matt Mackall
revset: introduce revset core
r11275
def head(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 getargs(x, 0, 0, _("head takes no arguments"))
Matt Mackall
revset: introduce revset core
r11275 hs = set()
for b, ls in repo.branchmap().iteritems():
hs.update(repo[h].rev() for h in ls)
return [r for r in subset if r in hs]
def reverse(repo, subset, x):
l = getset(repo, subset, x)
l.reverse()
return l
Wagner Bruna
revset: predicate to avoid lookup errors...
r11944 def present(repo, subset, x):
try:
return getset(repo, subset, x)
except error.RepoLookupError:
return []
Matt Mackall
revset: introduce revset core
r11275 def sort(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 l = getargs(x, 1, 2, _("sort wants one or two arguments"))
Matt Mackall
revset: introduce revset core
r11275 keys = "rev"
if len(l) == 2:
Martin Geisler
revset: all your error messages are belong to _
r11383 keys = getstring(l[1], _("sort spec must be a string"))
Matt Mackall
revset: introduce revset core
r11275
s = l[0]
keys = keys.split()
l = []
def invert(s):
return "".join(chr(255 - ord(c)) for c in s)
for r in getset(repo, subset, s):
c = repo[r]
e = []
for k in keys:
if k == 'rev':
e.append(r)
elif k == '-rev':
e.append(-r)
elif k == 'branch':
e.append(c.branch())
elif k == '-branch':
e.append(invert(c.branch()))
elif k == 'desc':
e.append(c.description())
elif k == '-desc':
e.append(invert(c.description()))
elif k in 'user author':
e.append(c.user())
elif k in '-user -author':
e.append(invert(c.user()))
elif k == 'date':
e.append(c.date()[0])
elif k == '-date':
e.append(-c.date()[0])
else:
Martin Geisler
revset: all your error messages are belong to _
r11383 raise error.ParseError(_("unknown sort key %r") % k)
Matt Mackall
revset: introduce revset core
r11275 e.append(r)
l.append(e)
l.sort()
return [e[-1] for e in l]
def getall(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 getargs(x, 0, 0, _("all takes no arguments"))
Matt Mackall
revset: introduce revset core
r11275 return subset
def heads(repo, subset, x):
s = getset(repo, subset, x)
ps = set(parents(repo, subset, x))
return [r for r in s if r not in ps]
def roots(repo, subset, x):
s = getset(repo, subset, x)
cs = set(children(repo, subset, x))
return [r for r in s if r not in cs]
def outgoing(repo, subset, x):
Matt Mackall
revset: delay import of hg to avoid start-up import loops
r11293 import hg # avoid start-up nasties
Martin Geisler
revset: all your error messages are belong to _
r11383 l = getargs(x, 0, 1, _("outgoing wants a repository path"))
Wagner Bruna
revset: fix outgoing argument handling
r11882 dest = l and getstring(l[0], _("outgoing wants a repository path")) or ''
Matt Mackall
revset: introduce revset core
r11275 dest = repo.ui.expandpath(dest or 'default-push', dest or 'default')
dest, branches = hg.parseurl(dest)
other = hg.repository(hg.remoteui(repo, {}), dest)
repo.ui.pushbuffer()
Dirkjan Ochtman
move discovery methods from localrepo into new discovery module
r11301 o = discovery.findoutgoing(repo, other)
Matt Mackall
revset: introduce revset core
r11275 repo.ui.popbuffer()
cl = repo.changelog
o = set([cl.rev(r) for r in repo.changelog.nodesbetween(o, None)[0]])
return [r for r in subset if r in o]
Matt Mackall
revset: add tagged predicate
r11280 def tagged(repo, subset, x):
Martin Geisler
revset: all your error messages are belong to _
r11383 getargs(x, 0, 0, _("tagged takes no arguments"))
Matt Mackall
revset: add tagged predicate
r11280 cl = repo.changelog
s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip'])
return [r for r in subset if r in s]
Matt Mackall
revset: introduce revset core
r11275 symbols = {
Matt Mackall
revset: sort the predicate list
r11284 "adds": adds,
"all": getall,
Matt Mackall
revset: introduce revset core
r11275 "ancestor": ancestor,
"ancestors": ancestors,
Matt Mackall
revset: sort the predicate list
r11284 "author": author,
Matt Mackall
revset: introduce revset core
r11275 "branch": branch,
Matt Mackall
revset: sort the predicate list
r11284 "children": children,
"closed": closed,
"contains": contains,
"date": date,
"descendants": descendants,
"file": hasfile,
"follow": follow,
"grep": grep,
"head": head,
"heads": heads,
Matt Mackall
revset: introduce revset core
r11275 "keyword": keyword,
Matt Mackall
revset: sort the predicate list
r11284 "limit": limit,
"max": maxrev,
Nicolas Dumazet
revset: add min function
r11708 "min": minrev,
Matt Mackall
revset: sort the predicate list
r11284 "merge": merge,
"modifies": modifies,
"outgoing": outgoing,
Matt Mackall
revset: introduce revset core
r11275 "p1": p1,
"p2": p2,
"parents": parents,
Wagner Bruna
revset: predicate to avoid lookup errors...
r11944 "present": present,
Matt Mackall
revset: sort the predicate list
r11284 "removes": removes,
"reverse": reverse,
Matt Mackall
revset: introduce revset core
r11275 "roots": roots,
Matt Mackall
revset: sort the predicate list
r11284 "sort": sort,
Matt Mackall
revset: add tagged predicate
r11280 "tagged": tagged,
Matt Mackall
revset: sort the predicate list
r11284 "user": author,
Matt Mackall
revset: introduce revset core
r11275 }
methods = {
"range": rangeset,
"string": stringset,
"symbol": symbolset,
"and": andset,
"or": orset,
"not": notset,
"list": listset,
"func": func,
}
Matt Mackall
revset: optimize the parse tree directly...
r11279 def optimize(x, small):
if x == None:
return 0, x
Matt Mackall
revset: introduce revset core
r11275 smallbonus = 1
if small:
smallbonus = .5
op = x[0]
Matt Mackall
revset: fix - handling in the optimizer
r11283 if op == 'minus':
Matt Mackall
revset: optimize the parse tree directly...
r11279 return optimize(('and', x[1], ('not', x[2])), small)
elif op == 'dagrange':
return optimize(('and', ('func', ('symbol', 'descendants'), x[1]),
('func', ('symbol', 'ancestors'), x[2])), small)
elif op == 'dagrangepre':
return optimize(('func', ('symbol', 'ancestors'), x[1]), small)
elif op == 'dagrangepost':
return optimize(('func', ('symbol', 'descendants'), x[1]), small)
elif op == 'rangepre':
return optimize(('range', ('string', '0'), x[1]), small)
elif op == 'rangepost':
return optimize(('range', x[1], ('string', 'tip')), small)
Matt Mackall
revset: make negate work for sort specs
r11467 elif op == 'negate':
return optimize(('string',
'-' + getstring(x[1], _("can't negate that"))), small)
Matt Mackall
revset: optimize the parse tree directly...
r11279 elif op in 'string symbol negate':
return smallbonus, x # single revisions are small
Matt Mackall
revset: introduce revset core
r11275 elif op == 'and' or op == 'dagrange':
Matt Mackall
revset: optimize the parse tree directly...
r11279 wa, ta = optimize(x[1], True)
wb, tb = optimize(x[2], True)
w = min(wa, wb)
if wa > wb:
return w, (op, tb, ta)
return w, (op, ta, tb)
elif op == 'or':
wa, ta = optimize(x[1], False)
wb, tb = optimize(x[2], False)
if wb < wa:
wb, wa = wa, wb
return max(wa, wb), (op, ta, tb)
Matt Mackall
revset: introduce revset core
r11275 elif op == 'not':
Matt Mackall
revset: optimize the parse tree directly...
r11279 o = optimize(x[1], not small)
return o[0], (op, o[1])
Matt Mackall
revset: introduce revset core
r11275 elif op == 'group':
Matt Mackall
revset: optimize the parse tree directly...
r11279 return optimize(x[1], small)
elif op in 'range list':
wa, ta = optimize(x[1], small)
wb, tb = optimize(x[2], small)
return wa + wb, (op, ta, tb)
Matt Mackall
revset: introduce revset core
r11275 elif op == 'func':
Martin Geisler
revset: all your error messages are belong to _
r11383 f = getstring(x[1], _("not a symbol"))
Matt Mackall
revset: optimize the parse tree directly...
r11279 wa, ta = optimize(x[2], small)
Matt Mackall
revset: introduce revset core
r11275 if f in "grep date user author keyword branch file":
Matt Mackall
revset: optimize the parse tree directly...
r11279 w = 10 # slow
elif f in "modifies adds removes outgoing":
w = 30 # slower
Matt Mackall
revset: introduce revset core
r11275 elif f == "contains":
Matt Mackall
revset: optimize the parse tree directly...
r11279 w = 100 # very slow
Matt Mackall
revset: introduce revset core
r11275 elif f == "ancestor":
Matt Mackall
revset: optimize the parse tree directly...
r11279 w = 1 * smallbonus
Matt Mackall
revset: introduce revset core
r11275 elif f == "reverse limit":
Matt Mackall
revset: optimize the parse tree directly...
r11279 w = 0
Matt Mackall
revset: introduce revset core
r11275 elif f in "sort":
Matt Mackall
revset: optimize the parse tree directly...
r11279 w = 10 # assume most sorts look at changelog
Matt Mackall
revset: introduce revset core
r11275 else:
Matt Mackall
revset: optimize the parse tree directly...
r11279 w = 1
return w + wa, (op, x[1], ta)
return 1, x
Matt Mackall
revset: introduce revset core
r11275
parse = parser.parser(tokenize, elements).parse
def match(spec):
Matt Mackall
revset: nicer exception for empty queries
r11385 if not spec:
raise error.ParseError(_("empty query"))
Matt Mackall
revset: introduce revset core
r11275 tree = parse(spec)
Matt Mackall
revset: optimize the parse tree directly...
r11279 weight, tree = optimize(tree, True)
Matt Mackall
revset: introduce revset core
r11275 def mfunc(repo, subset):
return getset(repo, subset, tree)
return mfunc