mercurial/revset.py
changeset 14070 305c97670d7a
parent 14061 611d2f8a4ba2
child 14072 2e4d79dcc0a0
equal deleted inserted replaced
14069:e38846a79a23 14070:305c97670d7a
    11 import match as matchmod
    11 import match as matchmod
    12 from i18n import _
    12 from i18n import _
    13 
    13 
    14 elements = {
    14 elements = {
    15     "(": (20, ("group", 1, ")"), ("func", 1, ")")),
    15     "(": (20, ("group", 1, ")"), ("func", 1, ")")),
       
    16     "~": (18, None, ("ancestor", 18)),
       
    17     "^": (18, None, ("parent", 18), ("parentpost", 18)),
    16     "-": (5, ("negate", 19), ("minus", 5)),
    18     "-": (5, ("negate", 19), ("minus", 5)),
    17     "::": (17, ("dagrangepre", 17), ("dagrange", 17),
    19     "::": (17, ("dagrangepre", 17), ("dagrange", 17),
    18            ("dagrangepost", 17)),
    20            ("dagrangepost", 17)),
    19     "..": (17, ("dagrangepre", 17), ("dagrange", 17),
    21     "..": (17, ("dagrangepre", 17), ("dagrange", 17),
    20            ("dagrangepost", 17)),
    22            ("dagrangepost", 17)),
    45             yield ('::', None, pos)
    47             yield ('::', None, pos)
    46             pos += 1 # skip ahead
    48             pos += 1 # skip ahead
    47         elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
    49         elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
    48             yield ('..', None, pos)
    50             yield ('..', None, pos)
    49             pos += 1 # skip ahead
    51             pos += 1 # skip ahead
    50         elif c in "():,-|&+!": # handle simple operators
    52         elif c in "():,-|&+!~^": # handle simple operators
    51             yield (c, None, pos)
    53             yield (c, None, pos)
    52         elif (c in '"\'' or c == 'r' and
    54         elif (c in '"\'' or c == 'r' and
    53               program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
    55               program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
    54             if c == 'r':
    56             if c == 'r':
    55                 pos += 1
    57                 pos += 1
   207     if not args:
   209     if not args:
   208         return []
   210         return []
   209     s = set(repo.changelog.ancestors(*args)) | set(args)
   211     s = set(repo.changelog.ancestors(*args)) | set(args)
   210     return [r for r in subset if r in s]
   212     return [r for r in subset if r in s]
   211 
   213 
       
   214 def ancestorspec(repo, subset, x, n):
       
   215     """``set~n``
       
   216     Changesets that are the Nth ancestor (first parents only) of a changeset in set.
       
   217     """
       
   218     try:
       
   219         n = int(n[1])
       
   220     except ValueError:
       
   221         raise error.ParseError(_("~ expects a number"))
       
   222     ps = set()
       
   223     cl = repo.changelog
       
   224     for r in getset(repo, subset, x):
       
   225         for i in range(n):
       
   226             r = cl.parentrevs(r)[0]
       
   227         ps.add(r)
       
   228     return [r for r in subset if r in ps]
       
   229 
   212 def author(repo, subset, x):
   230 def author(repo, subset, x):
   213     """``author(string)``
   231     """``author(string)``
   214     Alias for ``user(string)``.
   232     Alias for ``user(string)``.
   215     """
   233     """
   216     # i18n: "author" is a keyword
   234     # i18n: "author" is a keyword
   584 
   602 
   585     ps = set()
   603     ps = set()
   586     cl = repo.changelog
   604     cl = repo.changelog
   587     for r in getset(repo, range(len(repo)), x):
   605     for r in getset(repo, range(len(repo)), x):
   588         ps.update(cl.parentrevs(r))
   606         ps.update(cl.parentrevs(r))
       
   607     return [r for r in subset if r in ps]
       
   608 
       
   609 def parentspec(repo, subset, x, n):
       
   610     """``set^0``
       
   611     The set.
       
   612     ``set^1`` (or ``set^``), ``set^2``
       
   613     First or second parent, respectively, of all changesets in set.
       
   614     """
       
   615     try:
       
   616         n = int(n[1])
       
   617         if n not in (0,1,2):
       
   618             raise ValueError
       
   619     except ValueError:
       
   620         raise error.ParseError(_("^ expects a number 0, 1, or 2"))
       
   621     ps = set()
       
   622     cl = repo.changelog
       
   623     for r in getset(repo, subset, x):
       
   624         if n == 0:
       
   625             ps.add(r)
       
   626         elif n == 1:
       
   627             ps.add(cl.parentrevs(r)[0])
       
   628         elif n == 2:
       
   629             parents = cl.parentrevs(r)
       
   630             if len(parents) > 1:
       
   631                 ps.add(parents[1])
   589     return [r for r in subset if r in ps]
   632     return [r for r in subset if r in ps]
   590 
   633 
   591 def present(repo, subset, x):
   634 def present(repo, subset, x):
   592     """``present(set)``
   635     """``present(set)``
   593     An empty set, if any revision in set isn't found; otherwise,
   636     An empty set, if any revision in set isn't found; otherwise,
   767     "and": andset,
   810     "and": andset,
   768     "or": orset,
   811     "or": orset,
   769     "not": notset,
   812     "not": notset,
   770     "list": listset,
   813     "list": listset,
   771     "func": func,
   814     "func": func,
       
   815     "ancestor": ancestorspec,
       
   816     "parent": parentspec,
       
   817     "parentpost": p1,
   772 }
   818 }
   773 
   819 
   774 def optimize(x, small):
   820 def optimize(x, small):
   775     if x is None:
   821     if x is None:
   776         return 0, x
   822         return 0, x
   812             wb, wa = wa, wb
   858             wb, wa = wa, wb
   813         return max(wa, wb), (op, ta, tb)
   859         return max(wa, wb), (op, ta, tb)
   814     elif op == 'not':
   860     elif op == 'not':
   815         o = optimize(x[1], not small)
   861         o = optimize(x[1], not small)
   816         return o[0], (op, o[1])
   862         return o[0], (op, o[1])
       
   863     elif op == 'parentpost':
       
   864         o = optimize(x[1], small)
       
   865         return o[0], (op, o[1])
   817     elif op == 'group':
   866     elif op == 'group':
   818         return optimize(x[1], small)
   867         return optimize(x[1], small)
   819     elif op in 'range list':
   868     elif op in 'range list parent ancestorspec':
   820         wa, ta = optimize(x[1], small)
   869         wa, ta = optimize(x[1], small)
   821         wb, tb = optimize(x[2], small)
   870         wb, tb = optimize(x[2], small)
   822         return wa + wb, (op, ta, tb)
   871         return wa + wb, (op, ta, tb)
   823     elif op == 'func':
   872     elif op == 'func':
   824         f = getstring(x[1], _("not a symbol"))
   873         f = getstring(x[1], _("not a symbol"))