##// END OF EJS Templates
parser: verify excessive number of args excluding kwargs in buildargsdict()...
Yuya Nishihara -
r31920:a98540ea default
parent child Browse files
Show More
@@ -1,583 +1,584 b''
1 # parser.py - simple top-down operator precedence parser for mercurial
1 # parser.py - simple top-down operator precedence parser for mercurial
2 #
2 #
3 # Copyright 2010 Matt Mackall <mpm@selenic.com>
3 # Copyright 2010 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 # see http://effbot.org/zone/simple-top-down-parsing.htm and
8 # see http://effbot.org/zone/simple-top-down-parsing.htm and
9 # http://eli.thegreenplace.net/2010/01/02/top-down-operator-precedence-parsing/
9 # http://eli.thegreenplace.net/2010/01/02/top-down-operator-precedence-parsing/
10 # for background
10 # for background
11
11
12 # takes a tokenizer and elements
12 # takes a tokenizer and elements
13 # tokenizer is an iterator that returns (type, value, pos) tuples
13 # tokenizer is an iterator that returns (type, value, pos) tuples
14 # elements is a mapping of types to binding strength, primary, prefix, infix
14 # elements is a mapping of types to binding strength, primary, prefix, infix
15 # and suffix actions
15 # and suffix actions
16 # an action is a tree node name, a tree label, and an optional match
16 # an action is a tree node name, a tree label, and an optional match
17 # __call__(program) parses program into a labeled tree
17 # __call__(program) parses program into a labeled tree
18
18
19 from __future__ import absolute_import
19 from __future__ import absolute_import
20
20
21 from .i18n import _
21 from .i18n import _
22 from . import (
22 from . import (
23 error,
23 error,
24 util,
24 util,
25 )
25 )
26
26
27 class parser(object):
27 class parser(object):
28 def __init__(self, elements, methods=None):
28 def __init__(self, elements, methods=None):
29 self._elements = elements
29 self._elements = elements
30 self._methods = methods
30 self._methods = methods
31 self.current = None
31 self.current = None
32 def _advance(self):
32 def _advance(self):
33 'advance the tokenizer'
33 'advance the tokenizer'
34 t = self.current
34 t = self.current
35 self.current = next(self._iter, None)
35 self.current = next(self._iter, None)
36 return t
36 return t
37 def _hasnewterm(self):
37 def _hasnewterm(self):
38 'True if next token may start new term'
38 'True if next token may start new term'
39 return any(self._elements[self.current[0]][1:3])
39 return any(self._elements[self.current[0]][1:3])
40 def _match(self, m):
40 def _match(self, m):
41 'make sure the tokenizer matches an end condition'
41 'make sure the tokenizer matches an end condition'
42 if self.current[0] != m:
42 if self.current[0] != m:
43 raise error.ParseError(_("unexpected token: %s") % self.current[0],
43 raise error.ParseError(_("unexpected token: %s") % self.current[0],
44 self.current[2])
44 self.current[2])
45 self._advance()
45 self._advance()
46 def _parseoperand(self, bind, m=None):
46 def _parseoperand(self, bind, m=None):
47 'gather right-hand-side operand until an end condition or binding met'
47 'gather right-hand-side operand until an end condition or binding met'
48 if m and self.current[0] == m:
48 if m and self.current[0] == m:
49 expr = None
49 expr = None
50 else:
50 else:
51 expr = self._parse(bind)
51 expr = self._parse(bind)
52 if m:
52 if m:
53 self._match(m)
53 self._match(m)
54 return expr
54 return expr
55 def _parse(self, bind=0):
55 def _parse(self, bind=0):
56 token, value, pos = self._advance()
56 token, value, pos = self._advance()
57 # handle prefix rules on current token, take as primary if unambiguous
57 # handle prefix rules on current token, take as primary if unambiguous
58 primary, prefix = self._elements[token][1:3]
58 primary, prefix = self._elements[token][1:3]
59 if primary and not (prefix and self._hasnewterm()):
59 if primary and not (prefix and self._hasnewterm()):
60 expr = (primary, value)
60 expr = (primary, value)
61 elif prefix:
61 elif prefix:
62 expr = (prefix[0], self._parseoperand(*prefix[1:]))
62 expr = (prefix[0], self._parseoperand(*prefix[1:]))
63 else:
63 else:
64 raise error.ParseError(_("not a prefix: %s") % token, pos)
64 raise error.ParseError(_("not a prefix: %s") % token, pos)
65 # gather tokens until we meet a lower binding strength
65 # gather tokens until we meet a lower binding strength
66 while bind < self._elements[self.current[0]][0]:
66 while bind < self._elements[self.current[0]][0]:
67 token, value, pos = self._advance()
67 token, value, pos = self._advance()
68 # handle infix rules, take as suffix if unambiguous
68 # handle infix rules, take as suffix if unambiguous
69 infix, suffix = self._elements[token][3:]
69 infix, suffix = self._elements[token][3:]
70 if suffix and not (infix and self._hasnewterm()):
70 if suffix and not (infix and self._hasnewterm()):
71 expr = (suffix, expr)
71 expr = (suffix, expr)
72 elif infix:
72 elif infix:
73 expr = (infix[0], expr, self._parseoperand(*infix[1:]))
73 expr = (infix[0], expr, self._parseoperand(*infix[1:]))
74 else:
74 else:
75 raise error.ParseError(_("not an infix: %s") % token, pos)
75 raise error.ParseError(_("not an infix: %s") % token, pos)
76 return expr
76 return expr
77 def parse(self, tokeniter):
77 def parse(self, tokeniter):
78 'generate a parse tree from tokens'
78 'generate a parse tree from tokens'
79 self._iter = tokeniter
79 self._iter = tokeniter
80 self._advance()
80 self._advance()
81 res = self._parse()
81 res = self._parse()
82 token, value, pos = self.current
82 token, value, pos = self.current
83 return res, pos
83 return res, pos
84 def eval(self, tree):
84 def eval(self, tree):
85 'recursively evaluate a parse tree using node methods'
85 'recursively evaluate a parse tree using node methods'
86 if not isinstance(tree, tuple):
86 if not isinstance(tree, tuple):
87 return tree
87 return tree
88 return self._methods[tree[0]](*[self.eval(t) for t in tree[1:]])
88 return self._methods[tree[0]](*[self.eval(t) for t in tree[1:]])
89 def __call__(self, tokeniter):
89 def __call__(self, tokeniter):
90 'parse tokens into a parse tree and evaluate if methods given'
90 'parse tokens into a parse tree and evaluate if methods given'
91 t = self.parse(tokeniter)
91 t = self.parse(tokeniter)
92 if self._methods:
92 if self._methods:
93 return self.eval(t)
93 return self.eval(t)
94 return t
94 return t
95
95
96 def splitargspec(spec):
96 def splitargspec(spec):
97 """Parse spec of function arguments into (poskeys, varkey, keys)
97 """Parse spec of function arguments into (poskeys, varkey, keys)
98
98
99 >>> splitargspec('')
99 >>> splitargspec('')
100 ([], None, [])
100 ([], None, [])
101 >>> splitargspec('foo bar')
101 >>> splitargspec('foo bar')
102 ([], None, ['foo', 'bar'])
102 ([], None, ['foo', 'bar'])
103 >>> splitargspec('foo *bar baz')
103 >>> splitargspec('foo *bar baz')
104 (['foo'], 'bar', ['baz'])
104 (['foo'], 'bar', ['baz'])
105 >>> splitargspec('*foo')
105 >>> splitargspec('*foo')
106 ([], 'foo', [])
106 ([], 'foo', [])
107 """
107 """
108 pre, sep, post = spec.partition('*')
108 pre, sep, post = spec.partition('*')
109 pres = pre.split()
109 pres = pre.split()
110 posts = post.split()
110 posts = post.split()
111 if sep:
111 if sep:
112 if not posts:
112 if not posts:
113 raise error.ProgrammingError('no *varkey name provided')
113 raise error.ProgrammingError('no *varkey name provided')
114 return pres, posts[0], posts[1:]
114 return pres, posts[0], posts[1:]
115 return [], None, pres
115 return [], None, pres
116
116
117 def buildargsdict(trees, funcname, argspec, keyvaluenode, keynode):
117 def buildargsdict(trees, funcname, argspec, keyvaluenode, keynode):
118 """Build dict from list containing positional and keyword arguments
118 """Build dict from list containing positional and keyword arguments
119
119
120 Arguments are specified by a tuple of ``(poskeys, varkey, keys)`` where
120 Arguments are specified by a tuple of ``(poskeys, varkey, keys)`` where
121
121
122 - ``poskeys``: list of names of positional arguments
122 - ``poskeys``: list of names of positional arguments
123 - ``varkey``: optional argument name that takes up remainder
123 - ``varkey``: optional argument name that takes up remainder
124 - ``keys``: list of names that can be either positional or keyword arguments
124 - ``keys``: list of names that can be either positional or keyword arguments
125
125
126 If ``varkey`` specified, all ``keys`` must be given as keyword arguments.
126 If ``varkey`` specified, all ``keys`` must be given as keyword arguments.
127
127
128 Invalid keywords, too few positional arguments, or too many positional
128 Invalid keywords, too few positional arguments, or too many positional
129 arguments are rejected, but missing keyword arguments are just omitted.
129 arguments are rejected, but missing keyword arguments are just omitted.
130 """
130 """
131 poskeys, varkey, keys = argspec
131 poskeys, varkey, keys = argspec
132 kwstart = next((i for i, x in enumerate(trees) if x[0] == keyvaluenode),
132 kwstart = next((i for i, x in enumerate(trees) if x[0] == keyvaluenode),
133 len(trees))
133 len(trees))
134 if kwstart < len(poskeys):
134 if kwstart < len(poskeys):
135 raise error.ParseError(_("%(func)s takes at least %(nargs)d positional "
135 raise error.ParseError(_("%(func)s takes at least %(nargs)d positional "
136 "arguments")
136 "arguments")
137 % {'func': funcname, 'nargs': len(poskeys)})
137 % {'func': funcname, 'nargs': len(poskeys)})
138 if not varkey and len(trees) > len(poskeys) + len(keys):
138 if not varkey and kwstart > len(poskeys) + len(keys):
139 raise error.ParseError(_("%(func)s takes at most %(nargs)d arguments")
139 raise error.ParseError(_("%(func)s takes at most %(nargs)d positional "
140 "arguments")
140 % {'func': funcname,
141 % {'func': funcname,
141 'nargs': len(poskeys) + len(keys)})
142 'nargs': len(poskeys) + len(keys)})
142 args = {}
143 args = {}
143 # consume positional arguments
144 # consume positional arguments
144 for k, x in zip(poskeys, trees[:kwstart]):
145 for k, x in zip(poskeys, trees[:kwstart]):
145 args[k] = x
146 args[k] = x
146 if varkey:
147 if varkey:
147 args[varkey] = trees[len(args):kwstart]
148 args[varkey] = trees[len(args):kwstart]
148 else:
149 else:
149 for k, x in zip(keys, trees[len(args):kwstart]):
150 for k, x in zip(keys, trees[len(args):kwstart]):
150 args[k] = x
151 args[k] = x
151 # remainder should be keyword arguments
152 # remainder should be keyword arguments
152 for x in trees[kwstart:]:
153 for x in trees[kwstart:]:
153 if x[0] != keyvaluenode or x[1][0] != keynode:
154 if x[0] != keyvaluenode or x[1][0] != keynode:
154 raise error.ParseError(_("%(func)s got an invalid argument")
155 raise error.ParseError(_("%(func)s got an invalid argument")
155 % {'func': funcname})
156 % {'func': funcname})
156 k = x[1][1]
157 k = x[1][1]
157 if k not in keys:
158 if k not in keys:
158 raise error.ParseError(_("%(func)s got an unexpected keyword "
159 raise error.ParseError(_("%(func)s got an unexpected keyword "
159 "argument '%(key)s'")
160 "argument '%(key)s'")
160 % {'func': funcname, 'key': k})
161 % {'func': funcname, 'key': k})
161 if k in args:
162 if k in args:
162 raise error.ParseError(_("%(func)s got multiple values for keyword "
163 raise error.ParseError(_("%(func)s got multiple values for keyword "
163 "argument '%(key)s'")
164 "argument '%(key)s'")
164 % {'func': funcname, 'key': k})
165 % {'func': funcname, 'key': k})
165 args[k] = x[2]
166 args[k] = x[2]
166 return args
167 return args
167
168
168 def unescapestr(s):
169 def unescapestr(s):
169 try:
170 try:
170 return util.unescapestr(s)
171 return util.unescapestr(s)
171 except ValueError as e:
172 except ValueError as e:
172 # mangle Python's exception into our format
173 # mangle Python's exception into our format
173 raise error.ParseError(str(e).lower())
174 raise error.ParseError(str(e).lower())
174
175
175 def _prettyformat(tree, leafnodes, level, lines):
176 def _prettyformat(tree, leafnodes, level, lines):
176 if not isinstance(tree, tuple) or tree[0] in leafnodes:
177 if not isinstance(tree, tuple) or tree[0] in leafnodes:
177 lines.append((level, str(tree)))
178 lines.append((level, str(tree)))
178 else:
179 else:
179 lines.append((level, '(%s' % tree[0]))
180 lines.append((level, '(%s' % tree[0]))
180 for s in tree[1:]:
181 for s in tree[1:]:
181 _prettyformat(s, leafnodes, level + 1, lines)
182 _prettyformat(s, leafnodes, level + 1, lines)
182 lines[-1:] = [(lines[-1][0], lines[-1][1] + ')')]
183 lines[-1:] = [(lines[-1][0], lines[-1][1] + ')')]
183
184
184 def prettyformat(tree, leafnodes):
185 def prettyformat(tree, leafnodes):
185 lines = []
186 lines = []
186 _prettyformat(tree, leafnodes, 0, lines)
187 _prettyformat(tree, leafnodes, 0, lines)
187 output = '\n'.join((' ' * l + s) for l, s in lines)
188 output = '\n'.join((' ' * l + s) for l, s in lines)
188 return output
189 return output
189
190
190 def simplifyinfixops(tree, targetnodes):
191 def simplifyinfixops(tree, targetnodes):
191 """Flatten chained infix operations to reduce usage of Python stack
192 """Flatten chained infix operations to reduce usage of Python stack
192
193
193 >>> def f(tree):
194 >>> def f(tree):
194 ... print prettyformat(simplifyinfixops(tree, ('or',)), ('symbol',))
195 ... print prettyformat(simplifyinfixops(tree, ('or',)), ('symbol',))
195 >>> f(('or',
196 >>> f(('or',
196 ... ('or',
197 ... ('or',
197 ... ('symbol', '1'),
198 ... ('symbol', '1'),
198 ... ('symbol', '2')),
199 ... ('symbol', '2')),
199 ... ('symbol', '3')))
200 ... ('symbol', '3')))
200 (or
201 (or
201 ('symbol', '1')
202 ('symbol', '1')
202 ('symbol', '2')
203 ('symbol', '2')
203 ('symbol', '3'))
204 ('symbol', '3'))
204 >>> f(('func',
205 >>> f(('func',
205 ... ('symbol', 'p1'),
206 ... ('symbol', 'p1'),
206 ... ('or',
207 ... ('or',
207 ... ('or',
208 ... ('or',
208 ... ('func',
209 ... ('func',
209 ... ('symbol', 'sort'),
210 ... ('symbol', 'sort'),
210 ... ('list',
211 ... ('list',
211 ... ('or',
212 ... ('or',
212 ... ('or',
213 ... ('or',
213 ... ('symbol', '1'),
214 ... ('symbol', '1'),
214 ... ('symbol', '2')),
215 ... ('symbol', '2')),
215 ... ('symbol', '3')),
216 ... ('symbol', '3')),
216 ... ('negate',
217 ... ('negate',
217 ... ('symbol', 'rev')))),
218 ... ('symbol', 'rev')))),
218 ... ('and',
219 ... ('and',
219 ... ('symbol', '4'),
220 ... ('symbol', '4'),
220 ... ('group',
221 ... ('group',
221 ... ('or',
222 ... ('or',
222 ... ('or',
223 ... ('or',
223 ... ('symbol', '5'),
224 ... ('symbol', '5'),
224 ... ('symbol', '6')),
225 ... ('symbol', '6')),
225 ... ('symbol', '7'))))),
226 ... ('symbol', '7'))))),
226 ... ('symbol', '8'))))
227 ... ('symbol', '8'))))
227 (func
228 (func
228 ('symbol', 'p1')
229 ('symbol', 'p1')
229 (or
230 (or
230 (func
231 (func
231 ('symbol', 'sort')
232 ('symbol', 'sort')
232 (list
233 (list
233 (or
234 (or
234 ('symbol', '1')
235 ('symbol', '1')
235 ('symbol', '2')
236 ('symbol', '2')
236 ('symbol', '3'))
237 ('symbol', '3'))
237 (negate
238 (negate
238 ('symbol', 'rev'))))
239 ('symbol', 'rev'))))
239 (and
240 (and
240 ('symbol', '4')
241 ('symbol', '4')
241 (group
242 (group
242 (or
243 (or
243 ('symbol', '5')
244 ('symbol', '5')
244 ('symbol', '6')
245 ('symbol', '6')
245 ('symbol', '7'))))
246 ('symbol', '7'))))
246 ('symbol', '8')))
247 ('symbol', '8')))
247 """
248 """
248 if not isinstance(tree, tuple):
249 if not isinstance(tree, tuple):
249 return tree
250 return tree
250 op = tree[0]
251 op = tree[0]
251 if op not in targetnodes:
252 if op not in targetnodes:
252 return (op,) + tuple(simplifyinfixops(x, targetnodes) for x in tree[1:])
253 return (op,) + tuple(simplifyinfixops(x, targetnodes) for x in tree[1:])
253
254
254 # walk down left nodes taking each right node. no recursion to left nodes
255 # walk down left nodes taking each right node. no recursion to left nodes
255 # because infix operators are left-associative, i.e. left tree is deep.
256 # because infix operators are left-associative, i.e. left tree is deep.
256 # e.g. '1 + 2 + 3' -> (+ (+ 1 2) 3) -> (+ 1 2 3)
257 # e.g. '1 + 2 + 3' -> (+ (+ 1 2) 3) -> (+ 1 2 3)
257 simplified = []
258 simplified = []
258 x = tree
259 x = tree
259 while x[0] == op:
260 while x[0] == op:
260 l, r = x[1:]
261 l, r = x[1:]
261 simplified.append(simplifyinfixops(r, targetnodes))
262 simplified.append(simplifyinfixops(r, targetnodes))
262 x = l
263 x = l
263 simplified.append(simplifyinfixops(x, targetnodes))
264 simplified.append(simplifyinfixops(x, targetnodes))
264 simplified.append(op)
265 simplified.append(op)
265 return tuple(reversed(simplified))
266 return tuple(reversed(simplified))
266
267
267 def parseerrordetail(inst):
268 def parseerrordetail(inst):
268 """Compose error message from specified ParseError object
269 """Compose error message from specified ParseError object
269 """
270 """
270 if len(inst.args) > 1:
271 if len(inst.args) > 1:
271 return _('at %d: %s') % (inst.args[1], inst.args[0])
272 return _('at %d: %s') % (inst.args[1], inst.args[0])
272 else:
273 else:
273 return inst.args[0]
274 return inst.args[0]
274
275
275 class alias(object):
276 class alias(object):
276 """Parsed result of alias"""
277 """Parsed result of alias"""
277
278
278 def __init__(self, name, args, err, replacement):
279 def __init__(self, name, args, err, replacement):
279 self.name = name
280 self.name = name
280 self.args = args
281 self.args = args
281 self.error = err
282 self.error = err
282 self.replacement = replacement
283 self.replacement = replacement
283 # whether own `error` information is already shown or not.
284 # whether own `error` information is already shown or not.
284 # this avoids showing same warning multiple times at each
285 # this avoids showing same warning multiple times at each
285 # `expandaliases`.
286 # `expandaliases`.
286 self.warned = False
287 self.warned = False
287
288
288 class basealiasrules(object):
289 class basealiasrules(object):
289 """Parsing and expansion rule set of aliases
290 """Parsing and expansion rule set of aliases
290
291
291 This is a helper for fileset/revset/template aliases. A concrete rule set
292 This is a helper for fileset/revset/template aliases. A concrete rule set
292 should be made by sub-classing this and implementing class/static methods.
293 should be made by sub-classing this and implementing class/static methods.
293
294
294 It supports alias expansion of symbol and function-call styles::
295 It supports alias expansion of symbol and function-call styles::
295
296
296 # decl = defn
297 # decl = defn
297 h = heads(default)
298 h = heads(default)
298 b($1) = ancestors($1) - ancestors(default)
299 b($1) = ancestors($1) - ancestors(default)
299 """
300 """
300 # typically a config section, which will be included in error messages
301 # typically a config section, which will be included in error messages
301 _section = None
302 _section = None
302 # tag of symbol node
303 # tag of symbol node
303 _symbolnode = 'symbol'
304 _symbolnode = 'symbol'
304
305
305 def __new__(cls):
306 def __new__(cls):
306 raise TypeError("'%s' is not instantiatable" % cls.__name__)
307 raise TypeError("'%s' is not instantiatable" % cls.__name__)
307
308
308 @staticmethod
309 @staticmethod
309 def _parse(spec):
310 def _parse(spec):
310 """Parse an alias name, arguments and definition"""
311 """Parse an alias name, arguments and definition"""
311 raise NotImplementedError
312 raise NotImplementedError
312
313
313 @staticmethod
314 @staticmethod
314 def _trygetfunc(tree):
315 def _trygetfunc(tree):
315 """Return (name, args) if tree is a function; otherwise None"""
316 """Return (name, args) if tree is a function; otherwise None"""
316 raise NotImplementedError
317 raise NotImplementedError
317
318
318 @classmethod
319 @classmethod
319 def _builddecl(cls, decl):
320 def _builddecl(cls, decl):
320 """Parse an alias declaration into ``(name, args, errorstr)``
321 """Parse an alias declaration into ``(name, args, errorstr)``
321
322
322 This function analyzes the parsed tree. The parsing rule is provided
323 This function analyzes the parsed tree. The parsing rule is provided
323 by ``_parse()``.
324 by ``_parse()``.
324
325
325 - ``name``: of declared alias (may be ``decl`` itself at error)
326 - ``name``: of declared alias (may be ``decl`` itself at error)
326 - ``args``: list of argument names (or None for symbol declaration)
327 - ``args``: list of argument names (or None for symbol declaration)
327 - ``errorstr``: detail about detected error (or None)
328 - ``errorstr``: detail about detected error (or None)
328
329
329 >>> sym = lambda x: ('symbol', x)
330 >>> sym = lambda x: ('symbol', x)
330 >>> symlist = lambda *xs: ('list',) + tuple(sym(x) for x in xs)
331 >>> symlist = lambda *xs: ('list',) + tuple(sym(x) for x in xs)
331 >>> func = lambda n, a: ('func', sym(n), a)
332 >>> func = lambda n, a: ('func', sym(n), a)
332 >>> parsemap = {
333 >>> parsemap = {
333 ... 'foo': sym('foo'),
334 ... 'foo': sym('foo'),
334 ... '$foo': sym('$foo'),
335 ... '$foo': sym('$foo'),
335 ... 'foo::bar': ('dagrange', sym('foo'), sym('bar')),
336 ... 'foo::bar': ('dagrange', sym('foo'), sym('bar')),
336 ... 'foo()': func('foo', None),
337 ... 'foo()': func('foo', None),
337 ... '$foo()': func('$foo', None),
338 ... '$foo()': func('$foo', None),
338 ... 'foo($1, $2)': func('foo', symlist('$1', '$2')),
339 ... 'foo($1, $2)': func('foo', symlist('$1', '$2')),
339 ... 'foo(bar_bar, baz.baz)':
340 ... 'foo(bar_bar, baz.baz)':
340 ... func('foo', symlist('bar_bar', 'baz.baz')),
341 ... func('foo', symlist('bar_bar', 'baz.baz')),
341 ... 'foo(bar($1, $2))':
342 ... 'foo(bar($1, $2))':
342 ... func('foo', func('bar', symlist('$1', '$2'))),
343 ... func('foo', func('bar', symlist('$1', '$2'))),
343 ... 'foo($1, $2, nested($1, $2))':
344 ... 'foo($1, $2, nested($1, $2))':
344 ... func('foo', (symlist('$1', '$2') +
345 ... func('foo', (symlist('$1', '$2') +
345 ... (func('nested', symlist('$1', '$2')),))),
346 ... (func('nested', symlist('$1', '$2')),))),
346 ... 'foo("bar")': func('foo', ('string', 'bar')),
347 ... 'foo("bar")': func('foo', ('string', 'bar')),
347 ... 'foo($1, $2': error.ParseError('unexpected token: end', 10),
348 ... 'foo($1, $2': error.ParseError('unexpected token: end', 10),
348 ... 'foo("bar': error.ParseError('unterminated string', 5),
349 ... 'foo("bar': error.ParseError('unterminated string', 5),
349 ... 'foo($1, $2, $1)': func('foo', symlist('$1', '$2', '$1')),
350 ... 'foo($1, $2, $1)': func('foo', symlist('$1', '$2', '$1')),
350 ... }
351 ... }
351 >>> def parse(expr):
352 >>> def parse(expr):
352 ... x = parsemap[expr]
353 ... x = parsemap[expr]
353 ... if isinstance(x, Exception):
354 ... if isinstance(x, Exception):
354 ... raise x
355 ... raise x
355 ... return x
356 ... return x
356 >>> def trygetfunc(tree):
357 >>> def trygetfunc(tree):
357 ... if not tree or tree[0] != 'func' or tree[1][0] != 'symbol':
358 ... if not tree or tree[0] != 'func' or tree[1][0] != 'symbol':
358 ... return None
359 ... return None
359 ... if not tree[2]:
360 ... if not tree[2]:
360 ... return tree[1][1], []
361 ... return tree[1][1], []
361 ... if tree[2][0] == 'list':
362 ... if tree[2][0] == 'list':
362 ... return tree[1][1], list(tree[2][1:])
363 ... return tree[1][1], list(tree[2][1:])
363 ... return tree[1][1], [tree[2]]
364 ... return tree[1][1], [tree[2]]
364 >>> class aliasrules(basealiasrules):
365 >>> class aliasrules(basealiasrules):
365 ... _parse = staticmethod(parse)
366 ... _parse = staticmethod(parse)
366 ... _trygetfunc = staticmethod(trygetfunc)
367 ... _trygetfunc = staticmethod(trygetfunc)
367 >>> builddecl = aliasrules._builddecl
368 >>> builddecl = aliasrules._builddecl
368 >>> builddecl('foo')
369 >>> builddecl('foo')
369 ('foo', None, None)
370 ('foo', None, None)
370 >>> builddecl('$foo')
371 >>> builddecl('$foo')
371 ('$foo', None, "invalid symbol '$foo'")
372 ('$foo', None, "invalid symbol '$foo'")
372 >>> builddecl('foo::bar')
373 >>> builddecl('foo::bar')
373 ('foo::bar', None, 'invalid format')
374 ('foo::bar', None, 'invalid format')
374 >>> builddecl('foo()')
375 >>> builddecl('foo()')
375 ('foo', [], None)
376 ('foo', [], None)
376 >>> builddecl('$foo()')
377 >>> builddecl('$foo()')
377 ('$foo()', None, "invalid function '$foo'")
378 ('$foo()', None, "invalid function '$foo'")
378 >>> builddecl('foo($1, $2)')
379 >>> builddecl('foo($1, $2)')
379 ('foo', ['$1', '$2'], None)
380 ('foo', ['$1', '$2'], None)
380 >>> builddecl('foo(bar_bar, baz.baz)')
381 >>> builddecl('foo(bar_bar, baz.baz)')
381 ('foo', ['bar_bar', 'baz.baz'], None)
382 ('foo', ['bar_bar', 'baz.baz'], None)
382 >>> builddecl('foo($1, $2, nested($1, $2))')
383 >>> builddecl('foo($1, $2, nested($1, $2))')
383 ('foo($1, $2, nested($1, $2))', None, 'invalid argument list')
384 ('foo($1, $2, nested($1, $2))', None, 'invalid argument list')
384 >>> builddecl('foo(bar($1, $2))')
385 >>> builddecl('foo(bar($1, $2))')
385 ('foo(bar($1, $2))', None, 'invalid argument list')
386 ('foo(bar($1, $2))', None, 'invalid argument list')
386 >>> builddecl('foo("bar")')
387 >>> builddecl('foo("bar")')
387 ('foo("bar")', None, 'invalid argument list')
388 ('foo("bar")', None, 'invalid argument list')
388 >>> builddecl('foo($1, $2')
389 >>> builddecl('foo($1, $2')
389 ('foo($1, $2', None, 'at 10: unexpected token: end')
390 ('foo($1, $2', None, 'at 10: unexpected token: end')
390 >>> builddecl('foo("bar')
391 >>> builddecl('foo("bar')
391 ('foo("bar', None, 'at 5: unterminated string')
392 ('foo("bar', None, 'at 5: unterminated string')
392 >>> builddecl('foo($1, $2, $1)')
393 >>> builddecl('foo($1, $2, $1)')
393 ('foo', None, 'argument names collide with each other')
394 ('foo', None, 'argument names collide with each other')
394 """
395 """
395 try:
396 try:
396 tree = cls._parse(decl)
397 tree = cls._parse(decl)
397 except error.ParseError as inst:
398 except error.ParseError as inst:
398 return (decl, None, parseerrordetail(inst))
399 return (decl, None, parseerrordetail(inst))
399
400
400 if tree[0] == cls._symbolnode:
401 if tree[0] == cls._symbolnode:
401 # "name = ...." style
402 # "name = ...." style
402 name = tree[1]
403 name = tree[1]
403 if name.startswith('$'):
404 if name.startswith('$'):
404 return (decl, None, _("invalid symbol '%s'") % name)
405 return (decl, None, _("invalid symbol '%s'") % name)
405 return (name, None, None)
406 return (name, None, None)
406
407
407 func = cls._trygetfunc(tree)
408 func = cls._trygetfunc(tree)
408 if func:
409 if func:
409 # "name(arg, ....) = ...." style
410 # "name(arg, ....) = ...." style
410 name, args = func
411 name, args = func
411 if name.startswith('$'):
412 if name.startswith('$'):
412 return (decl, None, _("invalid function '%s'") % name)
413 return (decl, None, _("invalid function '%s'") % name)
413 if any(t[0] != cls._symbolnode for t in args):
414 if any(t[0] != cls._symbolnode for t in args):
414 return (decl, None, _("invalid argument list"))
415 return (decl, None, _("invalid argument list"))
415 if len(args) != len(set(args)):
416 if len(args) != len(set(args)):
416 return (name, None, _("argument names collide with each other"))
417 return (name, None, _("argument names collide with each other"))
417 return (name, [t[1] for t in args], None)
418 return (name, [t[1] for t in args], None)
418
419
419 return (decl, None, _("invalid format"))
420 return (decl, None, _("invalid format"))
420
421
421 @classmethod
422 @classmethod
422 def _relabelargs(cls, tree, args):
423 def _relabelargs(cls, tree, args):
423 """Mark alias arguments as ``_aliasarg``"""
424 """Mark alias arguments as ``_aliasarg``"""
424 if not isinstance(tree, tuple):
425 if not isinstance(tree, tuple):
425 return tree
426 return tree
426 op = tree[0]
427 op = tree[0]
427 if op != cls._symbolnode:
428 if op != cls._symbolnode:
428 return (op,) + tuple(cls._relabelargs(x, args) for x in tree[1:])
429 return (op,) + tuple(cls._relabelargs(x, args) for x in tree[1:])
429
430
430 assert len(tree) == 2
431 assert len(tree) == 2
431 sym = tree[1]
432 sym = tree[1]
432 if sym in args:
433 if sym in args:
433 op = '_aliasarg'
434 op = '_aliasarg'
434 elif sym.startswith('$'):
435 elif sym.startswith('$'):
435 raise error.ParseError(_("invalid symbol '%s'") % sym)
436 raise error.ParseError(_("invalid symbol '%s'") % sym)
436 return (op, sym)
437 return (op, sym)
437
438
438 @classmethod
439 @classmethod
439 def _builddefn(cls, defn, args):
440 def _builddefn(cls, defn, args):
440 """Parse an alias definition into a tree and marks substitutions
441 """Parse an alias definition into a tree and marks substitutions
441
442
442 This function marks alias argument references as ``_aliasarg``. The
443 This function marks alias argument references as ``_aliasarg``. The
443 parsing rule is provided by ``_parse()``.
444 parsing rule is provided by ``_parse()``.
444
445
445 ``args`` is a list of alias argument names, or None if the alias
446 ``args`` is a list of alias argument names, or None if the alias
446 is declared as a symbol.
447 is declared as a symbol.
447
448
448 >>> parsemap = {
449 >>> parsemap = {
449 ... '$1 or foo': ('or', ('symbol', '$1'), ('symbol', 'foo')),
450 ... '$1 or foo': ('or', ('symbol', '$1'), ('symbol', 'foo')),
450 ... '$1 or $bar': ('or', ('symbol', '$1'), ('symbol', '$bar')),
451 ... '$1 or $bar': ('or', ('symbol', '$1'), ('symbol', '$bar')),
451 ... '$10 or baz': ('or', ('symbol', '$10'), ('symbol', 'baz')),
452 ... '$10 or baz': ('or', ('symbol', '$10'), ('symbol', 'baz')),
452 ... '"$1" or "foo"': ('or', ('string', '$1'), ('string', 'foo')),
453 ... '"$1" or "foo"': ('or', ('string', '$1'), ('string', 'foo')),
453 ... }
454 ... }
454 >>> class aliasrules(basealiasrules):
455 >>> class aliasrules(basealiasrules):
455 ... _parse = staticmethod(parsemap.__getitem__)
456 ... _parse = staticmethod(parsemap.__getitem__)
456 ... _trygetfunc = staticmethod(lambda x: None)
457 ... _trygetfunc = staticmethod(lambda x: None)
457 >>> builddefn = aliasrules._builddefn
458 >>> builddefn = aliasrules._builddefn
458 >>> def pprint(tree):
459 >>> def pprint(tree):
459 ... print prettyformat(tree, ('_aliasarg', 'string', 'symbol'))
460 ... print prettyformat(tree, ('_aliasarg', 'string', 'symbol'))
460 >>> args = ['$1', '$2', 'foo']
461 >>> args = ['$1', '$2', 'foo']
461 >>> pprint(builddefn('$1 or foo', args))
462 >>> pprint(builddefn('$1 or foo', args))
462 (or
463 (or
463 ('_aliasarg', '$1')
464 ('_aliasarg', '$1')
464 ('_aliasarg', 'foo'))
465 ('_aliasarg', 'foo'))
465 >>> try:
466 >>> try:
466 ... builddefn('$1 or $bar', args)
467 ... builddefn('$1 or $bar', args)
467 ... except error.ParseError as inst:
468 ... except error.ParseError as inst:
468 ... print parseerrordetail(inst)
469 ... print parseerrordetail(inst)
469 invalid symbol '$bar'
470 invalid symbol '$bar'
470 >>> args = ['$1', '$10', 'foo']
471 >>> args = ['$1', '$10', 'foo']
471 >>> pprint(builddefn('$10 or baz', args))
472 >>> pprint(builddefn('$10 or baz', args))
472 (or
473 (or
473 ('_aliasarg', '$10')
474 ('_aliasarg', '$10')
474 ('symbol', 'baz'))
475 ('symbol', 'baz'))
475 >>> pprint(builddefn('"$1" or "foo"', args))
476 >>> pprint(builddefn('"$1" or "foo"', args))
476 (or
477 (or
477 ('string', '$1')
478 ('string', '$1')
478 ('string', 'foo'))
479 ('string', 'foo'))
479 """
480 """
480 tree = cls._parse(defn)
481 tree = cls._parse(defn)
481 if args:
482 if args:
482 args = set(args)
483 args = set(args)
483 else:
484 else:
484 args = set()
485 args = set()
485 return cls._relabelargs(tree, args)
486 return cls._relabelargs(tree, args)
486
487
487 @classmethod
488 @classmethod
488 def build(cls, decl, defn):
489 def build(cls, decl, defn):
489 """Parse an alias declaration and definition into an alias object"""
490 """Parse an alias declaration and definition into an alias object"""
490 repl = efmt = None
491 repl = efmt = None
491 name, args, err = cls._builddecl(decl)
492 name, args, err = cls._builddecl(decl)
492 if err:
493 if err:
493 efmt = _('bad declaration of %(section)s "%(name)s": %(error)s')
494 efmt = _('bad declaration of %(section)s "%(name)s": %(error)s')
494 else:
495 else:
495 try:
496 try:
496 repl = cls._builddefn(defn, args)
497 repl = cls._builddefn(defn, args)
497 except error.ParseError as inst:
498 except error.ParseError as inst:
498 err = parseerrordetail(inst)
499 err = parseerrordetail(inst)
499 efmt = _('bad definition of %(section)s "%(name)s": %(error)s')
500 efmt = _('bad definition of %(section)s "%(name)s": %(error)s')
500 if err:
501 if err:
501 err = efmt % {'section': cls._section, 'name': name, 'error': err}
502 err = efmt % {'section': cls._section, 'name': name, 'error': err}
502 return alias(name, args, err, repl)
503 return alias(name, args, err, repl)
503
504
504 @classmethod
505 @classmethod
505 def buildmap(cls, items):
506 def buildmap(cls, items):
506 """Parse a list of alias (name, replacement) pairs into a dict of
507 """Parse a list of alias (name, replacement) pairs into a dict of
507 alias objects"""
508 alias objects"""
508 aliases = {}
509 aliases = {}
509 for decl, defn in items:
510 for decl, defn in items:
510 a = cls.build(decl, defn)
511 a = cls.build(decl, defn)
511 aliases[a.name] = a
512 aliases[a.name] = a
512 return aliases
513 return aliases
513
514
514 @classmethod
515 @classmethod
515 def _getalias(cls, aliases, tree):
516 def _getalias(cls, aliases, tree):
516 """If tree looks like an unexpanded alias, return (alias, pattern-args)
517 """If tree looks like an unexpanded alias, return (alias, pattern-args)
517 pair. Return None otherwise.
518 pair. Return None otherwise.
518 """
519 """
519 if not isinstance(tree, tuple):
520 if not isinstance(tree, tuple):
520 return None
521 return None
521 if tree[0] == cls._symbolnode:
522 if tree[0] == cls._symbolnode:
522 name = tree[1]
523 name = tree[1]
523 a = aliases.get(name)
524 a = aliases.get(name)
524 if a and a.args is None:
525 if a and a.args is None:
525 return a, None
526 return a, None
526 func = cls._trygetfunc(tree)
527 func = cls._trygetfunc(tree)
527 if func:
528 if func:
528 name, args = func
529 name, args = func
529 a = aliases.get(name)
530 a = aliases.get(name)
530 if a and a.args is not None:
531 if a and a.args is not None:
531 return a, args
532 return a, args
532 return None
533 return None
533
534
534 @classmethod
535 @classmethod
535 def _expandargs(cls, tree, args):
536 def _expandargs(cls, tree, args):
536 """Replace _aliasarg instances with the substitution value of the
537 """Replace _aliasarg instances with the substitution value of the
537 same name in args, recursively.
538 same name in args, recursively.
538 """
539 """
539 if not isinstance(tree, tuple):
540 if not isinstance(tree, tuple):
540 return tree
541 return tree
541 if tree[0] == '_aliasarg':
542 if tree[0] == '_aliasarg':
542 sym = tree[1]
543 sym = tree[1]
543 return args[sym]
544 return args[sym]
544 return tuple(cls._expandargs(t, args) for t in tree)
545 return tuple(cls._expandargs(t, args) for t in tree)
545
546
546 @classmethod
547 @classmethod
547 def _expand(cls, aliases, tree, expanding, cache):
548 def _expand(cls, aliases, tree, expanding, cache):
548 if not isinstance(tree, tuple):
549 if not isinstance(tree, tuple):
549 return tree
550 return tree
550 r = cls._getalias(aliases, tree)
551 r = cls._getalias(aliases, tree)
551 if r is None:
552 if r is None:
552 return tuple(cls._expand(aliases, t, expanding, cache)
553 return tuple(cls._expand(aliases, t, expanding, cache)
553 for t in tree)
554 for t in tree)
554 a, l = r
555 a, l = r
555 if a.error:
556 if a.error:
556 raise error.Abort(a.error)
557 raise error.Abort(a.error)
557 if a in expanding:
558 if a in expanding:
558 raise error.ParseError(_('infinite expansion of %(section)s '
559 raise error.ParseError(_('infinite expansion of %(section)s '
559 '"%(name)s" detected')
560 '"%(name)s" detected')
560 % {'section': cls._section, 'name': a.name})
561 % {'section': cls._section, 'name': a.name})
561 # get cacheable replacement tree by expanding aliases recursively
562 # get cacheable replacement tree by expanding aliases recursively
562 expanding.append(a)
563 expanding.append(a)
563 if a.name not in cache:
564 if a.name not in cache:
564 cache[a.name] = cls._expand(aliases, a.replacement, expanding,
565 cache[a.name] = cls._expand(aliases, a.replacement, expanding,
565 cache)
566 cache)
566 result = cache[a.name]
567 result = cache[a.name]
567 expanding.pop()
568 expanding.pop()
568 if a.args is None:
569 if a.args is None:
569 return result
570 return result
570 # substitute function arguments in replacement tree
571 # substitute function arguments in replacement tree
571 if len(l) != len(a.args):
572 if len(l) != len(a.args):
572 raise error.ParseError(_('invalid number of arguments: %d')
573 raise error.ParseError(_('invalid number of arguments: %d')
573 % len(l))
574 % len(l))
574 l = [cls._expand(aliases, t, [], cache) for t in l]
575 l = [cls._expand(aliases, t, [], cache) for t in l]
575 return cls._expandargs(result, dict(zip(a.args, l)))
576 return cls._expandargs(result, dict(zip(a.args, l)))
576
577
577 @classmethod
578 @classmethod
578 def expand(cls, aliases, tree):
579 def expand(cls, aliases, tree):
579 """Expand aliases in tree, recursively.
580 """Expand aliases in tree, recursively.
580
581
581 'aliases' is a dictionary mapping user defined aliases to alias objects.
582 'aliases' is a dictionary mapping user defined aliases to alias objects.
582 """
583 """
583 return cls._expand(aliases, tree, [], {})
584 return cls._expand(aliases, tree, [], {})
@@ -1,3720 +1,3720 b''
1 $ HGENCODING=utf-8
1 $ HGENCODING=utf-8
2 $ export HGENCODING
2 $ export HGENCODING
3 $ cat > testrevset.py << EOF
3 $ cat > testrevset.py << EOF
4 > import mercurial.revset
4 > import mercurial.revset
5 >
5 >
6 > baseset = mercurial.revset.baseset
6 > baseset = mercurial.revset.baseset
7 >
7 >
8 > def r3232(repo, subset, x):
8 > def r3232(repo, subset, x):
9 > """"simple revset that return [3,2,3,2]
9 > """"simple revset that return [3,2,3,2]
10 >
10 >
11 > revisions duplicated on purpose.
11 > revisions duplicated on purpose.
12 > """
12 > """
13 > if 3 not in subset:
13 > if 3 not in subset:
14 > if 2 in subset:
14 > if 2 in subset:
15 > return baseset([2,2])
15 > return baseset([2,2])
16 > return baseset()
16 > return baseset()
17 > return baseset([3,3,2,2])
17 > return baseset([3,3,2,2])
18 >
18 >
19 > mercurial.revset.symbols['r3232'] = r3232
19 > mercurial.revset.symbols['r3232'] = r3232
20 > EOF
20 > EOF
21 $ cat >> $HGRCPATH << EOF
21 $ cat >> $HGRCPATH << EOF
22 > [extensions]
22 > [extensions]
23 > testrevset=$TESTTMP/testrevset.py
23 > testrevset=$TESTTMP/testrevset.py
24 > EOF
24 > EOF
25
25
26 $ try() {
26 $ try() {
27 > hg debugrevspec --debug "$@"
27 > hg debugrevspec --debug "$@"
28 > }
28 > }
29
29
30 $ log() {
30 $ log() {
31 > hg log --template '{rev}\n' -r "$1"
31 > hg log --template '{rev}\n' -r "$1"
32 > }
32 > }
33
33
34 extension to build '_intlist()' and '_hexlist()', which is necessary because
34 extension to build '_intlist()' and '_hexlist()', which is necessary because
35 these predicates use '\0' as a separator:
35 these predicates use '\0' as a separator:
36
36
37 $ cat <<EOF > debugrevlistspec.py
37 $ cat <<EOF > debugrevlistspec.py
38 > from __future__ import absolute_import
38 > from __future__ import absolute_import
39 > from mercurial import (
39 > from mercurial import (
40 > cmdutil,
40 > cmdutil,
41 > node as nodemod,
41 > node as nodemod,
42 > revset,
42 > revset,
43 > revsetlang,
43 > revsetlang,
44 > smartset,
44 > smartset,
45 > )
45 > )
46 > cmdtable = {}
46 > cmdtable = {}
47 > command = cmdutil.command(cmdtable)
47 > command = cmdutil.command(cmdtable)
48 > @command('debugrevlistspec',
48 > @command('debugrevlistspec',
49 > [('', 'optimize', None, 'print parsed tree after optimizing'),
49 > [('', 'optimize', None, 'print parsed tree after optimizing'),
50 > ('', 'bin', None, 'unhexlify arguments')])
50 > ('', 'bin', None, 'unhexlify arguments')])
51 > def debugrevlistspec(ui, repo, fmt, *args, **opts):
51 > def debugrevlistspec(ui, repo, fmt, *args, **opts):
52 > if opts['bin']:
52 > if opts['bin']:
53 > args = map(nodemod.bin, args)
53 > args = map(nodemod.bin, args)
54 > expr = revsetlang.formatspec(fmt, list(args))
54 > expr = revsetlang.formatspec(fmt, list(args))
55 > if ui.verbose:
55 > if ui.verbose:
56 > tree = revsetlang.parse(expr, lookup=repo.__contains__)
56 > tree = revsetlang.parse(expr, lookup=repo.__contains__)
57 > ui.note(revsetlang.prettyformat(tree), "\n")
57 > ui.note(revsetlang.prettyformat(tree), "\n")
58 > if opts["optimize"]:
58 > if opts["optimize"]:
59 > opttree = revsetlang.optimize(revsetlang.analyze(tree))
59 > opttree = revsetlang.optimize(revsetlang.analyze(tree))
60 > ui.note("* optimized:\n", revsetlang.prettyformat(opttree),
60 > ui.note("* optimized:\n", revsetlang.prettyformat(opttree),
61 > "\n")
61 > "\n")
62 > func = revset.match(ui, expr, repo)
62 > func = revset.match(ui, expr, repo)
63 > revs = func(repo)
63 > revs = func(repo)
64 > if ui.verbose:
64 > if ui.verbose:
65 > ui.note("* set:\n", smartset.prettyformat(revs), "\n")
65 > ui.note("* set:\n", smartset.prettyformat(revs), "\n")
66 > for c in revs:
66 > for c in revs:
67 > ui.write("%s\n" % c)
67 > ui.write("%s\n" % c)
68 > EOF
68 > EOF
69 $ cat <<EOF >> $HGRCPATH
69 $ cat <<EOF >> $HGRCPATH
70 > [extensions]
70 > [extensions]
71 > debugrevlistspec = $TESTTMP/debugrevlistspec.py
71 > debugrevlistspec = $TESTTMP/debugrevlistspec.py
72 > EOF
72 > EOF
73 $ trylist() {
73 $ trylist() {
74 > hg debugrevlistspec --debug "$@"
74 > hg debugrevlistspec --debug "$@"
75 > }
75 > }
76
76
77 $ hg init repo
77 $ hg init repo
78 $ cd repo
78 $ cd repo
79
79
80 $ echo a > a
80 $ echo a > a
81 $ hg branch a
81 $ hg branch a
82 marked working directory as branch a
82 marked working directory as branch a
83 (branches are permanent and global, did you want a bookmark?)
83 (branches are permanent and global, did you want a bookmark?)
84 $ hg ci -Aqm0
84 $ hg ci -Aqm0
85
85
86 $ echo b > b
86 $ echo b > b
87 $ hg branch b
87 $ hg branch b
88 marked working directory as branch b
88 marked working directory as branch b
89 $ hg ci -Aqm1
89 $ hg ci -Aqm1
90
90
91 $ rm a
91 $ rm a
92 $ hg branch a-b-c-
92 $ hg branch a-b-c-
93 marked working directory as branch a-b-c-
93 marked working directory as branch a-b-c-
94 $ hg ci -Aqm2 -u Bob
94 $ hg ci -Aqm2 -u Bob
95
95
96 $ hg log -r "extra('branch', 'a-b-c-')" --template '{rev}\n'
96 $ hg log -r "extra('branch', 'a-b-c-')" --template '{rev}\n'
97 2
97 2
98 $ hg log -r "extra('branch')" --template '{rev}\n'
98 $ hg log -r "extra('branch')" --template '{rev}\n'
99 0
99 0
100 1
100 1
101 2
101 2
102 $ hg log -r "extra('branch', 're:a')" --template '{rev} {branch}\n'
102 $ hg log -r "extra('branch', 're:a')" --template '{rev} {branch}\n'
103 0 a
103 0 a
104 2 a-b-c-
104 2 a-b-c-
105
105
106 $ hg co 1
106 $ hg co 1
107 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 $ hg branch +a+b+c+
108 $ hg branch +a+b+c+
109 marked working directory as branch +a+b+c+
109 marked working directory as branch +a+b+c+
110 $ hg ci -Aqm3
110 $ hg ci -Aqm3
111
111
112 $ hg co 2 # interleave
112 $ hg co 2 # interleave
113 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
113 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
114 $ echo bb > b
114 $ echo bb > b
115 $ hg branch -- -a-b-c-
115 $ hg branch -- -a-b-c-
116 marked working directory as branch -a-b-c-
116 marked working directory as branch -a-b-c-
117 $ hg ci -Aqm4 -d "May 12 2005"
117 $ hg ci -Aqm4 -d "May 12 2005"
118
118
119 $ hg co 3
119 $ hg co 3
120 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
120 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
121 $ hg branch !a/b/c/
121 $ hg branch !a/b/c/
122 marked working directory as branch !a/b/c/
122 marked working directory as branch !a/b/c/
123 $ hg ci -Aqm"5 bug"
123 $ hg ci -Aqm"5 bug"
124
124
125 $ hg merge 4
125 $ hg merge 4
126 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
126 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
127 (branch merge, don't forget to commit)
127 (branch merge, don't forget to commit)
128 $ hg branch _a_b_c_
128 $ hg branch _a_b_c_
129 marked working directory as branch _a_b_c_
129 marked working directory as branch _a_b_c_
130 $ hg ci -Aqm"6 issue619"
130 $ hg ci -Aqm"6 issue619"
131
131
132 $ hg branch .a.b.c.
132 $ hg branch .a.b.c.
133 marked working directory as branch .a.b.c.
133 marked working directory as branch .a.b.c.
134 $ hg ci -Aqm7
134 $ hg ci -Aqm7
135
135
136 $ hg branch all
136 $ hg branch all
137 marked working directory as branch all
137 marked working directory as branch all
138
138
139 $ hg co 4
139 $ hg co 4
140 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 $ hg branch Γ©
141 $ hg branch Γ©
142 marked working directory as branch \xc3\xa9 (esc)
142 marked working directory as branch \xc3\xa9 (esc)
143 $ hg ci -Aqm9
143 $ hg ci -Aqm9
144
144
145 $ hg tag -r6 1.0
145 $ hg tag -r6 1.0
146 $ hg bookmark -r6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
146 $ hg bookmark -r6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
147
147
148 $ hg clone --quiet -U -r 7 . ../remote1
148 $ hg clone --quiet -U -r 7 . ../remote1
149 $ hg clone --quiet -U -r 8 . ../remote2
149 $ hg clone --quiet -U -r 8 . ../remote2
150 $ echo "[paths]" >> .hg/hgrc
150 $ echo "[paths]" >> .hg/hgrc
151 $ echo "default = ../remote1" >> .hg/hgrc
151 $ echo "default = ../remote1" >> .hg/hgrc
152
152
153 trivial
153 trivial
154
154
155 $ try 0:1
155 $ try 0:1
156 (range
156 (range
157 ('symbol', '0')
157 ('symbol', '0')
158 ('symbol', '1'))
158 ('symbol', '1'))
159 * set:
159 * set:
160 <spanset+ 0:1>
160 <spanset+ 0:1>
161 0
161 0
162 1
162 1
163 $ try --optimize :
163 $ try --optimize :
164 (rangeall
164 (rangeall
165 None)
165 None)
166 * optimized:
166 * optimized:
167 (rangeall
167 (rangeall
168 None
168 None
169 define)
169 define)
170 * set:
170 * set:
171 <spanset+ 0:9>
171 <spanset+ 0:9>
172 0
172 0
173 1
173 1
174 2
174 2
175 3
175 3
176 4
176 4
177 5
177 5
178 6
178 6
179 7
179 7
180 8
180 8
181 9
181 9
182 $ try 3::6
182 $ try 3::6
183 (dagrange
183 (dagrange
184 ('symbol', '3')
184 ('symbol', '3')
185 ('symbol', '6'))
185 ('symbol', '6'))
186 * set:
186 * set:
187 <baseset+ [3, 5, 6]>
187 <baseset+ [3, 5, 6]>
188 3
188 3
189 5
189 5
190 6
190 6
191 $ try '0|1|2'
191 $ try '0|1|2'
192 (or
192 (or
193 (list
193 (list
194 ('symbol', '0')
194 ('symbol', '0')
195 ('symbol', '1')
195 ('symbol', '1')
196 ('symbol', '2')))
196 ('symbol', '2')))
197 * set:
197 * set:
198 <baseset [0, 1, 2]>
198 <baseset [0, 1, 2]>
199 0
199 0
200 1
200 1
201 2
201 2
202
202
203 names that should work without quoting
203 names that should work without quoting
204
204
205 $ try a
205 $ try a
206 ('symbol', 'a')
206 ('symbol', 'a')
207 * set:
207 * set:
208 <baseset [0]>
208 <baseset [0]>
209 0
209 0
210 $ try b-a
210 $ try b-a
211 (minus
211 (minus
212 ('symbol', 'b')
212 ('symbol', 'b')
213 ('symbol', 'a'))
213 ('symbol', 'a'))
214 * set:
214 * set:
215 <filteredset
215 <filteredset
216 <baseset [1]>,
216 <baseset [1]>,
217 <not
217 <not
218 <baseset [0]>>>
218 <baseset [0]>>>
219 1
219 1
220 $ try _a_b_c_
220 $ try _a_b_c_
221 ('symbol', '_a_b_c_')
221 ('symbol', '_a_b_c_')
222 * set:
222 * set:
223 <baseset [6]>
223 <baseset [6]>
224 6
224 6
225 $ try _a_b_c_-a
225 $ try _a_b_c_-a
226 (minus
226 (minus
227 ('symbol', '_a_b_c_')
227 ('symbol', '_a_b_c_')
228 ('symbol', 'a'))
228 ('symbol', 'a'))
229 * set:
229 * set:
230 <filteredset
230 <filteredset
231 <baseset [6]>,
231 <baseset [6]>,
232 <not
232 <not
233 <baseset [0]>>>
233 <baseset [0]>>>
234 6
234 6
235 $ try .a.b.c.
235 $ try .a.b.c.
236 ('symbol', '.a.b.c.')
236 ('symbol', '.a.b.c.')
237 * set:
237 * set:
238 <baseset [7]>
238 <baseset [7]>
239 7
239 7
240 $ try .a.b.c.-a
240 $ try .a.b.c.-a
241 (minus
241 (minus
242 ('symbol', '.a.b.c.')
242 ('symbol', '.a.b.c.')
243 ('symbol', 'a'))
243 ('symbol', 'a'))
244 * set:
244 * set:
245 <filteredset
245 <filteredset
246 <baseset [7]>,
246 <baseset [7]>,
247 <not
247 <not
248 <baseset [0]>>>
248 <baseset [0]>>>
249 7
249 7
250
250
251 names that should be caught by fallback mechanism
251 names that should be caught by fallback mechanism
252
252
253 $ try -- '-a-b-c-'
253 $ try -- '-a-b-c-'
254 ('symbol', '-a-b-c-')
254 ('symbol', '-a-b-c-')
255 * set:
255 * set:
256 <baseset [4]>
256 <baseset [4]>
257 4
257 4
258 $ log -a-b-c-
258 $ log -a-b-c-
259 4
259 4
260 $ try '+a+b+c+'
260 $ try '+a+b+c+'
261 ('symbol', '+a+b+c+')
261 ('symbol', '+a+b+c+')
262 * set:
262 * set:
263 <baseset [3]>
263 <baseset [3]>
264 3
264 3
265 $ try '+a+b+c+:'
265 $ try '+a+b+c+:'
266 (rangepost
266 (rangepost
267 ('symbol', '+a+b+c+'))
267 ('symbol', '+a+b+c+'))
268 * set:
268 * set:
269 <spanset+ 3:9>
269 <spanset+ 3:9>
270 3
270 3
271 4
271 4
272 5
272 5
273 6
273 6
274 7
274 7
275 8
275 8
276 9
276 9
277 $ try ':+a+b+c+'
277 $ try ':+a+b+c+'
278 (rangepre
278 (rangepre
279 ('symbol', '+a+b+c+'))
279 ('symbol', '+a+b+c+'))
280 * set:
280 * set:
281 <spanset+ 0:3>
281 <spanset+ 0:3>
282 0
282 0
283 1
283 1
284 2
284 2
285 3
285 3
286 $ try -- '-a-b-c-:+a+b+c+'
286 $ try -- '-a-b-c-:+a+b+c+'
287 (range
287 (range
288 ('symbol', '-a-b-c-')
288 ('symbol', '-a-b-c-')
289 ('symbol', '+a+b+c+'))
289 ('symbol', '+a+b+c+'))
290 * set:
290 * set:
291 <spanset- 3:4>
291 <spanset- 3:4>
292 4
292 4
293 3
293 3
294 $ log '-a-b-c-:+a+b+c+'
294 $ log '-a-b-c-:+a+b+c+'
295 4
295 4
296 3
296 3
297
297
298 $ try -- -a-b-c--a # complains
298 $ try -- -a-b-c--a # complains
299 (minus
299 (minus
300 (minus
300 (minus
301 (minus
301 (minus
302 (negate
302 (negate
303 ('symbol', 'a'))
303 ('symbol', 'a'))
304 ('symbol', 'b'))
304 ('symbol', 'b'))
305 ('symbol', 'c'))
305 ('symbol', 'c'))
306 (negate
306 (negate
307 ('symbol', 'a')))
307 ('symbol', 'a')))
308 abort: unknown revision '-a'!
308 abort: unknown revision '-a'!
309 [255]
309 [255]
310 $ try Γ©
310 $ try Γ©
311 ('symbol', '\xc3\xa9')
311 ('symbol', '\xc3\xa9')
312 * set:
312 * set:
313 <baseset [9]>
313 <baseset [9]>
314 9
314 9
315
315
316 no quoting needed
316 no quoting needed
317
317
318 $ log ::a-b-c-
318 $ log ::a-b-c-
319 0
319 0
320 1
320 1
321 2
321 2
322
322
323 quoting needed
323 quoting needed
324
324
325 $ try '"-a-b-c-"-a'
325 $ try '"-a-b-c-"-a'
326 (minus
326 (minus
327 ('string', '-a-b-c-')
327 ('string', '-a-b-c-')
328 ('symbol', 'a'))
328 ('symbol', 'a'))
329 * set:
329 * set:
330 <filteredset
330 <filteredset
331 <baseset [4]>,
331 <baseset [4]>,
332 <not
332 <not
333 <baseset [0]>>>
333 <baseset [0]>>>
334 4
334 4
335
335
336 $ log '1 or 2'
336 $ log '1 or 2'
337 1
337 1
338 2
338 2
339 $ log '1|2'
339 $ log '1|2'
340 1
340 1
341 2
341 2
342 $ log '1 and 2'
342 $ log '1 and 2'
343 $ log '1&2'
343 $ log '1&2'
344 $ try '1&2|3' # precedence - and is higher
344 $ try '1&2|3' # precedence - and is higher
345 (or
345 (or
346 (list
346 (list
347 (and
347 (and
348 ('symbol', '1')
348 ('symbol', '1')
349 ('symbol', '2'))
349 ('symbol', '2'))
350 ('symbol', '3')))
350 ('symbol', '3')))
351 * set:
351 * set:
352 <addset
352 <addset
353 <baseset []>,
353 <baseset []>,
354 <baseset [3]>>
354 <baseset [3]>>
355 3
355 3
356 $ try '1|2&3'
356 $ try '1|2&3'
357 (or
357 (or
358 (list
358 (list
359 ('symbol', '1')
359 ('symbol', '1')
360 (and
360 (and
361 ('symbol', '2')
361 ('symbol', '2')
362 ('symbol', '3'))))
362 ('symbol', '3'))))
363 * set:
363 * set:
364 <addset
364 <addset
365 <baseset [1]>,
365 <baseset [1]>,
366 <baseset []>>
366 <baseset []>>
367 1
367 1
368 $ try '1&2&3' # associativity
368 $ try '1&2&3' # associativity
369 (and
369 (and
370 (and
370 (and
371 ('symbol', '1')
371 ('symbol', '1')
372 ('symbol', '2'))
372 ('symbol', '2'))
373 ('symbol', '3'))
373 ('symbol', '3'))
374 * set:
374 * set:
375 <baseset []>
375 <baseset []>
376 $ try '1|(2|3)'
376 $ try '1|(2|3)'
377 (or
377 (or
378 (list
378 (list
379 ('symbol', '1')
379 ('symbol', '1')
380 (group
380 (group
381 (or
381 (or
382 (list
382 (list
383 ('symbol', '2')
383 ('symbol', '2')
384 ('symbol', '3'))))))
384 ('symbol', '3'))))))
385 * set:
385 * set:
386 <addset
386 <addset
387 <baseset [1]>,
387 <baseset [1]>,
388 <baseset [2, 3]>>
388 <baseset [2, 3]>>
389 1
389 1
390 2
390 2
391 3
391 3
392 $ log '1.0' # tag
392 $ log '1.0' # tag
393 6
393 6
394 $ log 'a' # branch
394 $ log 'a' # branch
395 0
395 0
396 $ log '2785f51ee'
396 $ log '2785f51ee'
397 0
397 0
398 $ log 'date(2005)'
398 $ log 'date(2005)'
399 4
399 4
400 $ log 'date(this is a test)'
400 $ log 'date(this is a test)'
401 hg: parse error at 10: unexpected token: symbol
401 hg: parse error at 10: unexpected token: symbol
402 [255]
402 [255]
403 $ log 'date()'
403 $ log 'date()'
404 hg: parse error: date requires a string
404 hg: parse error: date requires a string
405 [255]
405 [255]
406 $ log 'date'
406 $ log 'date'
407 abort: unknown revision 'date'!
407 abort: unknown revision 'date'!
408 [255]
408 [255]
409 $ log 'date('
409 $ log 'date('
410 hg: parse error at 5: not a prefix: end
410 hg: parse error at 5: not a prefix: end
411 [255]
411 [255]
412 $ log 'date("\xy")'
412 $ log 'date("\xy")'
413 hg: parse error: invalid \x escape
413 hg: parse error: invalid \x escape
414 [255]
414 [255]
415 $ log 'date(tip)'
415 $ log 'date(tip)'
416 abort: invalid date: 'tip'
416 abort: invalid date: 'tip'
417 [255]
417 [255]
418 $ log '0:date'
418 $ log '0:date'
419 abort: unknown revision 'date'!
419 abort: unknown revision 'date'!
420 [255]
420 [255]
421 $ log '::"date"'
421 $ log '::"date"'
422 abort: unknown revision 'date'!
422 abort: unknown revision 'date'!
423 [255]
423 [255]
424 $ hg book date -r 4
424 $ hg book date -r 4
425 $ log '0:date'
425 $ log '0:date'
426 0
426 0
427 1
427 1
428 2
428 2
429 3
429 3
430 4
430 4
431 $ log '::date'
431 $ log '::date'
432 0
432 0
433 1
433 1
434 2
434 2
435 4
435 4
436 $ log '::"date"'
436 $ log '::"date"'
437 0
437 0
438 1
438 1
439 2
439 2
440 4
440 4
441 $ log 'date(2005) and 1::'
441 $ log 'date(2005) and 1::'
442 4
442 4
443 $ hg book -d date
443 $ hg book -d date
444
444
445 function name should be a symbol
445 function name should be a symbol
446
446
447 $ log '"date"(2005)'
447 $ log '"date"(2005)'
448 hg: parse error: not a symbol
448 hg: parse error: not a symbol
449 [255]
449 [255]
450
450
451 keyword arguments
451 keyword arguments
452
452
453 $ log 'extra(branch, value=a)'
453 $ log 'extra(branch, value=a)'
454 0
454 0
455
455
456 $ log 'extra(branch, a, b)'
456 $ log 'extra(branch, a, b)'
457 hg: parse error: extra takes at most 2 arguments
457 hg: parse error: extra takes at most 2 positional arguments
458 [255]
458 [255]
459 $ log 'extra(a, label=b)'
459 $ log 'extra(a, label=b)'
460 hg: parse error: extra got multiple values for keyword argument 'label'
460 hg: parse error: extra got multiple values for keyword argument 'label'
461 [255]
461 [255]
462 $ log 'extra(label=branch, default)'
462 $ log 'extra(label=branch, default)'
463 hg: parse error: extra got an invalid argument
463 hg: parse error: extra got an invalid argument
464 [255]
464 [255]
465 $ log 'extra(branch, foo+bar=baz)'
465 $ log 'extra(branch, foo+bar=baz)'
466 hg: parse error: extra got an invalid argument
466 hg: parse error: extra got an invalid argument
467 [255]
467 [255]
468 $ log 'extra(unknown=branch)'
468 $ log 'extra(unknown=branch)'
469 hg: parse error: extra got an unexpected keyword argument 'unknown'
469 hg: parse error: extra got an unexpected keyword argument 'unknown'
470 [255]
470 [255]
471
471
472 $ try 'foo=bar|baz'
472 $ try 'foo=bar|baz'
473 (keyvalue
473 (keyvalue
474 ('symbol', 'foo')
474 ('symbol', 'foo')
475 (or
475 (or
476 (list
476 (list
477 ('symbol', 'bar')
477 ('symbol', 'bar')
478 ('symbol', 'baz'))))
478 ('symbol', 'baz'))))
479 hg: parse error: can't use a key-value pair in this context
479 hg: parse error: can't use a key-value pair in this context
480 [255]
480 [255]
481
481
482 right-hand side should be optimized recursively
482 right-hand side should be optimized recursively
483
483
484 $ try --optimize 'foo=(not public())'
484 $ try --optimize 'foo=(not public())'
485 (keyvalue
485 (keyvalue
486 ('symbol', 'foo')
486 ('symbol', 'foo')
487 (group
487 (group
488 (not
488 (not
489 (func
489 (func
490 ('symbol', 'public')
490 ('symbol', 'public')
491 None))))
491 None))))
492 * optimized:
492 * optimized:
493 (keyvalue
493 (keyvalue
494 ('symbol', 'foo')
494 ('symbol', 'foo')
495 (func
495 (func
496 ('symbol', '_notpublic')
496 ('symbol', '_notpublic')
497 None
497 None
498 any))
498 any))
499 hg: parse error: can't use a key-value pair in this context
499 hg: parse error: can't use a key-value pair in this context
500 [255]
500 [255]
501
501
502 parsed tree at stages:
502 parsed tree at stages:
503
503
504 $ hg debugrevspec -p all '()'
504 $ hg debugrevspec -p all '()'
505 * parsed:
505 * parsed:
506 (group
506 (group
507 None)
507 None)
508 * expanded:
508 * expanded:
509 (group
509 (group
510 None)
510 None)
511 * concatenated:
511 * concatenated:
512 (group
512 (group
513 None)
513 None)
514 * analyzed:
514 * analyzed:
515 None
515 None
516 * optimized:
516 * optimized:
517 None
517 None
518 hg: parse error: missing argument
518 hg: parse error: missing argument
519 [255]
519 [255]
520
520
521 $ hg debugrevspec --no-optimized -p all '()'
521 $ hg debugrevspec --no-optimized -p all '()'
522 * parsed:
522 * parsed:
523 (group
523 (group
524 None)
524 None)
525 * expanded:
525 * expanded:
526 (group
526 (group
527 None)
527 None)
528 * concatenated:
528 * concatenated:
529 (group
529 (group
530 None)
530 None)
531 * analyzed:
531 * analyzed:
532 None
532 None
533 hg: parse error: missing argument
533 hg: parse error: missing argument
534 [255]
534 [255]
535
535
536 $ hg debugrevspec -p parsed -p analyzed -p optimized '(0|1)-1'
536 $ hg debugrevspec -p parsed -p analyzed -p optimized '(0|1)-1'
537 * parsed:
537 * parsed:
538 (minus
538 (minus
539 (group
539 (group
540 (or
540 (or
541 (list
541 (list
542 ('symbol', '0')
542 ('symbol', '0')
543 ('symbol', '1'))))
543 ('symbol', '1'))))
544 ('symbol', '1'))
544 ('symbol', '1'))
545 * analyzed:
545 * analyzed:
546 (and
546 (and
547 (or
547 (or
548 (list
548 (list
549 ('symbol', '0')
549 ('symbol', '0')
550 ('symbol', '1'))
550 ('symbol', '1'))
551 define)
551 define)
552 (not
552 (not
553 ('symbol', '1')
553 ('symbol', '1')
554 follow)
554 follow)
555 define)
555 define)
556 * optimized:
556 * optimized:
557 (difference
557 (difference
558 (func
558 (func
559 ('symbol', '_list')
559 ('symbol', '_list')
560 ('string', '0\x001')
560 ('string', '0\x001')
561 define)
561 define)
562 ('symbol', '1')
562 ('symbol', '1')
563 define)
563 define)
564 0
564 0
565
565
566 $ hg debugrevspec -p unknown '0'
566 $ hg debugrevspec -p unknown '0'
567 abort: invalid stage name: unknown
567 abort: invalid stage name: unknown
568 [255]
568 [255]
569
569
570 $ hg debugrevspec -p all --optimize '0'
570 $ hg debugrevspec -p all --optimize '0'
571 abort: cannot use --optimize with --show-stage
571 abort: cannot use --optimize with --show-stage
572 [255]
572 [255]
573
573
574 verify optimized tree:
574 verify optimized tree:
575
575
576 $ hg debugrevspec --verify '0|1'
576 $ hg debugrevspec --verify '0|1'
577
577
578 $ hg debugrevspec --verify -v -p analyzed -p optimized 'r3232() & 2'
578 $ hg debugrevspec --verify -v -p analyzed -p optimized 'r3232() & 2'
579 * analyzed:
579 * analyzed:
580 (and
580 (and
581 (func
581 (func
582 ('symbol', 'r3232')
582 ('symbol', 'r3232')
583 None
583 None
584 define)
584 define)
585 ('symbol', '2')
585 ('symbol', '2')
586 define)
586 define)
587 * optimized:
587 * optimized:
588 (and
588 (and
589 ('symbol', '2')
589 ('symbol', '2')
590 (func
590 (func
591 ('symbol', 'r3232')
591 ('symbol', 'r3232')
592 None
592 None
593 define)
593 define)
594 define)
594 define)
595 * analyzed set:
595 * analyzed set:
596 <baseset [2]>
596 <baseset [2]>
597 * optimized set:
597 * optimized set:
598 <baseset [2, 2]>
598 <baseset [2, 2]>
599 --- analyzed
599 --- analyzed
600 +++ optimized
600 +++ optimized
601 2
601 2
602 +2
602 +2
603 [1]
603 [1]
604
604
605 $ hg debugrevspec --no-optimized --verify-optimized '0'
605 $ hg debugrevspec --no-optimized --verify-optimized '0'
606 abort: cannot use --verify-optimized with --no-optimized
606 abort: cannot use --verify-optimized with --no-optimized
607 [255]
607 [255]
608
608
609 Test that symbols only get parsed as functions if there's an opening
609 Test that symbols only get parsed as functions if there's an opening
610 parenthesis.
610 parenthesis.
611
611
612 $ hg book only -r 9
612 $ hg book only -r 9
613 $ log 'only(only)' # Outer "only" is a function, inner "only" is the bookmark
613 $ log 'only(only)' # Outer "only" is a function, inner "only" is the bookmark
614 8
614 8
615 9
615 9
616
616
617 ':y' behaves like '0:y', but can't be rewritten as such since the revision '0'
617 ':y' behaves like '0:y', but can't be rewritten as such since the revision '0'
618 may be hidden (issue5385)
618 may be hidden (issue5385)
619
619
620 $ try -p parsed -p analyzed ':'
620 $ try -p parsed -p analyzed ':'
621 * parsed:
621 * parsed:
622 (rangeall
622 (rangeall
623 None)
623 None)
624 * analyzed:
624 * analyzed:
625 (rangeall
625 (rangeall
626 None
626 None
627 define)
627 define)
628 * set:
628 * set:
629 <spanset+ 0:9>
629 <spanset+ 0:9>
630 0
630 0
631 1
631 1
632 2
632 2
633 3
633 3
634 4
634 4
635 5
635 5
636 6
636 6
637 7
637 7
638 8
638 8
639 9
639 9
640 $ try -p analyzed ':1'
640 $ try -p analyzed ':1'
641 * analyzed:
641 * analyzed:
642 (rangepre
642 (rangepre
643 ('symbol', '1')
643 ('symbol', '1')
644 define)
644 define)
645 * set:
645 * set:
646 <spanset+ 0:1>
646 <spanset+ 0:1>
647 0
647 0
648 1
648 1
649 $ try -p analyzed ':(1|2)'
649 $ try -p analyzed ':(1|2)'
650 * analyzed:
650 * analyzed:
651 (rangepre
651 (rangepre
652 (or
652 (or
653 (list
653 (list
654 ('symbol', '1')
654 ('symbol', '1')
655 ('symbol', '2'))
655 ('symbol', '2'))
656 define)
656 define)
657 define)
657 define)
658 * set:
658 * set:
659 <spanset+ 0:2>
659 <spanset+ 0:2>
660 0
660 0
661 1
661 1
662 2
662 2
663 $ try -p analyzed ':(1&2)'
663 $ try -p analyzed ':(1&2)'
664 * analyzed:
664 * analyzed:
665 (rangepre
665 (rangepre
666 (and
666 (and
667 ('symbol', '1')
667 ('symbol', '1')
668 ('symbol', '2')
668 ('symbol', '2')
669 define)
669 define)
670 define)
670 define)
671 * set:
671 * set:
672 <baseset []>
672 <baseset []>
673
673
674 infix/suffix resolution of ^ operator (issue2884):
674 infix/suffix resolution of ^ operator (issue2884):
675
675
676 x^:y means (x^):y
676 x^:y means (x^):y
677
677
678 $ try '1^:2'
678 $ try '1^:2'
679 (range
679 (range
680 (parentpost
680 (parentpost
681 ('symbol', '1'))
681 ('symbol', '1'))
682 ('symbol', '2'))
682 ('symbol', '2'))
683 * set:
683 * set:
684 <spanset+ 0:2>
684 <spanset+ 0:2>
685 0
685 0
686 1
686 1
687 2
687 2
688
688
689 $ try '1^::2'
689 $ try '1^::2'
690 (dagrange
690 (dagrange
691 (parentpost
691 (parentpost
692 ('symbol', '1'))
692 ('symbol', '1'))
693 ('symbol', '2'))
693 ('symbol', '2'))
694 * set:
694 * set:
695 <baseset+ [0, 1, 2]>
695 <baseset+ [0, 1, 2]>
696 0
696 0
697 1
697 1
698 2
698 2
699
699
700 $ try '9^:'
700 $ try '9^:'
701 (rangepost
701 (rangepost
702 (parentpost
702 (parentpost
703 ('symbol', '9')))
703 ('symbol', '9')))
704 * set:
704 * set:
705 <spanset+ 8:9>
705 <spanset+ 8:9>
706 8
706 8
707 9
707 9
708
708
709 x^:y should be resolved before omitting group operators
709 x^:y should be resolved before omitting group operators
710
710
711 $ try '1^(:2)'
711 $ try '1^(:2)'
712 (parent
712 (parent
713 ('symbol', '1')
713 ('symbol', '1')
714 (group
714 (group
715 (rangepre
715 (rangepre
716 ('symbol', '2'))))
716 ('symbol', '2'))))
717 hg: parse error: ^ expects a number 0, 1, or 2
717 hg: parse error: ^ expects a number 0, 1, or 2
718 [255]
718 [255]
719
719
720 x^:y should be resolved recursively
720 x^:y should be resolved recursively
721
721
722 $ try 'sort(1^:2)'
722 $ try 'sort(1^:2)'
723 (func
723 (func
724 ('symbol', 'sort')
724 ('symbol', 'sort')
725 (range
725 (range
726 (parentpost
726 (parentpost
727 ('symbol', '1'))
727 ('symbol', '1'))
728 ('symbol', '2')))
728 ('symbol', '2')))
729 * set:
729 * set:
730 <spanset+ 0:2>
730 <spanset+ 0:2>
731 0
731 0
732 1
732 1
733 2
733 2
734
734
735 $ try '(3^:4)^:2'
735 $ try '(3^:4)^:2'
736 (range
736 (range
737 (parentpost
737 (parentpost
738 (group
738 (group
739 (range
739 (range
740 (parentpost
740 (parentpost
741 ('symbol', '3'))
741 ('symbol', '3'))
742 ('symbol', '4'))))
742 ('symbol', '4'))))
743 ('symbol', '2'))
743 ('symbol', '2'))
744 * set:
744 * set:
745 <spanset+ 0:2>
745 <spanset+ 0:2>
746 0
746 0
747 1
747 1
748 2
748 2
749
749
750 $ try '(3^::4)^::2'
750 $ try '(3^::4)^::2'
751 (dagrange
751 (dagrange
752 (parentpost
752 (parentpost
753 (group
753 (group
754 (dagrange
754 (dagrange
755 (parentpost
755 (parentpost
756 ('symbol', '3'))
756 ('symbol', '3'))
757 ('symbol', '4'))))
757 ('symbol', '4'))))
758 ('symbol', '2'))
758 ('symbol', '2'))
759 * set:
759 * set:
760 <baseset+ [0, 1, 2]>
760 <baseset+ [0, 1, 2]>
761 0
761 0
762 1
762 1
763 2
763 2
764
764
765 $ try '(9^:)^:'
765 $ try '(9^:)^:'
766 (rangepost
766 (rangepost
767 (parentpost
767 (parentpost
768 (group
768 (group
769 (rangepost
769 (rangepost
770 (parentpost
770 (parentpost
771 ('symbol', '9'))))))
771 ('symbol', '9'))))))
772 * set:
772 * set:
773 <spanset+ 4:9>
773 <spanset+ 4:9>
774 4
774 4
775 5
775 5
776 6
776 6
777 7
777 7
778 8
778 8
779 9
779 9
780
780
781 x^ in alias should also be resolved
781 x^ in alias should also be resolved
782
782
783 $ try 'A' --config 'revsetalias.A=1^:2'
783 $ try 'A' --config 'revsetalias.A=1^:2'
784 ('symbol', 'A')
784 ('symbol', 'A')
785 * expanded:
785 * expanded:
786 (range
786 (range
787 (parentpost
787 (parentpost
788 ('symbol', '1'))
788 ('symbol', '1'))
789 ('symbol', '2'))
789 ('symbol', '2'))
790 * set:
790 * set:
791 <spanset+ 0:2>
791 <spanset+ 0:2>
792 0
792 0
793 1
793 1
794 2
794 2
795
795
796 $ try 'A:2' --config 'revsetalias.A=1^'
796 $ try 'A:2' --config 'revsetalias.A=1^'
797 (range
797 (range
798 ('symbol', 'A')
798 ('symbol', 'A')
799 ('symbol', '2'))
799 ('symbol', '2'))
800 * expanded:
800 * expanded:
801 (range
801 (range
802 (parentpost
802 (parentpost
803 ('symbol', '1'))
803 ('symbol', '1'))
804 ('symbol', '2'))
804 ('symbol', '2'))
805 * set:
805 * set:
806 <spanset+ 0:2>
806 <spanset+ 0:2>
807 0
807 0
808 1
808 1
809 2
809 2
810
810
811 but not beyond the boundary of alias expansion, because the resolution should
811 but not beyond the boundary of alias expansion, because the resolution should
812 be made at the parsing stage
812 be made at the parsing stage
813
813
814 $ try '1^A' --config 'revsetalias.A=:2'
814 $ try '1^A' --config 'revsetalias.A=:2'
815 (parent
815 (parent
816 ('symbol', '1')
816 ('symbol', '1')
817 ('symbol', 'A'))
817 ('symbol', 'A'))
818 * expanded:
818 * expanded:
819 (parent
819 (parent
820 ('symbol', '1')
820 ('symbol', '1')
821 (rangepre
821 (rangepre
822 ('symbol', '2')))
822 ('symbol', '2')))
823 hg: parse error: ^ expects a number 0, 1, or 2
823 hg: parse error: ^ expects a number 0, 1, or 2
824 [255]
824 [255]
825
825
826 ancestor can accept 0 or more arguments
826 ancestor can accept 0 or more arguments
827
827
828 $ log 'ancestor()'
828 $ log 'ancestor()'
829 $ log 'ancestor(1)'
829 $ log 'ancestor(1)'
830 1
830 1
831 $ log 'ancestor(4,5)'
831 $ log 'ancestor(4,5)'
832 1
832 1
833 $ log 'ancestor(4,5) and 4'
833 $ log 'ancestor(4,5) and 4'
834 $ log 'ancestor(0,0,1,3)'
834 $ log 'ancestor(0,0,1,3)'
835 0
835 0
836 $ log 'ancestor(3,1,5,3,5,1)'
836 $ log 'ancestor(3,1,5,3,5,1)'
837 1
837 1
838 $ log 'ancestor(0,1,3,5)'
838 $ log 'ancestor(0,1,3,5)'
839 0
839 0
840 $ log 'ancestor(1,2,3,4,5)'
840 $ log 'ancestor(1,2,3,4,5)'
841 1
841 1
842
842
843 test ancestors
843 test ancestors
844
844
845 $ log 'ancestors(5)'
845 $ log 'ancestors(5)'
846 0
846 0
847 1
847 1
848 3
848 3
849 5
849 5
850 $ log 'ancestor(ancestors(5))'
850 $ log 'ancestor(ancestors(5))'
851 0
851 0
852 $ log '::r3232()'
852 $ log '::r3232()'
853 0
853 0
854 1
854 1
855 2
855 2
856 3
856 3
857
857
858 $ log 'author(bob)'
858 $ log 'author(bob)'
859 2
859 2
860 $ log 'author("re:bob|test")'
860 $ log 'author("re:bob|test")'
861 0
861 0
862 1
862 1
863 2
863 2
864 3
864 3
865 4
865 4
866 5
866 5
867 6
867 6
868 7
868 7
869 8
869 8
870 9
870 9
871 $ log 'author(r"re:\S")'
871 $ log 'author(r"re:\S")'
872 0
872 0
873 1
873 1
874 2
874 2
875 3
875 3
876 4
876 4
877 5
877 5
878 6
878 6
879 7
879 7
880 8
880 8
881 9
881 9
882 $ log 'branch(Γ©)'
882 $ log 'branch(Γ©)'
883 8
883 8
884 9
884 9
885 $ log 'branch(a)'
885 $ log 'branch(a)'
886 0
886 0
887 $ hg log -r 'branch("re:a")' --template '{rev} {branch}\n'
887 $ hg log -r 'branch("re:a")' --template '{rev} {branch}\n'
888 0 a
888 0 a
889 2 a-b-c-
889 2 a-b-c-
890 3 +a+b+c+
890 3 +a+b+c+
891 4 -a-b-c-
891 4 -a-b-c-
892 5 !a/b/c/
892 5 !a/b/c/
893 6 _a_b_c_
893 6 _a_b_c_
894 7 .a.b.c.
894 7 .a.b.c.
895 $ log 'children(ancestor(4,5))'
895 $ log 'children(ancestor(4,5))'
896 2
896 2
897 3
897 3
898
898
899 $ log 'children(4)'
899 $ log 'children(4)'
900 6
900 6
901 8
901 8
902 $ log 'children(null)'
902 $ log 'children(null)'
903 0
903 0
904
904
905 $ log 'closed()'
905 $ log 'closed()'
906 $ log 'contains(a)'
906 $ log 'contains(a)'
907 0
907 0
908 1
908 1
909 3
909 3
910 5
910 5
911 $ log 'contains("../repo/a")'
911 $ log 'contains("../repo/a")'
912 0
912 0
913 1
913 1
914 3
914 3
915 5
915 5
916 $ log 'desc(B)'
916 $ log 'desc(B)'
917 5
917 5
918 $ hg log -r 'desc(r"re:S?u")' --template "{rev} {desc|firstline}\n"
918 $ hg log -r 'desc(r"re:S?u")' --template "{rev} {desc|firstline}\n"
919 5 5 bug
919 5 5 bug
920 6 6 issue619
920 6 6 issue619
921 $ log 'descendants(2 or 3)'
921 $ log 'descendants(2 or 3)'
922 2
922 2
923 3
923 3
924 4
924 4
925 5
925 5
926 6
926 6
927 7
927 7
928 8
928 8
929 9
929 9
930 $ log 'file("b*")'
930 $ log 'file("b*")'
931 1
931 1
932 4
932 4
933 $ log 'filelog("b")'
933 $ log 'filelog("b")'
934 1
934 1
935 4
935 4
936 $ log 'filelog("../repo/b")'
936 $ log 'filelog("../repo/b")'
937 1
937 1
938 4
938 4
939 $ log 'follow()'
939 $ log 'follow()'
940 0
940 0
941 1
941 1
942 2
942 2
943 4
943 4
944 8
944 8
945 9
945 9
946 $ log 'grep("issue\d+")'
946 $ log 'grep("issue\d+")'
947 6
947 6
948 $ try 'grep("(")' # invalid regular expression
948 $ try 'grep("(")' # invalid regular expression
949 (func
949 (func
950 ('symbol', 'grep')
950 ('symbol', 'grep')
951 ('string', '('))
951 ('string', '('))
952 hg: parse error: invalid match pattern: unbalanced parenthesis
952 hg: parse error: invalid match pattern: unbalanced parenthesis
953 [255]
953 [255]
954 $ try 'grep("\bissue\d+")'
954 $ try 'grep("\bissue\d+")'
955 (func
955 (func
956 ('symbol', 'grep')
956 ('symbol', 'grep')
957 ('string', '\x08issue\\d+'))
957 ('string', '\x08issue\\d+'))
958 * set:
958 * set:
959 <filteredset
959 <filteredset
960 <fullreposet+ 0:9>,
960 <fullreposet+ 0:9>,
961 <grep '\x08issue\\d+'>>
961 <grep '\x08issue\\d+'>>
962 $ try 'grep(r"\bissue\d+")'
962 $ try 'grep(r"\bissue\d+")'
963 (func
963 (func
964 ('symbol', 'grep')
964 ('symbol', 'grep')
965 ('string', '\\bissue\\d+'))
965 ('string', '\\bissue\\d+'))
966 * set:
966 * set:
967 <filteredset
967 <filteredset
968 <fullreposet+ 0:9>,
968 <fullreposet+ 0:9>,
969 <grep '\\bissue\\d+'>>
969 <grep '\\bissue\\d+'>>
970 6
970 6
971 $ try 'grep(r"\")'
971 $ try 'grep(r"\")'
972 hg: parse error at 7: unterminated string
972 hg: parse error at 7: unterminated string
973 [255]
973 [255]
974 $ log 'head()'
974 $ log 'head()'
975 0
975 0
976 1
976 1
977 2
977 2
978 3
978 3
979 4
979 4
980 5
980 5
981 6
981 6
982 7
982 7
983 9
983 9
984 $ log 'heads(6::)'
984 $ log 'heads(6::)'
985 7
985 7
986 $ log 'keyword(issue)'
986 $ log 'keyword(issue)'
987 6
987 6
988 $ log 'keyword("test a")'
988 $ log 'keyword("test a")'
989 $ log 'limit(head(), 1)'
989 $ log 'limit(head(), 1)'
990 0
990 0
991 $ log 'limit(author("re:bob|test"), 3, 5)'
991 $ log 'limit(author("re:bob|test"), 3, 5)'
992 5
992 5
993 6
993 6
994 7
994 7
995 $ log 'limit(author("re:bob|test"), offset=6)'
995 $ log 'limit(author("re:bob|test"), offset=6)'
996 6
996 6
997 $ log 'limit(author("re:bob|test"), offset=10)'
997 $ log 'limit(author("re:bob|test"), offset=10)'
998 $ log 'limit(all(), 1, -1)'
998 $ log 'limit(all(), 1, -1)'
999 hg: parse error: negative offset
999 hg: parse error: negative offset
1000 [255]
1000 [255]
1001 $ log 'matching(6)'
1001 $ log 'matching(6)'
1002 6
1002 6
1003 $ log 'matching(6:7, "phase parents user date branch summary files description substate")'
1003 $ log 'matching(6:7, "phase parents user date branch summary files description substate")'
1004 6
1004 6
1005 7
1005 7
1006
1006
1007 Testing min and max
1007 Testing min and max
1008
1008
1009 max: simple
1009 max: simple
1010
1010
1011 $ log 'max(contains(a))'
1011 $ log 'max(contains(a))'
1012 5
1012 5
1013
1013
1014 max: simple on unordered set)
1014 max: simple on unordered set)
1015
1015
1016 $ log 'max((4+0+2+5+7) and contains(a))'
1016 $ log 'max((4+0+2+5+7) and contains(a))'
1017 5
1017 5
1018
1018
1019 max: no result
1019 max: no result
1020
1020
1021 $ log 'max(contains(stringthatdoesnotappearanywhere))'
1021 $ log 'max(contains(stringthatdoesnotappearanywhere))'
1022
1022
1023 max: no result on unordered set
1023 max: no result on unordered set
1024
1024
1025 $ log 'max((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1025 $ log 'max((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1026
1026
1027 min: simple
1027 min: simple
1028
1028
1029 $ log 'min(contains(a))'
1029 $ log 'min(contains(a))'
1030 0
1030 0
1031
1031
1032 min: simple on unordered set
1032 min: simple on unordered set
1033
1033
1034 $ log 'min((4+0+2+5+7) and contains(a))'
1034 $ log 'min((4+0+2+5+7) and contains(a))'
1035 0
1035 0
1036
1036
1037 min: empty
1037 min: empty
1038
1038
1039 $ log 'min(contains(stringthatdoesnotappearanywhere))'
1039 $ log 'min(contains(stringthatdoesnotappearanywhere))'
1040
1040
1041 min: empty on unordered set
1041 min: empty on unordered set
1042
1042
1043 $ log 'min((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1043 $ log 'min((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1044
1044
1045
1045
1046 $ log 'merge()'
1046 $ log 'merge()'
1047 6
1047 6
1048 $ log 'branchpoint()'
1048 $ log 'branchpoint()'
1049 1
1049 1
1050 4
1050 4
1051 $ log 'modifies(b)'
1051 $ log 'modifies(b)'
1052 4
1052 4
1053 $ log 'modifies("path:b")'
1053 $ log 'modifies("path:b")'
1054 4
1054 4
1055 $ log 'modifies("*")'
1055 $ log 'modifies("*")'
1056 4
1056 4
1057 6
1057 6
1058 $ log 'modifies("set:modified()")'
1058 $ log 'modifies("set:modified()")'
1059 4
1059 4
1060 $ log 'id(5)'
1060 $ log 'id(5)'
1061 2
1061 2
1062 $ log 'only(9)'
1062 $ log 'only(9)'
1063 8
1063 8
1064 9
1064 9
1065 $ log 'only(8)'
1065 $ log 'only(8)'
1066 8
1066 8
1067 $ log 'only(9, 5)'
1067 $ log 'only(9, 5)'
1068 2
1068 2
1069 4
1069 4
1070 8
1070 8
1071 9
1071 9
1072 $ log 'only(7 + 9, 5 + 2)'
1072 $ log 'only(7 + 9, 5 + 2)'
1073 4
1073 4
1074 6
1074 6
1075 7
1075 7
1076 8
1076 8
1077 9
1077 9
1078
1078
1079 Test empty set input
1079 Test empty set input
1080 $ log 'only(p2())'
1080 $ log 'only(p2())'
1081 $ log 'only(p1(), p2())'
1081 $ log 'only(p1(), p2())'
1082 0
1082 0
1083 1
1083 1
1084 2
1084 2
1085 4
1085 4
1086 8
1086 8
1087 9
1087 9
1088
1088
1089 Test '%' operator
1089 Test '%' operator
1090
1090
1091 $ log '9%'
1091 $ log '9%'
1092 8
1092 8
1093 9
1093 9
1094 $ log '9%5'
1094 $ log '9%5'
1095 2
1095 2
1096 4
1096 4
1097 8
1097 8
1098 9
1098 9
1099 $ log '(7 + 9)%(5 + 2)'
1099 $ log '(7 + 9)%(5 + 2)'
1100 4
1100 4
1101 6
1101 6
1102 7
1102 7
1103 8
1103 8
1104 9
1104 9
1105
1105
1106 Test operand of '%' is optimized recursively (issue4670)
1106 Test operand of '%' is optimized recursively (issue4670)
1107
1107
1108 $ try --optimize '8:9-8%'
1108 $ try --optimize '8:9-8%'
1109 (onlypost
1109 (onlypost
1110 (minus
1110 (minus
1111 (range
1111 (range
1112 ('symbol', '8')
1112 ('symbol', '8')
1113 ('symbol', '9'))
1113 ('symbol', '9'))
1114 ('symbol', '8')))
1114 ('symbol', '8')))
1115 * optimized:
1115 * optimized:
1116 (func
1116 (func
1117 ('symbol', 'only')
1117 ('symbol', 'only')
1118 (difference
1118 (difference
1119 (range
1119 (range
1120 ('symbol', '8')
1120 ('symbol', '8')
1121 ('symbol', '9')
1121 ('symbol', '9')
1122 define)
1122 define)
1123 ('symbol', '8')
1123 ('symbol', '8')
1124 define)
1124 define)
1125 define)
1125 define)
1126 * set:
1126 * set:
1127 <baseset+ [8, 9]>
1127 <baseset+ [8, 9]>
1128 8
1128 8
1129 9
1129 9
1130 $ try --optimize '(9)%(5)'
1130 $ try --optimize '(9)%(5)'
1131 (only
1131 (only
1132 (group
1132 (group
1133 ('symbol', '9'))
1133 ('symbol', '9'))
1134 (group
1134 (group
1135 ('symbol', '5')))
1135 ('symbol', '5')))
1136 * optimized:
1136 * optimized:
1137 (func
1137 (func
1138 ('symbol', 'only')
1138 ('symbol', 'only')
1139 (list
1139 (list
1140 ('symbol', '9')
1140 ('symbol', '9')
1141 ('symbol', '5'))
1141 ('symbol', '5'))
1142 define)
1142 define)
1143 * set:
1143 * set:
1144 <baseset+ [2, 4, 8, 9]>
1144 <baseset+ [2, 4, 8, 9]>
1145 2
1145 2
1146 4
1146 4
1147 8
1147 8
1148 9
1148 9
1149
1149
1150 Test the order of operations
1150 Test the order of operations
1151
1151
1152 $ log '7 + 9%5 + 2'
1152 $ log '7 + 9%5 + 2'
1153 7
1153 7
1154 2
1154 2
1155 4
1155 4
1156 8
1156 8
1157 9
1157 9
1158
1158
1159 Test explicit numeric revision
1159 Test explicit numeric revision
1160 $ log 'rev(-2)'
1160 $ log 'rev(-2)'
1161 $ log 'rev(-1)'
1161 $ log 'rev(-1)'
1162 -1
1162 -1
1163 $ log 'rev(0)'
1163 $ log 'rev(0)'
1164 0
1164 0
1165 $ log 'rev(9)'
1165 $ log 'rev(9)'
1166 9
1166 9
1167 $ log 'rev(10)'
1167 $ log 'rev(10)'
1168 $ log 'rev(tip)'
1168 $ log 'rev(tip)'
1169 hg: parse error: rev expects a number
1169 hg: parse error: rev expects a number
1170 [255]
1170 [255]
1171
1171
1172 Test hexadecimal revision
1172 Test hexadecimal revision
1173 $ log 'id(2)'
1173 $ log 'id(2)'
1174 abort: 00changelog.i@2: ambiguous identifier!
1174 abort: 00changelog.i@2: ambiguous identifier!
1175 [255]
1175 [255]
1176 $ log 'id(23268)'
1176 $ log 'id(23268)'
1177 4
1177 4
1178 $ log 'id(2785f51eece)'
1178 $ log 'id(2785f51eece)'
1179 0
1179 0
1180 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532c)'
1180 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532c)'
1181 8
1181 8
1182 $ log 'id(d5d0dcbdc4a)'
1182 $ log 'id(d5d0dcbdc4a)'
1183 $ log 'id(d5d0dcbdc4w)'
1183 $ log 'id(d5d0dcbdc4w)'
1184 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532d)'
1184 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532d)'
1185 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532q)'
1185 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532q)'
1186 $ log 'id(1.0)'
1186 $ log 'id(1.0)'
1187 $ log 'id(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)'
1187 $ log 'id(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)'
1188
1188
1189 Test null revision
1189 Test null revision
1190 $ log '(null)'
1190 $ log '(null)'
1191 -1
1191 -1
1192 $ log '(null:0)'
1192 $ log '(null:0)'
1193 -1
1193 -1
1194 0
1194 0
1195 $ log '(0:null)'
1195 $ log '(0:null)'
1196 0
1196 0
1197 -1
1197 -1
1198 $ log 'null::0'
1198 $ log 'null::0'
1199 -1
1199 -1
1200 0
1200 0
1201 $ log 'null:tip - 0:'
1201 $ log 'null:tip - 0:'
1202 -1
1202 -1
1203 $ log 'null: and null::' | head -1
1203 $ log 'null: and null::' | head -1
1204 -1
1204 -1
1205 $ log 'null: or 0:' | head -2
1205 $ log 'null: or 0:' | head -2
1206 -1
1206 -1
1207 0
1207 0
1208 $ log 'ancestors(null)'
1208 $ log 'ancestors(null)'
1209 -1
1209 -1
1210 $ log 'reverse(null:)' | tail -2
1210 $ log 'reverse(null:)' | tail -2
1211 0
1211 0
1212 -1
1212 -1
1213 BROKEN: should be '-1'
1213 BROKEN: should be '-1'
1214 $ log 'first(null:)'
1214 $ log 'first(null:)'
1215 BROKEN: should be '-1'
1215 BROKEN: should be '-1'
1216 $ log 'min(null:)'
1216 $ log 'min(null:)'
1217 $ log 'tip:null and all()' | tail -2
1217 $ log 'tip:null and all()' | tail -2
1218 1
1218 1
1219 0
1219 0
1220
1220
1221 Test working-directory revision
1221 Test working-directory revision
1222 $ hg debugrevspec 'wdir()'
1222 $ hg debugrevspec 'wdir()'
1223 2147483647
1223 2147483647
1224 $ hg debugrevspec 'tip or wdir()'
1224 $ hg debugrevspec 'tip or wdir()'
1225 9
1225 9
1226 2147483647
1226 2147483647
1227 $ hg debugrevspec '0:tip and wdir()'
1227 $ hg debugrevspec '0:tip and wdir()'
1228 $ log '0:wdir()' | tail -3
1228 $ log '0:wdir()' | tail -3
1229 8
1229 8
1230 9
1230 9
1231 2147483647
1231 2147483647
1232 $ log 'wdir():0' | head -3
1232 $ log 'wdir():0' | head -3
1233 2147483647
1233 2147483647
1234 9
1234 9
1235 8
1235 8
1236 $ log 'wdir():wdir()'
1236 $ log 'wdir():wdir()'
1237 2147483647
1237 2147483647
1238 $ log '(all() + wdir()) & min(. + wdir())'
1238 $ log '(all() + wdir()) & min(. + wdir())'
1239 9
1239 9
1240 $ log '(all() + wdir()) & max(. + wdir())'
1240 $ log '(all() + wdir()) & max(. + wdir())'
1241 2147483647
1241 2147483647
1242 $ log '(all() + wdir()) & first(wdir() + .)'
1242 $ log '(all() + wdir()) & first(wdir() + .)'
1243 2147483647
1243 2147483647
1244 $ log '(all() + wdir()) & last(. + wdir())'
1244 $ log '(all() + wdir()) & last(. + wdir())'
1245 2147483647
1245 2147483647
1246
1246
1247 $ log 'outgoing()'
1247 $ log 'outgoing()'
1248 8
1248 8
1249 9
1249 9
1250 $ log 'outgoing("../remote1")'
1250 $ log 'outgoing("../remote1")'
1251 8
1251 8
1252 9
1252 9
1253 $ log 'outgoing("../remote2")'
1253 $ log 'outgoing("../remote2")'
1254 3
1254 3
1255 5
1255 5
1256 6
1256 6
1257 7
1257 7
1258 9
1258 9
1259 $ log 'p1(merge())'
1259 $ log 'p1(merge())'
1260 5
1260 5
1261 $ log 'p2(merge())'
1261 $ log 'p2(merge())'
1262 4
1262 4
1263 $ log 'parents(merge())'
1263 $ log 'parents(merge())'
1264 4
1264 4
1265 5
1265 5
1266 $ log 'p1(branchpoint())'
1266 $ log 'p1(branchpoint())'
1267 0
1267 0
1268 2
1268 2
1269 $ log 'p2(branchpoint())'
1269 $ log 'p2(branchpoint())'
1270 $ log 'parents(branchpoint())'
1270 $ log 'parents(branchpoint())'
1271 0
1271 0
1272 2
1272 2
1273 $ log 'removes(a)'
1273 $ log 'removes(a)'
1274 2
1274 2
1275 6
1275 6
1276 $ log 'roots(all())'
1276 $ log 'roots(all())'
1277 0
1277 0
1278 $ log 'reverse(2 or 3 or 4 or 5)'
1278 $ log 'reverse(2 or 3 or 4 or 5)'
1279 5
1279 5
1280 4
1280 4
1281 3
1281 3
1282 2
1282 2
1283 $ log 'reverse(all())'
1283 $ log 'reverse(all())'
1284 9
1284 9
1285 8
1285 8
1286 7
1286 7
1287 6
1287 6
1288 5
1288 5
1289 4
1289 4
1290 3
1290 3
1291 2
1291 2
1292 1
1292 1
1293 0
1293 0
1294 $ log 'reverse(all()) & filelog(b)'
1294 $ log 'reverse(all()) & filelog(b)'
1295 4
1295 4
1296 1
1296 1
1297 $ log 'rev(5)'
1297 $ log 'rev(5)'
1298 5
1298 5
1299 $ log 'sort(limit(reverse(all()), 3))'
1299 $ log 'sort(limit(reverse(all()), 3))'
1300 7
1300 7
1301 8
1301 8
1302 9
1302 9
1303 $ log 'sort(2 or 3 or 4 or 5, date)'
1303 $ log 'sort(2 or 3 or 4 or 5, date)'
1304 2
1304 2
1305 3
1305 3
1306 5
1306 5
1307 4
1307 4
1308 $ log 'tagged()'
1308 $ log 'tagged()'
1309 6
1309 6
1310 $ log 'tag()'
1310 $ log 'tag()'
1311 6
1311 6
1312 $ log 'tag(1.0)'
1312 $ log 'tag(1.0)'
1313 6
1313 6
1314 $ log 'tag(tip)'
1314 $ log 'tag(tip)'
1315 9
1315 9
1316
1316
1317 Test order of revisions in compound expression
1317 Test order of revisions in compound expression
1318 ----------------------------------------------
1318 ----------------------------------------------
1319
1319
1320 The general rule is that only the outermost (= leftmost) predicate can
1320 The general rule is that only the outermost (= leftmost) predicate can
1321 enforce its ordering requirement. The other predicates should take the
1321 enforce its ordering requirement. The other predicates should take the
1322 ordering defined by it.
1322 ordering defined by it.
1323
1323
1324 'A & B' should follow the order of 'A':
1324 'A & B' should follow the order of 'A':
1325
1325
1326 $ log '2:0 & 0::2'
1326 $ log '2:0 & 0::2'
1327 2
1327 2
1328 1
1328 1
1329 0
1329 0
1330
1330
1331 'head()' combines sets in right order:
1331 'head()' combines sets in right order:
1332
1332
1333 $ log '2:0 & head()'
1333 $ log '2:0 & head()'
1334 2
1334 2
1335 1
1335 1
1336 0
1336 0
1337
1337
1338 'x:y' takes ordering parameter into account:
1338 'x:y' takes ordering parameter into account:
1339
1339
1340 $ try -p optimized '3:0 & 0:3 & not 2:1'
1340 $ try -p optimized '3:0 & 0:3 & not 2:1'
1341 * optimized:
1341 * optimized:
1342 (difference
1342 (difference
1343 (and
1343 (and
1344 (range
1344 (range
1345 ('symbol', '3')
1345 ('symbol', '3')
1346 ('symbol', '0')
1346 ('symbol', '0')
1347 define)
1347 define)
1348 (range
1348 (range
1349 ('symbol', '0')
1349 ('symbol', '0')
1350 ('symbol', '3')
1350 ('symbol', '3')
1351 follow)
1351 follow)
1352 define)
1352 define)
1353 (range
1353 (range
1354 ('symbol', '2')
1354 ('symbol', '2')
1355 ('symbol', '1')
1355 ('symbol', '1')
1356 any)
1356 any)
1357 define)
1357 define)
1358 * set:
1358 * set:
1359 <filteredset
1359 <filteredset
1360 <filteredset
1360 <filteredset
1361 <spanset- 0:3>,
1361 <spanset- 0:3>,
1362 <spanset+ 0:3>>,
1362 <spanset+ 0:3>>,
1363 <not
1363 <not
1364 <spanset+ 1:2>>>
1364 <spanset+ 1:2>>>
1365 3
1365 3
1366 0
1366 0
1367
1367
1368 'a + b', which is optimized to '_list(a b)', should take the ordering of
1368 'a + b', which is optimized to '_list(a b)', should take the ordering of
1369 the left expression:
1369 the left expression:
1370
1370
1371 $ try --optimize '2:0 & (0 + 1 + 2)'
1371 $ try --optimize '2:0 & (0 + 1 + 2)'
1372 (and
1372 (and
1373 (range
1373 (range
1374 ('symbol', '2')
1374 ('symbol', '2')
1375 ('symbol', '0'))
1375 ('symbol', '0'))
1376 (group
1376 (group
1377 (or
1377 (or
1378 (list
1378 (list
1379 ('symbol', '0')
1379 ('symbol', '0')
1380 ('symbol', '1')
1380 ('symbol', '1')
1381 ('symbol', '2')))))
1381 ('symbol', '2')))))
1382 * optimized:
1382 * optimized:
1383 (and
1383 (and
1384 (range
1384 (range
1385 ('symbol', '2')
1385 ('symbol', '2')
1386 ('symbol', '0')
1386 ('symbol', '0')
1387 define)
1387 define)
1388 (func
1388 (func
1389 ('symbol', '_list')
1389 ('symbol', '_list')
1390 ('string', '0\x001\x002')
1390 ('string', '0\x001\x002')
1391 follow)
1391 follow)
1392 define)
1392 define)
1393 * set:
1393 * set:
1394 <filteredset
1394 <filteredset
1395 <spanset- 0:2>,
1395 <spanset- 0:2>,
1396 <baseset [0, 1, 2]>>
1396 <baseset [0, 1, 2]>>
1397 2
1397 2
1398 1
1398 1
1399 0
1399 0
1400
1400
1401 'A + B' should take the ordering of the left expression:
1401 'A + B' should take the ordering of the left expression:
1402
1402
1403 $ try --optimize '2:0 & (0:1 + 2)'
1403 $ try --optimize '2:0 & (0:1 + 2)'
1404 (and
1404 (and
1405 (range
1405 (range
1406 ('symbol', '2')
1406 ('symbol', '2')
1407 ('symbol', '0'))
1407 ('symbol', '0'))
1408 (group
1408 (group
1409 (or
1409 (or
1410 (list
1410 (list
1411 (range
1411 (range
1412 ('symbol', '0')
1412 ('symbol', '0')
1413 ('symbol', '1'))
1413 ('symbol', '1'))
1414 ('symbol', '2')))))
1414 ('symbol', '2')))))
1415 * optimized:
1415 * optimized:
1416 (and
1416 (and
1417 (range
1417 (range
1418 ('symbol', '2')
1418 ('symbol', '2')
1419 ('symbol', '0')
1419 ('symbol', '0')
1420 define)
1420 define)
1421 (or
1421 (or
1422 (list
1422 (list
1423 ('symbol', '2')
1423 ('symbol', '2')
1424 (range
1424 (range
1425 ('symbol', '0')
1425 ('symbol', '0')
1426 ('symbol', '1')
1426 ('symbol', '1')
1427 follow))
1427 follow))
1428 follow)
1428 follow)
1429 define)
1429 define)
1430 * set:
1430 * set:
1431 <filteredset
1431 <filteredset
1432 <spanset- 0:2>,
1432 <spanset- 0:2>,
1433 <addset
1433 <addset
1434 <baseset [2]>,
1434 <baseset [2]>,
1435 <spanset+ 0:1>>>
1435 <spanset+ 0:1>>>
1436 2
1436 2
1437 1
1437 1
1438 0
1438 0
1439
1439
1440 '_intlist(a b)' should behave like 'a + b':
1440 '_intlist(a b)' should behave like 'a + b':
1441
1441
1442 $ trylist --optimize '2:0 & %ld' 0 1 2
1442 $ trylist --optimize '2:0 & %ld' 0 1 2
1443 (and
1443 (and
1444 (range
1444 (range
1445 ('symbol', '2')
1445 ('symbol', '2')
1446 ('symbol', '0'))
1446 ('symbol', '0'))
1447 (func
1447 (func
1448 ('symbol', '_intlist')
1448 ('symbol', '_intlist')
1449 ('string', '0\x001\x002')))
1449 ('string', '0\x001\x002')))
1450 * optimized:
1450 * optimized:
1451 (and
1451 (and
1452 (func
1452 (func
1453 ('symbol', '_intlist')
1453 ('symbol', '_intlist')
1454 ('string', '0\x001\x002')
1454 ('string', '0\x001\x002')
1455 follow)
1455 follow)
1456 (range
1456 (range
1457 ('symbol', '2')
1457 ('symbol', '2')
1458 ('symbol', '0')
1458 ('symbol', '0')
1459 define)
1459 define)
1460 define)
1460 define)
1461 * set:
1461 * set:
1462 <filteredset
1462 <filteredset
1463 <spanset- 0:2>,
1463 <spanset- 0:2>,
1464 <baseset+ [0, 1, 2]>>
1464 <baseset+ [0, 1, 2]>>
1465 2
1465 2
1466 1
1466 1
1467 0
1467 0
1468
1468
1469 $ trylist --optimize '%ld & 2:0' 0 2 1
1469 $ trylist --optimize '%ld & 2:0' 0 2 1
1470 (and
1470 (and
1471 (func
1471 (func
1472 ('symbol', '_intlist')
1472 ('symbol', '_intlist')
1473 ('string', '0\x002\x001'))
1473 ('string', '0\x002\x001'))
1474 (range
1474 (range
1475 ('symbol', '2')
1475 ('symbol', '2')
1476 ('symbol', '0')))
1476 ('symbol', '0')))
1477 * optimized:
1477 * optimized:
1478 (and
1478 (and
1479 (func
1479 (func
1480 ('symbol', '_intlist')
1480 ('symbol', '_intlist')
1481 ('string', '0\x002\x001')
1481 ('string', '0\x002\x001')
1482 define)
1482 define)
1483 (range
1483 (range
1484 ('symbol', '2')
1484 ('symbol', '2')
1485 ('symbol', '0')
1485 ('symbol', '0')
1486 follow)
1486 follow)
1487 define)
1487 define)
1488 * set:
1488 * set:
1489 <filteredset
1489 <filteredset
1490 <baseset [0, 2, 1]>,
1490 <baseset [0, 2, 1]>,
1491 <spanset- 0:2>>
1491 <spanset- 0:2>>
1492 0
1492 0
1493 2
1493 2
1494 1
1494 1
1495
1495
1496 '_hexlist(a b)' should behave like 'a + b':
1496 '_hexlist(a b)' should behave like 'a + b':
1497
1497
1498 $ trylist --optimize --bin '2:0 & %ln' `hg log -T '{node} ' -r0:2`
1498 $ trylist --optimize --bin '2:0 & %ln' `hg log -T '{node} ' -r0:2`
1499 (and
1499 (and
1500 (range
1500 (range
1501 ('symbol', '2')
1501 ('symbol', '2')
1502 ('symbol', '0'))
1502 ('symbol', '0'))
1503 (func
1503 (func
1504 ('symbol', '_hexlist')
1504 ('symbol', '_hexlist')
1505 ('string', '*'))) (glob)
1505 ('string', '*'))) (glob)
1506 * optimized:
1506 * optimized:
1507 (and
1507 (and
1508 (range
1508 (range
1509 ('symbol', '2')
1509 ('symbol', '2')
1510 ('symbol', '0')
1510 ('symbol', '0')
1511 define)
1511 define)
1512 (func
1512 (func
1513 ('symbol', '_hexlist')
1513 ('symbol', '_hexlist')
1514 ('string', '*') (glob)
1514 ('string', '*') (glob)
1515 follow)
1515 follow)
1516 define)
1516 define)
1517 * set:
1517 * set:
1518 <filteredset
1518 <filteredset
1519 <spanset- 0:2>,
1519 <spanset- 0:2>,
1520 <baseset [0, 1, 2]>>
1520 <baseset [0, 1, 2]>>
1521 2
1521 2
1522 1
1522 1
1523 0
1523 0
1524
1524
1525 $ trylist --optimize --bin '%ln & 2:0' `hg log -T '{node} ' -r0+2+1`
1525 $ trylist --optimize --bin '%ln & 2:0' `hg log -T '{node} ' -r0+2+1`
1526 (and
1526 (and
1527 (func
1527 (func
1528 ('symbol', '_hexlist')
1528 ('symbol', '_hexlist')
1529 ('string', '*')) (glob)
1529 ('string', '*')) (glob)
1530 (range
1530 (range
1531 ('symbol', '2')
1531 ('symbol', '2')
1532 ('symbol', '0')))
1532 ('symbol', '0')))
1533 * optimized:
1533 * optimized:
1534 (and
1534 (and
1535 (range
1535 (range
1536 ('symbol', '2')
1536 ('symbol', '2')
1537 ('symbol', '0')
1537 ('symbol', '0')
1538 follow)
1538 follow)
1539 (func
1539 (func
1540 ('symbol', '_hexlist')
1540 ('symbol', '_hexlist')
1541 ('string', '*') (glob)
1541 ('string', '*') (glob)
1542 define)
1542 define)
1543 define)
1543 define)
1544 * set:
1544 * set:
1545 <baseset [0, 2, 1]>
1545 <baseset [0, 2, 1]>
1546 0
1546 0
1547 2
1547 2
1548 1
1548 1
1549
1549
1550 '_list' should not go through the slow follow-order path if order doesn't
1550 '_list' should not go through the slow follow-order path if order doesn't
1551 matter:
1551 matter:
1552
1552
1553 $ try -p optimized '2:0 & not (0 + 1)'
1553 $ try -p optimized '2:0 & not (0 + 1)'
1554 * optimized:
1554 * optimized:
1555 (difference
1555 (difference
1556 (range
1556 (range
1557 ('symbol', '2')
1557 ('symbol', '2')
1558 ('symbol', '0')
1558 ('symbol', '0')
1559 define)
1559 define)
1560 (func
1560 (func
1561 ('symbol', '_list')
1561 ('symbol', '_list')
1562 ('string', '0\x001')
1562 ('string', '0\x001')
1563 any)
1563 any)
1564 define)
1564 define)
1565 * set:
1565 * set:
1566 <filteredset
1566 <filteredset
1567 <spanset- 0:2>,
1567 <spanset- 0:2>,
1568 <not
1568 <not
1569 <baseset [0, 1]>>>
1569 <baseset [0, 1]>>>
1570 2
1570 2
1571
1571
1572 $ try -p optimized '2:0 & not (0:2 & (0 + 1))'
1572 $ try -p optimized '2:0 & not (0:2 & (0 + 1))'
1573 * optimized:
1573 * optimized:
1574 (difference
1574 (difference
1575 (range
1575 (range
1576 ('symbol', '2')
1576 ('symbol', '2')
1577 ('symbol', '0')
1577 ('symbol', '0')
1578 define)
1578 define)
1579 (and
1579 (and
1580 (range
1580 (range
1581 ('symbol', '0')
1581 ('symbol', '0')
1582 ('symbol', '2')
1582 ('symbol', '2')
1583 any)
1583 any)
1584 (func
1584 (func
1585 ('symbol', '_list')
1585 ('symbol', '_list')
1586 ('string', '0\x001')
1586 ('string', '0\x001')
1587 any)
1587 any)
1588 any)
1588 any)
1589 define)
1589 define)
1590 * set:
1590 * set:
1591 <filteredset
1591 <filteredset
1592 <spanset- 0:2>,
1592 <spanset- 0:2>,
1593 <not
1593 <not
1594 <baseset [0, 1]>>>
1594 <baseset [0, 1]>>>
1595 2
1595 2
1596
1596
1597 because 'present()' does nothing other than suppressing an error, the
1597 because 'present()' does nothing other than suppressing an error, the
1598 ordering requirement should be forwarded to the nested expression
1598 ordering requirement should be forwarded to the nested expression
1599
1599
1600 $ try -p optimized 'present(2 + 0 + 1)'
1600 $ try -p optimized 'present(2 + 0 + 1)'
1601 * optimized:
1601 * optimized:
1602 (func
1602 (func
1603 ('symbol', 'present')
1603 ('symbol', 'present')
1604 (func
1604 (func
1605 ('symbol', '_list')
1605 ('symbol', '_list')
1606 ('string', '2\x000\x001')
1606 ('string', '2\x000\x001')
1607 define)
1607 define)
1608 define)
1608 define)
1609 * set:
1609 * set:
1610 <baseset [2, 0, 1]>
1610 <baseset [2, 0, 1]>
1611 2
1611 2
1612 0
1612 0
1613 1
1613 1
1614
1614
1615 $ try --optimize '2:0 & present(0 + 1 + 2)'
1615 $ try --optimize '2:0 & present(0 + 1 + 2)'
1616 (and
1616 (and
1617 (range
1617 (range
1618 ('symbol', '2')
1618 ('symbol', '2')
1619 ('symbol', '0'))
1619 ('symbol', '0'))
1620 (func
1620 (func
1621 ('symbol', 'present')
1621 ('symbol', 'present')
1622 (or
1622 (or
1623 (list
1623 (list
1624 ('symbol', '0')
1624 ('symbol', '0')
1625 ('symbol', '1')
1625 ('symbol', '1')
1626 ('symbol', '2')))))
1626 ('symbol', '2')))))
1627 * optimized:
1627 * optimized:
1628 (and
1628 (and
1629 (range
1629 (range
1630 ('symbol', '2')
1630 ('symbol', '2')
1631 ('symbol', '0')
1631 ('symbol', '0')
1632 define)
1632 define)
1633 (func
1633 (func
1634 ('symbol', 'present')
1634 ('symbol', 'present')
1635 (func
1635 (func
1636 ('symbol', '_list')
1636 ('symbol', '_list')
1637 ('string', '0\x001\x002')
1637 ('string', '0\x001\x002')
1638 follow)
1638 follow)
1639 follow)
1639 follow)
1640 define)
1640 define)
1641 * set:
1641 * set:
1642 <filteredset
1642 <filteredset
1643 <spanset- 0:2>,
1643 <spanset- 0:2>,
1644 <baseset [0, 1, 2]>>
1644 <baseset [0, 1, 2]>>
1645 2
1645 2
1646 1
1646 1
1647 0
1647 0
1648
1648
1649 'reverse()' should take effect only if it is the outermost expression:
1649 'reverse()' should take effect only if it is the outermost expression:
1650
1650
1651 $ try --optimize '0:2 & reverse(all())'
1651 $ try --optimize '0:2 & reverse(all())'
1652 (and
1652 (and
1653 (range
1653 (range
1654 ('symbol', '0')
1654 ('symbol', '0')
1655 ('symbol', '2'))
1655 ('symbol', '2'))
1656 (func
1656 (func
1657 ('symbol', 'reverse')
1657 ('symbol', 'reverse')
1658 (func
1658 (func
1659 ('symbol', 'all')
1659 ('symbol', 'all')
1660 None)))
1660 None)))
1661 * optimized:
1661 * optimized:
1662 (and
1662 (and
1663 (range
1663 (range
1664 ('symbol', '0')
1664 ('symbol', '0')
1665 ('symbol', '2')
1665 ('symbol', '2')
1666 define)
1666 define)
1667 (func
1667 (func
1668 ('symbol', 'reverse')
1668 ('symbol', 'reverse')
1669 (func
1669 (func
1670 ('symbol', 'all')
1670 ('symbol', 'all')
1671 None
1671 None
1672 define)
1672 define)
1673 follow)
1673 follow)
1674 define)
1674 define)
1675 * set:
1675 * set:
1676 <filteredset
1676 <filteredset
1677 <spanset+ 0:2>,
1677 <spanset+ 0:2>,
1678 <spanset+ 0:9>>
1678 <spanset+ 0:9>>
1679 0
1679 0
1680 1
1680 1
1681 2
1681 2
1682
1682
1683 'sort()' should take effect only if it is the outermost expression:
1683 'sort()' should take effect only if it is the outermost expression:
1684
1684
1685 $ try --optimize '0:2 & sort(all(), -rev)'
1685 $ try --optimize '0:2 & sort(all(), -rev)'
1686 (and
1686 (and
1687 (range
1687 (range
1688 ('symbol', '0')
1688 ('symbol', '0')
1689 ('symbol', '2'))
1689 ('symbol', '2'))
1690 (func
1690 (func
1691 ('symbol', 'sort')
1691 ('symbol', 'sort')
1692 (list
1692 (list
1693 (func
1693 (func
1694 ('symbol', 'all')
1694 ('symbol', 'all')
1695 None)
1695 None)
1696 (negate
1696 (negate
1697 ('symbol', 'rev')))))
1697 ('symbol', 'rev')))))
1698 * optimized:
1698 * optimized:
1699 (and
1699 (and
1700 (range
1700 (range
1701 ('symbol', '0')
1701 ('symbol', '0')
1702 ('symbol', '2')
1702 ('symbol', '2')
1703 define)
1703 define)
1704 (func
1704 (func
1705 ('symbol', 'sort')
1705 ('symbol', 'sort')
1706 (list
1706 (list
1707 (func
1707 (func
1708 ('symbol', 'all')
1708 ('symbol', 'all')
1709 None
1709 None
1710 define)
1710 define)
1711 ('string', '-rev'))
1711 ('string', '-rev'))
1712 follow)
1712 follow)
1713 define)
1713 define)
1714 * set:
1714 * set:
1715 <filteredset
1715 <filteredset
1716 <spanset+ 0:2>,
1716 <spanset+ 0:2>,
1717 <spanset+ 0:9>>
1717 <spanset+ 0:9>>
1718 0
1718 0
1719 1
1719 1
1720 2
1720 2
1721
1721
1722 invalid argument passed to noop sort():
1722 invalid argument passed to noop sort():
1723
1723
1724 $ log '0:2 & sort()'
1724 $ log '0:2 & sort()'
1725 hg: parse error: sort requires one or two arguments
1725 hg: parse error: sort requires one or two arguments
1726 [255]
1726 [255]
1727 $ log '0:2 & sort(all(), -invalid)'
1727 $ log '0:2 & sort(all(), -invalid)'
1728 hg: parse error: unknown sort key '-invalid'
1728 hg: parse error: unknown sort key '-invalid'
1729 [255]
1729 [255]
1730
1730
1731 for 'A & f(B)', 'B' should not be affected by the order of 'A':
1731 for 'A & f(B)', 'B' should not be affected by the order of 'A':
1732
1732
1733 $ try --optimize '2:0 & first(1 + 0 + 2)'
1733 $ try --optimize '2:0 & first(1 + 0 + 2)'
1734 (and
1734 (and
1735 (range
1735 (range
1736 ('symbol', '2')
1736 ('symbol', '2')
1737 ('symbol', '0'))
1737 ('symbol', '0'))
1738 (func
1738 (func
1739 ('symbol', 'first')
1739 ('symbol', 'first')
1740 (or
1740 (or
1741 (list
1741 (list
1742 ('symbol', '1')
1742 ('symbol', '1')
1743 ('symbol', '0')
1743 ('symbol', '0')
1744 ('symbol', '2')))))
1744 ('symbol', '2')))))
1745 * optimized:
1745 * optimized:
1746 (and
1746 (and
1747 (range
1747 (range
1748 ('symbol', '2')
1748 ('symbol', '2')
1749 ('symbol', '0')
1749 ('symbol', '0')
1750 define)
1750 define)
1751 (func
1751 (func
1752 ('symbol', 'first')
1752 ('symbol', 'first')
1753 (func
1753 (func
1754 ('symbol', '_list')
1754 ('symbol', '_list')
1755 ('string', '1\x000\x002')
1755 ('string', '1\x000\x002')
1756 define)
1756 define)
1757 follow)
1757 follow)
1758 define)
1758 define)
1759 * set:
1759 * set:
1760 <baseset
1760 <baseset
1761 <limit n=1, offset=0,
1761 <limit n=1, offset=0,
1762 <spanset- 0:2>,
1762 <spanset- 0:2>,
1763 <baseset [1, 0, 2]>>>
1763 <baseset [1, 0, 2]>>>
1764 1
1764 1
1765
1765
1766 $ try --optimize '2:0 & not last(0 + 2 + 1)'
1766 $ try --optimize '2:0 & not last(0 + 2 + 1)'
1767 (and
1767 (and
1768 (range
1768 (range
1769 ('symbol', '2')
1769 ('symbol', '2')
1770 ('symbol', '0'))
1770 ('symbol', '0'))
1771 (not
1771 (not
1772 (func
1772 (func
1773 ('symbol', 'last')
1773 ('symbol', 'last')
1774 (or
1774 (or
1775 (list
1775 (list
1776 ('symbol', '0')
1776 ('symbol', '0')
1777 ('symbol', '2')
1777 ('symbol', '2')
1778 ('symbol', '1'))))))
1778 ('symbol', '1'))))))
1779 * optimized:
1779 * optimized:
1780 (difference
1780 (difference
1781 (range
1781 (range
1782 ('symbol', '2')
1782 ('symbol', '2')
1783 ('symbol', '0')
1783 ('symbol', '0')
1784 define)
1784 define)
1785 (func
1785 (func
1786 ('symbol', 'last')
1786 ('symbol', 'last')
1787 (func
1787 (func
1788 ('symbol', '_list')
1788 ('symbol', '_list')
1789 ('string', '0\x002\x001')
1789 ('string', '0\x002\x001')
1790 define)
1790 define)
1791 any)
1791 any)
1792 define)
1792 define)
1793 * set:
1793 * set:
1794 <filteredset
1794 <filteredset
1795 <spanset- 0:2>,
1795 <spanset- 0:2>,
1796 <not
1796 <not
1797 <baseset
1797 <baseset
1798 <last n=1,
1798 <last n=1,
1799 <fullreposet+ 0:9>,
1799 <fullreposet+ 0:9>,
1800 <baseset [1, 2, 0]>>>>>
1800 <baseset [1, 2, 0]>>>>>
1801 2
1801 2
1802 0
1802 0
1803
1803
1804 for 'A & (op)(B)', 'B' should not be affected by the order of 'A':
1804 for 'A & (op)(B)', 'B' should not be affected by the order of 'A':
1805
1805
1806 $ try --optimize '2:0 & (1 + 0 + 2):(0 + 2 + 1)'
1806 $ try --optimize '2:0 & (1 + 0 + 2):(0 + 2 + 1)'
1807 (and
1807 (and
1808 (range
1808 (range
1809 ('symbol', '2')
1809 ('symbol', '2')
1810 ('symbol', '0'))
1810 ('symbol', '0'))
1811 (range
1811 (range
1812 (group
1812 (group
1813 (or
1813 (or
1814 (list
1814 (list
1815 ('symbol', '1')
1815 ('symbol', '1')
1816 ('symbol', '0')
1816 ('symbol', '0')
1817 ('symbol', '2'))))
1817 ('symbol', '2'))))
1818 (group
1818 (group
1819 (or
1819 (or
1820 (list
1820 (list
1821 ('symbol', '0')
1821 ('symbol', '0')
1822 ('symbol', '2')
1822 ('symbol', '2')
1823 ('symbol', '1'))))))
1823 ('symbol', '1'))))))
1824 * optimized:
1824 * optimized:
1825 (and
1825 (and
1826 (range
1826 (range
1827 ('symbol', '2')
1827 ('symbol', '2')
1828 ('symbol', '0')
1828 ('symbol', '0')
1829 define)
1829 define)
1830 (range
1830 (range
1831 (func
1831 (func
1832 ('symbol', '_list')
1832 ('symbol', '_list')
1833 ('string', '1\x000\x002')
1833 ('string', '1\x000\x002')
1834 define)
1834 define)
1835 (func
1835 (func
1836 ('symbol', '_list')
1836 ('symbol', '_list')
1837 ('string', '0\x002\x001')
1837 ('string', '0\x002\x001')
1838 define)
1838 define)
1839 follow)
1839 follow)
1840 define)
1840 define)
1841 * set:
1841 * set:
1842 <filteredset
1842 <filteredset
1843 <spanset- 0:2>,
1843 <spanset- 0:2>,
1844 <baseset [1]>>
1844 <baseset [1]>>
1845 1
1845 1
1846
1846
1847 'A & B' can be rewritten as 'B & A' by weight, but that's fine as long as
1847 'A & B' can be rewritten as 'B & A' by weight, but that's fine as long as
1848 the ordering rule is determined before the rewrite; in this example,
1848 the ordering rule is determined before the rewrite; in this example,
1849 'B' follows the order of the initial set, which is the same order as 'A'
1849 'B' follows the order of the initial set, which is the same order as 'A'
1850 since 'A' also follows the order:
1850 since 'A' also follows the order:
1851
1851
1852 $ try --optimize 'contains("glob:*") & (2 + 0 + 1)'
1852 $ try --optimize 'contains("glob:*") & (2 + 0 + 1)'
1853 (and
1853 (and
1854 (func
1854 (func
1855 ('symbol', 'contains')
1855 ('symbol', 'contains')
1856 ('string', 'glob:*'))
1856 ('string', 'glob:*'))
1857 (group
1857 (group
1858 (or
1858 (or
1859 (list
1859 (list
1860 ('symbol', '2')
1860 ('symbol', '2')
1861 ('symbol', '0')
1861 ('symbol', '0')
1862 ('symbol', '1')))))
1862 ('symbol', '1')))))
1863 * optimized:
1863 * optimized:
1864 (and
1864 (and
1865 (func
1865 (func
1866 ('symbol', '_list')
1866 ('symbol', '_list')
1867 ('string', '2\x000\x001')
1867 ('string', '2\x000\x001')
1868 follow)
1868 follow)
1869 (func
1869 (func
1870 ('symbol', 'contains')
1870 ('symbol', 'contains')
1871 ('string', 'glob:*')
1871 ('string', 'glob:*')
1872 define)
1872 define)
1873 define)
1873 define)
1874 * set:
1874 * set:
1875 <filteredset
1875 <filteredset
1876 <baseset+ [0, 1, 2]>,
1876 <baseset+ [0, 1, 2]>,
1877 <contains 'glob:*'>>
1877 <contains 'glob:*'>>
1878 0
1878 0
1879 1
1879 1
1880 2
1880 2
1881
1881
1882 and in this example, 'A & B' is rewritten as 'B & A', but 'A' overrides
1882 and in this example, 'A & B' is rewritten as 'B & A', but 'A' overrides
1883 the order appropriately:
1883 the order appropriately:
1884
1884
1885 $ try --optimize 'reverse(contains("glob:*")) & (0 + 2 + 1)'
1885 $ try --optimize 'reverse(contains("glob:*")) & (0 + 2 + 1)'
1886 (and
1886 (and
1887 (func
1887 (func
1888 ('symbol', 'reverse')
1888 ('symbol', 'reverse')
1889 (func
1889 (func
1890 ('symbol', 'contains')
1890 ('symbol', 'contains')
1891 ('string', 'glob:*')))
1891 ('string', 'glob:*')))
1892 (group
1892 (group
1893 (or
1893 (or
1894 (list
1894 (list
1895 ('symbol', '0')
1895 ('symbol', '0')
1896 ('symbol', '2')
1896 ('symbol', '2')
1897 ('symbol', '1')))))
1897 ('symbol', '1')))))
1898 * optimized:
1898 * optimized:
1899 (and
1899 (and
1900 (func
1900 (func
1901 ('symbol', '_list')
1901 ('symbol', '_list')
1902 ('string', '0\x002\x001')
1902 ('string', '0\x002\x001')
1903 follow)
1903 follow)
1904 (func
1904 (func
1905 ('symbol', 'reverse')
1905 ('symbol', 'reverse')
1906 (func
1906 (func
1907 ('symbol', 'contains')
1907 ('symbol', 'contains')
1908 ('string', 'glob:*')
1908 ('string', 'glob:*')
1909 define)
1909 define)
1910 define)
1910 define)
1911 define)
1911 define)
1912 * set:
1912 * set:
1913 <filteredset
1913 <filteredset
1914 <baseset- [0, 1, 2]>,
1914 <baseset- [0, 1, 2]>,
1915 <contains 'glob:*'>>
1915 <contains 'glob:*'>>
1916 2
1916 2
1917 1
1917 1
1918 0
1918 0
1919
1919
1920 'A + B' can be rewritten to 'B + A' by weight only when the order doesn't
1920 'A + B' can be rewritten to 'B + A' by weight only when the order doesn't
1921 matter (e.g. 'X & (A + B)' can be 'X & (B + A)', but '(A + B) & X' can't):
1921 matter (e.g. 'X & (A + B)' can be 'X & (B + A)', but '(A + B) & X' can't):
1922
1922
1923 $ try -p optimized '0:2 & (reverse(contains("a")) + 2)'
1923 $ try -p optimized '0:2 & (reverse(contains("a")) + 2)'
1924 * optimized:
1924 * optimized:
1925 (and
1925 (and
1926 (range
1926 (range
1927 ('symbol', '0')
1927 ('symbol', '0')
1928 ('symbol', '2')
1928 ('symbol', '2')
1929 define)
1929 define)
1930 (or
1930 (or
1931 (list
1931 (list
1932 ('symbol', '2')
1932 ('symbol', '2')
1933 (func
1933 (func
1934 ('symbol', 'reverse')
1934 ('symbol', 'reverse')
1935 (func
1935 (func
1936 ('symbol', 'contains')
1936 ('symbol', 'contains')
1937 ('string', 'a')
1937 ('string', 'a')
1938 define)
1938 define)
1939 follow))
1939 follow))
1940 follow)
1940 follow)
1941 define)
1941 define)
1942 * set:
1942 * set:
1943 <filteredset
1943 <filteredset
1944 <spanset+ 0:2>,
1944 <spanset+ 0:2>,
1945 <addset
1945 <addset
1946 <baseset [2]>,
1946 <baseset [2]>,
1947 <filteredset
1947 <filteredset
1948 <fullreposet+ 0:9>,
1948 <fullreposet+ 0:9>,
1949 <contains 'a'>>>>
1949 <contains 'a'>>>>
1950 0
1950 0
1951 1
1951 1
1952 2
1952 2
1953
1953
1954 $ try -p optimized '(reverse(contains("a")) + 2) & 0:2'
1954 $ try -p optimized '(reverse(contains("a")) + 2) & 0:2'
1955 * optimized:
1955 * optimized:
1956 (and
1956 (and
1957 (range
1957 (range
1958 ('symbol', '0')
1958 ('symbol', '0')
1959 ('symbol', '2')
1959 ('symbol', '2')
1960 follow)
1960 follow)
1961 (or
1961 (or
1962 (list
1962 (list
1963 (func
1963 (func
1964 ('symbol', 'reverse')
1964 ('symbol', 'reverse')
1965 (func
1965 (func
1966 ('symbol', 'contains')
1966 ('symbol', 'contains')
1967 ('string', 'a')
1967 ('string', 'a')
1968 define)
1968 define)
1969 define)
1969 define)
1970 ('symbol', '2'))
1970 ('symbol', '2'))
1971 define)
1971 define)
1972 define)
1972 define)
1973 * set:
1973 * set:
1974 <addset
1974 <addset
1975 <filteredset
1975 <filteredset
1976 <spanset- 0:2>,
1976 <spanset- 0:2>,
1977 <contains 'a'>>,
1977 <contains 'a'>>,
1978 <baseset [2]>>
1978 <baseset [2]>>
1979 1
1979 1
1980 0
1980 0
1981 2
1981 2
1982
1982
1983 test sort revset
1983 test sort revset
1984 --------------------------------------------
1984 --------------------------------------------
1985
1985
1986 test when adding two unordered revsets
1986 test when adding two unordered revsets
1987
1987
1988 $ log 'sort(keyword(issue) or modifies(b))'
1988 $ log 'sort(keyword(issue) or modifies(b))'
1989 4
1989 4
1990 6
1990 6
1991
1991
1992 test when sorting a reversed collection in the same way it is
1992 test when sorting a reversed collection in the same way it is
1993
1993
1994 $ log 'sort(reverse(all()), -rev)'
1994 $ log 'sort(reverse(all()), -rev)'
1995 9
1995 9
1996 8
1996 8
1997 7
1997 7
1998 6
1998 6
1999 5
1999 5
2000 4
2000 4
2001 3
2001 3
2002 2
2002 2
2003 1
2003 1
2004 0
2004 0
2005
2005
2006 test when sorting a reversed collection
2006 test when sorting a reversed collection
2007
2007
2008 $ log 'sort(reverse(all()), rev)'
2008 $ log 'sort(reverse(all()), rev)'
2009 0
2009 0
2010 1
2010 1
2011 2
2011 2
2012 3
2012 3
2013 4
2013 4
2014 5
2014 5
2015 6
2015 6
2016 7
2016 7
2017 8
2017 8
2018 9
2018 9
2019
2019
2020
2020
2021 test sorting two sorted collections in different orders
2021 test sorting two sorted collections in different orders
2022
2022
2023 $ log 'sort(outgoing() or reverse(removes(a)), rev)'
2023 $ log 'sort(outgoing() or reverse(removes(a)), rev)'
2024 2
2024 2
2025 6
2025 6
2026 8
2026 8
2027 9
2027 9
2028
2028
2029 test sorting two sorted collections in different orders backwards
2029 test sorting two sorted collections in different orders backwards
2030
2030
2031 $ log 'sort(outgoing() or reverse(removes(a)), -rev)'
2031 $ log 'sort(outgoing() or reverse(removes(a)), -rev)'
2032 9
2032 9
2033 8
2033 8
2034 6
2034 6
2035 2
2035 2
2036
2036
2037 test empty sort key which is noop
2037 test empty sort key which is noop
2038
2038
2039 $ log 'sort(0 + 2 + 1, "")'
2039 $ log 'sort(0 + 2 + 1, "")'
2040 0
2040 0
2041 2
2041 2
2042 1
2042 1
2043
2043
2044 test invalid sort keys
2044 test invalid sort keys
2045
2045
2046 $ log 'sort(all(), -invalid)'
2046 $ log 'sort(all(), -invalid)'
2047 hg: parse error: unknown sort key '-invalid'
2047 hg: parse error: unknown sort key '-invalid'
2048 [255]
2048 [255]
2049
2049
2050 $ cd ..
2050 $ cd ..
2051
2051
2052 test sorting by multiple keys including variable-length strings
2052 test sorting by multiple keys including variable-length strings
2053
2053
2054 $ hg init sorting
2054 $ hg init sorting
2055 $ cd sorting
2055 $ cd sorting
2056 $ cat <<EOF >> .hg/hgrc
2056 $ cat <<EOF >> .hg/hgrc
2057 > [ui]
2057 > [ui]
2058 > logtemplate = '{rev} {branch|p5}{desc|p5}{author|p5}{date|hgdate}\n'
2058 > logtemplate = '{rev} {branch|p5}{desc|p5}{author|p5}{date|hgdate}\n'
2059 > [templatealias]
2059 > [templatealias]
2060 > p5(s) = pad(s, 5)
2060 > p5(s) = pad(s, 5)
2061 > EOF
2061 > EOF
2062 $ hg branch -qf b12
2062 $ hg branch -qf b12
2063 $ hg ci -m m111 -u u112 -d '111 10800'
2063 $ hg ci -m m111 -u u112 -d '111 10800'
2064 $ hg branch -qf b11
2064 $ hg branch -qf b11
2065 $ hg ci -m m12 -u u111 -d '112 7200'
2065 $ hg ci -m m12 -u u111 -d '112 7200'
2066 $ hg branch -qf b111
2066 $ hg branch -qf b111
2067 $ hg ci -m m11 -u u12 -d '111 3600'
2067 $ hg ci -m m11 -u u12 -d '111 3600'
2068 $ hg branch -qf b112
2068 $ hg branch -qf b112
2069 $ hg ci -m m111 -u u11 -d '120 0'
2069 $ hg ci -m m111 -u u11 -d '120 0'
2070 $ hg branch -qf b111
2070 $ hg branch -qf b111
2071 $ hg ci -m m112 -u u111 -d '110 14400'
2071 $ hg ci -m m112 -u u111 -d '110 14400'
2072 created new head
2072 created new head
2073
2073
2074 compare revisions (has fast path):
2074 compare revisions (has fast path):
2075
2075
2076 $ hg log -r 'sort(all(), rev)'
2076 $ hg log -r 'sort(all(), rev)'
2077 0 b12 m111 u112 111 10800
2077 0 b12 m111 u112 111 10800
2078 1 b11 m12 u111 112 7200
2078 1 b11 m12 u111 112 7200
2079 2 b111 m11 u12 111 3600
2079 2 b111 m11 u12 111 3600
2080 3 b112 m111 u11 120 0
2080 3 b112 m111 u11 120 0
2081 4 b111 m112 u111 110 14400
2081 4 b111 m112 u111 110 14400
2082
2082
2083 $ hg log -r 'sort(all(), -rev)'
2083 $ hg log -r 'sort(all(), -rev)'
2084 4 b111 m112 u111 110 14400
2084 4 b111 m112 u111 110 14400
2085 3 b112 m111 u11 120 0
2085 3 b112 m111 u11 120 0
2086 2 b111 m11 u12 111 3600
2086 2 b111 m11 u12 111 3600
2087 1 b11 m12 u111 112 7200
2087 1 b11 m12 u111 112 7200
2088 0 b12 m111 u112 111 10800
2088 0 b12 m111 u112 111 10800
2089
2089
2090 compare variable-length strings (issue5218):
2090 compare variable-length strings (issue5218):
2091
2091
2092 $ hg log -r 'sort(all(), branch)'
2092 $ hg log -r 'sort(all(), branch)'
2093 1 b11 m12 u111 112 7200
2093 1 b11 m12 u111 112 7200
2094 2 b111 m11 u12 111 3600
2094 2 b111 m11 u12 111 3600
2095 4 b111 m112 u111 110 14400
2095 4 b111 m112 u111 110 14400
2096 3 b112 m111 u11 120 0
2096 3 b112 m111 u11 120 0
2097 0 b12 m111 u112 111 10800
2097 0 b12 m111 u112 111 10800
2098
2098
2099 $ hg log -r 'sort(all(), -branch)'
2099 $ hg log -r 'sort(all(), -branch)'
2100 0 b12 m111 u112 111 10800
2100 0 b12 m111 u112 111 10800
2101 3 b112 m111 u11 120 0
2101 3 b112 m111 u11 120 0
2102 2 b111 m11 u12 111 3600
2102 2 b111 m11 u12 111 3600
2103 4 b111 m112 u111 110 14400
2103 4 b111 m112 u111 110 14400
2104 1 b11 m12 u111 112 7200
2104 1 b11 m12 u111 112 7200
2105
2105
2106 $ hg log -r 'sort(all(), desc)'
2106 $ hg log -r 'sort(all(), desc)'
2107 2 b111 m11 u12 111 3600
2107 2 b111 m11 u12 111 3600
2108 0 b12 m111 u112 111 10800
2108 0 b12 m111 u112 111 10800
2109 3 b112 m111 u11 120 0
2109 3 b112 m111 u11 120 0
2110 4 b111 m112 u111 110 14400
2110 4 b111 m112 u111 110 14400
2111 1 b11 m12 u111 112 7200
2111 1 b11 m12 u111 112 7200
2112
2112
2113 $ hg log -r 'sort(all(), -desc)'
2113 $ hg log -r 'sort(all(), -desc)'
2114 1 b11 m12 u111 112 7200
2114 1 b11 m12 u111 112 7200
2115 4 b111 m112 u111 110 14400
2115 4 b111 m112 u111 110 14400
2116 0 b12 m111 u112 111 10800
2116 0 b12 m111 u112 111 10800
2117 3 b112 m111 u11 120 0
2117 3 b112 m111 u11 120 0
2118 2 b111 m11 u12 111 3600
2118 2 b111 m11 u12 111 3600
2119
2119
2120 $ hg log -r 'sort(all(), user)'
2120 $ hg log -r 'sort(all(), user)'
2121 3 b112 m111 u11 120 0
2121 3 b112 m111 u11 120 0
2122 1 b11 m12 u111 112 7200
2122 1 b11 m12 u111 112 7200
2123 4 b111 m112 u111 110 14400
2123 4 b111 m112 u111 110 14400
2124 0 b12 m111 u112 111 10800
2124 0 b12 m111 u112 111 10800
2125 2 b111 m11 u12 111 3600
2125 2 b111 m11 u12 111 3600
2126
2126
2127 $ hg log -r 'sort(all(), -user)'
2127 $ hg log -r 'sort(all(), -user)'
2128 2 b111 m11 u12 111 3600
2128 2 b111 m11 u12 111 3600
2129 0 b12 m111 u112 111 10800
2129 0 b12 m111 u112 111 10800
2130 1 b11 m12 u111 112 7200
2130 1 b11 m12 u111 112 7200
2131 4 b111 m112 u111 110 14400
2131 4 b111 m112 u111 110 14400
2132 3 b112 m111 u11 120 0
2132 3 b112 m111 u11 120 0
2133
2133
2134 compare dates (tz offset should have no effect):
2134 compare dates (tz offset should have no effect):
2135
2135
2136 $ hg log -r 'sort(all(), date)'
2136 $ hg log -r 'sort(all(), date)'
2137 4 b111 m112 u111 110 14400
2137 4 b111 m112 u111 110 14400
2138 0 b12 m111 u112 111 10800
2138 0 b12 m111 u112 111 10800
2139 2 b111 m11 u12 111 3600
2139 2 b111 m11 u12 111 3600
2140 1 b11 m12 u111 112 7200
2140 1 b11 m12 u111 112 7200
2141 3 b112 m111 u11 120 0
2141 3 b112 m111 u11 120 0
2142
2142
2143 $ hg log -r 'sort(all(), -date)'
2143 $ hg log -r 'sort(all(), -date)'
2144 3 b112 m111 u11 120 0
2144 3 b112 m111 u11 120 0
2145 1 b11 m12 u111 112 7200
2145 1 b11 m12 u111 112 7200
2146 0 b12 m111 u112 111 10800
2146 0 b12 m111 u112 111 10800
2147 2 b111 m11 u12 111 3600
2147 2 b111 m11 u12 111 3600
2148 4 b111 m112 u111 110 14400
2148 4 b111 m112 u111 110 14400
2149
2149
2150 be aware that 'sort(x, -k)' is not exactly the same as 'reverse(sort(x, k))'
2150 be aware that 'sort(x, -k)' is not exactly the same as 'reverse(sort(x, k))'
2151 because '-k' reverses the comparison, not the list itself:
2151 because '-k' reverses the comparison, not the list itself:
2152
2152
2153 $ hg log -r 'sort(0 + 2, date)'
2153 $ hg log -r 'sort(0 + 2, date)'
2154 0 b12 m111 u112 111 10800
2154 0 b12 m111 u112 111 10800
2155 2 b111 m11 u12 111 3600
2155 2 b111 m11 u12 111 3600
2156
2156
2157 $ hg log -r 'sort(0 + 2, -date)'
2157 $ hg log -r 'sort(0 + 2, -date)'
2158 0 b12 m111 u112 111 10800
2158 0 b12 m111 u112 111 10800
2159 2 b111 m11 u12 111 3600
2159 2 b111 m11 u12 111 3600
2160
2160
2161 $ hg log -r 'reverse(sort(0 + 2, date))'
2161 $ hg log -r 'reverse(sort(0 + 2, date))'
2162 2 b111 m11 u12 111 3600
2162 2 b111 m11 u12 111 3600
2163 0 b12 m111 u112 111 10800
2163 0 b12 m111 u112 111 10800
2164
2164
2165 sort by multiple keys:
2165 sort by multiple keys:
2166
2166
2167 $ hg log -r 'sort(all(), "branch -rev")'
2167 $ hg log -r 'sort(all(), "branch -rev")'
2168 1 b11 m12 u111 112 7200
2168 1 b11 m12 u111 112 7200
2169 4 b111 m112 u111 110 14400
2169 4 b111 m112 u111 110 14400
2170 2 b111 m11 u12 111 3600
2170 2 b111 m11 u12 111 3600
2171 3 b112 m111 u11 120 0
2171 3 b112 m111 u11 120 0
2172 0 b12 m111 u112 111 10800
2172 0 b12 m111 u112 111 10800
2173
2173
2174 $ hg log -r 'sort(all(), "-desc -date")'
2174 $ hg log -r 'sort(all(), "-desc -date")'
2175 1 b11 m12 u111 112 7200
2175 1 b11 m12 u111 112 7200
2176 4 b111 m112 u111 110 14400
2176 4 b111 m112 u111 110 14400
2177 3 b112 m111 u11 120 0
2177 3 b112 m111 u11 120 0
2178 0 b12 m111 u112 111 10800
2178 0 b12 m111 u112 111 10800
2179 2 b111 m11 u12 111 3600
2179 2 b111 m11 u12 111 3600
2180
2180
2181 $ hg log -r 'sort(all(), "user -branch date rev")'
2181 $ hg log -r 'sort(all(), "user -branch date rev")'
2182 3 b112 m111 u11 120 0
2182 3 b112 m111 u11 120 0
2183 4 b111 m112 u111 110 14400
2183 4 b111 m112 u111 110 14400
2184 1 b11 m12 u111 112 7200
2184 1 b11 m12 u111 112 7200
2185 0 b12 m111 u112 111 10800
2185 0 b12 m111 u112 111 10800
2186 2 b111 m11 u12 111 3600
2186 2 b111 m11 u12 111 3600
2187
2187
2188 toposort prioritises graph branches
2188 toposort prioritises graph branches
2189
2189
2190 $ hg up 2
2190 $ hg up 2
2191 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
2191 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
2192 $ touch a
2192 $ touch a
2193 $ hg addremove
2193 $ hg addremove
2194 adding a
2194 adding a
2195 $ hg ci -m 't1' -u 'tu' -d '130 0'
2195 $ hg ci -m 't1' -u 'tu' -d '130 0'
2196 created new head
2196 created new head
2197 $ echo 'a' >> a
2197 $ echo 'a' >> a
2198 $ hg ci -m 't2' -u 'tu' -d '130 0'
2198 $ hg ci -m 't2' -u 'tu' -d '130 0'
2199 $ hg book book1
2199 $ hg book book1
2200 $ hg up 4
2200 $ hg up 4
2201 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2201 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2202 (leaving bookmark book1)
2202 (leaving bookmark book1)
2203 $ touch a
2203 $ touch a
2204 $ hg addremove
2204 $ hg addremove
2205 adding a
2205 adding a
2206 $ hg ci -m 't3' -u 'tu' -d '130 0'
2206 $ hg ci -m 't3' -u 'tu' -d '130 0'
2207
2207
2208 $ hg log -r 'sort(all(), topo)'
2208 $ hg log -r 'sort(all(), topo)'
2209 7 b111 t3 tu 130 0
2209 7 b111 t3 tu 130 0
2210 4 b111 m112 u111 110 14400
2210 4 b111 m112 u111 110 14400
2211 3 b112 m111 u11 120 0
2211 3 b112 m111 u11 120 0
2212 6 b111 t2 tu 130 0
2212 6 b111 t2 tu 130 0
2213 5 b111 t1 tu 130 0
2213 5 b111 t1 tu 130 0
2214 2 b111 m11 u12 111 3600
2214 2 b111 m11 u12 111 3600
2215 1 b11 m12 u111 112 7200
2215 1 b11 m12 u111 112 7200
2216 0 b12 m111 u112 111 10800
2216 0 b12 m111 u112 111 10800
2217
2217
2218 $ hg log -r 'sort(all(), -topo)'
2218 $ hg log -r 'sort(all(), -topo)'
2219 0 b12 m111 u112 111 10800
2219 0 b12 m111 u112 111 10800
2220 1 b11 m12 u111 112 7200
2220 1 b11 m12 u111 112 7200
2221 2 b111 m11 u12 111 3600
2221 2 b111 m11 u12 111 3600
2222 5 b111 t1 tu 130 0
2222 5 b111 t1 tu 130 0
2223 6 b111 t2 tu 130 0
2223 6 b111 t2 tu 130 0
2224 3 b112 m111 u11 120 0
2224 3 b112 m111 u11 120 0
2225 4 b111 m112 u111 110 14400
2225 4 b111 m112 u111 110 14400
2226 7 b111 t3 tu 130 0
2226 7 b111 t3 tu 130 0
2227
2227
2228 $ hg log -r 'sort(all(), topo, topo.firstbranch=book1)'
2228 $ hg log -r 'sort(all(), topo, topo.firstbranch=book1)'
2229 6 b111 t2 tu 130 0
2229 6 b111 t2 tu 130 0
2230 5 b111 t1 tu 130 0
2230 5 b111 t1 tu 130 0
2231 7 b111 t3 tu 130 0
2231 7 b111 t3 tu 130 0
2232 4 b111 m112 u111 110 14400
2232 4 b111 m112 u111 110 14400
2233 3 b112 m111 u11 120 0
2233 3 b112 m111 u11 120 0
2234 2 b111 m11 u12 111 3600
2234 2 b111 m11 u12 111 3600
2235 1 b11 m12 u111 112 7200
2235 1 b11 m12 u111 112 7200
2236 0 b12 m111 u112 111 10800
2236 0 b12 m111 u112 111 10800
2237
2237
2238 topographical sorting can't be combined with other sort keys, and you can't
2238 topographical sorting can't be combined with other sort keys, and you can't
2239 use the topo.firstbranch option when topo sort is not active:
2239 use the topo.firstbranch option when topo sort is not active:
2240
2240
2241 $ hg log -r 'sort(all(), "topo user")'
2241 $ hg log -r 'sort(all(), "topo user")'
2242 hg: parse error: topo sort order cannot be combined with other sort keys
2242 hg: parse error: topo sort order cannot be combined with other sort keys
2243 [255]
2243 [255]
2244
2244
2245 $ hg log -r 'sort(all(), user, topo.firstbranch=book1)'
2245 $ hg log -r 'sort(all(), user, topo.firstbranch=book1)'
2246 hg: parse error: topo.firstbranch can only be used when using the topo sort key
2246 hg: parse error: topo.firstbranch can only be used when using the topo sort key
2247 [255]
2247 [255]
2248
2248
2249 topo.firstbranch should accept any kind of expressions:
2249 topo.firstbranch should accept any kind of expressions:
2250
2250
2251 $ hg log -r 'sort(0, topo, topo.firstbranch=(book1))'
2251 $ hg log -r 'sort(0, topo, topo.firstbranch=(book1))'
2252 0 b12 m111 u112 111 10800
2252 0 b12 m111 u112 111 10800
2253
2253
2254 $ cd ..
2254 $ cd ..
2255 $ cd repo
2255 $ cd repo
2256
2256
2257 test subtracting something from an addset
2257 test subtracting something from an addset
2258
2258
2259 $ log '(outgoing() or removes(a)) - removes(a)'
2259 $ log '(outgoing() or removes(a)) - removes(a)'
2260 8
2260 8
2261 9
2261 9
2262
2262
2263 test intersecting something with an addset
2263 test intersecting something with an addset
2264
2264
2265 $ log 'parents(outgoing() or removes(a))'
2265 $ log 'parents(outgoing() or removes(a))'
2266 1
2266 1
2267 4
2267 4
2268 5
2268 5
2269 8
2269 8
2270
2270
2271 test that `or` operation combines elements in the right order:
2271 test that `or` operation combines elements in the right order:
2272
2272
2273 $ log '3:4 or 2:5'
2273 $ log '3:4 or 2:5'
2274 3
2274 3
2275 4
2275 4
2276 2
2276 2
2277 5
2277 5
2278 $ log '3:4 or 5:2'
2278 $ log '3:4 or 5:2'
2279 3
2279 3
2280 4
2280 4
2281 5
2281 5
2282 2
2282 2
2283 $ log 'sort(3:4 or 2:5)'
2283 $ log 'sort(3:4 or 2:5)'
2284 2
2284 2
2285 3
2285 3
2286 4
2286 4
2287 5
2287 5
2288 $ log 'sort(3:4 or 5:2)'
2288 $ log 'sort(3:4 or 5:2)'
2289 2
2289 2
2290 3
2290 3
2291 4
2291 4
2292 5
2292 5
2293
2293
2294 test that more than one `-r`s are combined in the right order and deduplicated:
2294 test that more than one `-r`s are combined in the right order and deduplicated:
2295
2295
2296 $ hg log -T '{rev}\n' -r 3 -r 3 -r 4 -r 5:2 -r 'ancestors(4)'
2296 $ hg log -T '{rev}\n' -r 3 -r 3 -r 4 -r 5:2 -r 'ancestors(4)'
2297 3
2297 3
2298 4
2298 4
2299 5
2299 5
2300 2
2300 2
2301 0
2301 0
2302 1
2302 1
2303
2303
2304 test that `or` operation skips duplicated revisions from right-hand side
2304 test that `or` operation skips duplicated revisions from right-hand side
2305
2305
2306 $ try 'reverse(1::5) or ancestors(4)'
2306 $ try 'reverse(1::5) or ancestors(4)'
2307 (or
2307 (or
2308 (list
2308 (list
2309 (func
2309 (func
2310 ('symbol', 'reverse')
2310 ('symbol', 'reverse')
2311 (dagrange
2311 (dagrange
2312 ('symbol', '1')
2312 ('symbol', '1')
2313 ('symbol', '5')))
2313 ('symbol', '5')))
2314 (func
2314 (func
2315 ('symbol', 'ancestors')
2315 ('symbol', 'ancestors')
2316 ('symbol', '4'))))
2316 ('symbol', '4'))))
2317 * set:
2317 * set:
2318 <addset
2318 <addset
2319 <baseset- [1, 3, 5]>,
2319 <baseset- [1, 3, 5]>,
2320 <generatorset+>>
2320 <generatorset+>>
2321 5
2321 5
2322 3
2322 3
2323 1
2323 1
2324 0
2324 0
2325 2
2325 2
2326 4
2326 4
2327 $ try 'sort(ancestors(4) or reverse(1::5))'
2327 $ try 'sort(ancestors(4) or reverse(1::5))'
2328 (func
2328 (func
2329 ('symbol', 'sort')
2329 ('symbol', 'sort')
2330 (or
2330 (or
2331 (list
2331 (list
2332 (func
2332 (func
2333 ('symbol', 'ancestors')
2333 ('symbol', 'ancestors')
2334 ('symbol', '4'))
2334 ('symbol', '4'))
2335 (func
2335 (func
2336 ('symbol', 'reverse')
2336 ('symbol', 'reverse')
2337 (dagrange
2337 (dagrange
2338 ('symbol', '1')
2338 ('symbol', '1')
2339 ('symbol', '5'))))))
2339 ('symbol', '5'))))))
2340 * set:
2340 * set:
2341 <addset+
2341 <addset+
2342 <generatorset+>,
2342 <generatorset+>,
2343 <baseset- [1, 3, 5]>>
2343 <baseset- [1, 3, 5]>>
2344 0
2344 0
2345 1
2345 1
2346 2
2346 2
2347 3
2347 3
2348 4
2348 4
2349 5
2349 5
2350
2350
2351 test optimization of trivial `or` operation
2351 test optimization of trivial `or` operation
2352
2352
2353 $ try --optimize '0|(1)|"2"|-2|tip|null'
2353 $ try --optimize '0|(1)|"2"|-2|tip|null'
2354 (or
2354 (or
2355 (list
2355 (list
2356 ('symbol', '0')
2356 ('symbol', '0')
2357 (group
2357 (group
2358 ('symbol', '1'))
2358 ('symbol', '1'))
2359 ('string', '2')
2359 ('string', '2')
2360 (negate
2360 (negate
2361 ('symbol', '2'))
2361 ('symbol', '2'))
2362 ('symbol', 'tip')
2362 ('symbol', 'tip')
2363 ('symbol', 'null')))
2363 ('symbol', 'null')))
2364 * optimized:
2364 * optimized:
2365 (func
2365 (func
2366 ('symbol', '_list')
2366 ('symbol', '_list')
2367 ('string', '0\x001\x002\x00-2\x00tip\x00null')
2367 ('string', '0\x001\x002\x00-2\x00tip\x00null')
2368 define)
2368 define)
2369 * set:
2369 * set:
2370 <baseset [0, 1, 2, 8, 9, -1]>
2370 <baseset [0, 1, 2, 8, 9, -1]>
2371 0
2371 0
2372 1
2372 1
2373 2
2373 2
2374 8
2374 8
2375 9
2375 9
2376 -1
2376 -1
2377
2377
2378 $ try --optimize '0|1|2:3'
2378 $ try --optimize '0|1|2:3'
2379 (or
2379 (or
2380 (list
2380 (list
2381 ('symbol', '0')
2381 ('symbol', '0')
2382 ('symbol', '1')
2382 ('symbol', '1')
2383 (range
2383 (range
2384 ('symbol', '2')
2384 ('symbol', '2')
2385 ('symbol', '3'))))
2385 ('symbol', '3'))))
2386 * optimized:
2386 * optimized:
2387 (or
2387 (or
2388 (list
2388 (list
2389 (func
2389 (func
2390 ('symbol', '_list')
2390 ('symbol', '_list')
2391 ('string', '0\x001')
2391 ('string', '0\x001')
2392 define)
2392 define)
2393 (range
2393 (range
2394 ('symbol', '2')
2394 ('symbol', '2')
2395 ('symbol', '3')
2395 ('symbol', '3')
2396 define))
2396 define))
2397 define)
2397 define)
2398 * set:
2398 * set:
2399 <addset
2399 <addset
2400 <baseset [0, 1]>,
2400 <baseset [0, 1]>,
2401 <spanset+ 2:3>>
2401 <spanset+ 2:3>>
2402 0
2402 0
2403 1
2403 1
2404 2
2404 2
2405 3
2405 3
2406
2406
2407 $ try --optimize '0:1|2|3:4|5|6'
2407 $ try --optimize '0:1|2|3:4|5|6'
2408 (or
2408 (or
2409 (list
2409 (list
2410 (range
2410 (range
2411 ('symbol', '0')
2411 ('symbol', '0')
2412 ('symbol', '1'))
2412 ('symbol', '1'))
2413 ('symbol', '2')
2413 ('symbol', '2')
2414 (range
2414 (range
2415 ('symbol', '3')
2415 ('symbol', '3')
2416 ('symbol', '4'))
2416 ('symbol', '4'))
2417 ('symbol', '5')
2417 ('symbol', '5')
2418 ('symbol', '6')))
2418 ('symbol', '6')))
2419 * optimized:
2419 * optimized:
2420 (or
2420 (or
2421 (list
2421 (list
2422 (range
2422 (range
2423 ('symbol', '0')
2423 ('symbol', '0')
2424 ('symbol', '1')
2424 ('symbol', '1')
2425 define)
2425 define)
2426 ('symbol', '2')
2426 ('symbol', '2')
2427 (range
2427 (range
2428 ('symbol', '3')
2428 ('symbol', '3')
2429 ('symbol', '4')
2429 ('symbol', '4')
2430 define)
2430 define)
2431 (func
2431 (func
2432 ('symbol', '_list')
2432 ('symbol', '_list')
2433 ('string', '5\x006')
2433 ('string', '5\x006')
2434 define))
2434 define))
2435 define)
2435 define)
2436 * set:
2436 * set:
2437 <addset
2437 <addset
2438 <addset
2438 <addset
2439 <spanset+ 0:1>,
2439 <spanset+ 0:1>,
2440 <baseset [2]>>,
2440 <baseset [2]>>,
2441 <addset
2441 <addset
2442 <spanset+ 3:4>,
2442 <spanset+ 3:4>,
2443 <baseset [5, 6]>>>
2443 <baseset [5, 6]>>>
2444 0
2444 0
2445 1
2445 1
2446 2
2446 2
2447 3
2447 3
2448 4
2448 4
2449 5
2449 5
2450 6
2450 6
2451
2451
2452 unoptimized `or` looks like this
2452 unoptimized `or` looks like this
2453
2453
2454 $ try --no-optimized -p analyzed '0|1|2|3|4'
2454 $ try --no-optimized -p analyzed '0|1|2|3|4'
2455 * analyzed:
2455 * analyzed:
2456 (or
2456 (or
2457 (list
2457 (list
2458 ('symbol', '0')
2458 ('symbol', '0')
2459 ('symbol', '1')
2459 ('symbol', '1')
2460 ('symbol', '2')
2460 ('symbol', '2')
2461 ('symbol', '3')
2461 ('symbol', '3')
2462 ('symbol', '4'))
2462 ('symbol', '4'))
2463 define)
2463 define)
2464 * set:
2464 * set:
2465 <addset
2465 <addset
2466 <addset
2466 <addset
2467 <baseset [0]>,
2467 <baseset [0]>,
2468 <baseset [1]>>,
2468 <baseset [1]>>,
2469 <addset
2469 <addset
2470 <baseset [2]>,
2470 <baseset [2]>,
2471 <addset
2471 <addset
2472 <baseset [3]>,
2472 <baseset [3]>,
2473 <baseset [4]>>>>
2473 <baseset [4]>>>>
2474 0
2474 0
2475 1
2475 1
2476 2
2476 2
2477 3
2477 3
2478 4
2478 4
2479
2479
2480 test that `_list` should be narrowed by provided `subset`
2480 test that `_list` should be narrowed by provided `subset`
2481
2481
2482 $ log '0:2 and (null|1|2|3)'
2482 $ log '0:2 and (null|1|2|3)'
2483 1
2483 1
2484 2
2484 2
2485
2485
2486 test that `_list` should remove duplicates
2486 test that `_list` should remove duplicates
2487
2487
2488 $ log '0|1|2|1|2|-1|tip'
2488 $ log '0|1|2|1|2|-1|tip'
2489 0
2489 0
2490 1
2490 1
2491 2
2491 2
2492 9
2492 9
2493
2493
2494 test unknown revision in `_list`
2494 test unknown revision in `_list`
2495
2495
2496 $ log '0|unknown'
2496 $ log '0|unknown'
2497 abort: unknown revision 'unknown'!
2497 abort: unknown revision 'unknown'!
2498 [255]
2498 [255]
2499
2499
2500 test integer range in `_list`
2500 test integer range in `_list`
2501
2501
2502 $ log '-1|-10'
2502 $ log '-1|-10'
2503 9
2503 9
2504 0
2504 0
2505
2505
2506 $ log '-10|-11'
2506 $ log '-10|-11'
2507 abort: unknown revision '-11'!
2507 abort: unknown revision '-11'!
2508 [255]
2508 [255]
2509
2509
2510 $ log '9|10'
2510 $ log '9|10'
2511 abort: unknown revision '10'!
2511 abort: unknown revision '10'!
2512 [255]
2512 [255]
2513
2513
2514 test '0000' != '0' in `_list`
2514 test '0000' != '0' in `_list`
2515
2515
2516 $ log '0|0000'
2516 $ log '0|0000'
2517 0
2517 0
2518 -1
2518 -1
2519
2519
2520 test ',' in `_list`
2520 test ',' in `_list`
2521 $ log '0,1'
2521 $ log '0,1'
2522 hg: parse error: can't use a list in this context
2522 hg: parse error: can't use a list in this context
2523 (see hg help "revsets.x or y")
2523 (see hg help "revsets.x or y")
2524 [255]
2524 [255]
2525 $ try '0,1,2'
2525 $ try '0,1,2'
2526 (list
2526 (list
2527 ('symbol', '0')
2527 ('symbol', '0')
2528 ('symbol', '1')
2528 ('symbol', '1')
2529 ('symbol', '2'))
2529 ('symbol', '2'))
2530 hg: parse error: can't use a list in this context
2530 hg: parse error: can't use a list in this context
2531 (see hg help "revsets.x or y")
2531 (see hg help "revsets.x or y")
2532 [255]
2532 [255]
2533
2533
2534 test that chained `or` operations make balanced addsets
2534 test that chained `or` operations make balanced addsets
2535
2535
2536 $ try '0:1|1:2|2:3|3:4|4:5'
2536 $ try '0:1|1:2|2:3|3:4|4:5'
2537 (or
2537 (or
2538 (list
2538 (list
2539 (range
2539 (range
2540 ('symbol', '0')
2540 ('symbol', '0')
2541 ('symbol', '1'))
2541 ('symbol', '1'))
2542 (range
2542 (range
2543 ('symbol', '1')
2543 ('symbol', '1')
2544 ('symbol', '2'))
2544 ('symbol', '2'))
2545 (range
2545 (range
2546 ('symbol', '2')
2546 ('symbol', '2')
2547 ('symbol', '3'))
2547 ('symbol', '3'))
2548 (range
2548 (range
2549 ('symbol', '3')
2549 ('symbol', '3')
2550 ('symbol', '4'))
2550 ('symbol', '4'))
2551 (range
2551 (range
2552 ('symbol', '4')
2552 ('symbol', '4')
2553 ('symbol', '5'))))
2553 ('symbol', '5'))))
2554 * set:
2554 * set:
2555 <addset
2555 <addset
2556 <addset
2556 <addset
2557 <spanset+ 0:1>,
2557 <spanset+ 0:1>,
2558 <spanset+ 1:2>>,
2558 <spanset+ 1:2>>,
2559 <addset
2559 <addset
2560 <spanset+ 2:3>,
2560 <spanset+ 2:3>,
2561 <addset
2561 <addset
2562 <spanset+ 3:4>,
2562 <spanset+ 3:4>,
2563 <spanset+ 4:5>>>>
2563 <spanset+ 4:5>>>>
2564 0
2564 0
2565 1
2565 1
2566 2
2566 2
2567 3
2567 3
2568 4
2568 4
2569 5
2569 5
2570
2570
2571 no crash by empty group "()" while optimizing `or` operations
2571 no crash by empty group "()" while optimizing `or` operations
2572
2572
2573 $ try --optimize '0|()'
2573 $ try --optimize '0|()'
2574 (or
2574 (or
2575 (list
2575 (list
2576 ('symbol', '0')
2576 ('symbol', '0')
2577 (group
2577 (group
2578 None)))
2578 None)))
2579 * optimized:
2579 * optimized:
2580 (or
2580 (or
2581 (list
2581 (list
2582 ('symbol', '0')
2582 ('symbol', '0')
2583 None)
2583 None)
2584 define)
2584 define)
2585 hg: parse error: missing argument
2585 hg: parse error: missing argument
2586 [255]
2586 [255]
2587
2587
2588 test that chained `or` operations never eat up stack (issue4624)
2588 test that chained `or` operations never eat up stack (issue4624)
2589 (uses `0:1` instead of `0` to avoid future optimization of trivial revisions)
2589 (uses `0:1` instead of `0` to avoid future optimization of trivial revisions)
2590
2590
2591 $ hg log -T '{rev}\n' -r `python -c "print '+'.join(['0:1'] * 500)"`
2591 $ hg log -T '{rev}\n' -r `python -c "print '+'.join(['0:1'] * 500)"`
2592 0
2592 0
2593 1
2593 1
2594
2594
2595 test that repeated `-r` options never eat up stack (issue4565)
2595 test that repeated `-r` options never eat up stack (issue4565)
2596 (uses `-r 0::1` to avoid possible optimization at old-style parser)
2596 (uses `-r 0::1` to avoid possible optimization at old-style parser)
2597
2597
2598 $ hg log -T '{rev}\n' `python -c "for i in xrange(500): print '-r 0::1 ',"`
2598 $ hg log -T '{rev}\n' `python -c "for i in xrange(500): print '-r 0::1 ',"`
2599 0
2599 0
2600 1
2600 1
2601
2601
2602 check that conversion to only works
2602 check that conversion to only works
2603 $ try --optimize '::3 - ::1'
2603 $ try --optimize '::3 - ::1'
2604 (minus
2604 (minus
2605 (dagrangepre
2605 (dagrangepre
2606 ('symbol', '3'))
2606 ('symbol', '3'))
2607 (dagrangepre
2607 (dagrangepre
2608 ('symbol', '1')))
2608 ('symbol', '1')))
2609 * optimized:
2609 * optimized:
2610 (func
2610 (func
2611 ('symbol', 'only')
2611 ('symbol', 'only')
2612 (list
2612 (list
2613 ('symbol', '3')
2613 ('symbol', '3')
2614 ('symbol', '1'))
2614 ('symbol', '1'))
2615 define)
2615 define)
2616 * set:
2616 * set:
2617 <baseset+ [3]>
2617 <baseset+ [3]>
2618 3
2618 3
2619 $ try --optimize 'ancestors(1) - ancestors(3)'
2619 $ try --optimize 'ancestors(1) - ancestors(3)'
2620 (minus
2620 (minus
2621 (func
2621 (func
2622 ('symbol', 'ancestors')
2622 ('symbol', 'ancestors')
2623 ('symbol', '1'))
2623 ('symbol', '1'))
2624 (func
2624 (func
2625 ('symbol', 'ancestors')
2625 ('symbol', 'ancestors')
2626 ('symbol', '3')))
2626 ('symbol', '3')))
2627 * optimized:
2627 * optimized:
2628 (func
2628 (func
2629 ('symbol', 'only')
2629 ('symbol', 'only')
2630 (list
2630 (list
2631 ('symbol', '1')
2631 ('symbol', '1')
2632 ('symbol', '3'))
2632 ('symbol', '3'))
2633 define)
2633 define)
2634 * set:
2634 * set:
2635 <baseset+ []>
2635 <baseset+ []>
2636 $ try --optimize 'not ::2 and ::6'
2636 $ try --optimize 'not ::2 and ::6'
2637 (and
2637 (and
2638 (not
2638 (not
2639 (dagrangepre
2639 (dagrangepre
2640 ('symbol', '2')))
2640 ('symbol', '2')))
2641 (dagrangepre
2641 (dagrangepre
2642 ('symbol', '6')))
2642 ('symbol', '6')))
2643 * optimized:
2643 * optimized:
2644 (func
2644 (func
2645 ('symbol', 'only')
2645 ('symbol', 'only')
2646 (list
2646 (list
2647 ('symbol', '6')
2647 ('symbol', '6')
2648 ('symbol', '2'))
2648 ('symbol', '2'))
2649 define)
2649 define)
2650 * set:
2650 * set:
2651 <baseset+ [3, 4, 5, 6]>
2651 <baseset+ [3, 4, 5, 6]>
2652 3
2652 3
2653 4
2653 4
2654 5
2654 5
2655 6
2655 6
2656 $ try --optimize 'ancestors(6) and not ancestors(4)'
2656 $ try --optimize 'ancestors(6) and not ancestors(4)'
2657 (and
2657 (and
2658 (func
2658 (func
2659 ('symbol', 'ancestors')
2659 ('symbol', 'ancestors')
2660 ('symbol', '6'))
2660 ('symbol', '6'))
2661 (not
2661 (not
2662 (func
2662 (func
2663 ('symbol', 'ancestors')
2663 ('symbol', 'ancestors')
2664 ('symbol', '4'))))
2664 ('symbol', '4'))))
2665 * optimized:
2665 * optimized:
2666 (func
2666 (func
2667 ('symbol', 'only')
2667 ('symbol', 'only')
2668 (list
2668 (list
2669 ('symbol', '6')
2669 ('symbol', '6')
2670 ('symbol', '4'))
2670 ('symbol', '4'))
2671 define)
2671 define)
2672 * set:
2672 * set:
2673 <baseset+ [3, 5, 6]>
2673 <baseset+ [3, 5, 6]>
2674 3
2674 3
2675 5
2675 5
2676 6
2676 6
2677
2677
2678 no crash by empty group "()" while optimizing to "only()"
2678 no crash by empty group "()" while optimizing to "only()"
2679
2679
2680 $ try --optimize '::1 and ()'
2680 $ try --optimize '::1 and ()'
2681 (and
2681 (and
2682 (dagrangepre
2682 (dagrangepre
2683 ('symbol', '1'))
2683 ('symbol', '1'))
2684 (group
2684 (group
2685 None))
2685 None))
2686 * optimized:
2686 * optimized:
2687 (and
2687 (and
2688 None
2688 None
2689 (func
2689 (func
2690 ('symbol', 'ancestors')
2690 ('symbol', 'ancestors')
2691 ('symbol', '1')
2691 ('symbol', '1')
2692 define)
2692 define)
2693 define)
2693 define)
2694 hg: parse error: missing argument
2694 hg: parse error: missing argument
2695 [255]
2695 [255]
2696
2696
2697 invalid function call should not be optimized to only()
2697 invalid function call should not be optimized to only()
2698
2698
2699 $ log '"ancestors"(6) and not ancestors(4)'
2699 $ log '"ancestors"(6) and not ancestors(4)'
2700 hg: parse error: not a symbol
2700 hg: parse error: not a symbol
2701 [255]
2701 [255]
2702
2702
2703 $ log 'ancestors(6) and not "ancestors"(4)'
2703 $ log 'ancestors(6) and not "ancestors"(4)'
2704 hg: parse error: not a symbol
2704 hg: parse error: not a symbol
2705 [255]
2705 [255]
2706
2706
2707 we can use patterns when searching for tags
2707 we can use patterns when searching for tags
2708
2708
2709 $ log 'tag("1..*")'
2709 $ log 'tag("1..*")'
2710 abort: tag '1..*' does not exist!
2710 abort: tag '1..*' does not exist!
2711 [255]
2711 [255]
2712 $ log 'tag("re:1..*")'
2712 $ log 'tag("re:1..*")'
2713 6
2713 6
2714 $ log 'tag("re:[0-9].[0-9]")'
2714 $ log 'tag("re:[0-9].[0-9]")'
2715 6
2715 6
2716 $ log 'tag("literal:1.0")'
2716 $ log 'tag("literal:1.0")'
2717 6
2717 6
2718 $ log 'tag("re:0..*")'
2718 $ log 'tag("re:0..*")'
2719
2719
2720 $ log 'tag(unknown)'
2720 $ log 'tag(unknown)'
2721 abort: tag 'unknown' does not exist!
2721 abort: tag 'unknown' does not exist!
2722 [255]
2722 [255]
2723 $ log 'tag("re:unknown")'
2723 $ log 'tag("re:unknown")'
2724 $ log 'present(tag("unknown"))'
2724 $ log 'present(tag("unknown"))'
2725 $ log 'present(tag("re:unknown"))'
2725 $ log 'present(tag("re:unknown"))'
2726 $ log 'branch(unknown)'
2726 $ log 'branch(unknown)'
2727 abort: unknown revision 'unknown'!
2727 abort: unknown revision 'unknown'!
2728 [255]
2728 [255]
2729 $ log 'branch("literal:unknown")'
2729 $ log 'branch("literal:unknown")'
2730 abort: branch 'unknown' does not exist!
2730 abort: branch 'unknown' does not exist!
2731 [255]
2731 [255]
2732 $ log 'branch("re:unknown")'
2732 $ log 'branch("re:unknown")'
2733 $ log 'present(branch("unknown"))'
2733 $ log 'present(branch("unknown"))'
2734 $ log 'present(branch("re:unknown"))'
2734 $ log 'present(branch("re:unknown"))'
2735 $ log 'user(bob)'
2735 $ log 'user(bob)'
2736 2
2736 2
2737
2737
2738 $ log '4::8'
2738 $ log '4::8'
2739 4
2739 4
2740 8
2740 8
2741 $ log '4:8'
2741 $ log '4:8'
2742 4
2742 4
2743 5
2743 5
2744 6
2744 6
2745 7
2745 7
2746 8
2746 8
2747
2747
2748 $ log 'sort(!merge() & (modifies(b) | user(bob) | keyword(bug) | keyword(issue) & 1::9), "-date")'
2748 $ log 'sort(!merge() & (modifies(b) | user(bob) | keyword(bug) | keyword(issue) & 1::9), "-date")'
2749 4
2749 4
2750 2
2750 2
2751 5
2751 5
2752
2752
2753 $ log 'not 0 and 0:2'
2753 $ log 'not 0 and 0:2'
2754 1
2754 1
2755 2
2755 2
2756 $ log 'not 1 and 0:2'
2756 $ log 'not 1 and 0:2'
2757 0
2757 0
2758 2
2758 2
2759 $ log 'not 2 and 0:2'
2759 $ log 'not 2 and 0:2'
2760 0
2760 0
2761 1
2761 1
2762 $ log '(1 and 2)::'
2762 $ log '(1 and 2)::'
2763 $ log '(1 and 2):'
2763 $ log '(1 and 2):'
2764 $ log '(1 and 2):3'
2764 $ log '(1 and 2):3'
2765 $ log 'sort(head(), -rev)'
2765 $ log 'sort(head(), -rev)'
2766 9
2766 9
2767 7
2767 7
2768 6
2768 6
2769 5
2769 5
2770 4
2770 4
2771 3
2771 3
2772 2
2772 2
2773 1
2773 1
2774 0
2774 0
2775 $ log '4::8 - 8'
2775 $ log '4::8 - 8'
2776 4
2776 4
2777
2777
2778 matching() should preserve the order of the input set:
2778 matching() should preserve the order of the input set:
2779
2779
2780 $ log '(2 or 3 or 1) and matching(1 or 2 or 3)'
2780 $ log '(2 or 3 or 1) and matching(1 or 2 or 3)'
2781 2
2781 2
2782 3
2782 3
2783 1
2783 1
2784
2784
2785 $ log 'named("unknown")'
2785 $ log 'named("unknown")'
2786 abort: namespace 'unknown' does not exist!
2786 abort: namespace 'unknown' does not exist!
2787 [255]
2787 [255]
2788 $ log 'named("re:unknown")'
2788 $ log 'named("re:unknown")'
2789 abort: no namespace exists that match 'unknown'!
2789 abort: no namespace exists that match 'unknown'!
2790 [255]
2790 [255]
2791 $ log 'present(named("unknown"))'
2791 $ log 'present(named("unknown"))'
2792 $ log 'present(named("re:unknown"))'
2792 $ log 'present(named("re:unknown"))'
2793
2793
2794 $ log 'tag()'
2794 $ log 'tag()'
2795 6
2795 6
2796 $ log 'named("tags")'
2796 $ log 'named("tags")'
2797 6
2797 6
2798
2798
2799 issue2437
2799 issue2437
2800
2800
2801 $ log '3 and p1(5)'
2801 $ log '3 and p1(5)'
2802 3
2802 3
2803 $ log '4 and p2(6)'
2803 $ log '4 and p2(6)'
2804 4
2804 4
2805 $ log '1 and parents(:2)'
2805 $ log '1 and parents(:2)'
2806 1
2806 1
2807 $ log '2 and children(1:)'
2807 $ log '2 and children(1:)'
2808 2
2808 2
2809 $ log 'roots(all()) or roots(all())'
2809 $ log 'roots(all()) or roots(all())'
2810 0
2810 0
2811 $ hg debugrevspec 'roots(all()) or roots(all())'
2811 $ hg debugrevspec 'roots(all()) or roots(all())'
2812 0
2812 0
2813 $ log 'heads(branch(Γ©)) or heads(branch(Γ©))'
2813 $ log 'heads(branch(Γ©)) or heads(branch(Γ©))'
2814 9
2814 9
2815 $ log 'ancestors(8) and (heads(branch("-a-b-c-")) or heads(branch(Γ©)))'
2815 $ log 'ancestors(8) and (heads(branch("-a-b-c-")) or heads(branch(Γ©)))'
2816 4
2816 4
2817
2817
2818 issue2654: report a parse error if the revset was not completely parsed
2818 issue2654: report a parse error if the revset was not completely parsed
2819
2819
2820 $ log '1 OR 2'
2820 $ log '1 OR 2'
2821 hg: parse error at 2: invalid token
2821 hg: parse error at 2: invalid token
2822 [255]
2822 [255]
2823
2823
2824 or operator should preserve ordering:
2824 or operator should preserve ordering:
2825 $ log 'reverse(2::4) or tip'
2825 $ log 'reverse(2::4) or tip'
2826 4
2826 4
2827 2
2827 2
2828 9
2828 9
2829
2829
2830 parentrevspec
2830 parentrevspec
2831
2831
2832 $ log 'merge()^0'
2832 $ log 'merge()^0'
2833 6
2833 6
2834 $ log 'merge()^'
2834 $ log 'merge()^'
2835 5
2835 5
2836 $ log 'merge()^1'
2836 $ log 'merge()^1'
2837 5
2837 5
2838 $ log 'merge()^2'
2838 $ log 'merge()^2'
2839 4
2839 4
2840 $ log '(not merge())^2'
2840 $ log '(not merge())^2'
2841 $ log 'merge()^^'
2841 $ log 'merge()^^'
2842 3
2842 3
2843 $ log 'merge()^1^'
2843 $ log 'merge()^1^'
2844 3
2844 3
2845 $ log 'merge()^^^'
2845 $ log 'merge()^^^'
2846 1
2846 1
2847
2847
2848 $ log 'merge()~0'
2848 $ log 'merge()~0'
2849 6
2849 6
2850 $ log 'merge()~1'
2850 $ log 'merge()~1'
2851 5
2851 5
2852 $ log 'merge()~2'
2852 $ log 'merge()~2'
2853 3
2853 3
2854 $ log 'merge()~2^1'
2854 $ log 'merge()~2^1'
2855 1
2855 1
2856 $ log 'merge()~3'
2856 $ log 'merge()~3'
2857 1
2857 1
2858
2858
2859 $ log '(-3:tip)^'
2859 $ log '(-3:tip)^'
2860 4
2860 4
2861 6
2861 6
2862 8
2862 8
2863
2863
2864 $ log 'tip^foo'
2864 $ log 'tip^foo'
2865 hg: parse error: ^ expects a number 0, 1, or 2
2865 hg: parse error: ^ expects a number 0, 1, or 2
2866 [255]
2866 [255]
2867
2867
2868 Bogus function gets suggestions
2868 Bogus function gets suggestions
2869 $ log 'add()'
2869 $ log 'add()'
2870 hg: parse error: unknown identifier: add
2870 hg: parse error: unknown identifier: add
2871 (did you mean adds?)
2871 (did you mean adds?)
2872 [255]
2872 [255]
2873 $ log 'added()'
2873 $ log 'added()'
2874 hg: parse error: unknown identifier: added
2874 hg: parse error: unknown identifier: added
2875 (did you mean adds?)
2875 (did you mean adds?)
2876 [255]
2876 [255]
2877 $ log 'remo()'
2877 $ log 'remo()'
2878 hg: parse error: unknown identifier: remo
2878 hg: parse error: unknown identifier: remo
2879 (did you mean one of remote, removes?)
2879 (did you mean one of remote, removes?)
2880 [255]
2880 [255]
2881 $ log 'babar()'
2881 $ log 'babar()'
2882 hg: parse error: unknown identifier: babar
2882 hg: parse error: unknown identifier: babar
2883 [255]
2883 [255]
2884
2884
2885 Bogus function with a similar internal name doesn't suggest the internal name
2885 Bogus function with a similar internal name doesn't suggest the internal name
2886 $ log 'matches()'
2886 $ log 'matches()'
2887 hg: parse error: unknown identifier: matches
2887 hg: parse error: unknown identifier: matches
2888 (did you mean matching?)
2888 (did you mean matching?)
2889 [255]
2889 [255]
2890
2890
2891 Undocumented functions aren't suggested as similar either
2891 Undocumented functions aren't suggested as similar either
2892 $ log 'tagged2()'
2892 $ log 'tagged2()'
2893 hg: parse error: unknown identifier: tagged2
2893 hg: parse error: unknown identifier: tagged2
2894 [255]
2894 [255]
2895
2895
2896 multiple revspecs
2896 multiple revspecs
2897
2897
2898 $ hg log -r 'tip~1:tip' -r 'tip~2:tip~1' --template '{rev}\n'
2898 $ hg log -r 'tip~1:tip' -r 'tip~2:tip~1' --template '{rev}\n'
2899 8
2899 8
2900 9
2900 9
2901 4
2901 4
2902 5
2902 5
2903 6
2903 6
2904 7
2904 7
2905
2905
2906 test usage in revpair (with "+")
2906 test usage in revpair (with "+")
2907
2907
2908 (real pair)
2908 (real pair)
2909
2909
2910 $ hg diff -r 'tip^^' -r 'tip'
2910 $ hg diff -r 'tip^^' -r 'tip'
2911 diff -r 2326846efdab -r 24286f4ae135 .hgtags
2911 diff -r 2326846efdab -r 24286f4ae135 .hgtags
2912 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2912 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2913 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2913 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2914 @@ -0,0 +1,1 @@
2914 @@ -0,0 +1,1 @@
2915 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2915 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2916 $ hg diff -r 'tip^^::tip'
2916 $ hg diff -r 'tip^^::tip'
2917 diff -r 2326846efdab -r 24286f4ae135 .hgtags
2917 diff -r 2326846efdab -r 24286f4ae135 .hgtags
2918 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2918 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2919 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2919 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2920 @@ -0,0 +1,1 @@
2920 @@ -0,0 +1,1 @@
2921 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2921 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2922
2922
2923 (single rev)
2923 (single rev)
2924
2924
2925 $ hg diff -r 'tip^' -r 'tip^'
2925 $ hg diff -r 'tip^' -r 'tip^'
2926 $ hg diff -r 'tip^:tip^'
2926 $ hg diff -r 'tip^:tip^'
2927
2927
2928 (single rev that does not looks like a range)
2928 (single rev that does not looks like a range)
2929
2929
2930 $ hg diff -r 'tip^::tip^ or tip^'
2930 $ hg diff -r 'tip^::tip^ or tip^'
2931 diff -r d5d0dcbdc4d9 .hgtags
2931 diff -r d5d0dcbdc4d9 .hgtags
2932 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2932 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2933 +++ b/.hgtags * (glob)
2933 +++ b/.hgtags * (glob)
2934 @@ -0,0 +1,1 @@
2934 @@ -0,0 +1,1 @@
2935 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2935 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2936 $ hg diff -r 'tip^ or tip^'
2936 $ hg diff -r 'tip^ or tip^'
2937 diff -r d5d0dcbdc4d9 .hgtags
2937 diff -r d5d0dcbdc4d9 .hgtags
2938 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2938 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2939 +++ b/.hgtags * (glob)
2939 +++ b/.hgtags * (glob)
2940 @@ -0,0 +1,1 @@
2940 @@ -0,0 +1,1 @@
2941 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2941 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2942
2942
2943 (no rev)
2943 (no rev)
2944
2944
2945 $ hg diff -r 'author("babar") or author("celeste")'
2945 $ hg diff -r 'author("babar") or author("celeste")'
2946 abort: empty revision range
2946 abort: empty revision range
2947 [255]
2947 [255]
2948
2948
2949 aliases:
2949 aliases:
2950
2950
2951 $ echo '[revsetalias]' >> .hg/hgrc
2951 $ echo '[revsetalias]' >> .hg/hgrc
2952 $ echo 'm = merge()' >> .hg/hgrc
2952 $ echo 'm = merge()' >> .hg/hgrc
2953 (revset aliases can override builtin revsets)
2953 (revset aliases can override builtin revsets)
2954 $ echo 'p2($1) = p1($1)' >> .hg/hgrc
2954 $ echo 'p2($1) = p1($1)' >> .hg/hgrc
2955 $ echo 'sincem = descendants(m)' >> .hg/hgrc
2955 $ echo 'sincem = descendants(m)' >> .hg/hgrc
2956 $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
2956 $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
2957 $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
2957 $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
2958 $ echo 'rs4(ARG1, ARGA, ARGB, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
2958 $ echo 'rs4(ARG1, ARGA, ARGB, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
2959
2959
2960 $ try m
2960 $ try m
2961 ('symbol', 'm')
2961 ('symbol', 'm')
2962 * expanded:
2962 * expanded:
2963 (func
2963 (func
2964 ('symbol', 'merge')
2964 ('symbol', 'merge')
2965 None)
2965 None)
2966 * set:
2966 * set:
2967 <filteredset
2967 <filteredset
2968 <fullreposet+ 0:9>,
2968 <fullreposet+ 0:9>,
2969 <merge>>
2969 <merge>>
2970 6
2970 6
2971
2971
2972 $ HGPLAIN=1
2972 $ HGPLAIN=1
2973 $ export HGPLAIN
2973 $ export HGPLAIN
2974 $ try m
2974 $ try m
2975 ('symbol', 'm')
2975 ('symbol', 'm')
2976 abort: unknown revision 'm'!
2976 abort: unknown revision 'm'!
2977 [255]
2977 [255]
2978
2978
2979 $ HGPLAINEXCEPT=revsetalias
2979 $ HGPLAINEXCEPT=revsetalias
2980 $ export HGPLAINEXCEPT
2980 $ export HGPLAINEXCEPT
2981 $ try m
2981 $ try m
2982 ('symbol', 'm')
2982 ('symbol', 'm')
2983 * expanded:
2983 * expanded:
2984 (func
2984 (func
2985 ('symbol', 'merge')
2985 ('symbol', 'merge')
2986 None)
2986 None)
2987 * set:
2987 * set:
2988 <filteredset
2988 <filteredset
2989 <fullreposet+ 0:9>,
2989 <fullreposet+ 0:9>,
2990 <merge>>
2990 <merge>>
2991 6
2991 6
2992
2992
2993 $ unset HGPLAIN
2993 $ unset HGPLAIN
2994 $ unset HGPLAINEXCEPT
2994 $ unset HGPLAINEXCEPT
2995
2995
2996 $ try 'p2(.)'
2996 $ try 'p2(.)'
2997 (func
2997 (func
2998 ('symbol', 'p2')
2998 ('symbol', 'p2')
2999 ('symbol', '.'))
2999 ('symbol', '.'))
3000 * expanded:
3000 * expanded:
3001 (func
3001 (func
3002 ('symbol', 'p1')
3002 ('symbol', 'p1')
3003 ('symbol', '.'))
3003 ('symbol', '.'))
3004 * set:
3004 * set:
3005 <baseset+ [8]>
3005 <baseset+ [8]>
3006 8
3006 8
3007
3007
3008 $ HGPLAIN=1
3008 $ HGPLAIN=1
3009 $ export HGPLAIN
3009 $ export HGPLAIN
3010 $ try 'p2(.)'
3010 $ try 'p2(.)'
3011 (func
3011 (func
3012 ('symbol', 'p2')
3012 ('symbol', 'p2')
3013 ('symbol', '.'))
3013 ('symbol', '.'))
3014 * set:
3014 * set:
3015 <baseset+ []>
3015 <baseset+ []>
3016
3016
3017 $ HGPLAINEXCEPT=revsetalias
3017 $ HGPLAINEXCEPT=revsetalias
3018 $ export HGPLAINEXCEPT
3018 $ export HGPLAINEXCEPT
3019 $ try 'p2(.)'
3019 $ try 'p2(.)'
3020 (func
3020 (func
3021 ('symbol', 'p2')
3021 ('symbol', 'p2')
3022 ('symbol', '.'))
3022 ('symbol', '.'))
3023 * expanded:
3023 * expanded:
3024 (func
3024 (func
3025 ('symbol', 'p1')
3025 ('symbol', 'p1')
3026 ('symbol', '.'))
3026 ('symbol', '.'))
3027 * set:
3027 * set:
3028 <baseset+ [8]>
3028 <baseset+ [8]>
3029 8
3029 8
3030
3030
3031 $ unset HGPLAIN
3031 $ unset HGPLAIN
3032 $ unset HGPLAINEXCEPT
3032 $ unset HGPLAINEXCEPT
3033
3033
3034 test alias recursion
3034 test alias recursion
3035
3035
3036 $ try sincem
3036 $ try sincem
3037 ('symbol', 'sincem')
3037 ('symbol', 'sincem')
3038 * expanded:
3038 * expanded:
3039 (func
3039 (func
3040 ('symbol', 'descendants')
3040 ('symbol', 'descendants')
3041 (func
3041 (func
3042 ('symbol', 'merge')
3042 ('symbol', 'merge')
3043 None))
3043 None))
3044 * set:
3044 * set:
3045 <addset+
3045 <addset+
3046 <filteredset
3046 <filteredset
3047 <fullreposet+ 0:9>,
3047 <fullreposet+ 0:9>,
3048 <merge>>,
3048 <merge>>,
3049 <generatorset+>>
3049 <generatorset+>>
3050 6
3050 6
3051 7
3051 7
3052
3052
3053 test infinite recursion
3053 test infinite recursion
3054
3054
3055 $ echo 'recurse1 = recurse2' >> .hg/hgrc
3055 $ echo 'recurse1 = recurse2' >> .hg/hgrc
3056 $ echo 'recurse2 = recurse1' >> .hg/hgrc
3056 $ echo 'recurse2 = recurse1' >> .hg/hgrc
3057 $ try recurse1
3057 $ try recurse1
3058 ('symbol', 'recurse1')
3058 ('symbol', 'recurse1')
3059 hg: parse error: infinite expansion of revset alias "recurse1" detected
3059 hg: parse error: infinite expansion of revset alias "recurse1" detected
3060 [255]
3060 [255]
3061
3061
3062 $ echo 'level1($1, $2) = $1 or $2' >> .hg/hgrc
3062 $ echo 'level1($1, $2) = $1 or $2' >> .hg/hgrc
3063 $ echo 'level2($1, $2) = level1($2, $1)' >> .hg/hgrc
3063 $ echo 'level2($1, $2) = level1($2, $1)' >> .hg/hgrc
3064 $ try "level2(level1(1, 2), 3)"
3064 $ try "level2(level1(1, 2), 3)"
3065 (func
3065 (func
3066 ('symbol', 'level2')
3066 ('symbol', 'level2')
3067 (list
3067 (list
3068 (func
3068 (func
3069 ('symbol', 'level1')
3069 ('symbol', 'level1')
3070 (list
3070 (list
3071 ('symbol', '1')
3071 ('symbol', '1')
3072 ('symbol', '2')))
3072 ('symbol', '2')))
3073 ('symbol', '3')))
3073 ('symbol', '3')))
3074 * expanded:
3074 * expanded:
3075 (or
3075 (or
3076 (list
3076 (list
3077 ('symbol', '3')
3077 ('symbol', '3')
3078 (or
3078 (or
3079 (list
3079 (list
3080 ('symbol', '1')
3080 ('symbol', '1')
3081 ('symbol', '2')))))
3081 ('symbol', '2')))))
3082 * set:
3082 * set:
3083 <addset
3083 <addset
3084 <baseset [3]>,
3084 <baseset [3]>,
3085 <baseset [1, 2]>>
3085 <baseset [1, 2]>>
3086 3
3086 3
3087 1
3087 1
3088 2
3088 2
3089
3089
3090 test nesting and variable passing
3090 test nesting and variable passing
3091
3091
3092 $ echo 'nested($1) = nested2($1)' >> .hg/hgrc
3092 $ echo 'nested($1) = nested2($1)' >> .hg/hgrc
3093 $ echo 'nested2($1) = nested3($1)' >> .hg/hgrc
3093 $ echo 'nested2($1) = nested3($1)' >> .hg/hgrc
3094 $ echo 'nested3($1) = max($1)' >> .hg/hgrc
3094 $ echo 'nested3($1) = max($1)' >> .hg/hgrc
3095 $ try 'nested(2:5)'
3095 $ try 'nested(2:5)'
3096 (func
3096 (func
3097 ('symbol', 'nested')
3097 ('symbol', 'nested')
3098 (range
3098 (range
3099 ('symbol', '2')
3099 ('symbol', '2')
3100 ('symbol', '5')))
3100 ('symbol', '5')))
3101 * expanded:
3101 * expanded:
3102 (func
3102 (func
3103 ('symbol', 'max')
3103 ('symbol', 'max')
3104 (range
3104 (range
3105 ('symbol', '2')
3105 ('symbol', '2')
3106 ('symbol', '5')))
3106 ('symbol', '5')))
3107 * set:
3107 * set:
3108 <baseset
3108 <baseset
3109 <max
3109 <max
3110 <fullreposet+ 0:9>,
3110 <fullreposet+ 0:9>,
3111 <spanset+ 2:5>>>
3111 <spanset+ 2:5>>>
3112 5
3112 5
3113
3113
3114 test chained `or` operations are flattened at parsing phase
3114 test chained `or` operations are flattened at parsing phase
3115
3115
3116 $ echo 'chainedorops($1, $2, $3) = $1|$2|$3' >> .hg/hgrc
3116 $ echo 'chainedorops($1, $2, $3) = $1|$2|$3' >> .hg/hgrc
3117 $ try 'chainedorops(0:1, 1:2, 2:3)'
3117 $ try 'chainedorops(0:1, 1:2, 2:3)'
3118 (func
3118 (func
3119 ('symbol', 'chainedorops')
3119 ('symbol', 'chainedorops')
3120 (list
3120 (list
3121 (range
3121 (range
3122 ('symbol', '0')
3122 ('symbol', '0')
3123 ('symbol', '1'))
3123 ('symbol', '1'))
3124 (range
3124 (range
3125 ('symbol', '1')
3125 ('symbol', '1')
3126 ('symbol', '2'))
3126 ('symbol', '2'))
3127 (range
3127 (range
3128 ('symbol', '2')
3128 ('symbol', '2')
3129 ('symbol', '3'))))
3129 ('symbol', '3'))))
3130 * expanded:
3130 * expanded:
3131 (or
3131 (or
3132 (list
3132 (list
3133 (range
3133 (range
3134 ('symbol', '0')
3134 ('symbol', '0')
3135 ('symbol', '1'))
3135 ('symbol', '1'))
3136 (range
3136 (range
3137 ('symbol', '1')
3137 ('symbol', '1')
3138 ('symbol', '2'))
3138 ('symbol', '2'))
3139 (range
3139 (range
3140 ('symbol', '2')
3140 ('symbol', '2')
3141 ('symbol', '3'))))
3141 ('symbol', '3'))))
3142 * set:
3142 * set:
3143 <addset
3143 <addset
3144 <spanset+ 0:1>,
3144 <spanset+ 0:1>,
3145 <addset
3145 <addset
3146 <spanset+ 1:2>,
3146 <spanset+ 1:2>,
3147 <spanset+ 2:3>>>
3147 <spanset+ 2:3>>>
3148 0
3148 0
3149 1
3149 1
3150 2
3150 2
3151 3
3151 3
3152
3152
3153 test variable isolation, variable placeholders are rewritten as string
3153 test variable isolation, variable placeholders are rewritten as string
3154 then parsed and matched again as string. Check they do not leak too
3154 then parsed and matched again as string. Check they do not leak too
3155 far away.
3155 far away.
3156
3156
3157 $ echo 'injectparamasstring = max("$1")' >> .hg/hgrc
3157 $ echo 'injectparamasstring = max("$1")' >> .hg/hgrc
3158 $ echo 'callinjection($1) = descendants(injectparamasstring)' >> .hg/hgrc
3158 $ echo 'callinjection($1) = descendants(injectparamasstring)' >> .hg/hgrc
3159 $ try 'callinjection(2:5)'
3159 $ try 'callinjection(2:5)'
3160 (func
3160 (func
3161 ('symbol', 'callinjection')
3161 ('symbol', 'callinjection')
3162 (range
3162 (range
3163 ('symbol', '2')
3163 ('symbol', '2')
3164 ('symbol', '5')))
3164 ('symbol', '5')))
3165 * expanded:
3165 * expanded:
3166 (func
3166 (func
3167 ('symbol', 'descendants')
3167 ('symbol', 'descendants')
3168 (func
3168 (func
3169 ('symbol', 'max')
3169 ('symbol', 'max')
3170 ('string', '$1')))
3170 ('string', '$1')))
3171 abort: unknown revision '$1'!
3171 abort: unknown revision '$1'!
3172 [255]
3172 [255]
3173
3173
3174 test scope of alias expansion: 'universe' is expanded prior to 'shadowall(0)',
3174 test scope of alias expansion: 'universe' is expanded prior to 'shadowall(0)',
3175 but 'all()' should never be substituted to '0()'.
3175 but 'all()' should never be substituted to '0()'.
3176
3176
3177 $ echo 'universe = all()' >> .hg/hgrc
3177 $ echo 'universe = all()' >> .hg/hgrc
3178 $ echo 'shadowall(all) = all and universe' >> .hg/hgrc
3178 $ echo 'shadowall(all) = all and universe' >> .hg/hgrc
3179 $ try 'shadowall(0)'
3179 $ try 'shadowall(0)'
3180 (func
3180 (func
3181 ('symbol', 'shadowall')
3181 ('symbol', 'shadowall')
3182 ('symbol', '0'))
3182 ('symbol', '0'))
3183 * expanded:
3183 * expanded:
3184 (and
3184 (and
3185 ('symbol', '0')
3185 ('symbol', '0')
3186 (func
3186 (func
3187 ('symbol', 'all')
3187 ('symbol', 'all')
3188 None))
3188 None))
3189 * set:
3189 * set:
3190 <filteredset
3190 <filteredset
3191 <baseset [0]>,
3191 <baseset [0]>,
3192 <spanset+ 0:9>>
3192 <spanset+ 0:9>>
3193 0
3193 0
3194
3194
3195 test unknown reference:
3195 test unknown reference:
3196
3196
3197 $ try "unknownref(0)" --config 'revsetalias.unknownref($1)=$1:$2'
3197 $ try "unknownref(0)" --config 'revsetalias.unknownref($1)=$1:$2'
3198 (func
3198 (func
3199 ('symbol', 'unknownref')
3199 ('symbol', 'unknownref')
3200 ('symbol', '0'))
3200 ('symbol', '0'))
3201 abort: bad definition of revset alias "unknownref": invalid symbol '$2'
3201 abort: bad definition of revset alias "unknownref": invalid symbol '$2'
3202 [255]
3202 [255]
3203
3203
3204 $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
3204 $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
3205 ('symbol', 'tip')
3205 ('symbol', 'tip')
3206 warning: bad definition of revset alias "anotherbadone": at 7: not a prefix: end
3206 warning: bad definition of revset alias "anotherbadone": at 7: not a prefix: end
3207 * set:
3207 * set:
3208 <baseset [9]>
3208 <baseset [9]>
3209 9
3209 9
3210
3210
3211 $ try 'tip'
3211 $ try 'tip'
3212 ('symbol', 'tip')
3212 ('symbol', 'tip')
3213 * set:
3213 * set:
3214 <baseset [9]>
3214 <baseset [9]>
3215 9
3215 9
3216
3216
3217 $ hg debugrevspec --debug --config revsetalias.'bad name'='tip' "tip"
3217 $ hg debugrevspec --debug --config revsetalias.'bad name'='tip' "tip"
3218 ('symbol', 'tip')
3218 ('symbol', 'tip')
3219 warning: bad declaration of revset alias "bad name": at 4: invalid token
3219 warning: bad declaration of revset alias "bad name": at 4: invalid token
3220 * set:
3220 * set:
3221 <baseset [9]>
3221 <baseset [9]>
3222 9
3222 9
3223 $ echo 'strictreplacing($1, $10) = $10 or desc("$1")' >> .hg/hgrc
3223 $ echo 'strictreplacing($1, $10) = $10 or desc("$1")' >> .hg/hgrc
3224 $ try 'strictreplacing("foo", tip)'
3224 $ try 'strictreplacing("foo", tip)'
3225 (func
3225 (func
3226 ('symbol', 'strictreplacing')
3226 ('symbol', 'strictreplacing')
3227 (list
3227 (list
3228 ('string', 'foo')
3228 ('string', 'foo')
3229 ('symbol', 'tip')))
3229 ('symbol', 'tip')))
3230 * expanded:
3230 * expanded:
3231 (or
3231 (or
3232 (list
3232 (list
3233 ('symbol', 'tip')
3233 ('symbol', 'tip')
3234 (func
3234 (func
3235 ('symbol', 'desc')
3235 ('symbol', 'desc')
3236 ('string', '$1'))))
3236 ('string', '$1'))))
3237 * set:
3237 * set:
3238 <addset
3238 <addset
3239 <baseset [9]>,
3239 <baseset [9]>,
3240 <filteredset
3240 <filteredset
3241 <fullreposet+ 0:9>,
3241 <fullreposet+ 0:9>,
3242 <desc '$1'>>>
3242 <desc '$1'>>>
3243 9
3243 9
3244
3244
3245 $ try 'd(2:5)'
3245 $ try 'd(2:5)'
3246 (func
3246 (func
3247 ('symbol', 'd')
3247 ('symbol', 'd')
3248 (range
3248 (range
3249 ('symbol', '2')
3249 ('symbol', '2')
3250 ('symbol', '5')))
3250 ('symbol', '5')))
3251 * expanded:
3251 * expanded:
3252 (func
3252 (func
3253 ('symbol', 'reverse')
3253 ('symbol', 'reverse')
3254 (func
3254 (func
3255 ('symbol', 'sort')
3255 ('symbol', 'sort')
3256 (list
3256 (list
3257 (range
3257 (range
3258 ('symbol', '2')
3258 ('symbol', '2')
3259 ('symbol', '5'))
3259 ('symbol', '5'))
3260 ('symbol', 'date'))))
3260 ('symbol', 'date'))))
3261 * set:
3261 * set:
3262 <baseset [4, 5, 3, 2]>
3262 <baseset [4, 5, 3, 2]>
3263 4
3263 4
3264 5
3264 5
3265 3
3265 3
3266 2
3266 2
3267 $ try 'rs(2 or 3, date)'
3267 $ try 'rs(2 or 3, date)'
3268 (func
3268 (func
3269 ('symbol', 'rs')
3269 ('symbol', 'rs')
3270 (list
3270 (list
3271 (or
3271 (or
3272 (list
3272 (list
3273 ('symbol', '2')
3273 ('symbol', '2')
3274 ('symbol', '3')))
3274 ('symbol', '3')))
3275 ('symbol', 'date')))
3275 ('symbol', 'date')))
3276 * expanded:
3276 * expanded:
3277 (func
3277 (func
3278 ('symbol', 'reverse')
3278 ('symbol', 'reverse')
3279 (func
3279 (func
3280 ('symbol', 'sort')
3280 ('symbol', 'sort')
3281 (list
3281 (list
3282 (or
3282 (or
3283 (list
3283 (list
3284 ('symbol', '2')
3284 ('symbol', '2')
3285 ('symbol', '3')))
3285 ('symbol', '3')))
3286 ('symbol', 'date'))))
3286 ('symbol', 'date'))))
3287 * set:
3287 * set:
3288 <baseset [3, 2]>
3288 <baseset [3, 2]>
3289 3
3289 3
3290 2
3290 2
3291 $ try 'rs()'
3291 $ try 'rs()'
3292 (func
3292 (func
3293 ('symbol', 'rs')
3293 ('symbol', 'rs')
3294 None)
3294 None)
3295 hg: parse error: invalid number of arguments: 0
3295 hg: parse error: invalid number of arguments: 0
3296 [255]
3296 [255]
3297 $ try 'rs(2)'
3297 $ try 'rs(2)'
3298 (func
3298 (func
3299 ('symbol', 'rs')
3299 ('symbol', 'rs')
3300 ('symbol', '2'))
3300 ('symbol', '2'))
3301 hg: parse error: invalid number of arguments: 1
3301 hg: parse error: invalid number of arguments: 1
3302 [255]
3302 [255]
3303 $ try 'rs(2, data, 7)'
3303 $ try 'rs(2, data, 7)'
3304 (func
3304 (func
3305 ('symbol', 'rs')
3305 ('symbol', 'rs')
3306 (list
3306 (list
3307 ('symbol', '2')
3307 ('symbol', '2')
3308 ('symbol', 'data')
3308 ('symbol', 'data')
3309 ('symbol', '7')))
3309 ('symbol', '7')))
3310 hg: parse error: invalid number of arguments: 3
3310 hg: parse error: invalid number of arguments: 3
3311 [255]
3311 [255]
3312 $ try 'rs4(2 or 3, x, x, date)'
3312 $ try 'rs4(2 or 3, x, x, date)'
3313 (func
3313 (func
3314 ('symbol', 'rs4')
3314 ('symbol', 'rs4')
3315 (list
3315 (list
3316 (or
3316 (or
3317 (list
3317 (list
3318 ('symbol', '2')
3318 ('symbol', '2')
3319 ('symbol', '3')))
3319 ('symbol', '3')))
3320 ('symbol', 'x')
3320 ('symbol', 'x')
3321 ('symbol', 'x')
3321 ('symbol', 'x')
3322 ('symbol', 'date')))
3322 ('symbol', 'date')))
3323 * expanded:
3323 * expanded:
3324 (func
3324 (func
3325 ('symbol', 'reverse')
3325 ('symbol', 'reverse')
3326 (func
3326 (func
3327 ('symbol', 'sort')
3327 ('symbol', 'sort')
3328 (list
3328 (list
3329 (or
3329 (or
3330 (list
3330 (list
3331 ('symbol', '2')
3331 ('symbol', '2')
3332 ('symbol', '3')))
3332 ('symbol', '3')))
3333 ('symbol', 'date'))))
3333 ('symbol', 'date'))))
3334 * set:
3334 * set:
3335 <baseset [3, 2]>
3335 <baseset [3, 2]>
3336 3
3336 3
3337 2
3337 2
3338
3338
3339 issue4553: check that revset aliases override existing hash prefix
3339 issue4553: check that revset aliases override existing hash prefix
3340
3340
3341 $ hg log -qr e
3341 $ hg log -qr e
3342 6:e0cc66ef77e8
3342 6:e0cc66ef77e8
3343
3343
3344 $ hg log -qr e --config revsetalias.e="all()"
3344 $ hg log -qr e --config revsetalias.e="all()"
3345 0:2785f51eece5
3345 0:2785f51eece5
3346 1:d75937da8da0
3346 1:d75937da8da0
3347 2:5ed5505e9f1c
3347 2:5ed5505e9f1c
3348 3:8528aa5637f2
3348 3:8528aa5637f2
3349 4:2326846efdab
3349 4:2326846efdab
3350 5:904fa392b941
3350 5:904fa392b941
3351 6:e0cc66ef77e8
3351 6:e0cc66ef77e8
3352 7:013af1973af4
3352 7:013af1973af4
3353 8:d5d0dcbdc4d9
3353 8:d5d0dcbdc4d9
3354 9:24286f4ae135
3354 9:24286f4ae135
3355
3355
3356 $ hg log -qr e: --config revsetalias.e="0"
3356 $ hg log -qr e: --config revsetalias.e="0"
3357 0:2785f51eece5
3357 0:2785f51eece5
3358 1:d75937da8da0
3358 1:d75937da8da0
3359 2:5ed5505e9f1c
3359 2:5ed5505e9f1c
3360 3:8528aa5637f2
3360 3:8528aa5637f2
3361 4:2326846efdab
3361 4:2326846efdab
3362 5:904fa392b941
3362 5:904fa392b941
3363 6:e0cc66ef77e8
3363 6:e0cc66ef77e8
3364 7:013af1973af4
3364 7:013af1973af4
3365 8:d5d0dcbdc4d9
3365 8:d5d0dcbdc4d9
3366 9:24286f4ae135
3366 9:24286f4ae135
3367
3367
3368 $ hg log -qr :e --config revsetalias.e="9"
3368 $ hg log -qr :e --config revsetalias.e="9"
3369 0:2785f51eece5
3369 0:2785f51eece5
3370 1:d75937da8da0
3370 1:d75937da8da0
3371 2:5ed5505e9f1c
3371 2:5ed5505e9f1c
3372 3:8528aa5637f2
3372 3:8528aa5637f2
3373 4:2326846efdab
3373 4:2326846efdab
3374 5:904fa392b941
3374 5:904fa392b941
3375 6:e0cc66ef77e8
3375 6:e0cc66ef77e8
3376 7:013af1973af4
3376 7:013af1973af4
3377 8:d5d0dcbdc4d9
3377 8:d5d0dcbdc4d9
3378 9:24286f4ae135
3378 9:24286f4ae135
3379
3379
3380 $ hg log -qr e:
3380 $ hg log -qr e:
3381 6:e0cc66ef77e8
3381 6:e0cc66ef77e8
3382 7:013af1973af4
3382 7:013af1973af4
3383 8:d5d0dcbdc4d9
3383 8:d5d0dcbdc4d9
3384 9:24286f4ae135
3384 9:24286f4ae135
3385
3385
3386 $ hg log -qr :e
3386 $ hg log -qr :e
3387 0:2785f51eece5
3387 0:2785f51eece5
3388 1:d75937da8da0
3388 1:d75937da8da0
3389 2:5ed5505e9f1c
3389 2:5ed5505e9f1c
3390 3:8528aa5637f2
3390 3:8528aa5637f2
3391 4:2326846efdab
3391 4:2326846efdab
3392 5:904fa392b941
3392 5:904fa392b941
3393 6:e0cc66ef77e8
3393 6:e0cc66ef77e8
3394
3394
3395 issue2549 - correct optimizations
3395 issue2549 - correct optimizations
3396
3396
3397 $ try 'limit(1 or 2 or 3, 2) and not 2'
3397 $ try 'limit(1 or 2 or 3, 2) and not 2'
3398 (and
3398 (and
3399 (func
3399 (func
3400 ('symbol', 'limit')
3400 ('symbol', 'limit')
3401 (list
3401 (list
3402 (or
3402 (or
3403 (list
3403 (list
3404 ('symbol', '1')
3404 ('symbol', '1')
3405 ('symbol', '2')
3405 ('symbol', '2')
3406 ('symbol', '3')))
3406 ('symbol', '3')))
3407 ('symbol', '2')))
3407 ('symbol', '2')))
3408 (not
3408 (not
3409 ('symbol', '2')))
3409 ('symbol', '2')))
3410 * set:
3410 * set:
3411 <filteredset
3411 <filteredset
3412 <baseset
3412 <baseset
3413 <limit n=2, offset=0,
3413 <limit n=2, offset=0,
3414 <fullreposet+ 0:9>,
3414 <fullreposet+ 0:9>,
3415 <baseset [1, 2, 3]>>>,
3415 <baseset [1, 2, 3]>>>,
3416 <not
3416 <not
3417 <baseset [2]>>>
3417 <baseset [2]>>>
3418 1
3418 1
3419 $ try 'max(1 or 2) and not 2'
3419 $ try 'max(1 or 2) and not 2'
3420 (and
3420 (and
3421 (func
3421 (func
3422 ('symbol', 'max')
3422 ('symbol', 'max')
3423 (or
3423 (or
3424 (list
3424 (list
3425 ('symbol', '1')
3425 ('symbol', '1')
3426 ('symbol', '2'))))
3426 ('symbol', '2'))))
3427 (not
3427 (not
3428 ('symbol', '2')))
3428 ('symbol', '2')))
3429 * set:
3429 * set:
3430 <filteredset
3430 <filteredset
3431 <baseset
3431 <baseset
3432 <max
3432 <max
3433 <fullreposet+ 0:9>,
3433 <fullreposet+ 0:9>,
3434 <baseset [1, 2]>>>,
3434 <baseset [1, 2]>>>,
3435 <not
3435 <not
3436 <baseset [2]>>>
3436 <baseset [2]>>>
3437 $ try 'min(1 or 2) and not 1'
3437 $ try 'min(1 or 2) and not 1'
3438 (and
3438 (and
3439 (func
3439 (func
3440 ('symbol', 'min')
3440 ('symbol', 'min')
3441 (or
3441 (or
3442 (list
3442 (list
3443 ('symbol', '1')
3443 ('symbol', '1')
3444 ('symbol', '2'))))
3444 ('symbol', '2'))))
3445 (not
3445 (not
3446 ('symbol', '1')))
3446 ('symbol', '1')))
3447 * set:
3447 * set:
3448 <filteredset
3448 <filteredset
3449 <baseset
3449 <baseset
3450 <min
3450 <min
3451 <fullreposet+ 0:9>,
3451 <fullreposet+ 0:9>,
3452 <baseset [1, 2]>>>,
3452 <baseset [1, 2]>>>,
3453 <not
3453 <not
3454 <baseset [1]>>>
3454 <baseset [1]>>>
3455 $ try 'last(1 or 2, 1) and not 2'
3455 $ try 'last(1 or 2, 1) and not 2'
3456 (and
3456 (and
3457 (func
3457 (func
3458 ('symbol', 'last')
3458 ('symbol', 'last')
3459 (list
3459 (list
3460 (or
3460 (or
3461 (list
3461 (list
3462 ('symbol', '1')
3462 ('symbol', '1')
3463 ('symbol', '2')))
3463 ('symbol', '2')))
3464 ('symbol', '1')))
3464 ('symbol', '1')))
3465 (not
3465 (not
3466 ('symbol', '2')))
3466 ('symbol', '2')))
3467 * set:
3467 * set:
3468 <filteredset
3468 <filteredset
3469 <baseset
3469 <baseset
3470 <last n=1,
3470 <last n=1,
3471 <fullreposet+ 0:9>,
3471 <fullreposet+ 0:9>,
3472 <baseset [2, 1]>>>,
3472 <baseset [2, 1]>>>,
3473 <not
3473 <not
3474 <baseset [2]>>>
3474 <baseset [2]>>>
3475
3475
3476 issue4289 - ordering of built-ins
3476 issue4289 - ordering of built-ins
3477 $ hg log -M -q -r 3:2
3477 $ hg log -M -q -r 3:2
3478 3:8528aa5637f2
3478 3:8528aa5637f2
3479 2:5ed5505e9f1c
3479 2:5ed5505e9f1c
3480
3480
3481 test revsets started with 40-chars hash (issue3669)
3481 test revsets started with 40-chars hash (issue3669)
3482
3482
3483 $ ISSUE3669_TIP=`hg tip --template '{node}'`
3483 $ ISSUE3669_TIP=`hg tip --template '{node}'`
3484 $ hg log -r "${ISSUE3669_TIP}" --template '{rev}\n'
3484 $ hg log -r "${ISSUE3669_TIP}" --template '{rev}\n'
3485 9
3485 9
3486 $ hg log -r "${ISSUE3669_TIP}^" --template '{rev}\n'
3486 $ hg log -r "${ISSUE3669_TIP}^" --template '{rev}\n'
3487 8
3487 8
3488
3488
3489 test or-ed indirect predicates (issue3775)
3489 test or-ed indirect predicates (issue3775)
3490
3490
3491 $ log '6 or 6^1' | sort
3491 $ log '6 or 6^1' | sort
3492 5
3492 5
3493 6
3493 6
3494 $ log '6^1 or 6' | sort
3494 $ log '6^1 or 6' | sort
3495 5
3495 5
3496 6
3496 6
3497 $ log '4 or 4~1' | sort
3497 $ log '4 or 4~1' | sort
3498 2
3498 2
3499 4
3499 4
3500 $ log '4~1 or 4' | sort
3500 $ log '4~1 or 4' | sort
3501 2
3501 2
3502 4
3502 4
3503 $ log '(0 or 2):(4 or 6) or 0 or 6' | sort
3503 $ log '(0 or 2):(4 or 6) or 0 or 6' | sort
3504 0
3504 0
3505 1
3505 1
3506 2
3506 2
3507 3
3507 3
3508 4
3508 4
3509 5
3509 5
3510 6
3510 6
3511 $ log '0 or 6 or (0 or 2):(4 or 6)' | sort
3511 $ log '0 or 6 or (0 or 2):(4 or 6)' | sort
3512 0
3512 0
3513 1
3513 1
3514 2
3514 2
3515 3
3515 3
3516 4
3516 4
3517 5
3517 5
3518 6
3518 6
3519
3519
3520 tests for 'remote()' predicate:
3520 tests for 'remote()' predicate:
3521 #. (csets in remote) (id) (remote)
3521 #. (csets in remote) (id) (remote)
3522 1. less than local current branch "default"
3522 1. less than local current branch "default"
3523 2. same with local specified "default"
3523 2. same with local specified "default"
3524 3. more than local specified specified
3524 3. more than local specified specified
3525
3525
3526 $ hg clone --quiet -U . ../remote3
3526 $ hg clone --quiet -U . ../remote3
3527 $ cd ../remote3
3527 $ cd ../remote3
3528 $ hg update -q 7
3528 $ hg update -q 7
3529 $ echo r > r
3529 $ echo r > r
3530 $ hg ci -Aqm 10
3530 $ hg ci -Aqm 10
3531 $ log 'remote()'
3531 $ log 'remote()'
3532 7
3532 7
3533 $ log 'remote("a-b-c-")'
3533 $ log 'remote("a-b-c-")'
3534 2
3534 2
3535 $ cd ../repo
3535 $ cd ../repo
3536 $ log 'remote(".a.b.c.", "../remote3")'
3536 $ log 'remote(".a.b.c.", "../remote3")'
3537
3537
3538 tests for concatenation of strings/symbols by "##"
3538 tests for concatenation of strings/symbols by "##"
3539
3539
3540 $ try "278 ## '5f5' ## 1ee ## 'ce5'"
3540 $ try "278 ## '5f5' ## 1ee ## 'ce5'"
3541 (_concat
3541 (_concat
3542 (_concat
3542 (_concat
3543 (_concat
3543 (_concat
3544 ('symbol', '278')
3544 ('symbol', '278')
3545 ('string', '5f5'))
3545 ('string', '5f5'))
3546 ('symbol', '1ee'))
3546 ('symbol', '1ee'))
3547 ('string', 'ce5'))
3547 ('string', 'ce5'))
3548 * concatenated:
3548 * concatenated:
3549 ('string', '2785f51eece5')
3549 ('string', '2785f51eece5')
3550 * set:
3550 * set:
3551 <baseset [0]>
3551 <baseset [0]>
3552 0
3552 0
3553
3553
3554 $ echo 'cat4($1, $2, $3, $4) = $1 ## $2 ## $3 ## $4' >> .hg/hgrc
3554 $ echo 'cat4($1, $2, $3, $4) = $1 ## $2 ## $3 ## $4' >> .hg/hgrc
3555 $ try "cat4(278, '5f5', 1ee, 'ce5')"
3555 $ try "cat4(278, '5f5', 1ee, 'ce5')"
3556 (func
3556 (func
3557 ('symbol', 'cat4')
3557 ('symbol', 'cat4')
3558 (list
3558 (list
3559 ('symbol', '278')
3559 ('symbol', '278')
3560 ('string', '5f5')
3560 ('string', '5f5')
3561 ('symbol', '1ee')
3561 ('symbol', '1ee')
3562 ('string', 'ce5')))
3562 ('string', 'ce5')))
3563 * expanded:
3563 * expanded:
3564 (_concat
3564 (_concat
3565 (_concat
3565 (_concat
3566 (_concat
3566 (_concat
3567 ('symbol', '278')
3567 ('symbol', '278')
3568 ('string', '5f5'))
3568 ('string', '5f5'))
3569 ('symbol', '1ee'))
3569 ('symbol', '1ee'))
3570 ('string', 'ce5'))
3570 ('string', 'ce5'))
3571 * concatenated:
3571 * concatenated:
3572 ('string', '2785f51eece5')
3572 ('string', '2785f51eece5')
3573 * set:
3573 * set:
3574 <baseset [0]>
3574 <baseset [0]>
3575 0
3575 0
3576
3576
3577 (check concatenation in alias nesting)
3577 (check concatenation in alias nesting)
3578
3578
3579 $ echo 'cat2($1, $2) = $1 ## $2' >> .hg/hgrc
3579 $ echo 'cat2($1, $2) = $1 ## $2' >> .hg/hgrc
3580 $ echo 'cat2x2($1, $2, $3, $4) = cat2($1 ## $2, $3 ## $4)' >> .hg/hgrc
3580 $ echo 'cat2x2($1, $2, $3, $4) = cat2($1 ## $2, $3 ## $4)' >> .hg/hgrc
3581 $ log "cat2x2(278, '5f5', 1ee, 'ce5')"
3581 $ log "cat2x2(278, '5f5', 1ee, 'ce5')"
3582 0
3582 0
3583
3583
3584 (check operator priority)
3584 (check operator priority)
3585
3585
3586 $ echo 'cat2n2($1, $2, $3, $4) = $1 ## $2 or $3 ## $4~2' >> .hg/hgrc
3586 $ echo 'cat2n2($1, $2, $3, $4) = $1 ## $2 or $3 ## $4~2' >> .hg/hgrc
3587 $ log "cat2n2(2785f5, 1eece5, 24286f, 4ae135)"
3587 $ log "cat2n2(2785f5, 1eece5, 24286f, 4ae135)"
3588 0
3588 0
3589 4
3589 4
3590
3590
3591 $ cd ..
3591 $ cd ..
3592
3592
3593 prepare repository that has "default" branches of multiple roots
3593 prepare repository that has "default" branches of multiple roots
3594
3594
3595 $ hg init namedbranch
3595 $ hg init namedbranch
3596 $ cd namedbranch
3596 $ cd namedbranch
3597
3597
3598 $ echo default0 >> a
3598 $ echo default0 >> a
3599 $ hg ci -Aqm0
3599 $ hg ci -Aqm0
3600 $ echo default1 >> a
3600 $ echo default1 >> a
3601 $ hg ci -m1
3601 $ hg ci -m1
3602
3602
3603 $ hg branch -q stable
3603 $ hg branch -q stable
3604 $ echo stable2 >> a
3604 $ echo stable2 >> a
3605 $ hg ci -m2
3605 $ hg ci -m2
3606 $ echo stable3 >> a
3606 $ echo stable3 >> a
3607 $ hg ci -m3
3607 $ hg ci -m3
3608
3608
3609 $ hg update -q null
3609 $ hg update -q null
3610 $ echo default4 >> a
3610 $ echo default4 >> a
3611 $ hg ci -Aqm4
3611 $ hg ci -Aqm4
3612 $ echo default5 >> a
3612 $ echo default5 >> a
3613 $ hg ci -m5
3613 $ hg ci -m5
3614
3614
3615 "null" revision belongs to "default" branch (issue4683)
3615 "null" revision belongs to "default" branch (issue4683)
3616
3616
3617 $ log 'branch(null)'
3617 $ log 'branch(null)'
3618 0
3618 0
3619 1
3619 1
3620 4
3620 4
3621 5
3621 5
3622
3622
3623 "null" revision belongs to "default" branch, but it shouldn't appear in set
3623 "null" revision belongs to "default" branch, but it shouldn't appear in set
3624 unless explicitly specified (issue4682)
3624 unless explicitly specified (issue4682)
3625
3625
3626 $ log 'children(branch(default))'
3626 $ log 'children(branch(default))'
3627 1
3627 1
3628 2
3628 2
3629 5
3629 5
3630
3630
3631 $ cd ..
3631 $ cd ..
3632
3632
3633 test author/desc/keyword in problematic encoding
3633 test author/desc/keyword in problematic encoding
3634 # unicode: cp932:
3634 # unicode: cp932:
3635 # u30A2 0x83 0x41(= 'A')
3635 # u30A2 0x83 0x41(= 'A')
3636 # u30C2 0x83 0x61(= 'a')
3636 # u30C2 0x83 0x61(= 'a')
3637
3637
3638 $ hg init problematicencoding
3638 $ hg init problematicencoding
3639 $ cd problematicencoding
3639 $ cd problematicencoding
3640
3640
3641 $ python > setup.sh <<EOF
3641 $ python > setup.sh <<EOF
3642 > print u'''
3642 > print u'''
3643 > echo a > text
3643 > echo a > text
3644 > hg add text
3644 > hg add text
3645 > hg --encoding utf-8 commit -u '\u30A2' -m none
3645 > hg --encoding utf-8 commit -u '\u30A2' -m none
3646 > echo b > text
3646 > echo b > text
3647 > hg --encoding utf-8 commit -u '\u30C2' -m none
3647 > hg --encoding utf-8 commit -u '\u30C2' -m none
3648 > echo c > text
3648 > echo c > text
3649 > hg --encoding utf-8 commit -u none -m '\u30A2'
3649 > hg --encoding utf-8 commit -u none -m '\u30A2'
3650 > echo d > text
3650 > echo d > text
3651 > hg --encoding utf-8 commit -u none -m '\u30C2'
3651 > hg --encoding utf-8 commit -u none -m '\u30C2'
3652 > '''.encode('utf-8')
3652 > '''.encode('utf-8')
3653 > EOF
3653 > EOF
3654 $ sh < setup.sh
3654 $ sh < setup.sh
3655
3655
3656 test in problematic encoding
3656 test in problematic encoding
3657 $ python > test.sh <<EOF
3657 $ python > test.sh <<EOF
3658 > print u'''
3658 > print u'''
3659 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30A2)'
3659 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30A2)'
3660 > echo ====
3660 > echo ====
3661 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30C2)'
3661 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30C2)'
3662 > echo ====
3662 > echo ====
3663 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30A2)'
3663 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30A2)'
3664 > echo ====
3664 > echo ====
3665 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30C2)'
3665 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30C2)'
3666 > echo ====
3666 > echo ====
3667 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30A2)'
3667 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30A2)'
3668 > echo ====
3668 > echo ====
3669 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30C2)'
3669 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30C2)'
3670 > '''.encode('cp932')
3670 > '''.encode('cp932')
3671 > EOF
3671 > EOF
3672 $ sh < test.sh
3672 $ sh < test.sh
3673 0
3673 0
3674 ====
3674 ====
3675 1
3675 1
3676 ====
3676 ====
3677 2
3677 2
3678 ====
3678 ====
3679 3
3679 3
3680 ====
3680 ====
3681 0
3681 0
3682 2
3682 2
3683 ====
3683 ====
3684 1
3684 1
3685 3
3685 3
3686
3686
3687 test error message of bad revset
3687 test error message of bad revset
3688 $ hg log -r 'foo\\'
3688 $ hg log -r 'foo\\'
3689 hg: parse error at 3: syntax error in revset 'foo\\'
3689 hg: parse error at 3: syntax error in revset 'foo\\'
3690 [255]
3690 [255]
3691
3691
3692 $ cd ..
3692 $ cd ..
3693
3693
3694 Test that revset predicate of extension isn't loaded at failure of
3694 Test that revset predicate of extension isn't loaded at failure of
3695 loading it
3695 loading it
3696
3696
3697 $ cd repo
3697 $ cd repo
3698
3698
3699 $ cat <<EOF > $TESTTMP/custompredicate.py
3699 $ cat <<EOF > $TESTTMP/custompredicate.py
3700 > from mercurial import error, registrar, revset
3700 > from mercurial import error, registrar, revset
3701 >
3701 >
3702 > revsetpredicate = registrar.revsetpredicate()
3702 > revsetpredicate = registrar.revsetpredicate()
3703 >
3703 >
3704 > @revsetpredicate('custom1()')
3704 > @revsetpredicate('custom1()')
3705 > def custom1(repo, subset, x):
3705 > def custom1(repo, subset, x):
3706 > return revset.baseset([1])
3706 > return revset.baseset([1])
3707 >
3707 >
3708 > raise error.Abort('intentional failure of loading extension')
3708 > raise error.Abort('intentional failure of loading extension')
3709 > EOF
3709 > EOF
3710 $ cat <<EOF > .hg/hgrc
3710 $ cat <<EOF > .hg/hgrc
3711 > [extensions]
3711 > [extensions]
3712 > custompredicate = $TESTTMP/custompredicate.py
3712 > custompredicate = $TESTTMP/custompredicate.py
3713 > EOF
3713 > EOF
3714
3714
3715 $ hg debugrevspec "custom1()"
3715 $ hg debugrevspec "custom1()"
3716 *** failed to import extension custompredicate from $TESTTMP/custompredicate.py: intentional failure of loading extension
3716 *** failed to import extension custompredicate from $TESTTMP/custompredicate.py: intentional failure of loading extension
3717 hg: parse error: unknown identifier: custom1
3717 hg: parse error: unknown identifier: custom1
3718 [255]
3718 [255]
3719
3719
3720 $ cd ..
3720 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now