##// END OF EJS Templates
revsetlang: enable optimization of 'x + y' expression...
Yuya Nishihara -
r31800:c63cb2d1 default
parent child Browse files
Show More
@@ -1,702 +1,702
1 # revsetlang.py - parser, tokenizer and utility for revision set language
1 # revsetlang.py - parser, tokenizer and utility for revision set language
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 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import string
10 import string
11
11
12 from .i18n import _
12 from .i18n import _
13 from . import (
13 from . import (
14 error,
14 error,
15 node,
15 node,
16 parser,
16 parser,
17 pycompat,
17 pycompat,
18 util,
18 util,
19 )
19 )
20
20
21 elements = {
21 elements = {
22 # token-type: binding-strength, primary, prefix, infix, suffix
22 # token-type: binding-strength, primary, prefix, infix, suffix
23 "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None),
23 "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None),
24 "##": (20, None, None, ("_concat", 20), None),
24 "##": (20, None, None, ("_concat", 20), None),
25 "~": (18, None, None, ("ancestor", 18), None),
25 "~": (18, None, None, ("ancestor", 18), None),
26 "^": (18, None, None, ("parent", 18), "parentpost"),
26 "^": (18, None, None, ("parent", 18), "parentpost"),
27 "-": (5, None, ("negate", 19), ("minus", 5), None),
27 "-": (5, None, ("negate", 19), ("minus", 5), None),
28 "::": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"),
28 "::": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"),
29 "..": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"),
29 "..": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"),
30 ":": (15, "rangeall", ("rangepre", 15), ("range", 15), "rangepost"),
30 ":": (15, "rangeall", ("rangepre", 15), ("range", 15), "rangepost"),
31 "not": (10, None, ("not", 10), None, None),
31 "not": (10, None, ("not", 10), None, None),
32 "!": (10, None, ("not", 10), None, None),
32 "!": (10, None, ("not", 10), None, None),
33 "and": (5, None, None, ("and", 5), None),
33 "and": (5, None, None, ("and", 5), None),
34 "&": (5, None, None, ("and", 5), None),
34 "&": (5, None, None, ("and", 5), None),
35 "%": (5, None, None, ("only", 5), "onlypost"),
35 "%": (5, None, None, ("only", 5), "onlypost"),
36 "or": (4, None, None, ("or", 4), None),
36 "or": (4, None, None, ("or", 4), None),
37 "|": (4, None, None, ("or", 4), None),
37 "|": (4, None, None, ("or", 4), None),
38 "+": (4, None, None, ("or", 4), None),
38 "+": (4, None, None, ("or", 4), None),
39 "=": (3, None, None, ("keyvalue", 3), None),
39 "=": (3, None, None, ("keyvalue", 3), None),
40 ",": (2, None, None, ("list", 2), None),
40 ",": (2, None, None, ("list", 2), None),
41 ")": (0, None, None, None, None),
41 ")": (0, None, None, None, None),
42 "symbol": (0, "symbol", None, None, None),
42 "symbol": (0, "symbol", None, None, None),
43 "string": (0, "string", None, None, None),
43 "string": (0, "string", None, None, None),
44 "end": (0, None, None, None, None),
44 "end": (0, None, None, None, None),
45 }
45 }
46
46
47 keywords = set(['and', 'or', 'not'])
47 keywords = set(['and', 'or', 'not'])
48
48
49 _quoteletters = set(['"', "'"])
49 _quoteletters = set(['"', "'"])
50 _simpleopletters = set(pycompat.iterbytestr("():=,-|&+!~^%"))
50 _simpleopletters = set(pycompat.iterbytestr("():=,-|&+!~^%"))
51
51
52 # default set of valid characters for the initial letter of symbols
52 # default set of valid characters for the initial letter of symbols
53 _syminitletters = set(pycompat.iterbytestr(
53 _syminitletters = set(pycompat.iterbytestr(
54 string.ascii_letters.encode('ascii') +
54 string.ascii_letters.encode('ascii') +
55 string.digits.encode('ascii') +
55 string.digits.encode('ascii') +
56 '._@')) | set(map(pycompat.bytechr, xrange(128, 256)))
56 '._@')) | set(map(pycompat.bytechr, xrange(128, 256)))
57
57
58 # default set of valid characters for non-initial letters of symbols
58 # default set of valid characters for non-initial letters of symbols
59 _symletters = _syminitletters | set(pycompat.iterbytestr('-/'))
59 _symletters = _syminitletters | set(pycompat.iterbytestr('-/'))
60
60
61 def tokenize(program, lookup=None, syminitletters=None, symletters=None):
61 def tokenize(program, lookup=None, syminitletters=None, symletters=None):
62 '''
62 '''
63 Parse a revset statement into a stream of tokens
63 Parse a revset statement into a stream of tokens
64
64
65 ``syminitletters`` is the set of valid characters for the initial
65 ``syminitletters`` is the set of valid characters for the initial
66 letter of symbols.
66 letter of symbols.
67
67
68 By default, character ``c`` is recognized as valid for initial
68 By default, character ``c`` is recognized as valid for initial
69 letter of symbols, if ``c.isalnum() or c in '._@' or ord(c) > 127``.
69 letter of symbols, if ``c.isalnum() or c in '._@' or ord(c) > 127``.
70
70
71 ``symletters`` is the set of valid characters for non-initial
71 ``symletters`` is the set of valid characters for non-initial
72 letters of symbols.
72 letters of symbols.
73
73
74 By default, character ``c`` is recognized as valid for non-initial
74 By default, character ``c`` is recognized as valid for non-initial
75 letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``.
75 letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``.
76
76
77 Check that @ is a valid unquoted token character (issue3686):
77 Check that @ is a valid unquoted token character (issue3686):
78 >>> list(tokenize("@::"))
78 >>> list(tokenize("@::"))
79 [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
79 [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
80
80
81 '''
81 '''
82 program = pycompat.bytestr(program)
82 program = pycompat.bytestr(program)
83 if syminitletters is None:
83 if syminitletters is None:
84 syminitletters = _syminitletters
84 syminitletters = _syminitletters
85 if symletters is None:
85 if symletters is None:
86 symletters = _symletters
86 symletters = _symletters
87
87
88 if program and lookup:
88 if program and lookup:
89 # attempt to parse old-style ranges first to deal with
89 # attempt to parse old-style ranges first to deal with
90 # things like old-tag which contain query metacharacters
90 # things like old-tag which contain query metacharacters
91 parts = program.split(':', 1)
91 parts = program.split(':', 1)
92 if all(lookup(sym) for sym in parts if sym):
92 if all(lookup(sym) for sym in parts if sym):
93 if parts[0]:
93 if parts[0]:
94 yield ('symbol', parts[0], 0)
94 yield ('symbol', parts[0], 0)
95 if len(parts) > 1:
95 if len(parts) > 1:
96 s = len(parts[0])
96 s = len(parts[0])
97 yield (':', None, s)
97 yield (':', None, s)
98 if parts[1]:
98 if parts[1]:
99 yield ('symbol', parts[1], s + 1)
99 yield ('symbol', parts[1], s + 1)
100 yield ('end', None, len(program))
100 yield ('end', None, len(program))
101 return
101 return
102
102
103 pos, l = 0, len(program)
103 pos, l = 0, len(program)
104 while pos < l:
104 while pos < l:
105 c = program[pos]
105 c = program[pos]
106 if c.isspace(): # skip inter-token whitespace
106 if c.isspace(): # skip inter-token whitespace
107 pass
107 pass
108 elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
108 elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
109 yield ('::', None, pos)
109 yield ('::', None, pos)
110 pos += 1 # skip ahead
110 pos += 1 # skip ahead
111 elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
111 elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
112 yield ('..', None, pos)
112 yield ('..', None, pos)
113 pos += 1 # skip ahead
113 pos += 1 # skip ahead
114 elif c == '#' and program[pos:pos + 2] == '##': # look ahead carefully
114 elif c == '#' and program[pos:pos + 2] == '##': # look ahead carefully
115 yield ('##', None, pos)
115 yield ('##', None, pos)
116 pos += 1 # skip ahead
116 pos += 1 # skip ahead
117 elif c in _simpleopletters: # handle simple operators
117 elif c in _simpleopletters: # handle simple operators
118 yield (c, None, pos)
118 yield (c, None, pos)
119 elif (c in _quoteletters or c == 'r' and
119 elif (c in _quoteletters or c == 'r' and
120 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
120 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
121 if c == 'r':
121 if c == 'r':
122 pos += 1
122 pos += 1
123 c = program[pos]
123 c = program[pos]
124 decode = lambda x: x
124 decode = lambda x: x
125 else:
125 else:
126 decode = parser.unescapestr
126 decode = parser.unescapestr
127 pos += 1
127 pos += 1
128 s = pos
128 s = pos
129 while pos < l: # find closing quote
129 while pos < l: # find closing quote
130 d = program[pos]
130 d = program[pos]
131 if d == '\\': # skip over escaped characters
131 if d == '\\': # skip over escaped characters
132 pos += 2
132 pos += 2
133 continue
133 continue
134 if d == c:
134 if d == c:
135 yield ('string', decode(program[s:pos]), s)
135 yield ('string', decode(program[s:pos]), s)
136 break
136 break
137 pos += 1
137 pos += 1
138 else:
138 else:
139 raise error.ParseError(_("unterminated string"), s)
139 raise error.ParseError(_("unterminated string"), s)
140 # gather up a symbol/keyword
140 # gather up a symbol/keyword
141 elif c in syminitletters:
141 elif c in syminitletters:
142 s = pos
142 s = pos
143 pos += 1
143 pos += 1
144 while pos < l: # find end of symbol
144 while pos < l: # find end of symbol
145 d = program[pos]
145 d = program[pos]
146 if d not in symletters:
146 if d not in symletters:
147 break
147 break
148 if d == '.' and program[pos - 1] == '.': # special case for ..
148 if d == '.' and program[pos - 1] == '.': # special case for ..
149 pos -= 1
149 pos -= 1
150 break
150 break
151 pos += 1
151 pos += 1
152 sym = program[s:pos]
152 sym = program[s:pos]
153 if sym in keywords: # operator keywords
153 if sym in keywords: # operator keywords
154 yield (sym, None, s)
154 yield (sym, None, s)
155 elif '-' in sym:
155 elif '-' in sym:
156 # some jerk gave us foo-bar-baz, try to check if it's a symbol
156 # some jerk gave us foo-bar-baz, try to check if it's a symbol
157 if lookup and lookup(sym):
157 if lookup and lookup(sym):
158 # looks like a real symbol
158 # looks like a real symbol
159 yield ('symbol', sym, s)
159 yield ('symbol', sym, s)
160 else:
160 else:
161 # looks like an expression
161 # looks like an expression
162 parts = sym.split('-')
162 parts = sym.split('-')
163 for p in parts[:-1]:
163 for p in parts[:-1]:
164 if p: # possible consecutive -
164 if p: # possible consecutive -
165 yield ('symbol', p, s)
165 yield ('symbol', p, s)
166 s += len(p)
166 s += len(p)
167 yield ('-', None, pos)
167 yield ('-', None, pos)
168 s += 1
168 s += 1
169 if parts[-1]: # possible trailing -
169 if parts[-1]: # possible trailing -
170 yield ('symbol', parts[-1], s)
170 yield ('symbol', parts[-1], s)
171 else:
171 else:
172 yield ('symbol', sym, s)
172 yield ('symbol', sym, s)
173 pos -= 1
173 pos -= 1
174 else:
174 else:
175 raise error.ParseError(_("syntax error in revset '%s'") %
175 raise error.ParseError(_("syntax error in revset '%s'") %
176 program, pos)
176 program, pos)
177 pos += 1
177 pos += 1
178 yield ('end', None, pos)
178 yield ('end', None, pos)
179
179
180 # helpers
180 # helpers
181
181
182 _notset = object()
182 _notset = object()
183
183
184 def getsymbol(x):
184 def getsymbol(x):
185 if x and x[0] == 'symbol':
185 if x and x[0] == 'symbol':
186 return x[1]
186 return x[1]
187 raise error.ParseError(_('not a symbol'))
187 raise error.ParseError(_('not a symbol'))
188
188
189 def getstring(x, err):
189 def getstring(x, err):
190 if x and (x[0] == 'string' or x[0] == 'symbol'):
190 if x and (x[0] == 'string' or x[0] == 'symbol'):
191 return x[1]
191 return x[1]
192 raise error.ParseError(err)
192 raise error.ParseError(err)
193
193
194 def getinteger(x, err, default=_notset):
194 def getinteger(x, err, default=_notset):
195 if not x and default is not _notset:
195 if not x and default is not _notset:
196 return default
196 return default
197 try:
197 try:
198 return int(getstring(x, err))
198 return int(getstring(x, err))
199 except ValueError:
199 except ValueError:
200 raise error.ParseError(err)
200 raise error.ParseError(err)
201
201
202 def getlist(x):
202 def getlist(x):
203 if not x:
203 if not x:
204 return []
204 return []
205 if x[0] == 'list':
205 if x[0] == 'list':
206 return list(x[1:])
206 return list(x[1:])
207 return [x]
207 return [x]
208
208
209 def getrange(x, err):
209 def getrange(x, err):
210 if not x:
210 if not x:
211 raise error.ParseError(err)
211 raise error.ParseError(err)
212 op = x[0]
212 op = x[0]
213 if op == 'range':
213 if op == 'range':
214 return x[1], x[2]
214 return x[1], x[2]
215 elif op == 'rangepre':
215 elif op == 'rangepre':
216 return None, x[1]
216 return None, x[1]
217 elif op == 'rangepost':
217 elif op == 'rangepost':
218 return x[1], None
218 return x[1], None
219 elif op == 'rangeall':
219 elif op == 'rangeall':
220 return None, None
220 return None, None
221 raise error.ParseError(err)
221 raise error.ParseError(err)
222
222
223 def getargs(x, min, max, err):
223 def getargs(x, min, max, err):
224 l = getlist(x)
224 l = getlist(x)
225 if len(l) < min or (max >= 0 and len(l) > max):
225 if len(l) < min or (max >= 0 and len(l) > max):
226 raise error.ParseError(err)
226 raise error.ParseError(err)
227 return l
227 return l
228
228
229 def getargsdict(x, funcname, keys):
229 def getargsdict(x, funcname, keys):
230 return parser.buildargsdict(getlist(x), funcname, parser.splitargspec(keys),
230 return parser.buildargsdict(getlist(x), funcname, parser.splitargspec(keys),
231 keyvaluenode='keyvalue', keynode='symbol')
231 keyvaluenode='keyvalue', keynode='symbol')
232
232
233 # Constants for ordering requirement, used in _analyze():
233 # Constants for ordering requirement, used in _analyze():
234 #
234 #
235 # If 'define', any nested functions and operations can change the ordering of
235 # If 'define', any nested functions and operations can change the ordering of
236 # the entries in the set. If 'follow', any nested functions and operations
236 # the entries in the set. If 'follow', any nested functions and operations
237 # should take the ordering specified by the first operand to the '&' operator.
237 # should take the ordering specified by the first operand to the '&' operator.
238 #
238 #
239 # For instance,
239 # For instance,
240 #
240 #
241 # X & (Y | Z)
241 # X & (Y | Z)
242 # ^ ^^^^^^^
242 # ^ ^^^^^^^
243 # | follow
243 # | follow
244 # define
244 # define
245 #
245 #
246 # will be evaluated as 'or(y(x()), z(x()))', where 'x()' can change the order
246 # will be evaluated as 'or(y(x()), z(x()))', where 'x()' can change the order
247 # of the entries in the set, but 'y()', 'z()' and 'or()' shouldn't.
247 # of the entries in the set, but 'y()', 'z()' and 'or()' shouldn't.
248 #
248 #
249 # 'any' means the order doesn't matter. For instance,
249 # 'any' means the order doesn't matter. For instance,
250 #
250 #
251 # X & !Y
251 # X & !Y
252 # ^
252 # ^
253 # any
253 # any
254 #
254 #
255 # 'y()' can either enforce its ordering requirement or take the ordering
255 # 'y()' can either enforce its ordering requirement or take the ordering
256 # specified by 'x()' because 'not()' doesn't care the order.
256 # specified by 'x()' because 'not()' doesn't care the order.
257 #
257 #
258 # Transition of ordering requirement:
258 # Transition of ordering requirement:
259 #
259 #
260 # 1. starts with 'define'
260 # 1. starts with 'define'
261 # 2. shifts to 'follow' by 'x & y'
261 # 2. shifts to 'follow' by 'x & y'
262 # 3. changes back to 'define' on function call 'f(x)' or function-like
262 # 3. changes back to 'define' on function call 'f(x)' or function-like
263 # operation 'x (f) y' because 'f' may have its own ordering requirement
263 # operation 'x (f) y' because 'f' may have its own ordering requirement
264 # for 'x' and 'y' (e.g. 'first(x)')
264 # for 'x' and 'y' (e.g. 'first(x)')
265 #
265 #
266 anyorder = 'any' # don't care the order
266 anyorder = 'any' # don't care the order
267 defineorder = 'define' # should define the order
267 defineorder = 'define' # should define the order
268 followorder = 'follow' # must follow the current order
268 followorder = 'follow' # must follow the current order
269
269
270 # transition table for 'x & y', from the current expression 'x' to 'y'
270 # transition table for 'x & y', from the current expression 'x' to 'y'
271 _tofolloworder = {
271 _tofolloworder = {
272 anyorder: anyorder,
272 anyorder: anyorder,
273 defineorder: followorder,
273 defineorder: followorder,
274 followorder: followorder,
274 followorder: followorder,
275 }
275 }
276
276
277 def _matchonly(revs, bases):
277 def _matchonly(revs, bases):
278 """
278 """
279 >>> f = lambda *args: _matchonly(*map(parse, args))
279 >>> f = lambda *args: _matchonly(*map(parse, args))
280 >>> f('ancestors(A)', 'not ancestors(B)')
280 >>> f('ancestors(A)', 'not ancestors(B)')
281 ('list', ('symbol', 'A'), ('symbol', 'B'))
281 ('list', ('symbol', 'A'), ('symbol', 'B'))
282 """
282 """
283 if (revs is not None
283 if (revs is not None
284 and revs[0] == 'func'
284 and revs[0] == 'func'
285 and getsymbol(revs[1]) == 'ancestors'
285 and getsymbol(revs[1]) == 'ancestors'
286 and bases is not None
286 and bases is not None
287 and bases[0] == 'not'
287 and bases[0] == 'not'
288 and bases[1][0] == 'func'
288 and bases[1][0] == 'func'
289 and getsymbol(bases[1][1]) == 'ancestors'):
289 and getsymbol(bases[1][1]) == 'ancestors'):
290 return ('list', revs[2], bases[1][2])
290 return ('list', revs[2], bases[1][2])
291
291
292 def _fixops(x):
292 def _fixops(x):
293 """Rewrite raw parsed tree to resolve ambiguous syntax which cannot be
293 """Rewrite raw parsed tree to resolve ambiguous syntax which cannot be
294 handled well by our simple top-down parser"""
294 handled well by our simple top-down parser"""
295 if not isinstance(x, tuple):
295 if not isinstance(x, tuple):
296 return x
296 return x
297
297
298 op = x[0]
298 op = x[0]
299 if op == 'parent':
299 if op == 'parent':
300 # x^:y means (x^) : y, not x ^ (:y)
300 # x^:y means (x^) : y, not x ^ (:y)
301 # x^: means (x^) :, not x ^ (:)
301 # x^: means (x^) :, not x ^ (:)
302 post = ('parentpost', x[1])
302 post = ('parentpost', x[1])
303 if x[2][0] == 'dagrangepre':
303 if x[2][0] == 'dagrangepre':
304 return _fixops(('dagrange', post, x[2][1]))
304 return _fixops(('dagrange', post, x[2][1]))
305 elif x[2][0] == 'rangepre':
305 elif x[2][0] == 'rangepre':
306 return _fixops(('range', post, x[2][1]))
306 return _fixops(('range', post, x[2][1]))
307 elif x[2][0] == 'rangeall':
307 elif x[2][0] == 'rangeall':
308 return _fixops(('rangepost', post))
308 return _fixops(('rangepost', post))
309 elif op == 'or':
309 elif op == 'or':
310 # make number of arguments deterministic:
310 # make number of arguments deterministic:
311 # x + y + z -> (or x y z) -> (or (list x y z))
311 # x + y + z -> (or x y z) -> (or (list x y z))
312 return (op, _fixops(('list',) + x[1:]))
312 return (op, _fixops(('list',) + x[1:]))
313
313
314 return (op,) + tuple(_fixops(y) for y in x[1:])
314 return (op,) + tuple(_fixops(y) for y in x[1:])
315
315
316 def _analyze(x, order):
316 def _analyze(x, order):
317 if x is None:
317 if x is None:
318 return x
318 return x
319
319
320 op = x[0]
320 op = x[0]
321 if op == 'minus':
321 if op == 'minus':
322 return _analyze(('and', x[1], ('not', x[2])), order)
322 return _analyze(('and', x[1], ('not', x[2])), order)
323 elif op == 'only':
323 elif op == 'only':
324 t = ('func', ('symbol', 'only'), ('list', x[1], x[2]))
324 t = ('func', ('symbol', 'only'), ('list', x[1], x[2]))
325 return _analyze(t, order)
325 return _analyze(t, order)
326 elif op == 'onlypost':
326 elif op == 'onlypost':
327 return _analyze(('func', ('symbol', 'only'), x[1]), order)
327 return _analyze(('func', ('symbol', 'only'), x[1]), order)
328 elif op == 'dagrangepre':
328 elif op == 'dagrangepre':
329 return _analyze(('func', ('symbol', 'ancestors'), x[1]), order)
329 return _analyze(('func', ('symbol', 'ancestors'), x[1]), order)
330 elif op == 'dagrangepost':
330 elif op == 'dagrangepost':
331 return _analyze(('func', ('symbol', 'descendants'), x[1]), order)
331 return _analyze(('func', ('symbol', 'descendants'), x[1]), order)
332 elif op == 'negate':
332 elif op == 'negate':
333 s = getstring(x[1], _("can't negate that"))
333 s = getstring(x[1], _("can't negate that"))
334 return _analyze(('string', '-' + s), order)
334 return _analyze(('string', '-' + s), order)
335 elif op in ('string', 'symbol'):
335 elif op in ('string', 'symbol'):
336 return x
336 return x
337 elif op == 'and':
337 elif op == 'and':
338 ta = _analyze(x[1], order)
338 ta = _analyze(x[1], order)
339 tb = _analyze(x[2], _tofolloworder[order])
339 tb = _analyze(x[2], _tofolloworder[order])
340 return (op, ta, tb, order)
340 return (op, ta, tb, order)
341 elif op == 'or':
341 elif op == 'or':
342 return (op, _analyze(x[1], order), order)
342 return (op, _analyze(x[1], order), order)
343 elif op == 'not':
343 elif op == 'not':
344 return (op, _analyze(x[1], anyorder), order)
344 return (op, _analyze(x[1], anyorder), order)
345 elif op == 'rangeall':
345 elif op == 'rangeall':
346 return (op, None, order)
346 return (op, None, order)
347 elif op in ('rangepre', 'rangepost', 'parentpost'):
347 elif op in ('rangepre', 'rangepost', 'parentpost'):
348 return (op, _analyze(x[1], defineorder), order)
348 return (op, _analyze(x[1], defineorder), order)
349 elif op == 'group':
349 elif op == 'group':
350 return _analyze(x[1], order)
350 return _analyze(x[1], order)
351 elif op in ('dagrange', 'range', 'parent', 'ancestor'):
351 elif op in ('dagrange', 'range', 'parent', 'ancestor'):
352 ta = _analyze(x[1], defineorder)
352 ta = _analyze(x[1], defineorder)
353 tb = _analyze(x[2], defineorder)
353 tb = _analyze(x[2], defineorder)
354 return (op, ta, tb, order)
354 return (op, ta, tb, order)
355 elif op == 'list':
355 elif op == 'list':
356 return (op,) + tuple(_analyze(y, order) for y in x[1:])
356 return (op,) + tuple(_analyze(y, order) for y in x[1:])
357 elif op == 'keyvalue':
357 elif op == 'keyvalue':
358 return (op, x[1], _analyze(x[2], order))
358 return (op, x[1], _analyze(x[2], order))
359 elif op == 'func':
359 elif op == 'func':
360 f = getsymbol(x[1])
360 f = getsymbol(x[1])
361 d = defineorder
361 d = defineorder
362 if f == 'present':
362 if f == 'present':
363 # 'present(set)' is known to return the argument set with no
363 # 'present(set)' is known to return the argument set with no
364 # modification, so forward the current order to its argument
364 # modification, so forward the current order to its argument
365 d = order
365 d = order
366 return (op, x[1], _analyze(x[2], d), order)
366 return (op, x[1], _analyze(x[2], d), order)
367 raise ValueError('invalid operator %r' % op)
367 raise ValueError('invalid operator %r' % op)
368
368
369 def analyze(x, order=defineorder):
369 def analyze(x, order=defineorder):
370 """Transform raw parsed tree to evaluatable tree which can be fed to
370 """Transform raw parsed tree to evaluatable tree which can be fed to
371 optimize() or getset()
371 optimize() or getset()
372
372
373 All pseudo operations should be mapped to real operations or functions
373 All pseudo operations should be mapped to real operations or functions
374 defined in methods or symbols table respectively.
374 defined in methods or symbols table respectively.
375
375
376 'order' specifies how the current expression 'x' is ordered (see the
376 'order' specifies how the current expression 'x' is ordered (see the
377 constants defined above.)
377 constants defined above.)
378 """
378 """
379 return _analyze(x, order)
379 return _analyze(x, order)
380
380
381 def _optimize(x, small):
381 def _optimize(x, small):
382 if x is None:
382 if x is None:
383 return 0, x
383 return 0, x
384
384
385 smallbonus = 1
385 smallbonus = 1
386 if small:
386 if small:
387 smallbonus = .5
387 smallbonus = .5
388
388
389 op = x[0]
389 op = x[0]
390 if op in ('string', 'symbol'):
390 if op in ('string', 'symbol'):
391 return smallbonus, x # single revisions are small
391 return smallbonus, x # single revisions are small
392 elif op == 'and':
392 elif op == 'and':
393 wa, ta = _optimize(x[1], True)
393 wa, ta = _optimize(x[1], True)
394 wb, tb = _optimize(x[2], True)
394 wb, tb = _optimize(x[2], True)
395 order = x[3]
395 order = x[3]
396 w = min(wa, wb)
396 w = min(wa, wb)
397
397
398 # (::x and not ::y)/(not ::y and ::x) have a fast path
398 # (::x and not ::y)/(not ::y and ::x) have a fast path
399 tm = _matchonly(ta, tb) or _matchonly(tb, ta)
399 tm = _matchonly(ta, tb) or _matchonly(tb, ta)
400 if tm:
400 if tm:
401 return w, ('func', ('symbol', 'only'), tm, order)
401 return w, ('func', ('symbol', 'only'), tm, order)
402
402
403 if tb is not None and tb[0] == 'not':
403 if tb is not None and tb[0] == 'not':
404 return wa, ('difference', ta, tb[1], order)
404 return wa, ('difference', ta, tb[1], order)
405
405
406 if wa > wb:
406 if wa > wb:
407 return w, (op, tb, ta, order)
407 return w, (op, tb, ta, order)
408 return w, (op, ta, tb, order)
408 return w, (op, ta, tb, order)
409 elif op == 'or':
409 elif op == 'or':
410 # fast path for machine-generated expression, that is likely to have
410 # fast path for machine-generated expression, that is likely to have
411 # lots of trivial revisions: 'a + b + c()' to '_list(a b) + c()'
411 # lots of trivial revisions: 'a + b + c()' to '_list(a b) + c()'
412 order = x[2]
412 order = x[2]
413 ws, ts, ss = [], [], []
413 ws, ts, ss = [], [], []
414 def flushss():
414 def flushss():
415 if not ss:
415 if not ss:
416 return
416 return
417 if len(ss) == 1:
417 if len(ss) == 1:
418 w, t = ss[0]
418 w, t = ss[0]
419 else:
419 else:
420 s = '\0'.join(t[1] for w, t in ss)
420 s = '\0'.join(t[1] for w, t in ss)
421 y = ('func', ('symbol', '_list'), ('string', s), order)
421 y = ('func', ('symbol', '_list'), ('string', s), order)
422 w, t = _optimize(y, False)
422 w, t = _optimize(y, False)
423 ws.append(w)
423 ws.append(w)
424 ts.append(t)
424 ts.append(t)
425 del ss[:]
425 del ss[:]
426 for y in getlist(x[1]):
426 for y in getlist(x[1]):
427 w, t = _optimize(y, False)
427 w, t = _optimize(y, False)
428 if t is not None and (t[0] == 'string' or t[0] == 'symbol'):
428 if t is not None and (t[0] == 'string' or t[0] == 'symbol'):
429 ss.append((w, t))
429 ss.append((w, t))
430 continue
430 continue
431 flushss()
431 flushss()
432 ws.append(w)
432 ws.append(w)
433 ts.append(t)
433 ts.append(t)
434 flushss()
434 flushss()
435 if len(ts) == 1:
435 if len(ts) == 1:
436 return ws[0], ts[0] # 'or' operation is fully optimized out
436 return ws[0], ts[0] # 'or' operation is fully optimized out
437 # we can't reorder trees by weight because it would change the order.
437 if order != defineorder:
438 # ("sort(a + b)" == "sort(b + a)", but "a + b" != "b + a")
438 # reorder by weight only when f(a + b) == f(b + a)
439 # ts = tuple(t for w, t in sorted(zip(ws, ts), key=lambda wt: wt[0]))
439 ts = [wt[1] for wt in sorted(zip(ws, ts), key=lambda wt: wt[0])]
440 return max(ws), (op, ('list',) + tuple(ts), order)
440 return max(ws), (op, ('list',) + tuple(ts), order)
441 elif op == 'not':
441 elif op == 'not':
442 # Optimize not public() to _notpublic() because we have a fast version
442 # Optimize not public() to _notpublic() because we have a fast version
443 if x[1][:3] == ('func', ('symbol', 'public'), None):
443 if x[1][:3] == ('func', ('symbol', 'public'), None):
444 order = x[1][3]
444 order = x[1][3]
445 newsym = ('func', ('symbol', '_notpublic'), None, order)
445 newsym = ('func', ('symbol', '_notpublic'), None, order)
446 o = _optimize(newsym, not small)
446 o = _optimize(newsym, not small)
447 return o[0], o[1]
447 return o[0], o[1]
448 else:
448 else:
449 o = _optimize(x[1], not small)
449 o = _optimize(x[1], not small)
450 order = x[2]
450 order = x[2]
451 return o[0], (op, o[1], order)
451 return o[0], (op, o[1], order)
452 elif op == 'rangeall':
452 elif op == 'rangeall':
453 return smallbonus, x
453 return smallbonus, x
454 elif op in ('rangepre', 'rangepost', 'parentpost'):
454 elif op in ('rangepre', 'rangepost', 'parentpost'):
455 o = _optimize(x[1], small)
455 o = _optimize(x[1], small)
456 order = x[2]
456 order = x[2]
457 return o[0], (op, o[1], order)
457 return o[0], (op, o[1], order)
458 elif op in ('dagrange', 'range', 'parent', 'ancestor'):
458 elif op in ('dagrange', 'range', 'parent', 'ancestor'):
459 wa, ta = _optimize(x[1], small)
459 wa, ta = _optimize(x[1], small)
460 wb, tb = _optimize(x[2], small)
460 wb, tb = _optimize(x[2], small)
461 order = x[3]
461 order = x[3]
462 return wa + wb, (op, ta, tb, order)
462 return wa + wb, (op, ta, tb, order)
463 elif op == 'list':
463 elif op == 'list':
464 ws, ts = zip(*(_optimize(y, small) for y in x[1:]))
464 ws, ts = zip(*(_optimize(y, small) for y in x[1:]))
465 return sum(ws), (op,) + ts
465 return sum(ws), (op,) + ts
466 elif op == 'keyvalue':
466 elif op == 'keyvalue':
467 w, t = _optimize(x[2], small)
467 w, t = _optimize(x[2], small)
468 return w, (op, x[1], t)
468 return w, (op, x[1], t)
469 elif op == 'func':
469 elif op == 'func':
470 f = getsymbol(x[1])
470 f = getsymbol(x[1])
471 wa, ta = _optimize(x[2], small)
471 wa, ta = _optimize(x[2], small)
472 if f in ('author', 'branch', 'closed', 'date', 'desc', 'file', 'grep',
472 if f in ('author', 'branch', 'closed', 'date', 'desc', 'file', 'grep',
473 'keyword', 'outgoing', 'user', 'destination'):
473 'keyword', 'outgoing', 'user', 'destination'):
474 w = 10 # slow
474 w = 10 # slow
475 elif f in ('modifies', 'adds', 'removes'):
475 elif f in ('modifies', 'adds', 'removes'):
476 w = 30 # slower
476 w = 30 # slower
477 elif f == "contains":
477 elif f == "contains":
478 w = 100 # very slow
478 w = 100 # very slow
479 elif f == "ancestor":
479 elif f == "ancestor":
480 w = 1 * smallbonus
480 w = 1 * smallbonus
481 elif f in ('reverse', 'limit', 'first', 'wdir', '_intlist'):
481 elif f in ('reverse', 'limit', 'first', 'wdir', '_intlist'):
482 w = 0
482 w = 0
483 elif f == "sort":
483 elif f == "sort":
484 w = 10 # assume most sorts look at changelog
484 w = 10 # assume most sorts look at changelog
485 else:
485 else:
486 w = 1
486 w = 1
487 order = x[3]
487 order = x[3]
488 return w + wa, (op, x[1], ta, order)
488 return w + wa, (op, x[1], ta, order)
489 raise ValueError('invalid operator %r' % op)
489 raise ValueError('invalid operator %r' % op)
490
490
491 def optimize(tree):
491 def optimize(tree):
492 """Optimize evaluatable tree
492 """Optimize evaluatable tree
493
493
494 All pseudo operations should be transformed beforehand.
494 All pseudo operations should be transformed beforehand.
495 """
495 """
496 _weight, newtree = _optimize(tree, small=True)
496 _weight, newtree = _optimize(tree, small=True)
497 return newtree
497 return newtree
498
498
499 # the set of valid characters for the initial letter of symbols in
499 # the set of valid characters for the initial letter of symbols in
500 # alias declarations and definitions
500 # alias declarations and definitions
501 _aliassyminitletters = _syminitletters | set(pycompat.sysstr('$'))
501 _aliassyminitletters = _syminitletters | set(pycompat.sysstr('$'))
502
502
503 def _parsewith(spec, lookup=None, syminitletters=None):
503 def _parsewith(spec, lookup=None, syminitletters=None):
504 """Generate a parse tree of given spec with given tokenizing options
504 """Generate a parse tree of given spec with given tokenizing options
505
505
506 >>> _parsewith('foo($1)', syminitletters=_aliassyminitletters)
506 >>> _parsewith('foo($1)', syminitletters=_aliassyminitletters)
507 ('func', ('symbol', 'foo'), ('symbol', '$1'))
507 ('func', ('symbol', 'foo'), ('symbol', '$1'))
508 >>> _parsewith('$1')
508 >>> _parsewith('$1')
509 Traceback (most recent call last):
509 Traceback (most recent call last):
510 ...
510 ...
511 ParseError: ("syntax error in revset '$1'", 0)
511 ParseError: ("syntax error in revset '$1'", 0)
512 >>> _parsewith('foo bar')
512 >>> _parsewith('foo bar')
513 Traceback (most recent call last):
513 Traceback (most recent call last):
514 ...
514 ...
515 ParseError: ('invalid token', 4)
515 ParseError: ('invalid token', 4)
516 """
516 """
517 p = parser.parser(elements)
517 p = parser.parser(elements)
518 tree, pos = p.parse(tokenize(spec, lookup=lookup,
518 tree, pos = p.parse(tokenize(spec, lookup=lookup,
519 syminitletters=syminitletters))
519 syminitletters=syminitletters))
520 if pos != len(spec):
520 if pos != len(spec):
521 raise error.ParseError(_('invalid token'), pos)
521 raise error.ParseError(_('invalid token'), pos)
522 return _fixops(parser.simplifyinfixops(tree, ('list', 'or')))
522 return _fixops(parser.simplifyinfixops(tree, ('list', 'or')))
523
523
524 class _aliasrules(parser.basealiasrules):
524 class _aliasrules(parser.basealiasrules):
525 """Parsing and expansion rule set of revset aliases"""
525 """Parsing and expansion rule set of revset aliases"""
526 _section = _('revset alias')
526 _section = _('revset alias')
527
527
528 @staticmethod
528 @staticmethod
529 def _parse(spec):
529 def _parse(spec):
530 """Parse alias declaration/definition ``spec``
530 """Parse alias declaration/definition ``spec``
531
531
532 This allows symbol names to use also ``$`` as an initial letter
532 This allows symbol names to use also ``$`` as an initial letter
533 (for backward compatibility), and callers of this function should
533 (for backward compatibility), and callers of this function should
534 examine whether ``$`` is used also for unexpected symbols or not.
534 examine whether ``$`` is used also for unexpected symbols or not.
535 """
535 """
536 return _parsewith(spec, syminitletters=_aliassyminitletters)
536 return _parsewith(spec, syminitletters=_aliassyminitletters)
537
537
538 @staticmethod
538 @staticmethod
539 def _trygetfunc(tree):
539 def _trygetfunc(tree):
540 if tree[0] == 'func' and tree[1][0] == 'symbol':
540 if tree[0] == 'func' and tree[1][0] == 'symbol':
541 return tree[1][1], getlist(tree[2])
541 return tree[1][1], getlist(tree[2])
542
542
543 def expandaliases(ui, tree):
543 def expandaliases(ui, tree):
544 aliases = _aliasrules.buildmap(ui.configitems('revsetalias'))
544 aliases = _aliasrules.buildmap(ui.configitems('revsetalias'))
545 tree = _aliasrules.expand(aliases, tree)
545 tree = _aliasrules.expand(aliases, tree)
546 # warn about problematic (but not referred) aliases
546 # warn about problematic (but not referred) aliases
547 for name, alias in sorted(aliases.iteritems()):
547 for name, alias in sorted(aliases.iteritems()):
548 if alias.error and not alias.warned:
548 if alias.error and not alias.warned:
549 ui.warn(_('warning: %s\n') % (alias.error))
549 ui.warn(_('warning: %s\n') % (alias.error))
550 alias.warned = True
550 alias.warned = True
551 return tree
551 return tree
552
552
553 def foldconcat(tree):
553 def foldconcat(tree):
554 """Fold elements to be concatenated by `##`
554 """Fold elements to be concatenated by `##`
555 """
555 """
556 if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
556 if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
557 return tree
557 return tree
558 if tree[0] == '_concat':
558 if tree[0] == '_concat':
559 pending = [tree]
559 pending = [tree]
560 l = []
560 l = []
561 while pending:
561 while pending:
562 e = pending.pop()
562 e = pending.pop()
563 if e[0] == '_concat':
563 if e[0] == '_concat':
564 pending.extend(reversed(e[1:]))
564 pending.extend(reversed(e[1:]))
565 elif e[0] in ('string', 'symbol'):
565 elif e[0] in ('string', 'symbol'):
566 l.append(e[1])
566 l.append(e[1])
567 else:
567 else:
568 msg = _("\"##\" can't concatenate \"%s\" element") % (e[0])
568 msg = _("\"##\" can't concatenate \"%s\" element") % (e[0])
569 raise error.ParseError(msg)
569 raise error.ParseError(msg)
570 return ('string', ''.join(l))
570 return ('string', ''.join(l))
571 else:
571 else:
572 return tuple(foldconcat(t) for t in tree)
572 return tuple(foldconcat(t) for t in tree)
573
573
574 def parse(spec, lookup=None):
574 def parse(spec, lookup=None):
575 return _parsewith(spec, lookup=lookup)
575 return _parsewith(spec, lookup=lookup)
576
576
577 def _quote(s):
577 def _quote(s):
578 r"""Quote a value in order to make it safe for the revset engine.
578 r"""Quote a value in order to make it safe for the revset engine.
579
579
580 >>> _quote('asdf')
580 >>> _quote('asdf')
581 "'asdf'"
581 "'asdf'"
582 >>> _quote("asdf'\"")
582 >>> _quote("asdf'\"")
583 '\'asdf\\\'"\''
583 '\'asdf\\\'"\''
584 >>> _quote('asdf\'')
584 >>> _quote('asdf\'')
585 "'asdf\\''"
585 "'asdf\\''"
586 >>> _quote(1)
586 >>> _quote(1)
587 "'1'"
587 "'1'"
588 """
588 """
589 return "'%s'" % util.escapestr(pycompat.bytestr(s))
589 return "'%s'" % util.escapestr(pycompat.bytestr(s))
590
590
591 def formatspec(expr, *args):
591 def formatspec(expr, *args):
592 '''
592 '''
593 This is a convenience function for using revsets internally, and
593 This is a convenience function for using revsets internally, and
594 escapes arguments appropriately. Aliases are intentionally ignored
594 escapes arguments appropriately. Aliases are intentionally ignored
595 so that intended expression behavior isn't accidentally subverted.
595 so that intended expression behavior isn't accidentally subverted.
596
596
597 Supported arguments:
597 Supported arguments:
598
598
599 %r = revset expression, parenthesized
599 %r = revset expression, parenthesized
600 %d = int(arg), no quoting
600 %d = int(arg), no quoting
601 %s = string(arg), escaped and single-quoted
601 %s = string(arg), escaped and single-quoted
602 %b = arg.branch(), escaped and single-quoted
602 %b = arg.branch(), escaped and single-quoted
603 %n = hex(arg), single-quoted
603 %n = hex(arg), single-quoted
604 %% = a literal '%'
604 %% = a literal '%'
605
605
606 Prefixing the type with 'l' specifies a parenthesized list of that type.
606 Prefixing the type with 'l' specifies a parenthesized list of that type.
607
607
608 >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()"))
608 >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()"))
609 '(10 or 11):: and ((this()) or (that()))'
609 '(10 or 11):: and ((this()) or (that()))'
610 >>> formatspec('%d:: and not %d::', 10, 20)
610 >>> formatspec('%d:: and not %d::', 10, 20)
611 '10:: and not 20::'
611 '10:: and not 20::'
612 >>> formatspec('%ld or %ld', [], [1])
612 >>> formatspec('%ld or %ld', [], [1])
613 "_list('') or 1"
613 "_list('') or 1"
614 >>> formatspec('keyword(%s)', 'foo\\xe9')
614 >>> formatspec('keyword(%s)', 'foo\\xe9')
615 "keyword('foo\\\\xe9')"
615 "keyword('foo\\\\xe9')"
616 >>> b = lambda: 'default'
616 >>> b = lambda: 'default'
617 >>> b.branch = b
617 >>> b.branch = b
618 >>> formatspec('branch(%b)', b)
618 >>> formatspec('branch(%b)', b)
619 "branch('default')"
619 "branch('default')"
620 >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd'])
620 >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd'])
621 "root(_list('a\\x00b\\x00c\\x00d'))"
621 "root(_list('a\\x00b\\x00c\\x00d'))"
622 '''
622 '''
623
623
624 def argtype(c, arg):
624 def argtype(c, arg):
625 if c == 'd':
625 if c == 'd':
626 return '%d' % int(arg)
626 return '%d' % int(arg)
627 elif c == 's':
627 elif c == 's':
628 return _quote(arg)
628 return _quote(arg)
629 elif c == 'r':
629 elif c == 'r':
630 parse(arg) # make sure syntax errors are confined
630 parse(arg) # make sure syntax errors are confined
631 return '(%s)' % arg
631 return '(%s)' % arg
632 elif c == 'n':
632 elif c == 'n':
633 return _quote(node.hex(arg))
633 return _quote(node.hex(arg))
634 elif c == 'b':
634 elif c == 'b':
635 return _quote(arg.branch())
635 return _quote(arg.branch())
636
636
637 def listexp(s, t):
637 def listexp(s, t):
638 l = len(s)
638 l = len(s)
639 if l == 0:
639 if l == 0:
640 return "_list('')"
640 return "_list('')"
641 elif l == 1:
641 elif l == 1:
642 return argtype(t, s[0])
642 return argtype(t, s[0])
643 elif t == 'd':
643 elif t == 'd':
644 return "_intlist('%s')" % "\0".join('%d' % int(a) for a in s)
644 return "_intlist('%s')" % "\0".join('%d' % int(a) for a in s)
645 elif t == 's':
645 elif t == 's':
646 return "_list('%s')" % "\0".join(s)
646 return "_list('%s')" % "\0".join(s)
647 elif t == 'n':
647 elif t == 'n':
648 return "_hexlist('%s')" % "\0".join(node.hex(a) for a in s)
648 return "_hexlist('%s')" % "\0".join(node.hex(a) for a in s)
649 elif t == 'b':
649 elif t == 'b':
650 return "_list('%s')" % "\0".join(a.branch() for a in s)
650 return "_list('%s')" % "\0".join(a.branch() for a in s)
651
651
652 m = l // 2
652 m = l // 2
653 return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t))
653 return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t))
654
654
655 expr = pycompat.bytestr(expr)
655 expr = pycompat.bytestr(expr)
656 ret = ''
656 ret = ''
657 pos = 0
657 pos = 0
658 arg = 0
658 arg = 0
659 while pos < len(expr):
659 while pos < len(expr):
660 c = expr[pos]
660 c = expr[pos]
661 if c == '%':
661 if c == '%':
662 pos += 1
662 pos += 1
663 d = expr[pos]
663 d = expr[pos]
664 if d == '%':
664 if d == '%':
665 ret += d
665 ret += d
666 elif d in 'dsnbr':
666 elif d in 'dsnbr':
667 ret += argtype(d, args[arg])
667 ret += argtype(d, args[arg])
668 arg += 1
668 arg += 1
669 elif d == 'l':
669 elif d == 'l':
670 # a list of some type
670 # a list of some type
671 pos += 1
671 pos += 1
672 d = expr[pos]
672 d = expr[pos]
673 ret += listexp(list(args[arg]), d)
673 ret += listexp(list(args[arg]), d)
674 arg += 1
674 arg += 1
675 else:
675 else:
676 raise error.Abort(_('unexpected revspec format character %s')
676 raise error.Abort(_('unexpected revspec format character %s')
677 % d)
677 % d)
678 else:
678 else:
679 ret += c
679 ret += c
680 pos += 1
680 pos += 1
681
681
682 return ret
682 return ret
683
683
684 def prettyformat(tree):
684 def prettyformat(tree):
685 return parser.prettyformat(tree, ('string', 'symbol'))
685 return parser.prettyformat(tree, ('string', 'symbol'))
686
686
687 def depth(tree):
687 def depth(tree):
688 if isinstance(tree, tuple):
688 if isinstance(tree, tuple):
689 return max(map(depth, tree)) + 1
689 return max(map(depth, tree)) + 1
690 else:
690 else:
691 return 0
691 return 0
692
692
693 def funcsused(tree):
693 def funcsused(tree):
694 if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
694 if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
695 return set()
695 return set()
696 else:
696 else:
697 funcs = set()
697 funcs = set()
698 for s in tree[1:]:
698 for s in tree[1:]:
699 funcs |= funcsused(s)
699 funcs |= funcsused(s)
700 if tree[0] == 'func':
700 if tree[0] == 'func':
701 funcs.add(tree[1][1])
701 funcs.add(tree[1][1])
702 return funcs
702 return funcs
@@ -1,3657 +1,3720
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 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 (range
1424 (range
1424 ('symbol', '0')
1425 ('symbol', '0')
1425 ('symbol', '1')
1426 ('symbol', '1')
1426 follow)
1427 follow))
1427 ('symbol', '2'))
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 <spanset+ 0:1>,
1434 <baseset [2]>,
1435 <baseset [2]>>>
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
1921 matter (e.g. 'X & (A + B)' can be 'X & (B + A)', but '(A + B) & X' can't):
1922
1923 $ try -p optimized '0:2 & (reverse(contains("a")) + 2)'
1924 * optimized:
1925 (and
1926 (range
1927 ('symbol', '0')
1928 ('symbol', '2')
1929 define)
1930 (or
1931 (list
1932 ('symbol', '2')
1933 (func
1934 ('symbol', 'reverse')
1935 (func
1936 ('symbol', 'contains')
1937 ('string', 'a')
1938 define)
1939 follow))
1940 follow)
1941 define)
1942 * set:
1943 <filteredset
1944 <spanset+ 0:2>,
1945 <addset
1946 <baseset [2]>,
1947 <filteredset
1948 <fullreposet+ 0:9>,
1949 <contains 'a'>>>>
1950 0
1951 1
1952 2
1953
1954 $ try -p optimized '(reverse(contains("a")) + 2) & 0:2'
1955 * optimized:
1956 (and
1957 (range
1958 ('symbol', '0')
1959 ('symbol', '2')
1960 follow)
1961 (or
1962 (list
1963 (func
1964 ('symbol', 'reverse')
1965 (func
1966 ('symbol', 'contains')
1967 ('string', 'a')
1968 define)
1969 define)
1970 ('symbol', '2'))
1971 define)
1972 define)
1973 * set:
1974 <addset
1975 <filteredset
1976 <spanset- 0:2>,
1977 <contains 'a'>>,
1978 <baseset [2]>>
1979 1
1980 0
1981 2
1982
1920 test sort revset
1983 test sort revset
1921 --------------------------------------------
1984 --------------------------------------------
1922
1985
1923 test when adding two unordered revsets
1986 test when adding two unordered revsets
1924
1987
1925 $ log 'sort(keyword(issue) or modifies(b))'
1988 $ log 'sort(keyword(issue) or modifies(b))'
1926 4
1989 4
1927 6
1990 6
1928
1991
1929 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
1930
1993
1931 $ log 'sort(reverse(all()), -rev)'
1994 $ log 'sort(reverse(all()), -rev)'
1932 9
1995 9
1933 8
1996 8
1934 7
1997 7
1935 6
1998 6
1936 5
1999 5
1937 4
2000 4
1938 3
2001 3
1939 2
2002 2
1940 1
2003 1
1941 0
2004 0
1942
2005
1943 test when sorting a reversed collection
2006 test when sorting a reversed collection
1944
2007
1945 $ log 'sort(reverse(all()), rev)'
2008 $ log 'sort(reverse(all()), rev)'
1946 0
2009 0
1947 1
2010 1
1948 2
2011 2
1949 3
2012 3
1950 4
2013 4
1951 5
2014 5
1952 6
2015 6
1953 7
2016 7
1954 8
2017 8
1955 9
2018 9
1956
2019
1957
2020
1958 test sorting two sorted collections in different orders
2021 test sorting two sorted collections in different orders
1959
2022
1960 $ log 'sort(outgoing() or reverse(removes(a)), rev)'
2023 $ log 'sort(outgoing() or reverse(removes(a)), rev)'
1961 2
2024 2
1962 6
2025 6
1963 8
2026 8
1964 9
2027 9
1965
2028
1966 test sorting two sorted collections in different orders backwards
2029 test sorting two sorted collections in different orders backwards
1967
2030
1968 $ log 'sort(outgoing() or reverse(removes(a)), -rev)'
2031 $ log 'sort(outgoing() or reverse(removes(a)), -rev)'
1969 9
2032 9
1970 8
2033 8
1971 6
2034 6
1972 2
2035 2
1973
2036
1974 test empty sort key which is noop
2037 test empty sort key which is noop
1975
2038
1976 $ log 'sort(0 + 2 + 1, "")'
2039 $ log 'sort(0 + 2 + 1, "")'
1977 0
2040 0
1978 2
2041 2
1979 1
2042 1
1980
2043
1981 test invalid sort keys
2044 test invalid sort keys
1982
2045
1983 $ log 'sort(all(), -invalid)'
2046 $ log 'sort(all(), -invalid)'
1984 hg: parse error: unknown sort key '-invalid'
2047 hg: parse error: unknown sort key '-invalid'
1985 [255]
2048 [255]
1986
2049
1987 $ cd ..
2050 $ cd ..
1988
2051
1989 test sorting by multiple keys including variable-length strings
2052 test sorting by multiple keys including variable-length strings
1990
2053
1991 $ hg init sorting
2054 $ hg init sorting
1992 $ cd sorting
2055 $ cd sorting
1993 $ cat <<EOF >> .hg/hgrc
2056 $ cat <<EOF >> .hg/hgrc
1994 > [ui]
2057 > [ui]
1995 > logtemplate = '{rev} {branch|p5}{desc|p5}{author|p5}{date|hgdate}\n'
2058 > logtemplate = '{rev} {branch|p5}{desc|p5}{author|p5}{date|hgdate}\n'
1996 > [templatealias]
2059 > [templatealias]
1997 > p5(s) = pad(s, 5)
2060 > p5(s) = pad(s, 5)
1998 > EOF
2061 > EOF
1999 $ hg branch -qf b12
2062 $ hg branch -qf b12
2000 $ hg ci -m m111 -u u112 -d '111 10800'
2063 $ hg ci -m m111 -u u112 -d '111 10800'
2001 $ hg branch -qf b11
2064 $ hg branch -qf b11
2002 $ hg ci -m m12 -u u111 -d '112 7200'
2065 $ hg ci -m m12 -u u111 -d '112 7200'
2003 $ hg branch -qf b111
2066 $ hg branch -qf b111
2004 $ hg ci -m m11 -u u12 -d '111 3600'
2067 $ hg ci -m m11 -u u12 -d '111 3600'
2005 $ hg branch -qf b112
2068 $ hg branch -qf b112
2006 $ hg ci -m m111 -u u11 -d '120 0'
2069 $ hg ci -m m111 -u u11 -d '120 0'
2007 $ hg branch -qf b111
2070 $ hg branch -qf b111
2008 $ hg ci -m m112 -u u111 -d '110 14400'
2071 $ hg ci -m m112 -u u111 -d '110 14400'
2009 created new head
2072 created new head
2010
2073
2011 compare revisions (has fast path):
2074 compare revisions (has fast path):
2012
2075
2013 $ hg log -r 'sort(all(), rev)'
2076 $ hg log -r 'sort(all(), rev)'
2014 0 b12 m111 u112 111 10800
2077 0 b12 m111 u112 111 10800
2015 1 b11 m12 u111 112 7200
2078 1 b11 m12 u111 112 7200
2016 2 b111 m11 u12 111 3600
2079 2 b111 m11 u12 111 3600
2017 3 b112 m111 u11 120 0
2080 3 b112 m111 u11 120 0
2018 4 b111 m112 u111 110 14400
2081 4 b111 m112 u111 110 14400
2019
2082
2020 $ hg log -r 'sort(all(), -rev)'
2083 $ hg log -r 'sort(all(), -rev)'
2021 4 b111 m112 u111 110 14400
2084 4 b111 m112 u111 110 14400
2022 3 b112 m111 u11 120 0
2085 3 b112 m111 u11 120 0
2023 2 b111 m11 u12 111 3600
2086 2 b111 m11 u12 111 3600
2024 1 b11 m12 u111 112 7200
2087 1 b11 m12 u111 112 7200
2025 0 b12 m111 u112 111 10800
2088 0 b12 m111 u112 111 10800
2026
2089
2027 compare variable-length strings (issue5218):
2090 compare variable-length strings (issue5218):
2028
2091
2029 $ hg log -r 'sort(all(), branch)'
2092 $ hg log -r 'sort(all(), branch)'
2030 1 b11 m12 u111 112 7200
2093 1 b11 m12 u111 112 7200
2031 2 b111 m11 u12 111 3600
2094 2 b111 m11 u12 111 3600
2032 4 b111 m112 u111 110 14400
2095 4 b111 m112 u111 110 14400
2033 3 b112 m111 u11 120 0
2096 3 b112 m111 u11 120 0
2034 0 b12 m111 u112 111 10800
2097 0 b12 m111 u112 111 10800
2035
2098
2036 $ hg log -r 'sort(all(), -branch)'
2099 $ hg log -r 'sort(all(), -branch)'
2037 0 b12 m111 u112 111 10800
2100 0 b12 m111 u112 111 10800
2038 3 b112 m111 u11 120 0
2101 3 b112 m111 u11 120 0
2039 2 b111 m11 u12 111 3600
2102 2 b111 m11 u12 111 3600
2040 4 b111 m112 u111 110 14400
2103 4 b111 m112 u111 110 14400
2041 1 b11 m12 u111 112 7200
2104 1 b11 m12 u111 112 7200
2042
2105
2043 $ hg log -r 'sort(all(), desc)'
2106 $ hg log -r 'sort(all(), desc)'
2044 2 b111 m11 u12 111 3600
2107 2 b111 m11 u12 111 3600
2045 0 b12 m111 u112 111 10800
2108 0 b12 m111 u112 111 10800
2046 3 b112 m111 u11 120 0
2109 3 b112 m111 u11 120 0
2047 4 b111 m112 u111 110 14400
2110 4 b111 m112 u111 110 14400
2048 1 b11 m12 u111 112 7200
2111 1 b11 m12 u111 112 7200
2049
2112
2050 $ hg log -r 'sort(all(), -desc)'
2113 $ hg log -r 'sort(all(), -desc)'
2051 1 b11 m12 u111 112 7200
2114 1 b11 m12 u111 112 7200
2052 4 b111 m112 u111 110 14400
2115 4 b111 m112 u111 110 14400
2053 0 b12 m111 u112 111 10800
2116 0 b12 m111 u112 111 10800
2054 3 b112 m111 u11 120 0
2117 3 b112 m111 u11 120 0
2055 2 b111 m11 u12 111 3600
2118 2 b111 m11 u12 111 3600
2056
2119
2057 $ hg log -r 'sort(all(), user)'
2120 $ hg log -r 'sort(all(), user)'
2058 3 b112 m111 u11 120 0
2121 3 b112 m111 u11 120 0
2059 1 b11 m12 u111 112 7200
2122 1 b11 m12 u111 112 7200
2060 4 b111 m112 u111 110 14400
2123 4 b111 m112 u111 110 14400
2061 0 b12 m111 u112 111 10800
2124 0 b12 m111 u112 111 10800
2062 2 b111 m11 u12 111 3600
2125 2 b111 m11 u12 111 3600
2063
2126
2064 $ hg log -r 'sort(all(), -user)'
2127 $ hg log -r 'sort(all(), -user)'
2065 2 b111 m11 u12 111 3600
2128 2 b111 m11 u12 111 3600
2066 0 b12 m111 u112 111 10800
2129 0 b12 m111 u112 111 10800
2067 1 b11 m12 u111 112 7200
2130 1 b11 m12 u111 112 7200
2068 4 b111 m112 u111 110 14400
2131 4 b111 m112 u111 110 14400
2069 3 b112 m111 u11 120 0
2132 3 b112 m111 u11 120 0
2070
2133
2071 compare dates (tz offset should have no effect):
2134 compare dates (tz offset should have no effect):
2072
2135
2073 $ hg log -r 'sort(all(), date)'
2136 $ hg log -r 'sort(all(), date)'
2074 4 b111 m112 u111 110 14400
2137 4 b111 m112 u111 110 14400
2075 0 b12 m111 u112 111 10800
2138 0 b12 m111 u112 111 10800
2076 2 b111 m11 u12 111 3600
2139 2 b111 m11 u12 111 3600
2077 1 b11 m12 u111 112 7200
2140 1 b11 m12 u111 112 7200
2078 3 b112 m111 u11 120 0
2141 3 b112 m111 u11 120 0
2079
2142
2080 $ hg log -r 'sort(all(), -date)'
2143 $ hg log -r 'sort(all(), -date)'
2081 3 b112 m111 u11 120 0
2144 3 b112 m111 u11 120 0
2082 1 b11 m12 u111 112 7200
2145 1 b11 m12 u111 112 7200
2083 0 b12 m111 u112 111 10800
2146 0 b12 m111 u112 111 10800
2084 2 b111 m11 u12 111 3600
2147 2 b111 m11 u12 111 3600
2085 4 b111 m112 u111 110 14400
2148 4 b111 m112 u111 110 14400
2086
2149
2087 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))'
2088 because '-k' reverses the comparison, not the list itself:
2151 because '-k' reverses the comparison, not the list itself:
2089
2152
2090 $ hg log -r 'sort(0 + 2, date)'
2153 $ hg log -r 'sort(0 + 2, date)'
2091 0 b12 m111 u112 111 10800
2154 0 b12 m111 u112 111 10800
2092 2 b111 m11 u12 111 3600
2155 2 b111 m11 u12 111 3600
2093
2156
2094 $ hg log -r 'sort(0 + 2, -date)'
2157 $ hg log -r 'sort(0 + 2, -date)'
2095 0 b12 m111 u112 111 10800
2158 0 b12 m111 u112 111 10800
2096 2 b111 m11 u12 111 3600
2159 2 b111 m11 u12 111 3600
2097
2160
2098 $ hg log -r 'reverse(sort(0 + 2, date))'
2161 $ hg log -r 'reverse(sort(0 + 2, date))'
2099 2 b111 m11 u12 111 3600
2162 2 b111 m11 u12 111 3600
2100 0 b12 m111 u112 111 10800
2163 0 b12 m111 u112 111 10800
2101
2164
2102 sort by multiple keys:
2165 sort by multiple keys:
2103
2166
2104 $ hg log -r 'sort(all(), "branch -rev")'
2167 $ hg log -r 'sort(all(), "branch -rev")'
2105 1 b11 m12 u111 112 7200
2168 1 b11 m12 u111 112 7200
2106 4 b111 m112 u111 110 14400
2169 4 b111 m112 u111 110 14400
2107 2 b111 m11 u12 111 3600
2170 2 b111 m11 u12 111 3600
2108 3 b112 m111 u11 120 0
2171 3 b112 m111 u11 120 0
2109 0 b12 m111 u112 111 10800
2172 0 b12 m111 u112 111 10800
2110
2173
2111 $ hg log -r 'sort(all(), "-desc -date")'
2174 $ hg log -r 'sort(all(), "-desc -date")'
2112 1 b11 m12 u111 112 7200
2175 1 b11 m12 u111 112 7200
2113 4 b111 m112 u111 110 14400
2176 4 b111 m112 u111 110 14400
2114 3 b112 m111 u11 120 0
2177 3 b112 m111 u11 120 0
2115 0 b12 m111 u112 111 10800
2178 0 b12 m111 u112 111 10800
2116 2 b111 m11 u12 111 3600
2179 2 b111 m11 u12 111 3600
2117
2180
2118 $ hg log -r 'sort(all(), "user -branch date rev")'
2181 $ hg log -r 'sort(all(), "user -branch date rev")'
2119 3 b112 m111 u11 120 0
2182 3 b112 m111 u11 120 0
2120 4 b111 m112 u111 110 14400
2183 4 b111 m112 u111 110 14400
2121 1 b11 m12 u111 112 7200
2184 1 b11 m12 u111 112 7200
2122 0 b12 m111 u112 111 10800
2185 0 b12 m111 u112 111 10800
2123 2 b111 m11 u12 111 3600
2186 2 b111 m11 u12 111 3600
2124
2187
2125 toposort prioritises graph branches
2188 toposort prioritises graph branches
2126
2189
2127 $ hg up 2
2190 $ hg up 2
2128 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
2129 $ touch a
2192 $ touch a
2130 $ hg addremove
2193 $ hg addremove
2131 adding a
2194 adding a
2132 $ hg ci -m 't1' -u 'tu' -d '130 0'
2195 $ hg ci -m 't1' -u 'tu' -d '130 0'
2133 created new head
2196 created new head
2134 $ echo 'a' >> a
2197 $ echo 'a' >> a
2135 $ hg ci -m 't2' -u 'tu' -d '130 0'
2198 $ hg ci -m 't2' -u 'tu' -d '130 0'
2136 $ hg book book1
2199 $ hg book book1
2137 $ hg up 4
2200 $ hg up 4
2138 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
2139 (leaving bookmark book1)
2202 (leaving bookmark book1)
2140 $ touch a
2203 $ touch a
2141 $ hg addremove
2204 $ hg addremove
2142 adding a
2205 adding a
2143 $ hg ci -m 't3' -u 'tu' -d '130 0'
2206 $ hg ci -m 't3' -u 'tu' -d '130 0'
2144
2207
2145 $ hg log -r 'sort(all(), topo)'
2208 $ hg log -r 'sort(all(), topo)'
2146 7 b111 t3 tu 130 0
2209 7 b111 t3 tu 130 0
2147 4 b111 m112 u111 110 14400
2210 4 b111 m112 u111 110 14400
2148 3 b112 m111 u11 120 0
2211 3 b112 m111 u11 120 0
2149 6 b111 t2 tu 130 0
2212 6 b111 t2 tu 130 0
2150 5 b111 t1 tu 130 0
2213 5 b111 t1 tu 130 0
2151 2 b111 m11 u12 111 3600
2214 2 b111 m11 u12 111 3600
2152 1 b11 m12 u111 112 7200
2215 1 b11 m12 u111 112 7200
2153 0 b12 m111 u112 111 10800
2216 0 b12 m111 u112 111 10800
2154
2217
2155 $ hg log -r 'sort(all(), -topo)'
2218 $ hg log -r 'sort(all(), -topo)'
2156 0 b12 m111 u112 111 10800
2219 0 b12 m111 u112 111 10800
2157 1 b11 m12 u111 112 7200
2220 1 b11 m12 u111 112 7200
2158 2 b111 m11 u12 111 3600
2221 2 b111 m11 u12 111 3600
2159 5 b111 t1 tu 130 0
2222 5 b111 t1 tu 130 0
2160 6 b111 t2 tu 130 0
2223 6 b111 t2 tu 130 0
2161 3 b112 m111 u11 120 0
2224 3 b112 m111 u11 120 0
2162 4 b111 m112 u111 110 14400
2225 4 b111 m112 u111 110 14400
2163 7 b111 t3 tu 130 0
2226 7 b111 t3 tu 130 0
2164
2227
2165 $ hg log -r 'sort(all(), topo, topo.firstbranch=book1)'
2228 $ hg log -r 'sort(all(), topo, topo.firstbranch=book1)'
2166 6 b111 t2 tu 130 0
2229 6 b111 t2 tu 130 0
2167 5 b111 t1 tu 130 0
2230 5 b111 t1 tu 130 0
2168 7 b111 t3 tu 130 0
2231 7 b111 t3 tu 130 0
2169 4 b111 m112 u111 110 14400
2232 4 b111 m112 u111 110 14400
2170 3 b112 m111 u11 120 0
2233 3 b112 m111 u11 120 0
2171 2 b111 m11 u12 111 3600
2234 2 b111 m11 u12 111 3600
2172 1 b11 m12 u111 112 7200
2235 1 b11 m12 u111 112 7200
2173 0 b12 m111 u112 111 10800
2236 0 b12 m111 u112 111 10800
2174
2237
2175 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
2176 use the topo.firstbranch option when topo sort is not active:
2239 use the topo.firstbranch option when topo sort is not active:
2177
2240
2178 $ hg log -r 'sort(all(), "topo user")'
2241 $ hg log -r 'sort(all(), "topo user")'
2179 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
2180 [255]
2243 [255]
2181
2244
2182 $ hg log -r 'sort(all(), user, topo.firstbranch=book1)'
2245 $ hg log -r 'sort(all(), user, topo.firstbranch=book1)'
2183 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
2184 [255]
2247 [255]
2185
2248
2186 topo.firstbranch should accept any kind of expressions:
2249 topo.firstbranch should accept any kind of expressions:
2187
2250
2188 $ hg log -r 'sort(0, topo, topo.firstbranch=(book1))'
2251 $ hg log -r 'sort(0, topo, topo.firstbranch=(book1))'
2189 0 b12 m111 u112 111 10800
2252 0 b12 m111 u112 111 10800
2190
2253
2191 $ cd ..
2254 $ cd ..
2192 $ cd repo
2255 $ cd repo
2193
2256
2194 test subtracting something from an addset
2257 test subtracting something from an addset
2195
2258
2196 $ log '(outgoing() or removes(a)) - removes(a)'
2259 $ log '(outgoing() or removes(a)) - removes(a)'
2197 8
2260 8
2198 9
2261 9
2199
2262
2200 test intersecting something with an addset
2263 test intersecting something with an addset
2201
2264
2202 $ log 'parents(outgoing() or removes(a))'
2265 $ log 'parents(outgoing() or removes(a))'
2203 1
2266 1
2204 4
2267 4
2205 5
2268 5
2206 8
2269 8
2207
2270
2208 test that `or` operation combines elements in the right order:
2271 test that `or` operation combines elements in the right order:
2209
2272
2210 $ log '3:4 or 2:5'
2273 $ log '3:4 or 2:5'
2211 3
2274 3
2212 4
2275 4
2213 2
2276 2
2214 5
2277 5
2215 $ log '3:4 or 5:2'
2278 $ log '3:4 or 5:2'
2216 3
2279 3
2217 4
2280 4
2218 5
2281 5
2219 2
2282 2
2220 $ log 'sort(3:4 or 2:5)'
2283 $ log 'sort(3:4 or 2:5)'
2221 2
2284 2
2222 3
2285 3
2223 4
2286 4
2224 5
2287 5
2225 $ log 'sort(3:4 or 5:2)'
2288 $ log 'sort(3:4 or 5:2)'
2226 2
2289 2
2227 3
2290 3
2228 4
2291 4
2229 5
2292 5
2230
2293
2231 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:
2232
2295
2233 $ 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)'
2234 3
2297 3
2235 4
2298 4
2236 5
2299 5
2237 2
2300 2
2238 0
2301 0
2239 1
2302 1
2240
2303
2241 test that `or` operation skips duplicated revisions from right-hand side
2304 test that `or` operation skips duplicated revisions from right-hand side
2242
2305
2243 $ try 'reverse(1::5) or ancestors(4)'
2306 $ try 'reverse(1::5) or ancestors(4)'
2244 (or
2307 (or
2245 (list
2308 (list
2246 (func
2309 (func
2247 ('symbol', 'reverse')
2310 ('symbol', 'reverse')
2248 (dagrange
2311 (dagrange
2249 ('symbol', '1')
2312 ('symbol', '1')
2250 ('symbol', '5')))
2313 ('symbol', '5')))
2251 (func
2314 (func
2252 ('symbol', 'ancestors')
2315 ('symbol', 'ancestors')
2253 ('symbol', '4'))))
2316 ('symbol', '4'))))
2254 * set:
2317 * set:
2255 <addset
2318 <addset
2256 <baseset- [1, 3, 5]>,
2319 <baseset- [1, 3, 5]>,
2257 <generatorset+>>
2320 <generatorset+>>
2258 5
2321 5
2259 3
2322 3
2260 1
2323 1
2261 0
2324 0
2262 2
2325 2
2263 4
2326 4
2264 $ try 'sort(ancestors(4) or reverse(1::5))'
2327 $ try 'sort(ancestors(4) or reverse(1::5))'
2265 (func
2328 (func
2266 ('symbol', 'sort')
2329 ('symbol', 'sort')
2267 (or
2330 (or
2268 (list
2331 (list
2269 (func
2332 (func
2270 ('symbol', 'ancestors')
2333 ('symbol', 'ancestors')
2271 ('symbol', '4'))
2334 ('symbol', '4'))
2272 (func
2335 (func
2273 ('symbol', 'reverse')
2336 ('symbol', 'reverse')
2274 (dagrange
2337 (dagrange
2275 ('symbol', '1')
2338 ('symbol', '1')
2276 ('symbol', '5'))))))
2339 ('symbol', '5'))))))
2277 * set:
2340 * set:
2278 <addset+
2341 <addset+
2279 <generatorset+>,
2342 <generatorset+>,
2280 <baseset- [1, 3, 5]>>
2343 <baseset- [1, 3, 5]>>
2281 0
2344 0
2282 1
2345 1
2283 2
2346 2
2284 3
2347 3
2285 4
2348 4
2286 5
2349 5
2287
2350
2288 test optimization of trivial `or` operation
2351 test optimization of trivial `or` operation
2289
2352
2290 $ try --optimize '0|(1)|"2"|-2|tip|null'
2353 $ try --optimize '0|(1)|"2"|-2|tip|null'
2291 (or
2354 (or
2292 (list
2355 (list
2293 ('symbol', '0')
2356 ('symbol', '0')
2294 (group
2357 (group
2295 ('symbol', '1'))
2358 ('symbol', '1'))
2296 ('string', '2')
2359 ('string', '2')
2297 (negate
2360 (negate
2298 ('symbol', '2'))
2361 ('symbol', '2'))
2299 ('symbol', 'tip')
2362 ('symbol', 'tip')
2300 ('symbol', 'null')))
2363 ('symbol', 'null')))
2301 * optimized:
2364 * optimized:
2302 (func
2365 (func
2303 ('symbol', '_list')
2366 ('symbol', '_list')
2304 ('string', '0\x001\x002\x00-2\x00tip\x00null')
2367 ('string', '0\x001\x002\x00-2\x00tip\x00null')
2305 define)
2368 define)
2306 * set:
2369 * set:
2307 <baseset [0, 1, 2, 8, 9, -1]>
2370 <baseset [0, 1, 2, 8, 9, -1]>
2308 0
2371 0
2309 1
2372 1
2310 2
2373 2
2311 8
2374 8
2312 9
2375 9
2313 -1
2376 -1
2314
2377
2315 $ try --optimize '0|1|2:3'
2378 $ try --optimize '0|1|2:3'
2316 (or
2379 (or
2317 (list
2380 (list
2318 ('symbol', '0')
2381 ('symbol', '0')
2319 ('symbol', '1')
2382 ('symbol', '1')
2320 (range
2383 (range
2321 ('symbol', '2')
2384 ('symbol', '2')
2322 ('symbol', '3'))))
2385 ('symbol', '3'))))
2323 * optimized:
2386 * optimized:
2324 (or
2387 (or
2325 (list
2388 (list
2326 (func
2389 (func
2327 ('symbol', '_list')
2390 ('symbol', '_list')
2328 ('string', '0\x001')
2391 ('string', '0\x001')
2329 define)
2392 define)
2330 (range
2393 (range
2331 ('symbol', '2')
2394 ('symbol', '2')
2332 ('symbol', '3')
2395 ('symbol', '3')
2333 define))
2396 define))
2334 define)
2397 define)
2335 * set:
2398 * set:
2336 <addset
2399 <addset
2337 <baseset [0, 1]>,
2400 <baseset [0, 1]>,
2338 <spanset+ 2:3>>
2401 <spanset+ 2:3>>
2339 0
2402 0
2340 1
2403 1
2341 2
2404 2
2342 3
2405 3
2343
2406
2344 $ try --optimize '0:1|2|3:4|5|6'
2407 $ try --optimize '0:1|2|3:4|5|6'
2345 (or
2408 (or
2346 (list
2409 (list
2347 (range
2410 (range
2348 ('symbol', '0')
2411 ('symbol', '0')
2349 ('symbol', '1'))
2412 ('symbol', '1'))
2350 ('symbol', '2')
2413 ('symbol', '2')
2351 (range
2414 (range
2352 ('symbol', '3')
2415 ('symbol', '3')
2353 ('symbol', '4'))
2416 ('symbol', '4'))
2354 ('symbol', '5')
2417 ('symbol', '5')
2355 ('symbol', '6')))
2418 ('symbol', '6')))
2356 * optimized:
2419 * optimized:
2357 (or
2420 (or
2358 (list
2421 (list
2359 (range
2422 (range
2360 ('symbol', '0')
2423 ('symbol', '0')
2361 ('symbol', '1')
2424 ('symbol', '1')
2362 define)
2425 define)
2363 ('symbol', '2')
2426 ('symbol', '2')
2364 (range
2427 (range
2365 ('symbol', '3')
2428 ('symbol', '3')
2366 ('symbol', '4')
2429 ('symbol', '4')
2367 define)
2430 define)
2368 (func
2431 (func
2369 ('symbol', '_list')
2432 ('symbol', '_list')
2370 ('string', '5\x006')
2433 ('string', '5\x006')
2371 define))
2434 define))
2372 define)
2435 define)
2373 * set:
2436 * set:
2374 <addset
2437 <addset
2375 <addset
2438 <addset
2376 <spanset+ 0:1>,
2439 <spanset+ 0:1>,
2377 <baseset [2]>>,
2440 <baseset [2]>>,
2378 <addset
2441 <addset
2379 <spanset+ 3:4>,
2442 <spanset+ 3:4>,
2380 <baseset [5, 6]>>>
2443 <baseset [5, 6]>>>
2381 0
2444 0
2382 1
2445 1
2383 2
2446 2
2384 3
2447 3
2385 4
2448 4
2386 5
2449 5
2387 6
2450 6
2388
2451
2389 unoptimized `or` looks like this
2452 unoptimized `or` looks like this
2390
2453
2391 $ try --no-optimized -p analyzed '0|1|2|3|4'
2454 $ try --no-optimized -p analyzed '0|1|2|3|4'
2392 * analyzed:
2455 * analyzed:
2393 (or
2456 (or
2394 (list
2457 (list
2395 ('symbol', '0')
2458 ('symbol', '0')
2396 ('symbol', '1')
2459 ('symbol', '1')
2397 ('symbol', '2')
2460 ('symbol', '2')
2398 ('symbol', '3')
2461 ('symbol', '3')
2399 ('symbol', '4'))
2462 ('symbol', '4'))
2400 define)
2463 define)
2401 * set:
2464 * set:
2402 <addset
2465 <addset
2403 <addset
2466 <addset
2404 <baseset [0]>,
2467 <baseset [0]>,
2405 <baseset [1]>>,
2468 <baseset [1]>>,
2406 <addset
2469 <addset
2407 <baseset [2]>,
2470 <baseset [2]>,
2408 <addset
2471 <addset
2409 <baseset [3]>,
2472 <baseset [3]>,
2410 <baseset [4]>>>>
2473 <baseset [4]>>>>
2411 0
2474 0
2412 1
2475 1
2413 2
2476 2
2414 3
2477 3
2415 4
2478 4
2416
2479
2417 test that `_list` should be narrowed by provided `subset`
2480 test that `_list` should be narrowed by provided `subset`
2418
2481
2419 $ log '0:2 and (null|1|2|3)'
2482 $ log '0:2 and (null|1|2|3)'
2420 1
2483 1
2421 2
2484 2
2422
2485
2423 test that `_list` should remove duplicates
2486 test that `_list` should remove duplicates
2424
2487
2425 $ log '0|1|2|1|2|-1|tip'
2488 $ log '0|1|2|1|2|-1|tip'
2426 0
2489 0
2427 1
2490 1
2428 2
2491 2
2429 9
2492 9
2430
2493
2431 test unknown revision in `_list`
2494 test unknown revision in `_list`
2432
2495
2433 $ log '0|unknown'
2496 $ log '0|unknown'
2434 abort: unknown revision 'unknown'!
2497 abort: unknown revision 'unknown'!
2435 [255]
2498 [255]
2436
2499
2437 test integer range in `_list`
2500 test integer range in `_list`
2438
2501
2439 $ log '-1|-10'
2502 $ log '-1|-10'
2440 9
2503 9
2441 0
2504 0
2442
2505
2443 $ log '-10|-11'
2506 $ log '-10|-11'
2444 abort: unknown revision '-11'!
2507 abort: unknown revision '-11'!
2445 [255]
2508 [255]
2446
2509
2447 $ log '9|10'
2510 $ log '9|10'
2448 abort: unknown revision '10'!
2511 abort: unknown revision '10'!
2449 [255]
2512 [255]
2450
2513
2451 test '0000' != '0' in `_list`
2514 test '0000' != '0' in `_list`
2452
2515
2453 $ log '0|0000'
2516 $ log '0|0000'
2454 0
2517 0
2455 -1
2518 -1
2456
2519
2457 test ',' in `_list`
2520 test ',' in `_list`
2458 $ log '0,1'
2521 $ log '0,1'
2459 hg: parse error: can't use a list in this context
2522 hg: parse error: can't use a list in this context
2460 (see hg help "revsets.x or y")
2523 (see hg help "revsets.x or y")
2461 [255]
2524 [255]
2462 $ try '0,1,2'
2525 $ try '0,1,2'
2463 (list
2526 (list
2464 ('symbol', '0')
2527 ('symbol', '0')
2465 ('symbol', '1')
2528 ('symbol', '1')
2466 ('symbol', '2'))
2529 ('symbol', '2'))
2467 hg: parse error: can't use a list in this context
2530 hg: parse error: can't use a list in this context
2468 (see hg help "revsets.x or y")
2531 (see hg help "revsets.x or y")
2469 [255]
2532 [255]
2470
2533
2471 test that chained `or` operations make balanced addsets
2534 test that chained `or` operations make balanced addsets
2472
2535
2473 $ try '0:1|1:2|2:3|3:4|4:5'
2536 $ try '0:1|1:2|2:3|3:4|4:5'
2474 (or
2537 (or
2475 (list
2538 (list
2476 (range
2539 (range
2477 ('symbol', '0')
2540 ('symbol', '0')
2478 ('symbol', '1'))
2541 ('symbol', '1'))
2479 (range
2542 (range
2480 ('symbol', '1')
2543 ('symbol', '1')
2481 ('symbol', '2'))
2544 ('symbol', '2'))
2482 (range
2545 (range
2483 ('symbol', '2')
2546 ('symbol', '2')
2484 ('symbol', '3'))
2547 ('symbol', '3'))
2485 (range
2548 (range
2486 ('symbol', '3')
2549 ('symbol', '3')
2487 ('symbol', '4'))
2550 ('symbol', '4'))
2488 (range
2551 (range
2489 ('symbol', '4')
2552 ('symbol', '4')
2490 ('symbol', '5'))))
2553 ('symbol', '5'))))
2491 * set:
2554 * set:
2492 <addset
2555 <addset
2493 <addset
2556 <addset
2494 <spanset+ 0:1>,
2557 <spanset+ 0:1>,
2495 <spanset+ 1:2>>,
2558 <spanset+ 1:2>>,
2496 <addset
2559 <addset
2497 <spanset+ 2:3>,
2560 <spanset+ 2:3>,
2498 <addset
2561 <addset
2499 <spanset+ 3:4>,
2562 <spanset+ 3:4>,
2500 <spanset+ 4:5>>>>
2563 <spanset+ 4:5>>>>
2501 0
2564 0
2502 1
2565 1
2503 2
2566 2
2504 3
2567 3
2505 4
2568 4
2506 5
2569 5
2507
2570
2508 no crash by empty group "()" while optimizing `or` operations
2571 no crash by empty group "()" while optimizing `or` operations
2509
2572
2510 $ try --optimize '0|()'
2573 $ try --optimize '0|()'
2511 (or
2574 (or
2512 (list
2575 (list
2513 ('symbol', '0')
2576 ('symbol', '0')
2514 (group
2577 (group
2515 None)))
2578 None)))
2516 * optimized:
2579 * optimized:
2517 (or
2580 (or
2518 (list
2581 (list
2519 ('symbol', '0')
2582 ('symbol', '0')
2520 None)
2583 None)
2521 define)
2584 define)
2522 hg: parse error: missing argument
2585 hg: parse error: missing argument
2523 [255]
2586 [255]
2524
2587
2525 test that chained `or` operations never eat up stack (issue4624)
2588 test that chained `or` operations never eat up stack (issue4624)
2526 (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)
2527
2590
2528 $ 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)"`
2529 0
2592 0
2530 1
2593 1
2531
2594
2532 test that repeated `-r` options never eat up stack (issue4565)
2595 test that repeated `-r` options never eat up stack (issue4565)
2533 (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)
2534
2597
2535 $ 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 ',"`
2536 0
2599 0
2537 1
2600 1
2538
2601
2539 check that conversion to only works
2602 check that conversion to only works
2540 $ try --optimize '::3 - ::1'
2603 $ try --optimize '::3 - ::1'
2541 (minus
2604 (minus
2542 (dagrangepre
2605 (dagrangepre
2543 ('symbol', '3'))
2606 ('symbol', '3'))
2544 (dagrangepre
2607 (dagrangepre
2545 ('symbol', '1')))
2608 ('symbol', '1')))
2546 * optimized:
2609 * optimized:
2547 (func
2610 (func
2548 ('symbol', 'only')
2611 ('symbol', 'only')
2549 (list
2612 (list
2550 ('symbol', '3')
2613 ('symbol', '3')
2551 ('symbol', '1'))
2614 ('symbol', '1'))
2552 define)
2615 define)
2553 * set:
2616 * set:
2554 <baseset+ [3]>
2617 <baseset+ [3]>
2555 3
2618 3
2556 $ try --optimize 'ancestors(1) - ancestors(3)'
2619 $ try --optimize 'ancestors(1) - ancestors(3)'
2557 (minus
2620 (minus
2558 (func
2621 (func
2559 ('symbol', 'ancestors')
2622 ('symbol', 'ancestors')
2560 ('symbol', '1'))
2623 ('symbol', '1'))
2561 (func
2624 (func
2562 ('symbol', 'ancestors')
2625 ('symbol', 'ancestors')
2563 ('symbol', '3')))
2626 ('symbol', '3')))
2564 * optimized:
2627 * optimized:
2565 (func
2628 (func
2566 ('symbol', 'only')
2629 ('symbol', 'only')
2567 (list
2630 (list
2568 ('symbol', '1')
2631 ('symbol', '1')
2569 ('symbol', '3'))
2632 ('symbol', '3'))
2570 define)
2633 define)
2571 * set:
2634 * set:
2572 <baseset+ []>
2635 <baseset+ []>
2573 $ try --optimize 'not ::2 and ::6'
2636 $ try --optimize 'not ::2 and ::6'
2574 (and
2637 (and
2575 (not
2638 (not
2576 (dagrangepre
2639 (dagrangepre
2577 ('symbol', '2')))
2640 ('symbol', '2')))
2578 (dagrangepre
2641 (dagrangepre
2579 ('symbol', '6')))
2642 ('symbol', '6')))
2580 * optimized:
2643 * optimized:
2581 (func
2644 (func
2582 ('symbol', 'only')
2645 ('symbol', 'only')
2583 (list
2646 (list
2584 ('symbol', '6')
2647 ('symbol', '6')
2585 ('symbol', '2'))
2648 ('symbol', '2'))
2586 define)
2649 define)
2587 * set:
2650 * set:
2588 <baseset+ [3, 4, 5, 6]>
2651 <baseset+ [3, 4, 5, 6]>
2589 3
2652 3
2590 4
2653 4
2591 5
2654 5
2592 6
2655 6
2593 $ try --optimize 'ancestors(6) and not ancestors(4)'
2656 $ try --optimize 'ancestors(6) and not ancestors(4)'
2594 (and
2657 (and
2595 (func
2658 (func
2596 ('symbol', 'ancestors')
2659 ('symbol', 'ancestors')
2597 ('symbol', '6'))
2660 ('symbol', '6'))
2598 (not
2661 (not
2599 (func
2662 (func
2600 ('symbol', 'ancestors')
2663 ('symbol', 'ancestors')
2601 ('symbol', '4'))))
2664 ('symbol', '4'))))
2602 * optimized:
2665 * optimized:
2603 (func
2666 (func
2604 ('symbol', 'only')
2667 ('symbol', 'only')
2605 (list
2668 (list
2606 ('symbol', '6')
2669 ('symbol', '6')
2607 ('symbol', '4'))
2670 ('symbol', '4'))
2608 define)
2671 define)
2609 * set:
2672 * set:
2610 <baseset+ [3, 5, 6]>
2673 <baseset+ [3, 5, 6]>
2611 3
2674 3
2612 5
2675 5
2613 6
2676 6
2614
2677
2615 no crash by empty group "()" while optimizing to "only()"
2678 no crash by empty group "()" while optimizing to "only()"
2616
2679
2617 $ try --optimize '::1 and ()'
2680 $ try --optimize '::1 and ()'
2618 (and
2681 (and
2619 (dagrangepre
2682 (dagrangepre
2620 ('symbol', '1'))
2683 ('symbol', '1'))
2621 (group
2684 (group
2622 None))
2685 None))
2623 * optimized:
2686 * optimized:
2624 (and
2687 (and
2625 None
2688 None
2626 (func
2689 (func
2627 ('symbol', 'ancestors')
2690 ('symbol', 'ancestors')
2628 ('symbol', '1')
2691 ('symbol', '1')
2629 define)
2692 define)
2630 define)
2693 define)
2631 hg: parse error: missing argument
2694 hg: parse error: missing argument
2632 [255]
2695 [255]
2633
2696
2634 invalid function call should not be optimized to only()
2697 invalid function call should not be optimized to only()
2635
2698
2636 $ log '"ancestors"(6) and not ancestors(4)'
2699 $ log '"ancestors"(6) and not ancestors(4)'
2637 hg: parse error: not a symbol
2700 hg: parse error: not a symbol
2638 [255]
2701 [255]
2639
2702
2640 $ log 'ancestors(6) and not "ancestors"(4)'
2703 $ log 'ancestors(6) and not "ancestors"(4)'
2641 hg: parse error: not a symbol
2704 hg: parse error: not a symbol
2642 [255]
2705 [255]
2643
2706
2644 we can use patterns when searching for tags
2707 we can use patterns when searching for tags
2645
2708
2646 $ log 'tag("1..*")'
2709 $ log 'tag("1..*")'
2647 abort: tag '1..*' does not exist!
2710 abort: tag '1..*' does not exist!
2648 [255]
2711 [255]
2649 $ log 'tag("re:1..*")'
2712 $ log 'tag("re:1..*")'
2650 6
2713 6
2651 $ log 'tag("re:[0-9].[0-9]")'
2714 $ log 'tag("re:[0-9].[0-9]")'
2652 6
2715 6
2653 $ log 'tag("literal:1.0")'
2716 $ log 'tag("literal:1.0")'
2654 6
2717 6
2655 $ log 'tag("re:0..*")'
2718 $ log 'tag("re:0..*")'
2656
2719
2657 $ log 'tag(unknown)'
2720 $ log 'tag(unknown)'
2658 abort: tag 'unknown' does not exist!
2721 abort: tag 'unknown' does not exist!
2659 [255]
2722 [255]
2660 $ log 'tag("re:unknown")'
2723 $ log 'tag("re:unknown")'
2661 $ log 'present(tag("unknown"))'
2724 $ log 'present(tag("unknown"))'
2662 $ log 'present(tag("re:unknown"))'
2725 $ log 'present(tag("re:unknown"))'
2663 $ log 'branch(unknown)'
2726 $ log 'branch(unknown)'
2664 abort: unknown revision 'unknown'!
2727 abort: unknown revision 'unknown'!
2665 [255]
2728 [255]
2666 $ log 'branch("literal:unknown")'
2729 $ log 'branch("literal:unknown")'
2667 abort: branch 'unknown' does not exist!
2730 abort: branch 'unknown' does not exist!
2668 [255]
2731 [255]
2669 $ log 'branch("re:unknown")'
2732 $ log 'branch("re:unknown")'
2670 $ log 'present(branch("unknown"))'
2733 $ log 'present(branch("unknown"))'
2671 $ log 'present(branch("re:unknown"))'
2734 $ log 'present(branch("re:unknown"))'
2672 $ log 'user(bob)'
2735 $ log 'user(bob)'
2673 2
2736 2
2674
2737
2675 $ log '4::8'
2738 $ log '4::8'
2676 4
2739 4
2677 8
2740 8
2678 $ log '4:8'
2741 $ log '4:8'
2679 4
2742 4
2680 5
2743 5
2681 6
2744 6
2682 7
2745 7
2683 8
2746 8
2684
2747
2685 $ 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")'
2686 4
2749 4
2687 2
2750 2
2688 5
2751 5
2689
2752
2690 $ log 'not 0 and 0:2'
2753 $ log 'not 0 and 0:2'
2691 1
2754 1
2692 2
2755 2
2693 $ log 'not 1 and 0:2'
2756 $ log 'not 1 and 0:2'
2694 0
2757 0
2695 2
2758 2
2696 $ log 'not 2 and 0:2'
2759 $ log 'not 2 and 0:2'
2697 0
2760 0
2698 1
2761 1
2699 $ log '(1 and 2)::'
2762 $ log '(1 and 2)::'
2700 $ log '(1 and 2):'
2763 $ log '(1 and 2):'
2701 $ log '(1 and 2):3'
2764 $ log '(1 and 2):3'
2702 $ log 'sort(head(), -rev)'
2765 $ log 'sort(head(), -rev)'
2703 9
2766 9
2704 7
2767 7
2705 6
2768 6
2706 5
2769 5
2707 4
2770 4
2708 3
2771 3
2709 2
2772 2
2710 1
2773 1
2711 0
2774 0
2712 $ log '4::8 - 8'
2775 $ log '4::8 - 8'
2713 4
2776 4
2714
2777
2715 matching() should preserve the order of the input set:
2778 matching() should preserve the order of the input set:
2716
2779
2717 $ 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)'
2718 2
2781 2
2719 3
2782 3
2720 1
2783 1
2721
2784
2722 $ log 'named("unknown")'
2785 $ log 'named("unknown")'
2723 abort: namespace 'unknown' does not exist!
2786 abort: namespace 'unknown' does not exist!
2724 [255]
2787 [255]
2725 $ log 'named("re:unknown")'
2788 $ log 'named("re:unknown")'
2726 abort: no namespace exists that match 'unknown'!
2789 abort: no namespace exists that match 'unknown'!
2727 [255]
2790 [255]
2728 $ log 'present(named("unknown"))'
2791 $ log 'present(named("unknown"))'
2729 $ log 'present(named("re:unknown"))'
2792 $ log 'present(named("re:unknown"))'
2730
2793
2731 $ log 'tag()'
2794 $ log 'tag()'
2732 6
2795 6
2733 $ log 'named("tags")'
2796 $ log 'named("tags")'
2734 6
2797 6
2735
2798
2736 issue2437
2799 issue2437
2737
2800
2738 $ log '3 and p1(5)'
2801 $ log '3 and p1(5)'
2739 3
2802 3
2740 $ log '4 and p2(6)'
2803 $ log '4 and p2(6)'
2741 4
2804 4
2742 $ log '1 and parents(:2)'
2805 $ log '1 and parents(:2)'
2743 1
2806 1
2744 $ log '2 and children(1:)'
2807 $ log '2 and children(1:)'
2745 2
2808 2
2746 $ log 'roots(all()) or roots(all())'
2809 $ log 'roots(all()) or roots(all())'
2747 0
2810 0
2748 $ hg debugrevspec 'roots(all()) or roots(all())'
2811 $ hg debugrevspec 'roots(all()) or roots(all())'
2749 0
2812 0
2750 $ log 'heads(branch(Γ©)) or heads(branch(Γ©))'
2813 $ log 'heads(branch(Γ©)) or heads(branch(Γ©))'
2751 9
2814 9
2752 $ 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(Γ©)))'
2753 4
2816 4
2754
2817
2755 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
2756
2819
2757 $ log '1 OR 2'
2820 $ log '1 OR 2'
2758 hg: parse error at 2: invalid token
2821 hg: parse error at 2: invalid token
2759 [255]
2822 [255]
2760
2823
2761 or operator should preserve ordering:
2824 or operator should preserve ordering:
2762 $ log 'reverse(2::4) or tip'
2825 $ log 'reverse(2::4) or tip'
2763 4
2826 4
2764 2
2827 2
2765 9
2828 9
2766
2829
2767 parentrevspec
2830 parentrevspec
2768
2831
2769 $ log 'merge()^0'
2832 $ log 'merge()^0'
2770 6
2833 6
2771 $ log 'merge()^'
2834 $ log 'merge()^'
2772 5
2835 5
2773 $ log 'merge()^1'
2836 $ log 'merge()^1'
2774 5
2837 5
2775 $ log 'merge()^2'
2838 $ log 'merge()^2'
2776 4
2839 4
2777 $ log '(not merge())^2'
2840 $ log '(not merge())^2'
2778 $ log 'merge()^^'
2841 $ log 'merge()^^'
2779 3
2842 3
2780 $ log 'merge()^1^'
2843 $ log 'merge()^1^'
2781 3
2844 3
2782 $ log 'merge()^^^'
2845 $ log 'merge()^^^'
2783 1
2846 1
2784
2847
2785 $ log 'merge()~0'
2848 $ log 'merge()~0'
2786 6
2849 6
2787 $ log 'merge()~1'
2850 $ log 'merge()~1'
2788 5
2851 5
2789 $ log 'merge()~2'
2852 $ log 'merge()~2'
2790 3
2853 3
2791 $ log 'merge()~2^1'
2854 $ log 'merge()~2^1'
2792 1
2855 1
2793 $ log 'merge()~3'
2856 $ log 'merge()~3'
2794 1
2857 1
2795
2858
2796 $ log '(-3:tip)^'
2859 $ log '(-3:tip)^'
2797 4
2860 4
2798 6
2861 6
2799 8
2862 8
2800
2863
2801 $ log 'tip^foo'
2864 $ log 'tip^foo'
2802 hg: parse error: ^ expects a number 0, 1, or 2
2865 hg: parse error: ^ expects a number 0, 1, or 2
2803 [255]
2866 [255]
2804
2867
2805 Bogus function gets suggestions
2868 Bogus function gets suggestions
2806 $ log 'add()'
2869 $ log 'add()'
2807 hg: parse error: unknown identifier: add
2870 hg: parse error: unknown identifier: add
2808 (did you mean adds?)
2871 (did you mean adds?)
2809 [255]
2872 [255]
2810 $ log 'added()'
2873 $ log 'added()'
2811 hg: parse error: unknown identifier: added
2874 hg: parse error: unknown identifier: added
2812 (did you mean adds?)
2875 (did you mean adds?)
2813 [255]
2876 [255]
2814 $ log 'remo()'
2877 $ log 'remo()'
2815 hg: parse error: unknown identifier: remo
2878 hg: parse error: unknown identifier: remo
2816 (did you mean one of remote, removes?)
2879 (did you mean one of remote, removes?)
2817 [255]
2880 [255]
2818 $ log 'babar()'
2881 $ log 'babar()'
2819 hg: parse error: unknown identifier: babar
2882 hg: parse error: unknown identifier: babar
2820 [255]
2883 [255]
2821
2884
2822 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
2823 $ log 'matches()'
2886 $ log 'matches()'
2824 hg: parse error: unknown identifier: matches
2887 hg: parse error: unknown identifier: matches
2825 (did you mean matching?)
2888 (did you mean matching?)
2826 [255]
2889 [255]
2827
2890
2828 Undocumented functions aren't suggested as similar either
2891 Undocumented functions aren't suggested as similar either
2829 $ log 'tagged2()'
2892 $ log 'tagged2()'
2830 hg: parse error: unknown identifier: tagged2
2893 hg: parse error: unknown identifier: tagged2
2831 [255]
2894 [255]
2832
2895
2833 multiple revspecs
2896 multiple revspecs
2834
2897
2835 $ 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'
2836 8
2899 8
2837 9
2900 9
2838 4
2901 4
2839 5
2902 5
2840 6
2903 6
2841 7
2904 7
2842
2905
2843 test usage in revpair (with "+")
2906 test usage in revpair (with "+")
2844
2907
2845 (real pair)
2908 (real pair)
2846
2909
2847 $ hg diff -r 'tip^^' -r 'tip'
2910 $ hg diff -r 'tip^^' -r 'tip'
2848 diff -r 2326846efdab -r 24286f4ae135 .hgtags
2911 diff -r 2326846efdab -r 24286f4ae135 .hgtags
2849 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2912 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2850 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2913 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2851 @@ -0,0 +1,1 @@
2914 @@ -0,0 +1,1 @@
2852 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2915 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2853 $ hg diff -r 'tip^^::tip'
2916 $ hg diff -r 'tip^^::tip'
2854 diff -r 2326846efdab -r 24286f4ae135 .hgtags
2917 diff -r 2326846efdab -r 24286f4ae135 .hgtags
2855 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2918 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2856 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2919 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2857 @@ -0,0 +1,1 @@
2920 @@ -0,0 +1,1 @@
2858 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2921 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2859
2922
2860 (single rev)
2923 (single rev)
2861
2924
2862 $ hg diff -r 'tip^' -r 'tip^'
2925 $ hg diff -r 'tip^' -r 'tip^'
2863 $ hg diff -r 'tip^:tip^'
2926 $ hg diff -r 'tip^:tip^'
2864
2927
2865 (single rev that does not looks like a range)
2928 (single rev that does not looks like a range)
2866
2929
2867 $ hg diff -r 'tip^::tip^ or tip^'
2930 $ hg diff -r 'tip^::tip^ or tip^'
2868 diff -r d5d0dcbdc4d9 .hgtags
2931 diff -r d5d0dcbdc4d9 .hgtags
2869 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2932 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2870 +++ b/.hgtags * (glob)
2933 +++ b/.hgtags * (glob)
2871 @@ -0,0 +1,1 @@
2934 @@ -0,0 +1,1 @@
2872 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2935 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2873 $ hg diff -r 'tip^ or tip^'
2936 $ hg diff -r 'tip^ or tip^'
2874 diff -r d5d0dcbdc4d9 .hgtags
2937 diff -r d5d0dcbdc4d9 .hgtags
2875 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2938 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2876 +++ b/.hgtags * (glob)
2939 +++ b/.hgtags * (glob)
2877 @@ -0,0 +1,1 @@
2940 @@ -0,0 +1,1 @@
2878 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2941 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
2879
2942
2880 (no rev)
2943 (no rev)
2881
2944
2882 $ hg diff -r 'author("babar") or author("celeste")'
2945 $ hg diff -r 'author("babar") or author("celeste")'
2883 abort: empty revision range
2946 abort: empty revision range
2884 [255]
2947 [255]
2885
2948
2886 aliases:
2949 aliases:
2887
2950
2888 $ echo '[revsetalias]' >> .hg/hgrc
2951 $ echo '[revsetalias]' >> .hg/hgrc
2889 $ echo 'm = merge()' >> .hg/hgrc
2952 $ echo 'm = merge()' >> .hg/hgrc
2890 (revset aliases can override builtin revsets)
2953 (revset aliases can override builtin revsets)
2891 $ echo 'p2($1) = p1($1)' >> .hg/hgrc
2954 $ echo 'p2($1) = p1($1)' >> .hg/hgrc
2892 $ echo 'sincem = descendants(m)' >> .hg/hgrc
2955 $ echo 'sincem = descendants(m)' >> .hg/hgrc
2893 $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
2956 $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
2894 $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
2957 $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
2895 $ 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
2896
2959
2897 $ try m
2960 $ try m
2898 ('symbol', 'm')
2961 ('symbol', 'm')
2899 * expanded:
2962 * expanded:
2900 (func
2963 (func
2901 ('symbol', 'merge')
2964 ('symbol', 'merge')
2902 None)
2965 None)
2903 * set:
2966 * set:
2904 <filteredset
2967 <filteredset
2905 <fullreposet+ 0:9>,
2968 <fullreposet+ 0:9>,
2906 <merge>>
2969 <merge>>
2907 6
2970 6
2908
2971
2909 $ HGPLAIN=1
2972 $ HGPLAIN=1
2910 $ export HGPLAIN
2973 $ export HGPLAIN
2911 $ try m
2974 $ try m
2912 ('symbol', 'm')
2975 ('symbol', 'm')
2913 abort: unknown revision 'm'!
2976 abort: unknown revision 'm'!
2914 [255]
2977 [255]
2915
2978
2916 $ HGPLAINEXCEPT=revsetalias
2979 $ HGPLAINEXCEPT=revsetalias
2917 $ export HGPLAINEXCEPT
2980 $ export HGPLAINEXCEPT
2918 $ try m
2981 $ try m
2919 ('symbol', 'm')
2982 ('symbol', 'm')
2920 * expanded:
2983 * expanded:
2921 (func
2984 (func
2922 ('symbol', 'merge')
2985 ('symbol', 'merge')
2923 None)
2986 None)
2924 * set:
2987 * set:
2925 <filteredset
2988 <filteredset
2926 <fullreposet+ 0:9>,
2989 <fullreposet+ 0:9>,
2927 <merge>>
2990 <merge>>
2928 6
2991 6
2929
2992
2930 $ unset HGPLAIN
2993 $ unset HGPLAIN
2931 $ unset HGPLAINEXCEPT
2994 $ unset HGPLAINEXCEPT
2932
2995
2933 $ try 'p2(.)'
2996 $ try 'p2(.)'
2934 (func
2997 (func
2935 ('symbol', 'p2')
2998 ('symbol', 'p2')
2936 ('symbol', '.'))
2999 ('symbol', '.'))
2937 * expanded:
3000 * expanded:
2938 (func
3001 (func
2939 ('symbol', 'p1')
3002 ('symbol', 'p1')
2940 ('symbol', '.'))
3003 ('symbol', '.'))
2941 * set:
3004 * set:
2942 <baseset+ [8]>
3005 <baseset+ [8]>
2943 8
3006 8
2944
3007
2945 $ HGPLAIN=1
3008 $ HGPLAIN=1
2946 $ export HGPLAIN
3009 $ export HGPLAIN
2947 $ try 'p2(.)'
3010 $ try 'p2(.)'
2948 (func
3011 (func
2949 ('symbol', 'p2')
3012 ('symbol', 'p2')
2950 ('symbol', '.'))
3013 ('symbol', '.'))
2951 * set:
3014 * set:
2952 <baseset+ []>
3015 <baseset+ []>
2953
3016
2954 $ HGPLAINEXCEPT=revsetalias
3017 $ HGPLAINEXCEPT=revsetalias
2955 $ export HGPLAINEXCEPT
3018 $ export HGPLAINEXCEPT
2956 $ try 'p2(.)'
3019 $ try 'p2(.)'
2957 (func
3020 (func
2958 ('symbol', 'p2')
3021 ('symbol', 'p2')
2959 ('symbol', '.'))
3022 ('symbol', '.'))
2960 * expanded:
3023 * expanded:
2961 (func
3024 (func
2962 ('symbol', 'p1')
3025 ('symbol', 'p1')
2963 ('symbol', '.'))
3026 ('symbol', '.'))
2964 * set:
3027 * set:
2965 <baseset+ [8]>
3028 <baseset+ [8]>
2966 8
3029 8
2967
3030
2968 $ unset HGPLAIN
3031 $ unset HGPLAIN
2969 $ unset HGPLAINEXCEPT
3032 $ unset HGPLAINEXCEPT
2970
3033
2971 test alias recursion
3034 test alias recursion
2972
3035
2973 $ try sincem
3036 $ try sincem
2974 ('symbol', 'sincem')
3037 ('symbol', 'sincem')
2975 * expanded:
3038 * expanded:
2976 (func
3039 (func
2977 ('symbol', 'descendants')
3040 ('symbol', 'descendants')
2978 (func
3041 (func
2979 ('symbol', 'merge')
3042 ('symbol', 'merge')
2980 None))
3043 None))
2981 * set:
3044 * set:
2982 <addset+
3045 <addset+
2983 <filteredset
3046 <filteredset
2984 <fullreposet+ 0:9>,
3047 <fullreposet+ 0:9>,
2985 <merge>>,
3048 <merge>>,
2986 <generatorset+>>
3049 <generatorset+>>
2987 6
3050 6
2988 7
3051 7
2989
3052
2990 test infinite recursion
3053 test infinite recursion
2991
3054
2992 $ echo 'recurse1 = recurse2' >> .hg/hgrc
3055 $ echo 'recurse1 = recurse2' >> .hg/hgrc
2993 $ echo 'recurse2 = recurse1' >> .hg/hgrc
3056 $ echo 'recurse2 = recurse1' >> .hg/hgrc
2994 $ try recurse1
3057 $ try recurse1
2995 ('symbol', 'recurse1')
3058 ('symbol', 'recurse1')
2996 hg: parse error: infinite expansion of revset alias "recurse1" detected
3059 hg: parse error: infinite expansion of revset alias "recurse1" detected
2997 [255]
3060 [255]
2998
3061
2999 $ echo 'level1($1, $2) = $1 or $2' >> .hg/hgrc
3062 $ echo 'level1($1, $2) = $1 or $2' >> .hg/hgrc
3000 $ echo 'level2($1, $2) = level1($2, $1)' >> .hg/hgrc
3063 $ echo 'level2($1, $2) = level1($2, $1)' >> .hg/hgrc
3001 $ try "level2(level1(1, 2), 3)"
3064 $ try "level2(level1(1, 2), 3)"
3002 (func
3065 (func
3003 ('symbol', 'level2')
3066 ('symbol', 'level2')
3004 (list
3067 (list
3005 (func
3068 (func
3006 ('symbol', 'level1')
3069 ('symbol', 'level1')
3007 (list
3070 (list
3008 ('symbol', '1')
3071 ('symbol', '1')
3009 ('symbol', '2')))
3072 ('symbol', '2')))
3010 ('symbol', '3')))
3073 ('symbol', '3')))
3011 * expanded:
3074 * expanded:
3012 (or
3075 (or
3013 (list
3076 (list
3014 ('symbol', '3')
3077 ('symbol', '3')
3015 (or
3078 (or
3016 (list
3079 (list
3017 ('symbol', '1')
3080 ('symbol', '1')
3018 ('symbol', '2')))))
3081 ('symbol', '2')))))
3019 * set:
3082 * set:
3020 <addset
3083 <addset
3021 <baseset [3]>,
3084 <baseset [3]>,
3022 <baseset [1, 2]>>
3085 <baseset [1, 2]>>
3023 3
3086 3
3024 1
3087 1
3025 2
3088 2
3026
3089
3027 test nesting and variable passing
3090 test nesting and variable passing
3028
3091
3029 $ echo 'nested($1) = nested2($1)' >> .hg/hgrc
3092 $ echo 'nested($1) = nested2($1)' >> .hg/hgrc
3030 $ echo 'nested2($1) = nested3($1)' >> .hg/hgrc
3093 $ echo 'nested2($1) = nested3($1)' >> .hg/hgrc
3031 $ echo 'nested3($1) = max($1)' >> .hg/hgrc
3094 $ echo 'nested3($1) = max($1)' >> .hg/hgrc
3032 $ try 'nested(2:5)'
3095 $ try 'nested(2:5)'
3033 (func
3096 (func
3034 ('symbol', 'nested')
3097 ('symbol', 'nested')
3035 (range
3098 (range
3036 ('symbol', '2')
3099 ('symbol', '2')
3037 ('symbol', '5')))
3100 ('symbol', '5')))
3038 * expanded:
3101 * expanded:
3039 (func
3102 (func
3040 ('symbol', 'max')
3103 ('symbol', 'max')
3041 (range
3104 (range
3042 ('symbol', '2')
3105 ('symbol', '2')
3043 ('symbol', '5')))
3106 ('symbol', '5')))
3044 * set:
3107 * set:
3045 <baseset
3108 <baseset
3046 <max
3109 <max
3047 <fullreposet+ 0:9>,
3110 <fullreposet+ 0:9>,
3048 <spanset+ 2:5>>>
3111 <spanset+ 2:5>>>
3049 5
3112 5
3050
3113
3051 test chained `or` operations are flattened at parsing phase
3114 test chained `or` operations are flattened at parsing phase
3052
3115
3053 $ echo 'chainedorops($1, $2, $3) = $1|$2|$3' >> .hg/hgrc
3116 $ echo 'chainedorops($1, $2, $3) = $1|$2|$3' >> .hg/hgrc
3054 $ try 'chainedorops(0:1, 1:2, 2:3)'
3117 $ try 'chainedorops(0:1, 1:2, 2:3)'
3055 (func
3118 (func
3056 ('symbol', 'chainedorops')
3119 ('symbol', 'chainedorops')
3057 (list
3120 (list
3058 (range
3121 (range
3059 ('symbol', '0')
3122 ('symbol', '0')
3060 ('symbol', '1'))
3123 ('symbol', '1'))
3061 (range
3124 (range
3062 ('symbol', '1')
3125 ('symbol', '1')
3063 ('symbol', '2'))
3126 ('symbol', '2'))
3064 (range
3127 (range
3065 ('symbol', '2')
3128 ('symbol', '2')
3066 ('symbol', '3'))))
3129 ('symbol', '3'))))
3067 * expanded:
3130 * expanded:
3068 (or
3131 (or
3069 (list
3132 (list
3070 (range
3133 (range
3071 ('symbol', '0')
3134 ('symbol', '0')
3072 ('symbol', '1'))
3135 ('symbol', '1'))
3073 (range
3136 (range
3074 ('symbol', '1')
3137 ('symbol', '1')
3075 ('symbol', '2'))
3138 ('symbol', '2'))
3076 (range
3139 (range
3077 ('symbol', '2')
3140 ('symbol', '2')
3078 ('symbol', '3'))))
3141 ('symbol', '3'))))
3079 * set:
3142 * set:
3080 <addset
3143 <addset
3081 <spanset+ 0:1>,
3144 <spanset+ 0:1>,
3082 <addset
3145 <addset
3083 <spanset+ 1:2>,
3146 <spanset+ 1:2>,
3084 <spanset+ 2:3>>>
3147 <spanset+ 2:3>>>
3085 0
3148 0
3086 1
3149 1
3087 2
3150 2
3088 3
3151 3
3089
3152
3090 test variable isolation, variable placeholders are rewritten as string
3153 test variable isolation, variable placeholders are rewritten as string
3091 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
3092 far away.
3155 far away.
3093
3156
3094 $ echo 'injectparamasstring = max("$1")' >> .hg/hgrc
3157 $ echo 'injectparamasstring = max("$1")' >> .hg/hgrc
3095 $ echo 'callinjection($1) = descendants(injectparamasstring)' >> .hg/hgrc
3158 $ echo 'callinjection($1) = descendants(injectparamasstring)' >> .hg/hgrc
3096 $ try 'callinjection(2:5)'
3159 $ try 'callinjection(2:5)'
3097 (func
3160 (func
3098 ('symbol', 'callinjection')
3161 ('symbol', 'callinjection')
3099 (range
3162 (range
3100 ('symbol', '2')
3163 ('symbol', '2')
3101 ('symbol', '5')))
3164 ('symbol', '5')))
3102 * expanded:
3165 * expanded:
3103 (func
3166 (func
3104 ('symbol', 'descendants')
3167 ('symbol', 'descendants')
3105 (func
3168 (func
3106 ('symbol', 'max')
3169 ('symbol', 'max')
3107 ('string', '$1')))
3170 ('string', '$1')))
3108 abort: unknown revision '$1'!
3171 abort: unknown revision '$1'!
3109 [255]
3172 [255]
3110
3173
3111 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)',
3112 but 'all()' should never be substituted to '0()'.
3175 but 'all()' should never be substituted to '0()'.
3113
3176
3114 $ echo 'universe = all()' >> .hg/hgrc
3177 $ echo 'universe = all()' >> .hg/hgrc
3115 $ echo 'shadowall(all) = all and universe' >> .hg/hgrc
3178 $ echo 'shadowall(all) = all and universe' >> .hg/hgrc
3116 $ try 'shadowall(0)'
3179 $ try 'shadowall(0)'
3117 (func
3180 (func
3118 ('symbol', 'shadowall')
3181 ('symbol', 'shadowall')
3119 ('symbol', '0'))
3182 ('symbol', '0'))
3120 * expanded:
3183 * expanded:
3121 (and
3184 (and
3122 ('symbol', '0')
3185 ('symbol', '0')
3123 (func
3186 (func
3124 ('symbol', 'all')
3187 ('symbol', 'all')
3125 None))
3188 None))
3126 * set:
3189 * set:
3127 <filteredset
3190 <filteredset
3128 <baseset [0]>,
3191 <baseset [0]>,
3129 <spanset+ 0:9>>
3192 <spanset+ 0:9>>
3130 0
3193 0
3131
3194
3132 test unknown reference:
3195 test unknown reference:
3133
3196
3134 $ try "unknownref(0)" --config 'revsetalias.unknownref($1)=$1:$2'
3197 $ try "unknownref(0)" --config 'revsetalias.unknownref($1)=$1:$2'
3135 (func
3198 (func
3136 ('symbol', 'unknownref')
3199 ('symbol', 'unknownref')
3137 ('symbol', '0'))
3200 ('symbol', '0'))
3138 abort: bad definition of revset alias "unknownref": invalid symbol '$2'
3201 abort: bad definition of revset alias "unknownref": invalid symbol '$2'
3139 [255]
3202 [255]
3140
3203
3141 $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
3204 $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
3142 ('symbol', 'tip')
3205 ('symbol', 'tip')
3143 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
3144 * set:
3207 * set:
3145 <baseset [9]>
3208 <baseset [9]>
3146 9
3209 9
3147
3210
3148 $ try 'tip'
3211 $ try 'tip'
3149 ('symbol', 'tip')
3212 ('symbol', 'tip')
3150 * set:
3213 * set:
3151 <baseset [9]>
3214 <baseset [9]>
3152 9
3215 9
3153
3216
3154 $ hg debugrevspec --debug --config revsetalias.'bad name'='tip' "tip"
3217 $ hg debugrevspec --debug --config revsetalias.'bad name'='tip' "tip"
3155 ('symbol', 'tip')
3218 ('symbol', 'tip')
3156 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
3157 * set:
3220 * set:
3158 <baseset [9]>
3221 <baseset [9]>
3159 9
3222 9
3160 $ echo 'strictreplacing($1, $10) = $10 or desc("$1")' >> .hg/hgrc
3223 $ echo 'strictreplacing($1, $10) = $10 or desc("$1")' >> .hg/hgrc
3161 $ try 'strictreplacing("foo", tip)'
3224 $ try 'strictreplacing("foo", tip)'
3162 (func
3225 (func
3163 ('symbol', 'strictreplacing')
3226 ('symbol', 'strictreplacing')
3164 (list
3227 (list
3165 ('string', 'foo')
3228 ('string', 'foo')
3166 ('symbol', 'tip')))
3229 ('symbol', 'tip')))
3167 * expanded:
3230 * expanded:
3168 (or
3231 (or
3169 (list
3232 (list
3170 ('symbol', 'tip')
3233 ('symbol', 'tip')
3171 (func
3234 (func
3172 ('symbol', 'desc')
3235 ('symbol', 'desc')
3173 ('string', '$1'))))
3236 ('string', '$1'))))
3174 * set:
3237 * set:
3175 <addset
3238 <addset
3176 <baseset [9]>,
3239 <baseset [9]>,
3177 <filteredset
3240 <filteredset
3178 <fullreposet+ 0:9>,
3241 <fullreposet+ 0:9>,
3179 <desc '$1'>>>
3242 <desc '$1'>>>
3180 9
3243 9
3181
3244
3182 $ try 'd(2:5)'
3245 $ try 'd(2:5)'
3183 (func
3246 (func
3184 ('symbol', 'd')
3247 ('symbol', 'd')
3185 (range
3248 (range
3186 ('symbol', '2')
3249 ('symbol', '2')
3187 ('symbol', '5')))
3250 ('symbol', '5')))
3188 * expanded:
3251 * expanded:
3189 (func
3252 (func
3190 ('symbol', 'reverse')
3253 ('symbol', 'reverse')
3191 (func
3254 (func
3192 ('symbol', 'sort')
3255 ('symbol', 'sort')
3193 (list
3256 (list
3194 (range
3257 (range
3195 ('symbol', '2')
3258 ('symbol', '2')
3196 ('symbol', '5'))
3259 ('symbol', '5'))
3197 ('symbol', 'date'))))
3260 ('symbol', 'date'))))
3198 * set:
3261 * set:
3199 <baseset [4, 5, 3, 2]>
3262 <baseset [4, 5, 3, 2]>
3200 4
3263 4
3201 5
3264 5
3202 3
3265 3
3203 2
3266 2
3204 $ try 'rs(2 or 3, date)'
3267 $ try 'rs(2 or 3, date)'
3205 (func
3268 (func
3206 ('symbol', 'rs')
3269 ('symbol', 'rs')
3207 (list
3270 (list
3208 (or
3271 (or
3209 (list
3272 (list
3210 ('symbol', '2')
3273 ('symbol', '2')
3211 ('symbol', '3')))
3274 ('symbol', '3')))
3212 ('symbol', 'date')))
3275 ('symbol', 'date')))
3213 * expanded:
3276 * expanded:
3214 (func
3277 (func
3215 ('symbol', 'reverse')
3278 ('symbol', 'reverse')
3216 (func
3279 (func
3217 ('symbol', 'sort')
3280 ('symbol', 'sort')
3218 (list
3281 (list
3219 (or
3282 (or
3220 (list
3283 (list
3221 ('symbol', '2')
3284 ('symbol', '2')
3222 ('symbol', '3')))
3285 ('symbol', '3')))
3223 ('symbol', 'date'))))
3286 ('symbol', 'date'))))
3224 * set:
3287 * set:
3225 <baseset [3, 2]>
3288 <baseset [3, 2]>
3226 3
3289 3
3227 2
3290 2
3228 $ try 'rs()'
3291 $ try 'rs()'
3229 (func
3292 (func
3230 ('symbol', 'rs')
3293 ('symbol', 'rs')
3231 None)
3294 None)
3232 hg: parse error: invalid number of arguments: 0
3295 hg: parse error: invalid number of arguments: 0
3233 [255]
3296 [255]
3234 $ try 'rs(2)'
3297 $ try 'rs(2)'
3235 (func
3298 (func
3236 ('symbol', 'rs')
3299 ('symbol', 'rs')
3237 ('symbol', '2'))
3300 ('symbol', '2'))
3238 hg: parse error: invalid number of arguments: 1
3301 hg: parse error: invalid number of arguments: 1
3239 [255]
3302 [255]
3240 $ try 'rs(2, data, 7)'
3303 $ try 'rs(2, data, 7)'
3241 (func
3304 (func
3242 ('symbol', 'rs')
3305 ('symbol', 'rs')
3243 (list
3306 (list
3244 ('symbol', '2')
3307 ('symbol', '2')
3245 ('symbol', 'data')
3308 ('symbol', 'data')
3246 ('symbol', '7')))
3309 ('symbol', '7')))
3247 hg: parse error: invalid number of arguments: 3
3310 hg: parse error: invalid number of arguments: 3
3248 [255]
3311 [255]
3249 $ try 'rs4(2 or 3, x, x, date)'
3312 $ try 'rs4(2 or 3, x, x, date)'
3250 (func
3313 (func
3251 ('symbol', 'rs4')
3314 ('symbol', 'rs4')
3252 (list
3315 (list
3253 (or
3316 (or
3254 (list
3317 (list
3255 ('symbol', '2')
3318 ('symbol', '2')
3256 ('symbol', '3')))
3319 ('symbol', '3')))
3257 ('symbol', 'x')
3320 ('symbol', 'x')
3258 ('symbol', 'x')
3321 ('symbol', 'x')
3259 ('symbol', 'date')))
3322 ('symbol', 'date')))
3260 * expanded:
3323 * expanded:
3261 (func
3324 (func
3262 ('symbol', 'reverse')
3325 ('symbol', 'reverse')
3263 (func
3326 (func
3264 ('symbol', 'sort')
3327 ('symbol', 'sort')
3265 (list
3328 (list
3266 (or
3329 (or
3267 (list
3330 (list
3268 ('symbol', '2')
3331 ('symbol', '2')
3269 ('symbol', '3')))
3332 ('symbol', '3')))
3270 ('symbol', 'date'))))
3333 ('symbol', 'date'))))
3271 * set:
3334 * set:
3272 <baseset [3, 2]>
3335 <baseset [3, 2]>
3273 3
3336 3
3274 2
3337 2
3275
3338
3276 issue4553: check that revset aliases override existing hash prefix
3339 issue4553: check that revset aliases override existing hash prefix
3277
3340
3278 $ hg log -qr e
3341 $ hg log -qr e
3279 6:e0cc66ef77e8
3342 6:e0cc66ef77e8
3280
3343
3281 $ hg log -qr e --config revsetalias.e="all()"
3344 $ hg log -qr e --config revsetalias.e="all()"
3282 0:2785f51eece5
3345 0:2785f51eece5
3283 1:d75937da8da0
3346 1:d75937da8da0
3284 2:5ed5505e9f1c
3347 2:5ed5505e9f1c
3285 3:8528aa5637f2
3348 3:8528aa5637f2
3286 4:2326846efdab
3349 4:2326846efdab
3287 5:904fa392b941
3350 5:904fa392b941
3288 6:e0cc66ef77e8
3351 6:e0cc66ef77e8
3289 7:013af1973af4
3352 7:013af1973af4
3290 8:d5d0dcbdc4d9
3353 8:d5d0dcbdc4d9
3291 9:24286f4ae135
3354 9:24286f4ae135
3292
3355
3293 $ hg log -qr e: --config revsetalias.e="0"
3356 $ hg log -qr e: --config revsetalias.e="0"
3294 0:2785f51eece5
3357 0:2785f51eece5
3295 1:d75937da8da0
3358 1:d75937da8da0
3296 2:5ed5505e9f1c
3359 2:5ed5505e9f1c
3297 3:8528aa5637f2
3360 3:8528aa5637f2
3298 4:2326846efdab
3361 4:2326846efdab
3299 5:904fa392b941
3362 5:904fa392b941
3300 6:e0cc66ef77e8
3363 6:e0cc66ef77e8
3301 7:013af1973af4
3364 7:013af1973af4
3302 8:d5d0dcbdc4d9
3365 8:d5d0dcbdc4d9
3303 9:24286f4ae135
3366 9:24286f4ae135
3304
3367
3305 $ hg log -qr :e --config revsetalias.e="9"
3368 $ hg log -qr :e --config revsetalias.e="9"
3306 0:2785f51eece5
3369 0:2785f51eece5
3307 1:d75937da8da0
3370 1:d75937da8da0
3308 2:5ed5505e9f1c
3371 2:5ed5505e9f1c
3309 3:8528aa5637f2
3372 3:8528aa5637f2
3310 4:2326846efdab
3373 4:2326846efdab
3311 5:904fa392b941
3374 5:904fa392b941
3312 6:e0cc66ef77e8
3375 6:e0cc66ef77e8
3313 7:013af1973af4
3376 7:013af1973af4
3314 8:d5d0dcbdc4d9
3377 8:d5d0dcbdc4d9
3315 9:24286f4ae135
3378 9:24286f4ae135
3316
3379
3317 $ hg log -qr e:
3380 $ hg log -qr e:
3318 6:e0cc66ef77e8
3381 6:e0cc66ef77e8
3319 7:013af1973af4
3382 7:013af1973af4
3320 8:d5d0dcbdc4d9
3383 8:d5d0dcbdc4d9
3321 9:24286f4ae135
3384 9:24286f4ae135
3322
3385
3323 $ hg log -qr :e
3386 $ hg log -qr :e
3324 0:2785f51eece5
3387 0:2785f51eece5
3325 1:d75937da8da0
3388 1:d75937da8da0
3326 2:5ed5505e9f1c
3389 2:5ed5505e9f1c
3327 3:8528aa5637f2
3390 3:8528aa5637f2
3328 4:2326846efdab
3391 4:2326846efdab
3329 5:904fa392b941
3392 5:904fa392b941
3330 6:e0cc66ef77e8
3393 6:e0cc66ef77e8
3331
3394
3332 issue2549 - correct optimizations
3395 issue2549 - correct optimizations
3333
3396
3334 $ try 'limit(1 or 2 or 3, 2) and not 2'
3397 $ try 'limit(1 or 2 or 3, 2) and not 2'
3335 (and
3398 (and
3336 (func
3399 (func
3337 ('symbol', 'limit')
3400 ('symbol', 'limit')
3338 (list
3401 (list
3339 (or
3402 (or
3340 (list
3403 (list
3341 ('symbol', '1')
3404 ('symbol', '1')
3342 ('symbol', '2')
3405 ('symbol', '2')
3343 ('symbol', '3')))
3406 ('symbol', '3')))
3344 ('symbol', '2')))
3407 ('symbol', '2')))
3345 (not
3408 (not
3346 ('symbol', '2')))
3409 ('symbol', '2')))
3347 * set:
3410 * set:
3348 <filteredset
3411 <filteredset
3349 <baseset
3412 <baseset
3350 <limit n=2, offset=0,
3413 <limit n=2, offset=0,
3351 <fullreposet+ 0:9>,
3414 <fullreposet+ 0:9>,
3352 <baseset [1, 2, 3]>>>,
3415 <baseset [1, 2, 3]>>>,
3353 <not
3416 <not
3354 <baseset [2]>>>
3417 <baseset [2]>>>
3355 1
3418 1
3356 $ try 'max(1 or 2) and not 2'
3419 $ try 'max(1 or 2) and not 2'
3357 (and
3420 (and
3358 (func
3421 (func
3359 ('symbol', 'max')
3422 ('symbol', 'max')
3360 (or
3423 (or
3361 (list
3424 (list
3362 ('symbol', '1')
3425 ('symbol', '1')
3363 ('symbol', '2'))))
3426 ('symbol', '2'))))
3364 (not
3427 (not
3365 ('symbol', '2')))
3428 ('symbol', '2')))
3366 * set:
3429 * set:
3367 <filteredset
3430 <filteredset
3368 <baseset
3431 <baseset
3369 <max
3432 <max
3370 <fullreposet+ 0:9>,
3433 <fullreposet+ 0:9>,
3371 <baseset [1, 2]>>>,
3434 <baseset [1, 2]>>>,
3372 <not
3435 <not
3373 <baseset [2]>>>
3436 <baseset [2]>>>
3374 $ try 'min(1 or 2) and not 1'
3437 $ try 'min(1 or 2) and not 1'
3375 (and
3438 (and
3376 (func
3439 (func
3377 ('symbol', 'min')
3440 ('symbol', 'min')
3378 (or
3441 (or
3379 (list
3442 (list
3380 ('symbol', '1')
3443 ('symbol', '1')
3381 ('symbol', '2'))))
3444 ('symbol', '2'))))
3382 (not
3445 (not
3383 ('symbol', '1')))
3446 ('symbol', '1')))
3384 * set:
3447 * set:
3385 <filteredset
3448 <filteredset
3386 <baseset
3449 <baseset
3387 <min
3450 <min
3388 <fullreposet+ 0:9>,
3451 <fullreposet+ 0:9>,
3389 <baseset [1, 2]>>>,
3452 <baseset [1, 2]>>>,
3390 <not
3453 <not
3391 <baseset [1]>>>
3454 <baseset [1]>>>
3392 $ try 'last(1 or 2, 1) and not 2'
3455 $ try 'last(1 or 2, 1) and not 2'
3393 (and
3456 (and
3394 (func
3457 (func
3395 ('symbol', 'last')
3458 ('symbol', 'last')
3396 (list
3459 (list
3397 (or
3460 (or
3398 (list
3461 (list
3399 ('symbol', '1')
3462 ('symbol', '1')
3400 ('symbol', '2')))
3463 ('symbol', '2')))
3401 ('symbol', '1')))
3464 ('symbol', '1')))
3402 (not
3465 (not
3403 ('symbol', '2')))
3466 ('symbol', '2')))
3404 * set:
3467 * set:
3405 <filteredset
3468 <filteredset
3406 <baseset
3469 <baseset
3407 <last n=1,
3470 <last n=1,
3408 <fullreposet+ 0:9>,
3471 <fullreposet+ 0:9>,
3409 <baseset [2, 1]>>>,
3472 <baseset [2, 1]>>>,
3410 <not
3473 <not
3411 <baseset [2]>>>
3474 <baseset [2]>>>
3412
3475
3413 issue4289 - ordering of built-ins
3476 issue4289 - ordering of built-ins
3414 $ hg log -M -q -r 3:2
3477 $ hg log -M -q -r 3:2
3415 3:8528aa5637f2
3478 3:8528aa5637f2
3416 2:5ed5505e9f1c
3479 2:5ed5505e9f1c
3417
3480
3418 test revsets started with 40-chars hash (issue3669)
3481 test revsets started with 40-chars hash (issue3669)
3419
3482
3420 $ ISSUE3669_TIP=`hg tip --template '{node}'`
3483 $ ISSUE3669_TIP=`hg tip --template '{node}'`
3421 $ hg log -r "${ISSUE3669_TIP}" --template '{rev}\n'
3484 $ hg log -r "${ISSUE3669_TIP}" --template '{rev}\n'
3422 9
3485 9
3423 $ hg log -r "${ISSUE3669_TIP}^" --template '{rev}\n'
3486 $ hg log -r "${ISSUE3669_TIP}^" --template '{rev}\n'
3424 8
3487 8
3425
3488
3426 test or-ed indirect predicates (issue3775)
3489 test or-ed indirect predicates (issue3775)
3427
3490
3428 $ log '6 or 6^1' | sort
3491 $ log '6 or 6^1' | sort
3429 5
3492 5
3430 6
3493 6
3431 $ log '6^1 or 6' | sort
3494 $ log '6^1 or 6' | sort
3432 5
3495 5
3433 6
3496 6
3434 $ log '4 or 4~1' | sort
3497 $ log '4 or 4~1' | sort
3435 2
3498 2
3436 4
3499 4
3437 $ log '4~1 or 4' | sort
3500 $ log '4~1 or 4' | sort
3438 2
3501 2
3439 4
3502 4
3440 $ 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
3441 0
3504 0
3442 1
3505 1
3443 2
3506 2
3444 3
3507 3
3445 4
3508 4
3446 5
3509 5
3447 6
3510 6
3448 $ 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
3449 0
3512 0
3450 1
3513 1
3451 2
3514 2
3452 3
3515 3
3453 4
3516 4
3454 5
3517 5
3455 6
3518 6
3456
3519
3457 tests for 'remote()' predicate:
3520 tests for 'remote()' predicate:
3458 #. (csets in remote) (id) (remote)
3521 #. (csets in remote) (id) (remote)
3459 1. less than local current branch "default"
3522 1. less than local current branch "default"
3460 2. same with local specified "default"
3523 2. same with local specified "default"
3461 3. more than local specified specified
3524 3. more than local specified specified
3462
3525
3463 $ hg clone --quiet -U . ../remote3
3526 $ hg clone --quiet -U . ../remote3
3464 $ cd ../remote3
3527 $ cd ../remote3
3465 $ hg update -q 7
3528 $ hg update -q 7
3466 $ echo r > r
3529 $ echo r > r
3467 $ hg ci -Aqm 10
3530 $ hg ci -Aqm 10
3468 $ log 'remote()'
3531 $ log 'remote()'
3469 7
3532 7
3470 $ log 'remote("a-b-c-")'
3533 $ log 'remote("a-b-c-")'
3471 2
3534 2
3472 $ cd ../repo
3535 $ cd ../repo
3473 $ log 'remote(".a.b.c.", "../remote3")'
3536 $ log 'remote(".a.b.c.", "../remote3")'
3474
3537
3475 tests for concatenation of strings/symbols by "##"
3538 tests for concatenation of strings/symbols by "##"
3476
3539
3477 $ try "278 ## '5f5' ## 1ee ## 'ce5'"
3540 $ try "278 ## '5f5' ## 1ee ## 'ce5'"
3478 (_concat
3541 (_concat
3479 (_concat
3542 (_concat
3480 (_concat
3543 (_concat
3481 ('symbol', '278')
3544 ('symbol', '278')
3482 ('string', '5f5'))
3545 ('string', '5f5'))
3483 ('symbol', '1ee'))
3546 ('symbol', '1ee'))
3484 ('string', 'ce5'))
3547 ('string', 'ce5'))
3485 * concatenated:
3548 * concatenated:
3486 ('string', '2785f51eece5')
3549 ('string', '2785f51eece5')
3487 * set:
3550 * set:
3488 <baseset [0]>
3551 <baseset [0]>
3489 0
3552 0
3490
3553
3491 $ 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
3492 $ try "cat4(278, '5f5', 1ee, 'ce5')"
3555 $ try "cat4(278, '5f5', 1ee, 'ce5')"
3493 (func
3556 (func
3494 ('symbol', 'cat4')
3557 ('symbol', 'cat4')
3495 (list
3558 (list
3496 ('symbol', '278')
3559 ('symbol', '278')
3497 ('string', '5f5')
3560 ('string', '5f5')
3498 ('symbol', '1ee')
3561 ('symbol', '1ee')
3499 ('string', 'ce5')))
3562 ('string', 'ce5')))
3500 * expanded:
3563 * expanded:
3501 (_concat
3564 (_concat
3502 (_concat
3565 (_concat
3503 (_concat
3566 (_concat
3504 ('symbol', '278')
3567 ('symbol', '278')
3505 ('string', '5f5'))
3568 ('string', '5f5'))
3506 ('symbol', '1ee'))
3569 ('symbol', '1ee'))
3507 ('string', 'ce5'))
3570 ('string', 'ce5'))
3508 * concatenated:
3571 * concatenated:
3509 ('string', '2785f51eece5')
3572 ('string', '2785f51eece5')
3510 * set:
3573 * set:
3511 <baseset [0]>
3574 <baseset [0]>
3512 0
3575 0
3513
3576
3514 (check concatenation in alias nesting)
3577 (check concatenation in alias nesting)
3515
3578
3516 $ echo 'cat2($1, $2) = $1 ## $2' >> .hg/hgrc
3579 $ echo 'cat2($1, $2) = $1 ## $2' >> .hg/hgrc
3517 $ 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
3518 $ log "cat2x2(278, '5f5', 1ee, 'ce5')"
3581 $ log "cat2x2(278, '5f5', 1ee, 'ce5')"
3519 0
3582 0
3520
3583
3521 (check operator priority)
3584 (check operator priority)
3522
3585
3523 $ 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
3524 $ log "cat2n2(2785f5, 1eece5, 24286f, 4ae135)"
3587 $ log "cat2n2(2785f5, 1eece5, 24286f, 4ae135)"
3525 0
3588 0
3526 4
3589 4
3527
3590
3528 $ cd ..
3591 $ cd ..
3529
3592
3530 prepare repository that has "default" branches of multiple roots
3593 prepare repository that has "default" branches of multiple roots
3531
3594
3532 $ hg init namedbranch
3595 $ hg init namedbranch
3533 $ cd namedbranch
3596 $ cd namedbranch
3534
3597
3535 $ echo default0 >> a
3598 $ echo default0 >> a
3536 $ hg ci -Aqm0
3599 $ hg ci -Aqm0
3537 $ echo default1 >> a
3600 $ echo default1 >> a
3538 $ hg ci -m1
3601 $ hg ci -m1
3539
3602
3540 $ hg branch -q stable
3603 $ hg branch -q stable
3541 $ echo stable2 >> a
3604 $ echo stable2 >> a
3542 $ hg ci -m2
3605 $ hg ci -m2
3543 $ echo stable3 >> a
3606 $ echo stable3 >> a
3544 $ hg ci -m3
3607 $ hg ci -m3
3545
3608
3546 $ hg update -q null
3609 $ hg update -q null
3547 $ echo default4 >> a
3610 $ echo default4 >> a
3548 $ hg ci -Aqm4
3611 $ hg ci -Aqm4
3549 $ echo default5 >> a
3612 $ echo default5 >> a
3550 $ hg ci -m5
3613 $ hg ci -m5
3551
3614
3552 "null" revision belongs to "default" branch (issue4683)
3615 "null" revision belongs to "default" branch (issue4683)
3553
3616
3554 $ log 'branch(null)'
3617 $ log 'branch(null)'
3555 0
3618 0
3556 1
3619 1
3557 4
3620 4
3558 5
3621 5
3559
3622
3560 "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
3561 unless explicitly specified (issue4682)
3624 unless explicitly specified (issue4682)
3562
3625
3563 $ log 'children(branch(default))'
3626 $ log 'children(branch(default))'
3564 1
3627 1
3565 2
3628 2
3566 5
3629 5
3567
3630
3568 $ cd ..
3631 $ cd ..
3569
3632
3570 test author/desc/keyword in problematic encoding
3633 test author/desc/keyword in problematic encoding
3571 # unicode: cp932:
3634 # unicode: cp932:
3572 # u30A2 0x83 0x41(= 'A')
3635 # u30A2 0x83 0x41(= 'A')
3573 # u30C2 0x83 0x61(= 'a')
3636 # u30C2 0x83 0x61(= 'a')
3574
3637
3575 $ hg init problematicencoding
3638 $ hg init problematicencoding
3576 $ cd problematicencoding
3639 $ cd problematicencoding
3577
3640
3578 $ python > setup.sh <<EOF
3641 $ python > setup.sh <<EOF
3579 > print u'''
3642 > print u'''
3580 > echo a > text
3643 > echo a > text
3581 > hg add text
3644 > hg add text
3582 > hg --encoding utf-8 commit -u '\u30A2' -m none
3645 > hg --encoding utf-8 commit -u '\u30A2' -m none
3583 > echo b > text
3646 > echo b > text
3584 > hg --encoding utf-8 commit -u '\u30C2' -m none
3647 > hg --encoding utf-8 commit -u '\u30C2' -m none
3585 > echo c > text
3648 > echo c > text
3586 > hg --encoding utf-8 commit -u none -m '\u30A2'
3649 > hg --encoding utf-8 commit -u none -m '\u30A2'
3587 > echo d > text
3650 > echo d > text
3588 > hg --encoding utf-8 commit -u none -m '\u30C2'
3651 > hg --encoding utf-8 commit -u none -m '\u30C2'
3589 > '''.encode('utf-8')
3652 > '''.encode('utf-8')
3590 > EOF
3653 > EOF
3591 $ sh < setup.sh
3654 $ sh < setup.sh
3592
3655
3593 test in problematic encoding
3656 test in problematic encoding
3594 $ python > test.sh <<EOF
3657 $ python > test.sh <<EOF
3595 > print u'''
3658 > print u'''
3596 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30A2)'
3659 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30A2)'
3597 > echo ====
3660 > echo ====
3598 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30C2)'
3661 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30C2)'
3599 > echo ====
3662 > echo ====
3600 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30A2)'
3663 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30A2)'
3601 > echo ====
3664 > echo ====
3602 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30C2)'
3665 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30C2)'
3603 > echo ====
3666 > echo ====
3604 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30A2)'
3667 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30A2)'
3605 > echo ====
3668 > echo ====
3606 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30C2)'
3669 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30C2)'
3607 > '''.encode('cp932')
3670 > '''.encode('cp932')
3608 > EOF
3671 > EOF
3609 $ sh < test.sh
3672 $ sh < test.sh
3610 0
3673 0
3611 ====
3674 ====
3612 1
3675 1
3613 ====
3676 ====
3614 2
3677 2
3615 ====
3678 ====
3616 3
3679 3
3617 ====
3680 ====
3618 0
3681 0
3619 2
3682 2
3620 ====
3683 ====
3621 1
3684 1
3622 3
3685 3
3623
3686
3624 test error message of bad revset
3687 test error message of bad revset
3625 $ hg log -r 'foo\\'
3688 $ hg log -r 'foo\\'
3626 hg: parse error at 3: syntax error in revset 'foo\\'
3689 hg: parse error at 3: syntax error in revset 'foo\\'
3627 [255]
3690 [255]
3628
3691
3629 $ cd ..
3692 $ cd ..
3630
3693
3631 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
3632 loading it
3695 loading it
3633
3696
3634 $ cd repo
3697 $ cd repo
3635
3698
3636 $ cat <<EOF > $TESTTMP/custompredicate.py
3699 $ cat <<EOF > $TESTTMP/custompredicate.py
3637 > from mercurial import error, registrar, revset
3700 > from mercurial import error, registrar, revset
3638 >
3701 >
3639 > revsetpredicate = registrar.revsetpredicate()
3702 > revsetpredicate = registrar.revsetpredicate()
3640 >
3703 >
3641 > @revsetpredicate('custom1()')
3704 > @revsetpredicate('custom1()')
3642 > def custom1(repo, subset, x):
3705 > def custom1(repo, subset, x):
3643 > return revset.baseset([1])
3706 > return revset.baseset([1])
3644 >
3707 >
3645 > raise error.Abort('intentional failure of loading extension')
3708 > raise error.Abort('intentional failure of loading extension')
3646 > EOF
3709 > EOF
3647 $ cat <<EOF > .hg/hgrc
3710 $ cat <<EOF > .hg/hgrc
3648 > [extensions]
3711 > [extensions]
3649 > custompredicate = $TESTTMP/custompredicate.py
3712 > custompredicate = $TESTTMP/custompredicate.py
3650 > EOF
3713 > EOF
3651
3714
3652 $ hg debugrevspec "custom1()"
3715 $ hg debugrevspec "custom1()"
3653 *** 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
3654 hg: parse error: unknown identifier: custom1
3717 hg: parse error: unknown identifier: custom1
3655 [255]
3718 [255]
3656
3719
3657 $ cd ..
3720 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now