--- a/mercurial/revset.py Fri Nov 28 19:50:52 2014 -0500
+++ b/mercurial/revset.py Tue Jan 06 23:46:18 2015 +0900
@@ -102,7 +102,8 @@
return baseset(sorted(reachable))
elements = {
- "(": (20, ("group", 1, ")"), ("func", 1, ")")),
+ "(": (21, ("group", 1, ")"), ("func", 1, ")")),
+ "##": (20, None, ("_concat", 20)),
"~": (18, None, ("ancestor", 18)),
"^": (18, None, ("parent", 18), ("parentpost", 18)),
"-": (5, ("negate", 19), ("minus", 5)),
@@ -148,6 +149,9 @@
elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
yield ('..', None, pos)
pos += 1 # skip ahead
+ elif c == '#' and program[pos:pos + 2] == '##': # look ahead carefully
+ yield ('##', None, pos)
+ pos += 1 # skip ahead
elif c in "():,-|&+!~^": # handle simple operators
yield (c, None, pos)
elif (c in '"\'' or c == 'r' and
@@ -2156,6 +2160,27 @@
alias.warned = True
return tree
+def foldconcat(tree):
+ """Fold elements to be concatenated by `##`
+ """
+ if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
+ return tree
+ if tree[0] == '_concat':
+ pending = [tree]
+ l = []
+ while pending:
+ e = pending.pop()
+ if e[0] == '_concat':
+ pending.extend(reversed(e[1:]))
+ elif e[0] in ('string', 'symbol'):
+ l.append(e[1])
+ else:
+ msg = _("\"##\" can't concatenate \"%s\" element") % (e[0])
+ raise error.ParseError(msg)
+ return ('string', ''.join(l))
+ else:
+ return tuple(foldconcat(t) for t in tree)
+
def parse(spec, lookup=None):
p = parser.parser(tokenize, elements)
return p.parse(spec, lookup=lookup)
@@ -2171,6 +2196,7 @@
raise error.ParseError(_("invalid token"), pos)
if ui:
tree = findaliases(ui, tree, showwarning=ui.warn)
+ tree = foldconcat(tree)
weight, tree = optimize(tree, True)
def mfunc(repo, subset):
if util.safehasattr(subset, 'isascending'):