##// END OF EJS Templates
revsetlang: raise ParseError to report invalid format character...
Yuya Nishihara -
r35575:4c3a4bb3 default
parent child Browse files
Show More
@@ -1,698 +1,699
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 "[": (21, None, None, ("subscript", 1, "]"), None),
24 "[": (21, None, None, ("subscript", 1, "]"), None),
25 "#": (21, None, None, ("relation", 21), None),
25 "#": (21, None, None, ("relation", 21), None),
26 "##": (20, None, None, ("_concat", 20), None),
26 "##": (20, None, None, ("_concat", 20), None),
27 "~": (18, None, None, ("ancestor", 18), None),
27 "~": (18, None, None, ("ancestor", 18), None),
28 "^": (18, None, None, ("parent", 18), "parentpost"),
28 "^": (18, None, None, ("parent", 18), "parentpost"),
29 "-": (5, None, ("negate", 19), ("minus", 5), None),
29 "-": (5, None, ("negate", 19), ("minus", 5), None),
30 "::": (17, "dagrangeall", ("dagrangepre", 17), ("dagrange", 17),
30 "::": (17, "dagrangeall", ("dagrangepre", 17), ("dagrange", 17),
31 "dagrangepost"),
31 "dagrangepost"),
32 "..": (17, "dagrangeall", ("dagrangepre", 17), ("dagrange", 17),
32 "..": (17, "dagrangeall", ("dagrangepre", 17), ("dagrange", 17),
33 "dagrangepost"),
33 "dagrangepost"),
34 ":": (15, "rangeall", ("rangepre", 15), ("range", 15), "rangepost"),
34 ":": (15, "rangeall", ("rangepre", 15), ("range", 15), "rangepost"),
35 "not": (10, None, ("not", 10), None, None),
35 "not": (10, None, ("not", 10), None, None),
36 "!": (10, None, ("not", 10), None, None),
36 "!": (10, None, ("not", 10), None, None),
37 "and": (5, None, None, ("and", 5), None),
37 "and": (5, None, None, ("and", 5), None),
38 "&": (5, None, None, ("and", 5), None),
38 "&": (5, None, None, ("and", 5), None),
39 "%": (5, None, None, ("only", 5), "onlypost"),
39 "%": (5, None, None, ("only", 5), "onlypost"),
40 "or": (4, None, None, ("or", 4), None),
40 "or": (4, None, None, ("or", 4), None),
41 "|": (4, None, None, ("or", 4), None),
41 "|": (4, None, None, ("or", 4), None),
42 "+": (4, None, None, ("or", 4), None),
42 "+": (4, None, None, ("or", 4), None),
43 "=": (3, None, None, ("keyvalue", 3), None),
43 "=": (3, None, None, ("keyvalue", 3), None),
44 ",": (2, None, None, ("list", 2), None),
44 ",": (2, None, None, ("list", 2), None),
45 ")": (0, None, None, None, None),
45 ")": (0, None, None, None, None),
46 "]": (0, None, None, None, None),
46 "]": (0, None, None, None, None),
47 "symbol": (0, "symbol", None, None, None),
47 "symbol": (0, "symbol", None, None, None),
48 "string": (0, "string", None, None, None),
48 "string": (0, "string", None, None, None),
49 "end": (0, None, None, None, None),
49 "end": (0, None, None, None, None),
50 }
50 }
51
51
52 keywords = {'and', 'or', 'not'}
52 keywords = {'and', 'or', 'not'}
53
53
54 symbols = {}
54 symbols = {}
55
55
56 _quoteletters = {'"', "'"}
56 _quoteletters = {'"', "'"}
57 _simpleopletters = set(pycompat.iterbytestr("()[]#:=,-|&+!~^%"))
57 _simpleopletters = set(pycompat.iterbytestr("()[]#:=,-|&+!~^%"))
58
58
59 # default set of valid characters for the initial letter of symbols
59 # default set of valid characters for the initial letter of symbols
60 _syminitletters = set(pycompat.iterbytestr(
60 _syminitletters = set(pycompat.iterbytestr(
61 string.ascii_letters.encode('ascii') +
61 string.ascii_letters.encode('ascii') +
62 string.digits.encode('ascii') +
62 string.digits.encode('ascii') +
63 '._@')) | set(map(pycompat.bytechr, xrange(128, 256)))
63 '._@')) | set(map(pycompat.bytechr, xrange(128, 256)))
64
64
65 # default set of valid characters for non-initial letters of symbols
65 # default set of valid characters for non-initial letters of symbols
66 _symletters = _syminitletters | set(pycompat.iterbytestr('-/'))
66 _symletters = _syminitletters | set(pycompat.iterbytestr('-/'))
67
67
68 def tokenize(program, lookup=None, syminitletters=None, symletters=None):
68 def tokenize(program, lookup=None, syminitletters=None, symletters=None):
69 '''
69 '''
70 Parse a revset statement into a stream of tokens
70 Parse a revset statement into a stream of tokens
71
71
72 ``syminitletters`` is the set of valid characters for the initial
72 ``syminitletters`` is the set of valid characters for the initial
73 letter of symbols.
73 letter of symbols.
74
74
75 By default, character ``c`` is recognized as valid for initial
75 By default, character ``c`` is recognized as valid for initial
76 letter of symbols, if ``c.isalnum() or c in '._@' or ord(c) > 127``.
76 letter of symbols, if ``c.isalnum() or c in '._@' or ord(c) > 127``.
77
77
78 ``symletters`` is the set of valid characters for non-initial
78 ``symletters`` is the set of valid characters for non-initial
79 letters of symbols.
79 letters of symbols.
80
80
81 By default, character ``c`` is recognized as valid for non-initial
81 By default, character ``c`` is recognized as valid for non-initial
82 letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``.
82 letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``.
83
83
84 Check that @ is a valid unquoted token character (issue3686):
84 Check that @ is a valid unquoted token character (issue3686):
85 >>> list(tokenize(b"@::"))
85 >>> list(tokenize(b"@::"))
86 [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
86 [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
87
87
88 '''
88 '''
89 program = pycompat.bytestr(program)
89 program = pycompat.bytestr(program)
90 if syminitletters is None:
90 if syminitletters is None:
91 syminitletters = _syminitletters
91 syminitletters = _syminitletters
92 if symletters is None:
92 if symletters is None:
93 symletters = _symletters
93 symletters = _symletters
94
94
95 if program and lookup:
95 if program and lookup:
96 # attempt to parse old-style ranges first to deal with
96 # attempt to parse old-style ranges first to deal with
97 # things like old-tag which contain query metacharacters
97 # things like old-tag which contain query metacharacters
98 parts = program.split(':', 1)
98 parts = program.split(':', 1)
99 if all(lookup(sym) for sym in parts if sym):
99 if all(lookup(sym) for sym in parts if sym):
100 if parts[0]:
100 if parts[0]:
101 yield ('symbol', parts[0], 0)
101 yield ('symbol', parts[0], 0)
102 if len(parts) > 1:
102 if len(parts) > 1:
103 s = len(parts[0])
103 s = len(parts[0])
104 yield (':', None, s)
104 yield (':', None, s)
105 if parts[1]:
105 if parts[1]:
106 yield ('symbol', parts[1], s + 1)
106 yield ('symbol', parts[1], s + 1)
107 yield ('end', None, len(program))
107 yield ('end', None, len(program))
108 return
108 return
109
109
110 pos, l = 0, len(program)
110 pos, l = 0, len(program)
111 while pos < l:
111 while pos < l:
112 c = program[pos]
112 c = program[pos]
113 if c.isspace(): # skip inter-token whitespace
113 if c.isspace(): # skip inter-token whitespace
114 pass
114 pass
115 elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
115 elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
116 yield ('::', None, pos)
116 yield ('::', None, pos)
117 pos += 1 # skip ahead
117 pos += 1 # skip ahead
118 elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
118 elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
119 yield ('..', None, pos)
119 yield ('..', None, pos)
120 pos += 1 # skip ahead
120 pos += 1 # skip ahead
121 elif c == '#' and program[pos:pos + 2] == '##': # look ahead carefully
121 elif c == '#' and program[pos:pos + 2] == '##': # look ahead carefully
122 yield ('##', None, pos)
122 yield ('##', None, pos)
123 pos += 1 # skip ahead
123 pos += 1 # skip ahead
124 elif c in _simpleopletters: # handle simple operators
124 elif c in _simpleopletters: # handle simple operators
125 yield (c, None, pos)
125 yield (c, None, pos)
126 elif (c in _quoteletters or c == 'r' and
126 elif (c in _quoteletters or c == 'r' and
127 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
127 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
128 if c == 'r':
128 if c == 'r':
129 pos += 1
129 pos += 1
130 c = program[pos]
130 c = program[pos]
131 decode = lambda x: x
131 decode = lambda x: x
132 else:
132 else:
133 decode = parser.unescapestr
133 decode = parser.unescapestr
134 pos += 1
134 pos += 1
135 s = pos
135 s = pos
136 while pos < l: # find closing quote
136 while pos < l: # find closing quote
137 d = program[pos]
137 d = program[pos]
138 if d == '\\': # skip over escaped characters
138 if d == '\\': # skip over escaped characters
139 pos += 2
139 pos += 2
140 continue
140 continue
141 if d == c:
141 if d == c:
142 yield ('string', decode(program[s:pos]), s)
142 yield ('string', decode(program[s:pos]), s)
143 break
143 break
144 pos += 1
144 pos += 1
145 else:
145 else:
146 raise error.ParseError(_("unterminated string"), s)
146 raise error.ParseError(_("unterminated string"), s)
147 # gather up a symbol/keyword
147 # gather up a symbol/keyword
148 elif c in syminitletters:
148 elif c in syminitletters:
149 s = pos
149 s = pos
150 pos += 1
150 pos += 1
151 while pos < l: # find end of symbol
151 while pos < l: # find end of symbol
152 d = program[pos]
152 d = program[pos]
153 if d not in symletters:
153 if d not in symletters:
154 break
154 break
155 if d == '.' and program[pos - 1] == '.': # special case for ..
155 if d == '.' and program[pos - 1] == '.': # special case for ..
156 pos -= 1
156 pos -= 1
157 break
157 break
158 pos += 1
158 pos += 1
159 sym = program[s:pos]
159 sym = program[s:pos]
160 if sym in keywords: # operator keywords
160 if sym in keywords: # operator keywords
161 yield (sym, None, s)
161 yield (sym, None, s)
162 elif '-' in sym:
162 elif '-' in sym:
163 # some jerk gave us foo-bar-baz, try to check if it's a symbol
163 # some jerk gave us foo-bar-baz, try to check if it's a symbol
164 if lookup and lookup(sym):
164 if lookup and lookup(sym):
165 # looks like a real symbol
165 # looks like a real symbol
166 yield ('symbol', sym, s)
166 yield ('symbol', sym, s)
167 else:
167 else:
168 # looks like an expression
168 # looks like an expression
169 parts = sym.split('-')
169 parts = sym.split('-')
170 for p in parts[:-1]:
170 for p in parts[:-1]:
171 if p: # possible consecutive -
171 if p: # possible consecutive -
172 yield ('symbol', p, s)
172 yield ('symbol', p, s)
173 s += len(p)
173 s += len(p)
174 yield ('-', None, pos)
174 yield ('-', None, pos)
175 s += 1
175 s += 1
176 if parts[-1]: # possible trailing -
176 if parts[-1]: # possible trailing -
177 yield ('symbol', parts[-1], s)
177 yield ('symbol', parts[-1], s)
178 else:
178 else:
179 yield ('symbol', sym, s)
179 yield ('symbol', sym, s)
180 pos -= 1
180 pos -= 1
181 else:
181 else:
182 raise error.ParseError(_("syntax error in revset '%s'") %
182 raise error.ParseError(_("syntax error in revset '%s'") %
183 program, pos)
183 program, pos)
184 pos += 1
184 pos += 1
185 yield ('end', None, pos)
185 yield ('end', None, pos)
186
186
187 # helpers
187 # helpers
188
188
189 _notset = object()
189 _notset = object()
190
190
191 def getsymbol(x):
191 def getsymbol(x):
192 if x and x[0] == 'symbol':
192 if x and x[0] == 'symbol':
193 return x[1]
193 return x[1]
194 raise error.ParseError(_('not a symbol'))
194 raise error.ParseError(_('not a symbol'))
195
195
196 def getstring(x, err):
196 def getstring(x, err):
197 if x and (x[0] == 'string' or x[0] == 'symbol'):
197 if x and (x[0] == 'string' or x[0] == 'symbol'):
198 return x[1]
198 return x[1]
199 raise error.ParseError(err)
199 raise error.ParseError(err)
200
200
201 def getinteger(x, err, default=_notset):
201 def getinteger(x, err, default=_notset):
202 if not x and default is not _notset:
202 if not x and default is not _notset:
203 return default
203 return default
204 try:
204 try:
205 return int(getstring(x, err))
205 return int(getstring(x, err))
206 except ValueError:
206 except ValueError:
207 raise error.ParseError(err)
207 raise error.ParseError(err)
208
208
209 def getboolean(x, err):
209 def getboolean(x, err):
210 value = util.parsebool(getsymbol(x))
210 value = util.parsebool(getsymbol(x))
211 if value is not None:
211 if value is not None:
212 return value
212 return value
213 raise error.ParseError(err)
213 raise error.ParseError(err)
214
214
215 def getlist(x):
215 def getlist(x):
216 if not x:
216 if not x:
217 return []
217 return []
218 if x[0] == 'list':
218 if x[0] == 'list':
219 return list(x[1:])
219 return list(x[1:])
220 return [x]
220 return [x]
221
221
222 def getrange(x, err):
222 def getrange(x, err):
223 if not x:
223 if not x:
224 raise error.ParseError(err)
224 raise error.ParseError(err)
225 op = x[0]
225 op = x[0]
226 if op == 'range':
226 if op == 'range':
227 return x[1], x[2]
227 return x[1], x[2]
228 elif op == 'rangepre':
228 elif op == 'rangepre':
229 return None, x[1]
229 return None, x[1]
230 elif op == 'rangepost':
230 elif op == 'rangepost':
231 return x[1], None
231 return x[1], None
232 elif op == 'rangeall':
232 elif op == 'rangeall':
233 return None, None
233 return None, None
234 raise error.ParseError(err)
234 raise error.ParseError(err)
235
235
236 def getargs(x, min, max, err):
236 def getargs(x, min, max, err):
237 l = getlist(x)
237 l = getlist(x)
238 if len(l) < min or (max >= 0 and len(l) > max):
238 if len(l) < min or (max >= 0 and len(l) > max):
239 raise error.ParseError(err)
239 raise error.ParseError(err)
240 return l
240 return l
241
241
242 def getargsdict(x, funcname, keys):
242 def getargsdict(x, funcname, keys):
243 return parser.buildargsdict(getlist(x), funcname, parser.splitargspec(keys),
243 return parser.buildargsdict(getlist(x), funcname, parser.splitargspec(keys),
244 keyvaluenode='keyvalue', keynode='symbol')
244 keyvaluenode='keyvalue', keynode='symbol')
245
245
246 # cache of {spec: raw parsed tree} built internally
246 # cache of {spec: raw parsed tree} built internally
247 _treecache = {}
247 _treecache = {}
248
248
249 def _cachedtree(spec):
249 def _cachedtree(spec):
250 # thread safe because parse() is reentrant and dict.__setitem__() is atomic
250 # thread safe because parse() is reentrant and dict.__setitem__() is atomic
251 tree = _treecache.get(spec)
251 tree = _treecache.get(spec)
252 if tree is None:
252 if tree is None:
253 _treecache[spec] = tree = parse(spec)
253 _treecache[spec] = tree = parse(spec)
254 return tree
254 return tree
255
255
256 def _build(tmplspec, *repls):
256 def _build(tmplspec, *repls):
257 """Create raw parsed tree from a template revset statement
257 """Create raw parsed tree from a template revset statement
258
258
259 >>> _build(b'f(_) and _', (b'string', b'1'), (b'symbol', b'2'))
259 >>> _build(b'f(_) and _', (b'string', b'1'), (b'symbol', b'2'))
260 ('and', ('func', ('symbol', 'f'), ('string', '1')), ('symbol', '2'))
260 ('and', ('func', ('symbol', 'f'), ('string', '1')), ('symbol', '2'))
261 """
261 """
262 template = _cachedtree(tmplspec)
262 template = _cachedtree(tmplspec)
263 return parser.buildtree(template, ('symbol', '_'), *repls)
263 return parser.buildtree(template, ('symbol', '_'), *repls)
264
264
265 def _match(patspec, tree):
265 def _match(patspec, tree):
266 """Test if a tree matches the given pattern statement; return the matches
266 """Test if a tree matches the given pattern statement; return the matches
267
267
268 >>> _match(b'f(_)', parse(b'f()'))
268 >>> _match(b'f(_)', parse(b'f()'))
269 >>> _match(b'f(_)', parse(b'f(1)'))
269 >>> _match(b'f(_)', parse(b'f(1)'))
270 [('func', ('symbol', 'f'), ('symbol', '1')), ('symbol', '1')]
270 [('func', ('symbol', 'f'), ('symbol', '1')), ('symbol', '1')]
271 >>> _match(b'f(_)', parse(b'f(1, 2)'))
271 >>> _match(b'f(_)', parse(b'f(1, 2)'))
272 """
272 """
273 pattern = _cachedtree(patspec)
273 pattern = _cachedtree(patspec)
274 return parser.matchtree(pattern, tree, ('symbol', '_'),
274 return parser.matchtree(pattern, tree, ('symbol', '_'),
275 {'keyvalue', 'list'})
275 {'keyvalue', 'list'})
276
276
277 def _matchonly(revs, bases):
277 def _matchonly(revs, bases):
278 return _match('ancestors(_) and not ancestors(_)', ('and', revs, bases))
278 return _match('ancestors(_) and not ancestors(_)', ('and', revs, bases))
279
279
280 def _fixops(x):
280 def _fixops(x):
281 """Rewrite raw parsed tree to resolve ambiguous syntax which cannot be
281 """Rewrite raw parsed tree to resolve ambiguous syntax which cannot be
282 handled well by our simple top-down parser"""
282 handled well by our simple top-down parser"""
283 if not isinstance(x, tuple):
283 if not isinstance(x, tuple):
284 return x
284 return x
285
285
286 op = x[0]
286 op = x[0]
287 if op == 'parent':
287 if op == 'parent':
288 # x^:y means (x^) : y, not x ^ (:y)
288 # x^:y means (x^) : y, not x ^ (:y)
289 # x^: means (x^) :, not x ^ (:)
289 # x^: means (x^) :, not x ^ (:)
290 post = ('parentpost', x[1])
290 post = ('parentpost', x[1])
291 if x[2][0] == 'dagrangepre':
291 if x[2][0] == 'dagrangepre':
292 return _fixops(('dagrange', post, x[2][1]))
292 return _fixops(('dagrange', post, x[2][1]))
293 elif x[2][0] == 'dagrangeall':
293 elif x[2][0] == 'dagrangeall':
294 return _fixops(('dagrangepost', post))
294 return _fixops(('dagrangepost', post))
295 elif x[2][0] == 'rangepre':
295 elif x[2][0] == 'rangepre':
296 return _fixops(('range', post, x[2][1]))
296 return _fixops(('range', post, x[2][1]))
297 elif x[2][0] == 'rangeall':
297 elif x[2][0] == 'rangeall':
298 return _fixops(('rangepost', post))
298 return _fixops(('rangepost', post))
299 elif op == 'or':
299 elif op == 'or':
300 # make number of arguments deterministic:
300 # make number of arguments deterministic:
301 # x + y + z -> (or x y z) -> (or (list x y z))
301 # x + y + z -> (or x y z) -> (or (list x y z))
302 return (op, _fixops(('list',) + x[1:]))
302 return (op, _fixops(('list',) + x[1:]))
303 elif op == 'subscript' and x[1][0] == 'relation':
303 elif op == 'subscript' and x[1][0] == 'relation':
304 # x#y[z] ternary
304 # x#y[z] ternary
305 return _fixops(('relsubscript', x[1][1], x[1][2], x[2]))
305 return _fixops(('relsubscript', x[1][1], x[1][2], x[2]))
306
306
307 return (op,) + tuple(_fixops(y) for y in x[1:])
307 return (op,) + tuple(_fixops(y) for y in x[1:])
308
308
309 def _analyze(x):
309 def _analyze(x):
310 if x is None:
310 if x is None:
311 return x
311 return x
312
312
313 op = x[0]
313 op = x[0]
314 if op == 'minus':
314 if op == 'minus':
315 return _analyze(_build('_ and not _', *x[1:]))
315 return _analyze(_build('_ and not _', *x[1:]))
316 elif op == 'only':
316 elif op == 'only':
317 return _analyze(_build('only(_, _)', *x[1:]))
317 return _analyze(_build('only(_, _)', *x[1:]))
318 elif op == 'onlypost':
318 elif op == 'onlypost':
319 return _analyze(_build('only(_)', x[1]))
319 return _analyze(_build('only(_)', x[1]))
320 elif op == 'dagrangeall':
320 elif op == 'dagrangeall':
321 raise error.ParseError(_("can't use '::' in this context"))
321 raise error.ParseError(_("can't use '::' in this context"))
322 elif op == 'dagrangepre':
322 elif op == 'dagrangepre':
323 return _analyze(_build('ancestors(_)', x[1]))
323 return _analyze(_build('ancestors(_)', x[1]))
324 elif op == 'dagrangepost':
324 elif op == 'dagrangepost':
325 return _analyze(_build('descendants(_)', x[1]))
325 return _analyze(_build('descendants(_)', x[1]))
326 elif op == 'negate':
326 elif op == 'negate':
327 s = getstring(x[1], _("can't negate that"))
327 s = getstring(x[1], _("can't negate that"))
328 return _analyze(('string', '-' + s))
328 return _analyze(('string', '-' + s))
329 elif op in ('string', 'symbol'):
329 elif op in ('string', 'symbol'):
330 return x
330 return x
331 elif op == 'rangeall':
331 elif op == 'rangeall':
332 return (op, None)
332 return (op, None)
333 elif op in {'or', 'not', 'rangepre', 'rangepost', 'parentpost'}:
333 elif op in {'or', 'not', 'rangepre', 'rangepost', 'parentpost'}:
334 return (op, _analyze(x[1]))
334 return (op, _analyze(x[1]))
335 elif op == 'group':
335 elif op == 'group':
336 return _analyze(x[1])
336 return _analyze(x[1])
337 elif op in {'and', 'dagrange', 'range', 'parent', 'ancestor', 'relation',
337 elif op in {'and', 'dagrange', 'range', 'parent', 'ancestor', 'relation',
338 'subscript'}:
338 'subscript'}:
339 ta = _analyze(x[1])
339 ta = _analyze(x[1])
340 tb = _analyze(x[2])
340 tb = _analyze(x[2])
341 return (op, ta, tb)
341 return (op, ta, tb)
342 elif op == 'relsubscript':
342 elif op == 'relsubscript':
343 ta = _analyze(x[1])
343 ta = _analyze(x[1])
344 tb = _analyze(x[2])
344 tb = _analyze(x[2])
345 tc = _analyze(x[3])
345 tc = _analyze(x[3])
346 return (op, ta, tb, tc)
346 return (op, ta, tb, tc)
347 elif op == 'list':
347 elif op == 'list':
348 return (op,) + tuple(_analyze(y) for y in x[1:])
348 return (op,) + tuple(_analyze(y) for y in x[1:])
349 elif op == 'keyvalue':
349 elif op == 'keyvalue':
350 return (op, x[1], _analyze(x[2]))
350 return (op, x[1], _analyze(x[2]))
351 elif op == 'func':
351 elif op == 'func':
352 return (op, x[1], _analyze(x[2]))
352 return (op, x[1], _analyze(x[2]))
353 raise ValueError('invalid operator %r' % op)
353 raise ValueError('invalid operator %r' % op)
354
354
355 def analyze(x):
355 def analyze(x):
356 """Transform raw parsed tree to evaluatable tree which can be fed to
356 """Transform raw parsed tree to evaluatable tree which can be fed to
357 optimize() or getset()
357 optimize() or getset()
358
358
359 All pseudo operations should be mapped to real operations or functions
359 All pseudo operations should be mapped to real operations or functions
360 defined in methods or symbols table respectively.
360 defined in methods or symbols table respectively.
361 """
361 """
362 return _analyze(x)
362 return _analyze(x)
363
363
364 def _optimize(x):
364 def _optimize(x):
365 if x is None:
365 if x is None:
366 return 0, x
366 return 0, x
367
367
368 op = x[0]
368 op = x[0]
369 if op in ('string', 'symbol'):
369 if op in ('string', 'symbol'):
370 return 0.5, x # single revisions are small
370 return 0.5, x # single revisions are small
371 elif op == 'and':
371 elif op == 'and':
372 wa, ta = _optimize(x[1])
372 wa, ta = _optimize(x[1])
373 wb, tb = _optimize(x[2])
373 wb, tb = _optimize(x[2])
374 w = min(wa, wb)
374 w = min(wa, wb)
375
375
376 # (draft/secret/_notpublic() & ::x) have a fast path
376 # (draft/secret/_notpublic() & ::x) have a fast path
377 m = _match('_() & ancestors(_)', ('and', ta, tb))
377 m = _match('_() & ancestors(_)', ('and', ta, tb))
378 if m and getsymbol(m[1]) in {'draft', 'secret', '_notpublic'}:
378 if m and getsymbol(m[1]) in {'draft', 'secret', '_notpublic'}:
379 return w, _build('_phaseandancestors(_, _)', m[1], m[2])
379 return w, _build('_phaseandancestors(_, _)', m[1], m[2])
380
380
381 # (::x and not ::y)/(not ::y and ::x) have a fast path
381 # (::x and not ::y)/(not ::y and ::x) have a fast path
382 m = _matchonly(ta, tb) or _matchonly(tb, ta)
382 m = _matchonly(ta, tb) or _matchonly(tb, ta)
383 if m:
383 if m:
384 return w, _build('only(_, _)', *m[1:])
384 return w, _build('only(_, _)', *m[1:])
385
385
386 m = _match('not _', tb)
386 m = _match('not _', tb)
387 if m:
387 if m:
388 return wa, ('difference', ta, m[1])
388 return wa, ('difference', ta, m[1])
389 if wa > wb:
389 if wa > wb:
390 op = 'andsmally'
390 op = 'andsmally'
391 return w, (op, ta, tb)
391 return w, (op, ta, tb)
392 elif op == 'or':
392 elif op == 'or':
393 # fast path for machine-generated expression, that is likely to have
393 # fast path for machine-generated expression, that is likely to have
394 # lots of trivial revisions: 'a + b + c()' to '_list(a b) + c()'
394 # lots of trivial revisions: 'a + b + c()' to '_list(a b) + c()'
395 ws, ts, ss = [], [], []
395 ws, ts, ss = [], [], []
396 def flushss():
396 def flushss():
397 if not ss:
397 if not ss:
398 return
398 return
399 if len(ss) == 1:
399 if len(ss) == 1:
400 w, t = ss[0]
400 w, t = ss[0]
401 else:
401 else:
402 s = '\0'.join(t[1] for w, t in ss)
402 s = '\0'.join(t[1] for w, t in ss)
403 y = _build('_list(_)', ('string', s))
403 y = _build('_list(_)', ('string', s))
404 w, t = _optimize(y)
404 w, t = _optimize(y)
405 ws.append(w)
405 ws.append(w)
406 ts.append(t)
406 ts.append(t)
407 del ss[:]
407 del ss[:]
408 for y in getlist(x[1]):
408 for y in getlist(x[1]):
409 w, t = _optimize(y)
409 w, t = _optimize(y)
410 if t is not None and (t[0] == 'string' or t[0] == 'symbol'):
410 if t is not None and (t[0] == 'string' or t[0] == 'symbol'):
411 ss.append((w, t))
411 ss.append((w, t))
412 continue
412 continue
413 flushss()
413 flushss()
414 ws.append(w)
414 ws.append(w)
415 ts.append(t)
415 ts.append(t)
416 flushss()
416 flushss()
417 if len(ts) == 1:
417 if len(ts) == 1:
418 return ws[0], ts[0] # 'or' operation is fully optimized out
418 return ws[0], ts[0] # 'or' operation is fully optimized out
419 return max(ws), (op, ('list',) + tuple(ts))
419 return max(ws), (op, ('list',) + tuple(ts))
420 elif op == 'not':
420 elif op == 'not':
421 # Optimize not public() to _notpublic() because we have a fast version
421 # Optimize not public() to _notpublic() because we have a fast version
422 if _match('public()', x[1]):
422 if _match('public()', x[1]):
423 o = _optimize(_build('_notpublic()'))
423 o = _optimize(_build('_notpublic()'))
424 return o[0], o[1]
424 return o[0], o[1]
425 else:
425 else:
426 o = _optimize(x[1])
426 o = _optimize(x[1])
427 return o[0], (op, o[1])
427 return o[0], (op, o[1])
428 elif op == 'rangeall':
428 elif op == 'rangeall':
429 return 1, x
429 return 1, x
430 elif op in ('rangepre', 'rangepost', 'parentpost'):
430 elif op in ('rangepre', 'rangepost', 'parentpost'):
431 o = _optimize(x[1])
431 o = _optimize(x[1])
432 return o[0], (op, o[1])
432 return o[0], (op, o[1])
433 elif op in ('dagrange', 'range'):
433 elif op in ('dagrange', 'range'):
434 wa, ta = _optimize(x[1])
434 wa, ta = _optimize(x[1])
435 wb, tb = _optimize(x[2])
435 wb, tb = _optimize(x[2])
436 return wa + wb, (op, ta, tb)
436 return wa + wb, (op, ta, tb)
437 elif op in ('parent', 'ancestor', 'relation', 'subscript'):
437 elif op in ('parent', 'ancestor', 'relation', 'subscript'):
438 w, t = _optimize(x[1])
438 w, t = _optimize(x[1])
439 return w, (op, t, x[2])
439 return w, (op, t, x[2])
440 elif op == 'relsubscript':
440 elif op == 'relsubscript':
441 w, t = _optimize(x[1])
441 w, t = _optimize(x[1])
442 return w, (op, t, x[2], x[3])
442 return w, (op, t, x[2], x[3])
443 elif op == 'list':
443 elif op == 'list':
444 ws, ts = zip(*(_optimize(y) for y in x[1:]))
444 ws, ts = zip(*(_optimize(y) for y in x[1:]))
445 return sum(ws), (op,) + ts
445 return sum(ws), (op,) + ts
446 elif op == 'keyvalue':
446 elif op == 'keyvalue':
447 w, t = _optimize(x[2])
447 w, t = _optimize(x[2])
448 return w, (op, x[1], t)
448 return w, (op, x[1], t)
449 elif op == 'func':
449 elif op == 'func':
450 f = getsymbol(x[1])
450 f = getsymbol(x[1])
451 wa, ta = _optimize(x[2])
451 wa, ta = _optimize(x[2])
452 w = getattr(symbols.get(f), '_weight', 1)
452 w = getattr(symbols.get(f), '_weight', 1)
453 return w + wa, (op, x[1], ta)
453 return w + wa, (op, x[1], ta)
454 raise ValueError('invalid operator %r' % op)
454 raise ValueError('invalid operator %r' % op)
455
455
456 def optimize(tree):
456 def optimize(tree):
457 """Optimize evaluatable tree
457 """Optimize evaluatable tree
458
458
459 All pseudo operations should be transformed beforehand.
459 All pseudo operations should be transformed beforehand.
460 """
460 """
461 _weight, newtree = _optimize(tree)
461 _weight, newtree = _optimize(tree)
462 return newtree
462 return newtree
463
463
464 # the set of valid characters for the initial letter of symbols in
464 # the set of valid characters for the initial letter of symbols in
465 # alias declarations and definitions
465 # alias declarations and definitions
466 _aliassyminitletters = _syminitletters | {'$'}
466 _aliassyminitletters = _syminitletters | {'$'}
467
467
468 def _parsewith(spec, lookup=None, syminitletters=None):
468 def _parsewith(spec, lookup=None, syminitletters=None):
469 """Generate a parse tree of given spec with given tokenizing options
469 """Generate a parse tree of given spec with given tokenizing options
470
470
471 >>> _parsewith(b'foo($1)', syminitletters=_aliassyminitletters)
471 >>> _parsewith(b'foo($1)', syminitletters=_aliassyminitletters)
472 ('func', ('symbol', 'foo'), ('symbol', '$1'))
472 ('func', ('symbol', 'foo'), ('symbol', '$1'))
473 >>> _parsewith(b'$1')
473 >>> _parsewith(b'$1')
474 Traceback (most recent call last):
474 Traceback (most recent call last):
475 ...
475 ...
476 ParseError: ("syntax error in revset '$1'", 0)
476 ParseError: ("syntax error in revset '$1'", 0)
477 >>> _parsewith(b'foo bar')
477 >>> _parsewith(b'foo bar')
478 Traceback (most recent call last):
478 Traceback (most recent call last):
479 ...
479 ...
480 ParseError: ('invalid token', 4)
480 ParseError: ('invalid token', 4)
481 """
481 """
482 p = parser.parser(elements)
482 p = parser.parser(elements)
483 tree, pos = p.parse(tokenize(spec, lookup=lookup,
483 tree, pos = p.parse(tokenize(spec, lookup=lookup,
484 syminitletters=syminitletters))
484 syminitletters=syminitletters))
485 if pos != len(spec):
485 if pos != len(spec):
486 raise error.ParseError(_('invalid token'), pos)
486 raise error.ParseError(_('invalid token'), pos)
487 return _fixops(parser.simplifyinfixops(tree, ('list', 'or')))
487 return _fixops(parser.simplifyinfixops(tree, ('list', 'or')))
488
488
489 class _aliasrules(parser.basealiasrules):
489 class _aliasrules(parser.basealiasrules):
490 """Parsing and expansion rule set of revset aliases"""
490 """Parsing and expansion rule set of revset aliases"""
491 _section = _('revset alias')
491 _section = _('revset alias')
492
492
493 @staticmethod
493 @staticmethod
494 def _parse(spec):
494 def _parse(spec):
495 """Parse alias declaration/definition ``spec``
495 """Parse alias declaration/definition ``spec``
496
496
497 This allows symbol names to use also ``$`` as an initial letter
497 This allows symbol names to use also ``$`` as an initial letter
498 (for backward compatibility), and callers of this function should
498 (for backward compatibility), and callers of this function should
499 examine whether ``$`` is used also for unexpected symbols or not.
499 examine whether ``$`` is used also for unexpected symbols or not.
500 """
500 """
501 return _parsewith(spec, syminitletters=_aliassyminitletters)
501 return _parsewith(spec, syminitletters=_aliassyminitletters)
502
502
503 @staticmethod
503 @staticmethod
504 def _trygetfunc(tree):
504 def _trygetfunc(tree):
505 if tree[0] == 'func' and tree[1][0] == 'symbol':
505 if tree[0] == 'func' and tree[1][0] == 'symbol':
506 return tree[1][1], getlist(tree[2])
506 return tree[1][1], getlist(tree[2])
507
507
508 def expandaliases(tree, aliases, warn=None):
508 def expandaliases(tree, aliases, warn=None):
509 """Expand aliases in a tree, aliases is a list of (name, value) tuples"""
509 """Expand aliases in a tree, aliases is a list of (name, value) tuples"""
510 aliases = _aliasrules.buildmap(aliases)
510 aliases = _aliasrules.buildmap(aliases)
511 tree = _aliasrules.expand(aliases, tree)
511 tree = _aliasrules.expand(aliases, tree)
512 # warn about problematic (but not referred) aliases
512 # warn about problematic (but not referred) aliases
513 if warn is not None:
513 if warn is not None:
514 for name, alias in sorted(aliases.iteritems()):
514 for name, alias in sorted(aliases.iteritems()):
515 if alias.error and not alias.warned:
515 if alias.error and not alias.warned:
516 warn(_('warning: %s\n') % (alias.error))
516 warn(_('warning: %s\n') % (alias.error))
517 alias.warned = True
517 alias.warned = True
518 return tree
518 return tree
519
519
520 def foldconcat(tree):
520 def foldconcat(tree):
521 """Fold elements to be concatenated by `##`
521 """Fold elements to be concatenated by `##`
522 """
522 """
523 if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
523 if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
524 return tree
524 return tree
525 if tree[0] == '_concat':
525 if tree[0] == '_concat':
526 pending = [tree]
526 pending = [tree]
527 l = []
527 l = []
528 while pending:
528 while pending:
529 e = pending.pop()
529 e = pending.pop()
530 if e[0] == '_concat':
530 if e[0] == '_concat':
531 pending.extend(reversed(e[1:]))
531 pending.extend(reversed(e[1:]))
532 elif e[0] in ('string', 'symbol'):
532 elif e[0] in ('string', 'symbol'):
533 l.append(e[1])
533 l.append(e[1])
534 else:
534 else:
535 msg = _("\"##\" can't concatenate \"%s\" element") % (e[0])
535 msg = _("\"##\" can't concatenate \"%s\" element") % (e[0])
536 raise error.ParseError(msg)
536 raise error.ParseError(msg)
537 return ('string', ''.join(l))
537 return ('string', ''.join(l))
538 else:
538 else:
539 return tuple(foldconcat(t) for t in tree)
539 return tuple(foldconcat(t) for t in tree)
540
540
541 def parse(spec, lookup=None):
541 def parse(spec, lookup=None):
542 return _parsewith(spec, lookup=lookup)
542 return _parsewith(spec, lookup=lookup)
543
543
544 def _quote(s):
544 def _quote(s):
545 r"""Quote a value in order to make it safe for the revset engine.
545 r"""Quote a value in order to make it safe for the revset engine.
546
546
547 >>> _quote(b'asdf')
547 >>> _quote(b'asdf')
548 "'asdf'"
548 "'asdf'"
549 >>> _quote(b"asdf'\"")
549 >>> _quote(b"asdf'\"")
550 '\'asdf\\\'"\''
550 '\'asdf\\\'"\''
551 >>> _quote(b'asdf\'')
551 >>> _quote(b'asdf\'')
552 "'asdf\\''"
552 "'asdf\\''"
553 >>> _quote(1)
553 >>> _quote(1)
554 "'1'"
554 "'1'"
555 """
555 """
556 return "'%s'" % util.escapestr(pycompat.bytestr(s))
556 return "'%s'" % util.escapestr(pycompat.bytestr(s))
557
557
558 def formatspec(expr, *args):
558 def formatspec(expr, *args):
559 '''
559 '''
560 This is a convenience function for using revsets internally, and
560 This is a convenience function for using revsets internally, and
561 escapes arguments appropriately. Aliases are intentionally ignored
561 escapes arguments appropriately. Aliases are intentionally ignored
562 so that intended expression behavior isn't accidentally subverted.
562 so that intended expression behavior isn't accidentally subverted.
563
563
564 Supported arguments:
564 Supported arguments:
565
565
566 %r = revset expression, parenthesized
566 %r = revset expression, parenthesized
567 %d = int(arg), no quoting
567 %d = int(arg), no quoting
568 %s = string(arg), escaped and single-quoted
568 %s = string(arg), escaped and single-quoted
569 %b = arg.branch(), escaped and single-quoted
569 %b = arg.branch(), escaped and single-quoted
570 %n = hex(arg), single-quoted
570 %n = hex(arg), single-quoted
571 %% = a literal '%'
571 %% = a literal '%'
572
572
573 Prefixing the type with 'l' specifies a parenthesized list of that type.
573 Prefixing the type with 'l' specifies a parenthesized list of that type.
574
574
575 >>> formatspec(b'%r:: and %lr', b'10 or 11', (b"this()", b"that()"))
575 >>> formatspec(b'%r:: and %lr', b'10 or 11', (b"this()", b"that()"))
576 '(10 or 11):: and ((this()) or (that()))'
576 '(10 or 11):: and ((this()) or (that()))'
577 >>> formatspec(b'%d:: and not %d::', 10, 20)
577 >>> formatspec(b'%d:: and not %d::', 10, 20)
578 '10:: and not 20::'
578 '10:: and not 20::'
579 >>> formatspec(b'%ld or %ld', [], [1])
579 >>> formatspec(b'%ld or %ld', [], [1])
580 "_list('') or 1"
580 "_list('') or 1"
581 >>> formatspec(b'keyword(%s)', b'foo\\xe9')
581 >>> formatspec(b'keyword(%s)', b'foo\\xe9')
582 "keyword('foo\\\\xe9')"
582 "keyword('foo\\\\xe9')"
583 >>> b = lambda: b'default'
583 >>> b = lambda: b'default'
584 >>> b.branch = b
584 >>> b.branch = b
585 >>> formatspec(b'branch(%b)', b)
585 >>> formatspec(b'branch(%b)', b)
586 "branch('default')"
586 "branch('default')"
587 >>> formatspec(b'root(%ls)', [b'a', b'b', b'c', b'd'])
587 >>> formatspec(b'root(%ls)', [b'a', b'b', b'c', b'd'])
588 "root(_list('a\\x00b\\x00c\\x00d'))"
588 "root(_list('a\\x00b\\x00c\\x00d'))"
589 '''
589 '''
590
590
591 def argtype(c, arg):
591 def argtype(c, arg):
592 if c == 'd':
592 if c == 'd':
593 return '%d' % int(arg)
593 return '%d' % int(arg)
594 elif c == 's':
594 elif c == 's':
595 return _quote(arg)
595 return _quote(arg)
596 elif c == 'r':
596 elif c == 'r':
597 parse(arg) # make sure syntax errors are confined
597 parse(arg) # make sure syntax errors are confined
598 return '(%s)' % arg
598 return '(%s)' % arg
599 elif c == 'n':
599 elif c == 'n':
600 return _quote(node.hex(arg))
600 return _quote(node.hex(arg))
601 elif c == 'b':
601 elif c == 'b':
602 return _quote(arg.branch())
602 return _quote(arg.branch())
603
603
604 def listexp(s, t):
604 def listexp(s, t):
605 l = len(s)
605 l = len(s)
606 if l == 0:
606 if l == 0:
607 return "_list('')"
607 return "_list('')"
608 elif l == 1:
608 elif l == 1:
609 return argtype(t, s[0])
609 return argtype(t, s[0])
610 elif t == 'd':
610 elif t == 'd':
611 return "_intlist('%s')" % "\0".join('%d' % int(a) for a in s)
611 return "_intlist('%s')" % "\0".join('%d' % int(a) for a in s)
612 elif t == 's':
612 elif t == 's':
613 return "_list('%s')" % "\0".join(s)
613 return "_list('%s')" % "\0".join(s)
614 elif t == 'n':
614 elif t == 'n':
615 return "_hexlist('%s')" % "\0".join(node.hex(a) for a in s)
615 return "_hexlist('%s')" % "\0".join(node.hex(a) for a in s)
616 elif t == 'b':
616 elif t == 'b':
617 return "_list('%s')" % "\0".join(a.branch() for a in s)
617 return "_list('%s')" % "\0".join(a.branch() for a in s)
618
618
619 m = l // 2
619 m = l // 2
620 return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t))
620 return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t))
621
621
622 expr = pycompat.bytestr(expr)
622 expr = pycompat.bytestr(expr)
623 argiter = iter(args)
623 argiter = iter(args)
624 ret = []
624 ret = []
625 pos = 0
625 pos = 0
626 while pos < len(expr):
626 while pos < len(expr):
627 q = expr.find('%', pos)
627 q = expr.find('%', pos)
628 if q < 0:
628 if q < 0:
629 ret.append(expr[pos:])
629 ret.append(expr[pos:])
630 break
630 break
631 ret.append(expr[pos:q])
631 ret.append(expr[pos:q])
632 pos = q + 1
632 pos = q + 1
633 d = expr[pos]
633 d = expr[pos]
634 if d == '%':
634 if d == '%':
635 ret.append(d)
635 ret.append(d)
636 elif d in 'dsnbr':
636 elif d in 'dsnbr':
637 ret.append(argtype(d, next(argiter)))
637 ret.append(argtype(d, next(argiter)))
638 elif d == 'l':
638 elif d == 'l':
639 # a list of some type
639 # a list of some type
640 pos += 1
640 pos += 1
641 d = expr[pos]
641 d = expr[pos]
642 ret.append(listexp(list(next(argiter)), d))
642 ret.append(listexp(list(next(argiter)), d))
643 else:
643 else:
644 raise error.Abort(_('unexpected revspec format character %s') % d)
644 raise error.ParseError(_('unexpected revspec format character %s')
645 % d)
645 pos += 1
646 pos += 1
646
647
647 return ''.join(ret)
648 return ''.join(ret)
648
649
649 def prettyformat(tree):
650 def prettyformat(tree):
650 return parser.prettyformat(tree, ('string', 'symbol'))
651 return parser.prettyformat(tree, ('string', 'symbol'))
651
652
652 def depth(tree):
653 def depth(tree):
653 if isinstance(tree, tuple):
654 if isinstance(tree, tuple):
654 return max(map(depth, tree)) + 1
655 return max(map(depth, tree)) + 1
655 else:
656 else:
656 return 0
657 return 0
657
658
658 def funcsused(tree):
659 def funcsused(tree):
659 if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
660 if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
660 return set()
661 return set()
661 else:
662 else:
662 funcs = set()
663 funcs = set()
663 for s in tree[1:]:
664 for s in tree[1:]:
664 funcs |= funcsused(s)
665 funcs |= funcsused(s)
665 if tree[0] == 'func':
666 if tree[0] == 'func':
666 funcs.add(tree[1][1])
667 funcs.add(tree[1][1])
667 return funcs
668 return funcs
668
669
669 _hashre = util.re.compile('[0-9a-fA-F]{1,40}$')
670 _hashre = util.re.compile('[0-9a-fA-F]{1,40}$')
670
671
671 def _ishashlikesymbol(symbol):
672 def _ishashlikesymbol(symbol):
672 """returns true if the symbol looks like a hash"""
673 """returns true if the symbol looks like a hash"""
673 return _hashre.match(symbol)
674 return _hashre.match(symbol)
674
675
675 def gethashlikesymbols(tree):
676 def gethashlikesymbols(tree):
676 """returns the list of symbols of the tree that look like hashes
677 """returns the list of symbols of the tree that look like hashes
677
678
678 >>> gethashlikesymbols(('dagrange', ('symbol', '3'), ('symbol', 'abe3ff')))
679 >>> gethashlikesymbols(('dagrange', ('symbol', '3'), ('symbol', 'abe3ff')))
679 ['3', 'abe3ff']
680 ['3', 'abe3ff']
680 >>> gethashlikesymbols(('func', ('symbol', 'precursors'), ('symbol', '.')))
681 >>> gethashlikesymbols(('func', ('symbol', 'precursors'), ('symbol', '.')))
681 []
682 []
682 >>> gethashlikesymbols(('func', ('symbol', 'precursors'), ('symbol', '34')))
683 >>> gethashlikesymbols(('func', ('symbol', 'precursors'), ('symbol', '34')))
683 ['34']
684 ['34']
684 >>> gethashlikesymbols(('symbol', 'abe3ffZ'))
685 >>> gethashlikesymbols(('symbol', 'abe3ffZ'))
685 []
686 []
686 """
687 """
687 if not tree:
688 if not tree:
688 return []
689 return []
689
690
690 if tree[0] == "symbol":
691 if tree[0] == "symbol":
691 if _ishashlikesymbol(tree[1]):
692 if _ishashlikesymbol(tree[1]):
692 return [tree[1]]
693 return [tree[1]]
693 elif len(tree) >= 3:
694 elif len(tree) >= 3:
694 results = []
695 results = []
695 for subtree in tree[1:]:
696 for subtree in tree[1:]:
696 results += gethashlikesymbols(subtree)
697 results += gethashlikesymbols(subtree)
697 return results
698 return results
698 return []
699 return []
@@ -1,4717 +1,4723
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo a > a
3 $ echo a > a
4 $ hg add a
4 $ hg add a
5 $ echo line 1 > b
5 $ echo line 1 > b
6 $ echo line 2 >> b
6 $ echo line 2 >> b
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
8
8
9 $ hg add b
9 $ hg add b
10 $ echo other 1 > c
10 $ echo other 1 > c
11 $ echo other 2 >> c
11 $ echo other 2 >> c
12 $ echo >> c
12 $ echo >> c
13 $ echo other 3 >> c
13 $ echo other 3 >> c
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
15
15
16 $ hg add c
16 $ hg add c
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
18 $ echo c >> c
18 $ echo c >> c
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
20
20
21 $ echo foo > .hg/branch
21 $ echo foo > .hg/branch
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
23
23
24 $ hg co -q 3
24 $ hg co -q 3
25 $ echo other 4 >> d
25 $ echo other 4 >> d
26 $ hg add d
26 $ hg add d
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
28
28
29 $ hg merge -q foo
29 $ hg merge -q foo
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
31
31
32 Test arithmetic operators have the right precedence:
32 Test arithmetic operators have the right precedence:
33
33
34 $ hg log -l 1 -T '{date(date, "%Y") + 5 * 10} {date(date, "%Y") - 2 * 3}\n'
34 $ hg log -l 1 -T '{date(date, "%Y") + 5 * 10} {date(date, "%Y") - 2 * 3}\n'
35 2020 1964
35 2020 1964
36 $ hg log -l 1 -T '{date(date, "%Y") * 5 + 10} {date(date, "%Y") * 3 - 2}\n'
36 $ hg log -l 1 -T '{date(date, "%Y") * 5 + 10} {date(date, "%Y") * 3 - 2}\n'
37 9860 5908
37 9860 5908
38
38
39 Test division:
39 Test division:
40
40
41 $ hg debugtemplate -r0 -v '{5 / 2} {mod(5, 2)}\n'
41 $ hg debugtemplate -r0 -v '{5 / 2} {mod(5, 2)}\n'
42 (template
42 (template
43 (/
43 (/
44 (integer '5')
44 (integer '5')
45 (integer '2'))
45 (integer '2'))
46 (string ' ')
46 (string ' ')
47 (func
47 (func
48 (symbol 'mod')
48 (symbol 'mod')
49 (list
49 (list
50 (integer '5')
50 (integer '5')
51 (integer '2')))
51 (integer '2')))
52 (string '\n'))
52 (string '\n'))
53 2 1
53 2 1
54 $ hg debugtemplate -r0 -v '{5 / -2} {mod(5, -2)}\n'
54 $ hg debugtemplate -r0 -v '{5 / -2} {mod(5, -2)}\n'
55 (template
55 (template
56 (/
56 (/
57 (integer '5')
57 (integer '5')
58 (negate
58 (negate
59 (integer '2')))
59 (integer '2')))
60 (string ' ')
60 (string ' ')
61 (func
61 (func
62 (symbol 'mod')
62 (symbol 'mod')
63 (list
63 (list
64 (integer '5')
64 (integer '5')
65 (negate
65 (negate
66 (integer '2'))))
66 (integer '2'))))
67 (string '\n'))
67 (string '\n'))
68 -3 -1
68 -3 -1
69 $ hg debugtemplate -r0 -v '{-5 / 2} {mod(-5, 2)}\n'
69 $ hg debugtemplate -r0 -v '{-5 / 2} {mod(-5, 2)}\n'
70 (template
70 (template
71 (/
71 (/
72 (negate
72 (negate
73 (integer '5'))
73 (integer '5'))
74 (integer '2'))
74 (integer '2'))
75 (string ' ')
75 (string ' ')
76 (func
76 (func
77 (symbol 'mod')
77 (symbol 'mod')
78 (list
78 (list
79 (negate
79 (negate
80 (integer '5'))
80 (integer '5'))
81 (integer '2')))
81 (integer '2')))
82 (string '\n'))
82 (string '\n'))
83 -3 1
83 -3 1
84 $ hg debugtemplate -r0 -v '{-5 / -2} {mod(-5, -2)}\n'
84 $ hg debugtemplate -r0 -v '{-5 / -2} {mod(-5, -2)}\n'
85 (template
85 (template
86 (/
86 (/
87 (negate
87 (negate
88 (integer '5'))
88 (integer '5'))
89 (negate
89 (negate
90 (integer '2')))
90 (integer '2')))
91 (string ' ')
91 (string ' ')
92 (func
92 (func
93 (symbol 'mod')
93 (symbol 'mod')
94 (list
94 (list
95 (negate
95 (negate
96 (integer '5'))
96 (integer '5'))
97 (negate
97 (negate
98 (integer '2'))))
98 (integer '2'))))
99 (string '\n'))
99 (string '\n'))
100 2 -1
100 2 -1
101
101
102 Filters bind closer than arithmetic:
102 Filters bind closer than arithmetic:
103
103
104 $ hg debugtemplate -r0 -v '{revset(".")|count - 1}\n'
104 $ hg debugtemplate -r0 -v '{revset(".")|count - 1}\n'
105 (template
105 (template
106 (-
106 (-
107 (|
107 (|
108 (func
108 (func
109 (symbol 'revset')
109 (symbol 'revset')
110 (string '.'))
110 (string '.'))
111 (symbol 'count'))
111 (symbol 'count'))
112 (integer '1'))
112 (integer '1'))
113 (string '\n'))
113 (string '\n'))
114 0
114 0
115
115
116 But negate binds closer still:
116 But negate binds closer still:
117
117
118 $ hg debugtemplate -r0 -v '{1-3|stringify}\n'
118 $ hg debugtemplate -r0 -v '{1-3|stringify}\n'
119 (template
119 (template
120 (-
120 (-
121 (integer '1')
121 (integer '1')
122 (|
122 (|
123 (integer '3')
123 (integer '3')
124 (symbol 'stringify')))
124 (symbol 'stringify')))
125 (string '\n'))
125 (string '\n'))
126 hg: parse error: arithmetic only defined on integers
126 hg: parse error: arithmetic only defined on integers
127 [255]
127 [255]
128 $ hg debugtemplate -r0 -v '{-3|stringify}\n'
128 $ hg debugtemplate -r0 -v '{-3|stringify}\n'
129 (template
129 (template
130 (|
130 (|
131 (negate
131 (negate
132 (integer '3'))
132 (integer '3'))
133 (symbol 'stringify'))
133 (symbol 'stringify'))
134 (string '\n'))
134 (string '\n'))
135 -3
135 -3
136
136
137 Filters bind as close as map operator:
137 Filters bind as close as map operator:
138
138
139 $ hg debugtemplate -r0 -v '{desc|splitlines % "{line}\n"}'
139 $ hg debugtemplate -r0 -v '{desc|splitlines % "{line}\n"}'
140 (template
140 (template
141 (%
141 (%
142 (|
142 (|
143 (symbol 'desc')
143 (symbol 'desc')
144 (symbol 'splitlines'))
144 (symbol 'splitlines'))
145 (template
145 (template
146 (symbol 'line')
146 (symbol 'line')
147 (string '\n'))))
147 (string '\n'))))
148 line 1
148 line 1
149 line 2
149 line 2
150
150
151 Keyword arguments:
151 Keyword arguments:
152
152
153 $ hg debugtemplate -r0 -v '{foo=bar|baz}'
153 $ hg debugtemplate -r0 -v '{foo=bar|baz}'
154 (template
154 (template
155 (keyvalue
155 (keyvalue
156 (symbol 'foo')
156 (symbol 'foo')
157 (|
157 (|
158 (symbol 'bar')
158 (symbol 'bar')
159 (symbol 'baz'))))
159 (symbol 'baz'))))
160 hg: parse error: can't use a key-value pair in this context
160 hg: parse error: can't use a key-value pair in this context
161 [255]
161 [255]
162
162
163 $ hg debugtemplate '{pad("foo", width=10, left=true)}\n'
163 $ hg debugtemplate '{pad("foo", width=10, left=true)}\n'
164 foo
164 foo
165
165
166 Call function which takes named arguments by filter syntax:
166 Call function which takes named arguments by filter syntax:
167
167
168 $ hg debugtemplate '{" "|separate}'
168 $ hg debugtemplate '{" "|separate}'
169 $ hg debugtemplate '{("not", "an", "argument", "list")|separate}'
169 $ hg debugtemplate '{("not", "an", "argument", "list")|separate}'
170 hg: parse error: unknown method 'list'
170 hg: parse error: unknown method 'list'
171 [255]
171 [255]
172
172
173 Second branch starting at nullrev:
173 Second branch starting at nullrev:
174
174
175 $ hg update null
175 $ hg update null
176 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
176 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
177 $ echo second > second
177 $ echo second > second
178 $ hg add second
178 $ hg add second
179 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
179 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
180 created new head
180 created new head
181
181
182 $ echo third > third
182 $ echo third > third
183 $ hg add third
183 $ hg add third
184 $ hg mv second fourth
184 $ hg mv second fourth
185 $ hg commit -m third -d "2020-01-01 10:01"
185 $ hg commit -m third -d "2020-01-01 10:01"
186
186
187 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
187 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
188 fourth (second)
188 fourth (second)
189 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
189 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
190 second -> fourth
190 second -> fourth
191 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
191 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
192 8 t
192 8 t
193 7 f
193 7 f
194
194
195 Working-directory revision has special identifiers, though they are still
195 Working-directory revision has special identifiers, though they are still
196 experimental:
196 experimental:
197
197
198 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
198 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
199 2147483647:ffffffffffffffffffffffffffffffffffffffff
199 2147483647:ffffffffffffffffffffffffffffffffffffffff
200
200
201 Some keywords are invalid for working-directory revision, but they should
201 Some keywords are invalid for working-directory revision, but they should
202 never cause crash:
202 never cause crash:
203
203
204 $ hg log -r 'wdir()' -T '{manifest}\n'
204 $ hg log -r 'wdir()' -T '{manifest}\n'
205
205
206
206
207 Internal resources shouldn't be exposed (issue5699):
207 Internal resources shouldn't be exposed (issue5699):
208
208
209 $ hg log -r. -T '{cache}{ctx}{repo}{revcache}{templ}{ui}'
209 $ hg log -r. -T '{cache}{ctx}{repo}{revcache}{templ}{ui}'
210
210
211 Never crash on internal resource not available:
211 Never crash on internal resource not available:
212
212
213 $ hg --cwd .. debugtemplate '{"c0bebeef"|shortest}\n'
213 $ hg --cwd .. debugtemplate '{"c0bebeef"|shortest}\n'
214 abort: template resource not available: ctx
214 abort: template resource not available: ctx
215 [255]
215 [255]
216
216
217 Quoting for ui.logtemplate
217 Quoting for ui.logtemplate
218
218
219 $ hg tip --config "ui.logtemplate={rev}\n"
219 $ hg tip --config "ui.logtemplate={rev}\n"
220 8
220 8
221 $ hg tip --config "ui.logtemplate='{rev}\n'"
221 $ hg tip --config "ui.logtemplate='{rev}\n'"
222 8
222 8
223 $ hg tip --config 'ui.logtemplate="{rev}\n"'
223 $ hg tip --config 'ui.logtemplate="{rev}\n"'
224 8
224 8
225 $ hg tip --config 'ui.logtemplate=n{rev}\n'
225 $ hg tip --config 'ui.logtemplate=n{rev}\n'
226 n8
226 n8
227
227
228 Make sure user/global hgrc does not affect tests
228 Make sure user/global hgrc does not affect tests
229
229
230 $ echo '[ui]' > .hg/hgrc
230 $ echo '[ui]' > .hg/hgrc
231 $ echo 'logtemplate =' >> .hg/hgrc
231 $ echo 'logtemplate =' >> .hg/hgrc
232 $ echo 'style =' >> .hg/hgrc
232 $ echo 'style =' >> .hg/hgrc
233
233
234 Add some simple styles to settings
234 Add some simple styles to settings
235
235
236 $ cat <<'EOF' >> .hg/hgrc
236 $ cat <<'EOF' >> .hg/hgrc
237 > [templates]
237 > [templates]
238 > simple = "{rev}\n"
238 > simple = "{rev}\n"
239 > simple2 = {rev}\n
239 > simple2 = {rev}\n
240 > rev = "should not precede {rev} keyword\n"
240 > rev = "should not precede {rev} keyword\n"
241 > EOF
241 > EOF
242
242
243 $ hg log -l1 -Tsimple
243 $ hg log -l1 -Tsimple
244 8
244 8
245 $ hg log -l1 -Tsimple2
245 $ hg log -l1 -Tsimple2
246 8
246 8
247 $ hg log -l1 -Trev
247 $ hg log -l1 -Trev
248 should not precede 8 keyword
248 should not precede 8 keyword
249 $ hg log -l1 -T '{simple}'
249 $ hg log -l1 -T '{simple}'
250 8
250 8
251
251
252 Map file shouldn't see user templates:
252 Map file shouldn't see user templates:
253
253
254 $ cat <<EOF > tmpl
254 $ cat <<EOF > tmpl
255 > changeset = 'nothing expanded:{simple}\n'
255 > changeset = 'nothing expanded:{simple}\n'
256 > EOF
256 > EOF
257 $ hg log -l1 --style ./tmpl
257 $ hg log -l1 --style ./tmpl
258 nothing expanded:
258 nothing expanded:
259
259
260 Test templates and style maps in files:
260 Test templates and style maps in files:
261
261
262 $ echo "{rev}" > tmpl
262 $ echo "{rev}" > tmpl
263 $ hg log -l1 -T./tmpl
263 $ hg log -l1 -T./tmpl
264 8
264 8
265 $ hg log -l1 -Tblah/blah
265 $ hg log -l1 -Tblah/blah
266 blah/blah (no-eol)
266 blah/blah (no-eol)
267
267
268 $ printf 'changeset = "{rev}\\n"\n' > map-simple
268 $ printf 'changeset = "{rev}\\n"\n' > map-simple
269 $ hg log -l1 -T./map-simple
269 $ hg log -l1 -T./map-simple
270 8
270 8
271
271
272 a map file may have [templates] and [templatealias] sections:
272 a map file may have [templates] and [templatealias] sections:
273
273
274 $ cat <<'EOF' > map-simple
274 $ cat <<'EOF' > map-simple
275 > [templates]
275 > [templates]
276 > changeset = "{a}\n"
276 > changeset = "{a}\n"
277 > [templatealias]
277 > [templatealias]
278 > a = rev
278 > a = rev
279 > EOF
279 > EOF
280 $ hg log -l1 -T./map-simple
280 $ hg log -l1 -T./map-simple
281 8
281 8
282
282
283 so it can be included in hgrc
283 so it can be included in hgrc
284
284
285 $ cat <<'EOF' > myhgrc
285 $ cat <<'EOF' > myhgrc
286 > %include map-simple
286 > %include map-simple
287 > [templates]
287 > [templates]
288 > foo = "{changeset}"
288 > foo = "{changeset}"
289 > EOF
289 > EOF
290 $ HGRCPATH=./myhgrc hg log -l1 -Tfoo
290 $ HGRCPATH=./myhgrc hg log -l1 -Tfoo
291 8
291 8
292 $ HGRCPATH=./myhgrc hg log -l1 -T'{a}\n'
292 $ HGRCPATH=./myhgrc hg log -l1 -T'{a}\n'
293 8
293 8
294
294
295 Test template map inheritance
295 Test template map inheritance
296
296
297 $ echo "__base__ = map-cmdline.default" > map-simple
297 $ echo "__base__ = map-cmdline.default" > map-simple
298 $ printf 'cset = "changeset: ***{rev}***\\n"\n' >> map-simple
298 $ printf 'cset = "changeset: ***{rev}***\\n"\n' >> map-simple
299 $ hg log -l1 -T./map-simple
299 $ hg log -l1 -T./map-simple
300 changeset: ***8***
300 changeset: ***8***
301 tag: tip
301 tag: tip
302 user: test
302 user: test
303 date: Wed Jan 01 10:01:00 2020 +0000
303 date: Wed Jan 01 10:01:00 2020 +0000
304 summary: third
304 summary: third
305
305
306
306
307 Test docheader, docfooter and separator in template map
307 Test docheader, docfooter and separator in template map
308
308
309 $ cat <<'EOF' > map-myjson
309 $ cat <<'EOF' > map-myjson
310 > docheader = '\{\n'
310 > docheader = '\{\n'
311 > docfooter = '\n}\n'
311 > docfooter = '\n}\n'
312 > separator = ',\n'
312 > separator = ',\n'
313 > changeset = ' {dict(rev, node|short)|json}'
313 > changeset = ' {dict(rev, node|short)|json}'
314 > EOF
314 > EOF
315 $ hg log -l2 -T./map-myjson
315 $ hg log -l2 -T./map-myjson
316 {
316 {
317 {"node": "95c24699272e", "rev": 8},
317 {"node": "95c24699272e", "rev": 8},
318 {"node": "29114dbae42b", "rev": 7}
318 {"node": "29114dbae42b", "rev": 7}
319 }
319 }
320
320
321 Test docheader, docfooter and separator in [templates] section
321 Test docheader, docfooter and separator in [templates] section
322
322
323 $ cat <<'EOF' >> .hg/hgrc
323 $ cat <<'EOF' >> .hg/hgrc
324 > [templates]
324 > [templates]
325 > myjson = ' {dict(rev, node|short)|json}'
325 > myjson = ' {dict(rev, node|short)|json}'
326 > myjson:docheader = '\{\n'
326 > myjson:docheader = '\{\n'
327 > myjson:docfooter = '\n}\n'
327 > myjson:docfooter = '\n}\n'
328 > myjson:separator = ',\n'
328 > myjson:separator = ',\n'
329 > :docheader = 'should not be selected as a docheader for literal templates\n'
329 > :docheader = 'should not be selected as a docheader for literal templates\n'
330 > EOF
330 > EOF
331 $ hg log -l2 -Tmyjson
331 $ hg log -l2 -Tmyjson
332 {
332 {
333 {"node": "95c24699272e", "rev": 8},
333 {"node": "95c24699272e", "rev": 8},
334 {"node": "29114dbae42b", "rev": 7}
334 {"node": "29114dbae42b", "rev": 7}
335 }
335 }
336 $ hg log -l1 -T'{rev}\n'
336 $ hg log -l1 -T'{rev}\n'
337 8
337 8
338
338
339 Template should precede style option
339 Template should precede style option
340
340
341 $ hg log -l1 --style default -T '{rev}\n'
341 $ hg log -l1 --style default -T '{rev}\n'
342 8
342 8
343
343
344 Add a commit with empty description, to ensure that the templates
344 Add a commit with empty description, to ensure that the templates
345 below will omit the description line.
345 below will omit the description line.
346
346
347 $ echo c >> c
347 $ echo c >> c
348 $ hg add c
348 $ hg add c
349 $ hg commit -qm ' '
349 $ hg commit -qm ' '
350
350
351 Default style is like normal output. Phases style should be the same
351 Default style is like normal output. Phases style should be the same
352 as default style, except for extra phase lines.
352 as default style, except for extra phase lines.
353
353
354 $ hg log > log.out
354 $ hg log > log.out
355 $ hg log --style default > style.out
355 $ hg log --style default > style.out
356 $ cmp log.out style.out || diff -u log.out style.out
356 $ cmp log.out style.out || diff -u log.out style.out
357 $ hg log -T phases > phases.out
357 $ hg log -T phases > phases.out
358 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
358 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
359 +phase: draft
359 +phase: draft
360 +phase: draft
360 +phase: draft
361 +phase: draft
361 +phase: draft
362 +phase: draft
362 +phase: draft
363 +phase: draft
363 +phase: draft
364 +phase: draft
364 +phase: draft
365 +phase: draft
365 +phase: draft
366 +phase: draft
366 +phase: draft
367 +phase: draft
367 +phase: draft
368 +phase: draft
368 +phase: draft
369
369
370 $ hg log -v > log.out
370 $ hg log -v > log.out
371 $ hg log -v --style default > style.out
371 $ hg log -v --style default > style.out
372 $ cmp log.out style.out || diff -u log.out style.out
372 $ cmp log.out style.out || diff -u log.out style.out
373 $ hg log -v -T phases > phases.out
373 $ hg log -v -T phases > phases.out
374 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
374 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
375 +phase: draft
375 +phase: draft
376 +phase: draft
376 +phase: draft
377 +phase: draft
377 +phase: draft
378 +phase: draft
378 +phase: draft
379 +phase: draft
379 +phase: draft
380 +phase: draft
380 +phase: draft
381 +phase: draft
381 +phase: draft
382 +phase: draft
382 +phase: draft
383 +phase: draft
383 +phase: draft
384 +phase: draft
384 +phase: draft
385
385
386 $ hg log -q > log.out
386 $ hg log -q > log.out
387 $ hg log -q --style default > style.out
387 $ hg log -q --style default > style.out
388 $ cmp log.out style.out || diff -u log.out style.out
388 $ cmp log.out style.out || diff -u log.out style.out
389 $ hg log -q -T phases > phases.out
389 $ hg log -q -T phases > phases.out
390 $ cmp log.out phases.out || diff -u log.out phases.out
390 $ cmp log.out phases.out || diff -u log.out phases.out
391
391
392 $ hg log --debug > log.out
392 $ hg log --debug > log.out
393 $ hg log --debug --style default > style.out
393 $ hg log --debug --style default > style.out
394 $ cmp log.out style.out || diff -u log.out style.out
394 $ cmp log.out style.out || diff -u log.out style.out
395 $ hg log --debug -T phases > phases.out
395 $ hg log --debug -T phases > phases.out
396 $ cmp log.out phases.out || diff -u log.out phases.out
396 $ cmp log.out phases.out || diff -u log.out phases.out
397
397
398 Default style of working-directory revision should also be the same (but
398 Default style of working-directory revision should also be the same (but
399 date may change while running tests):
399 date may change while running tests):
400
400
401 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
401 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
402 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
402 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
403 $ cmp log.out style.out || diff -u log.out style.out
403 $ cmp log.out style.out || diff -u log.out style.out
404
404
405 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
405 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
406 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
406 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
407 $ cmp log.out style.out || diff -u log.out style.out
407 $ cmp log.out style.out || diff -u log.out style.out
408
408
409 $ hg log -r 'wdir()' -q > log.out
409 $ hg log -r 'wdir()' -q > log.out
410 $ hg log -r 'wdir()' -q --style default > style.out
410 $ hg log -r 'wdir()' -q --style default > style.out
411 $ cmp log.out style.out || diff -u log.out style.out
411 $ cmp log.out style.out || diff -u log.out style.out
412
412
413 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
413 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
414 $ hg log -r 'wdir()' --debug --style default \
414 $ hg log -r 'wdir()' --debug --style default \
415 > | sed 's|^date:.*|date:|' > style.out
415 > | sed 's|^date:.*|date:|' > style.out
416 $ cmp log.out style.out || diff -u log.out style.out
416 $ cmp log.out style.out || diff -u log.out style.out
417
417
418 Default style should also preserve color information (issue2866):
418 Default style should also preserve color information (issue2866):
419
419
420 $ cp $HGRCPATH $HGRCPATH-bak
420 $ cp $HGRCPATH $HGRCPATH-bak
421 $ cat <<EOF >> $HGRCPATH
421 $ cat <<EOF >> $HGRCPATH
422 > [extensions]
422 > [extensions]
423 > color=
423 > color=
424 > EOF
424 > EOF
425
425
426 $ hg --color=debug log > log.out
426 $ hg --color=debug log > log.out
427 $ hg --color=debug log --style default > style.out
427 $ hg --color=debug log --style default > style.out
428 $ cmp log.out style.out || diff -u log.out style.out
428 $ cmp log.out style.out || diff -u log.out style.out
429 $ hg --color=debug log -T phases > phases.out
429 $ hg --color=debug log -T phases > phases.out
430 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
430 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
431 +[log.phase|phase: draft]
431 +[log.phase|phase: draft]
432 +[log.phase|phase: draft]
432 +[log.phase|phase: draft]
433 +[log.phase|phase: draft]
433 +[log.phase|phase: draft]
434 +[log.phase|phase: draft]
434 +[log.phase|phase: draft]
435 +[log.phase|phase: draft]
435 +[log.phase|phase: draft]
436 +[log.phase|phase: draft]
436 +[log.phase|phase: draft]
437 +[log.phase|phase: draft]
437 +[log.phase|phase: draft]
438 +[log.phase|phase: draft]
438 +[log.phase|phase: draft]
439 +[log.phase|phase: draft]
439 +[log.phase|phase: draft]
440 +[log.phase|phase: draft]
440 +[log.phase|phase: draft]
441
441
442 $ hg --color=debug -v log > log.out
442 $ hg --color=debug -v log > log.out
443 $ hg --color=debug -v log --style default > style.out
443 $ hg --color=debug -v log --style default > style.out
444 $ cmp log.out style.out || diff -u log.out style.out
444 $ cmp log.out style.out || diff -u log.out style.out
445 $ hg --color=debug -v log -T phases > phases.out
445 $ hg --color=debug -v log -T phases > phases.out
446 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
446 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
447 +[log.phase|phase: draft]
447 +[log.phase|phase: draft]
448 +[log.phase|phase: draft]
448 +[log.phase|phase: draft]
449 +[log.phase|phase: draft]
449 +[log.phase|phase: draft]
450 +[log.phase|phase: draft]
450 +[log.phase|phase: draft]
451 +[log.phase|phase: draft]
451 +[log.phase|phase: draft]
452 +[log.phase|phase: draft]
452 +[log.phase|phase: draft]
453 +[log.phase|phase: draft]
453 +[log.phase|phase: draft]
454 +[log.phase|phase: draft]
454 +[log.phase|phase: draft]
455 +[log.phase|phase: draft]
455 +[log.phase|phase: draft]
456 +[log.phase|phase: draft]
456 +[log.phase|phase: draft]
457
457
458 $ hg --color=debug -q log > log.out
458 $ hg --color=debug -q log > log.out
459 $ hg --color=debug -q log --style default > style.out
459 $ hg --color=debug -q log --style default > style.out
460 $ cmp log.out style.out || diff -u log.out style.out
460 $ cmp log.out style.out || diff -u log.out style.out
461 $ hg --color=debug -q log -T phases > phases.out
461 $ hg --color=debug -q log -T phases > phases.out
462 $ cmp log.out phases.out || diff -u log.out phases.out
462 $ cmp log.out phases.out || diff -u log.out phases.out
463
463
464 $ hg --color=debug --debug log > log.out
464 $ hg --color=debug --debug log > log.out
465 $ hg --color=debug --debug log --style default > style.out
465 $ hg --color=debug --debug log --style default > style.out
466 $ cmp log.out style.out || diff -u log.out style.out
466 $ cmp log.out style.out || diff -u log.out style.out
467 $ hg --color=debug --debug log -T phases > phases.out
467 $ hg --color=debug --debug log -T phases > phases.out
468 $ cmp log.out phases.out || diff -u log.out phases.out
468 $ cmp log.out phases.out || diff -u log.out phases.out
469
469
470 $ mv $HGRCPATH-bak $HGRCPATH
470 $ mv $HGRCPATH-bak $HGRCPATH
471
471
472 Remove commit with empty commit message, so as to not pollute further
472 Remove commit with empty commit message, so as to not pollute further
473 tests.
473 tests.
474
474
475 $ hg --config extensions.strip= strip -q .
475 $ hg --config extensions.strip= strip -q .
476
476
477 Revision with no copies (used to print a traceback):
477 Revision with no copies (used to print a traceback):
478
478
479 $ hg tip -v --template '\n'
479 $ hg tip -v --template '\n'
480
480
481
481
482 Compact style works:
482 Compact style works:
483
483
484 $ hg log -Tcompact
484 $ hg log -Tcompact
485 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
485 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
486 third
486 third
487
487
488 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
488 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
489 second
489 second
490
490
491 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
491 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
492 merge
492 merge
493
493
494 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
494 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
495 new head
495 new head
496
496
497 4 bbe44766e73d 1970-01-17 04:53 +0000 person
497 4 bbe44766e73d 1970-01-17 04:53 +0000 person
498 new branch
498 new branch
499
499
500 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
500 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
501 no user, no domain
501 no user, no domain
502
502
503 2 97054abb4ab8 1970-01-14 21:20 +0000 other
503 2 97054abb4ab8 1970-01-14 21:20 +0000 other
504 no person
504 no person
505
505
506 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
506 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
507 other 1
507 other 1
508
508
509 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
509 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
510 line 1
510 line 1
511
511
512
512
513 $ hg log -v --style compact
513 $ hg log -v --style compact
514 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
514 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
515 third
515 third
516
516
517 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
517 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
518 second
518 second
519
519
520 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
520 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
521 merge
521 merge
522
522
523 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
523 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
524 new head
524 new head
525
525
526 4 bbe44766e73d 1970-01-17 04:53 +0000 person
526 4 bbe44766e73d 1970-01-17 04:53 +0000 person
527 new branch
527 new branch
528
528
529 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
529 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
530 no user, no domain
530 no user, no domain
531
531
532 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
532 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
533 no person
533 no person
534
534
535 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
535 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
536 other 1
536 other 1
537 other 2
537 other 2
538
538
539 other 3
539 other 3
540
540
541 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
541 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
542 line 1
542 line 1
543 line 2
543 line 2
544
544
545
545
546 $ hg log --debug --style compact
546 $ hg log --debug --style compact
547 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
547 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
548 third
548 third
549
549
550 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
550 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
551 second
551 second
552
552
553 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
553 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
554 merge
554 merge
555
555
556 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
556 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
557 new head
557 new head
558
558
559 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
559 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
560 new branch
560 new branch
561
561
562 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
562 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
563 no user, no domain
563 no user, no domain
564
564
565 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
565 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
566 no person
566 no person
567
567
568 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
568 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
569 other 1
569 other 1
570 other 2
570 other 2
571
571
572 other 3
572 other 3
573
573
574 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
574 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
575 line 1
575 line 1
576 line 2
576 line 2
577
577
578
578
579 Test xml styles:
579 Test xml styles:
580
580
581 $ hg log --style xml -r 'not all()'
581 $ hg log --style xml -r 'not all()'
582 <?xml version="1.0"?>
582 <?xml version="1.0"?>
583 <log>
583 <log>
584 </log>
584 </log>
585
585
586 $ hg log --style xml
586 $ hg log --style xml
587 <?xml version="1.0"?>
587 <?xml version="1.0"?>
588 <log>
588 <log>
589 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
589 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
590 <tag>tip</tag>
590 <tag>tip</tag>
591 <author email="test">test</author>
591 <author email="test">test</author>
592 <date>2020-01-01T10:01:00+00:00</date>
592 <date>2020-01-01T10:01:00+00:00</date>
593 <msg xml:space="preserve">third</msg>
593 <msg xml:space="preserve">third</msg>
594 </logentry>
594 </logentry>
595 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
595 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
596 <parent revision="-1" node="0000000000000000000000000000000000000000" />
596 <parent revision="-1" node="0000000000000000000000000000000000000000" />
597 <author email="user@hostname">User Name</author>
597 <author email="user@hostname">User Name</author>
598 <date>1970-01-12T13:46:40+00:00</date>
598 <date>1970-01-12T13:46:40+00:00</date>
599 <msg xml:space="preserve">second</msg>
599 <msg xml:space="preserve">second</msg>
600 </logentry>
600 </logentry>
601 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
601 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
602 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
602 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
603 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
603 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
604 <author email="person">person</author>
604 <author email="person">person</author>
605 <date>1970-01-18T08:40:01+00:00</date>
605 <date>1970-01-18T08:40:01+00:00</date>
606 <msg xml:space="preserve">merge</msg>
606 <msg xml:space="preserve">merge</msg>
607 </logentry>
607 </logentry>
608 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
608 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
609 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
609 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
610 <author email="person">person</author>
610 <author email="person">person</author>
611 <date>1970-01-18T08:40:00+00:00</date>
611 <date>1970-01-18T08:40:00+00:00</date>
612 <msg xml:space="preserve">new head</msg>
612 <msg xml:space="preserve">new head</msg>
613 </logentry>
613 </logentry>
614 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
614 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
615 <branch>foo</branch>
615 <branch>foo</branch>
616 <author email="person">person</author>
616 <author email="person">person</author>
617 <date>1970-01-17T04:53:20+00:00</date>
617 <date>1970-01-17T04:53:20+00:00</date>
618 <msg xml:space="preserve">new branch</msg>
618 <msg xml:space="preserve">new branch</msg>
619 </logentry>
619 </logentry>
620 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
620 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
621 <author email="person">person</author>
621 <author email="person">person</author>
622 <date>1970-01-16T01:06:40+00:00</date>
622 <date>1970-01-16T01:06:40+00:00</date>
623 <msg xml:space="preserve">no user, no domain</msg>
623 <msg xml:space="preserve">no user, no domain</msg>
624 </logentry>
624 </logentry>
625 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
625 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
626 <author email="other@place">other</author>
626 <author email="other@place">other</author>
627 <date>1970-01-14T21:20:00+00:00</date>
627 <date>1970-01-14T21:20:00+00:00</date>
628 <msg xml:space="preserve">no person</msg>
628 <msg xml:space="preserve">no person</msg>
629 </logentry>
629 </logentry>
630 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
630 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
631 <author email="other@place">A. N. Other</author>
631 <author email="other@place">A. N. Other</author>
632 <date>1970-01-13T17:33:20+00:00</date>
632 <date>1970-01-13T17:33:20+00:00</date>
633 <msg xml:space="preserve">other 1
633 <msg xml:space="preserve">other 1
634 other 2
634 other 2
635
635
636 other 3</msg>
636 other 3</msg>
637 </logentry>
637 </logentry>
638 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
638 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
639 <author email="user@hostname">User Name</author>
639 <author email="user@hostname">User Name</author>
640 <date>1970-01-12T13:46:40+00:00</date>
640 <date>1970-01-12T13:46:40+00:00</date>
641 <msg xml:space="preserve">line 1
641 <msg xml:space="preserve">line 1
642 line 2</msg>
642 line 2</msg>
643 </logentry>
643 </logentry>
644 </log>
644 </log>
645
645
646 $ hg log -v --style xml
646 $ hg log -v --style xml
647 <?xml version="1.0"?>
647 <?xml version="1.0"?>
648 <log>
648 <log>
649 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
649 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
650 <tag>tip</tag>
650 <tag>tip</tag>
651 <author email="test">test</author>
651 <author email="test">test</author>
652 <date>2020-01-01T10:01:00+00:00</date>
652 <date>2020-01-01T10:01:00+00:00</date>
653 <msg xml:space="preserve">third</msg>
653 <msg xml:space="preserve">third</msg>
654 <paths>
654 <paths>
655 <path action="A">fourth</path>
655 <path action="A">fourth</path>
656 <path action="A">third</path>
656 <path action="A">third</path>
657 <path action="R">second</path>
657 <path action="R">second</path>
658 </paths>
658 </paths>
659 <copies>
659 <copies>
660 <copy source="second">fourth</copy>
660 <copy source="second">fourth</copy>
661 </copies>
661 </copies>
662 </logentry>
662 </logentry>
663 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
663 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
664 <parent revision="-1" node="0000000000000000000000000000000000000000" />
664 <parent revision="-1" node="0000000000000000000000000000000000000000" />
665 <author email="user@hostname">User Name</author>
665 <author email="user@hostname">User Name</author>
666 <date>1970-01-12T13:46:40+00:00</date>
666 <date>1970-01-12T13:46:40+00:00</date>
667 <msg xml:space="preserve">second</msg>
667 <msg xml:space="preserve">second</msg>
668 <paths>
668 <paths>
669 <path action="A">second</path>
669 <path action="A">second</path>
670 </paths>
670 </paths>
671 </logentry>
671 </logentry>
672 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
672 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
673 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
673 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
674 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
674 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
675 <author email="person">person</author>
675 <author email="person">person</author>
676 <date>1970-01-18T08:40:01+00:00</date>
676 <date>1970-01-18T08:40:01+00:00</date>
677 <msg xml:space="preserve">merge</msg>
677 <msg xml:space="preserve">merge</msg>
678 <paths>
678 <paths>
679 </paths>
679 </paths>
680 </logentry>
680 </logentry>
681 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
681 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
682 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
682 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
683 <author email="person">person</author>
683 <author email="person">person</author>
684 <date>1970-01-18T08:40:00+00:00</date>
684 <date>1970-01-18T08:40:00+00:00</date>
685 <msg xml:space="preserve">new head</msg>
685 <msg xml:space="preserve">new head</msg>
686 <paths>
686 <paths>
687 <path action="A">d</path>
687 <path action="A">d</path>
688 </paths>
688 </paths>
689 </logentry>
689 </logentry>
690 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
690 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
691 <branch>foo</branch>
691 <branch>foo</branch>
692 <author email="person">person</author>
692 <author email="person">person</author>
693 <date>1970-01-17T04:53:20+00:00</date>
693 <date>1970-01-17T04:53:20+00:00</date>
694 <msg xml:space="preserve">new branch</msg>
694 <msg xml:space="preserve">new branch</msg>
695 <paths>
695 <paths>
696 </paths>
696 </paths>
697 </logentry>
697 </logentry>
698 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
698 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
699 <author email="person">person</author>
699 <author email="person">person</author>
700 <date>1970-01-16T01:06:40+00:00</date>
700 <date>1970-01-16T01:06:40+00:00</date>
701 <msg xml:space="preserve">no user, no domain</msg>
701 <msg xml:space="preserve">no user, no domain</msg>
702 <paths>
702 <paths>
703 <path action="M">c</path>
703 <path action="M">c</path>
704 </paths>
704 </paths>
705 </logentry>
705 </logentry>
706 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
706 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
707 <author email="other@place">other</author>
707 <author email="other@place">other</author>
708 <date>1970-01-14T21:20:00+00:00</date>
708 <date>1970-01-14T21:20:00+00:00</date>
709 <msg xml:space="preserve">no person</msg>
709 <msg xml:space="preserve">no person</msg>
710 <paths>
710 <paths>
711 <path action="A">c</path>
711 <path action="A">c</path>
712 </paths>
712 </paths>
713 </logentry>
713 </logentry>
714 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
714 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
715 <author email="other@place">A. N. Other</author>
715 <author email="other@place">A. N. Other</author>
716 <date>1970-01-13T17:33:20+00:00</date>
716 <date>1970-01-13T17:33:20+00:00</date>
717 <msg xml:space="preserve">other 1
717 <msg xml:space="preserve">other 1
718 other 2
718 other 2
719
719
720 other 3</msg>
720 other 3</msg>
721 <paths>
721 <paths>
722 <path action="A">b</path>
722 <path action="A">b</path>
723 </paths>
723 </paths>
724 </logentry>
724 </logentry>
725 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
725 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
726 <author email="user@hostname">User Name</author>
726 <author email="user@hostname">User Name</author>
727 <date>1970-01-12T13:46:40+00:00</date>
727 <date>1970-01-12T13:46:40+00:00</date>
728 <msg xml:space="preserve">line 1
728 <msg xml:space="preserve">line 1
729 line 2</msg>
729 line 2</msg>
730 <paths>
730 <paths>
731 <path action="A">a</path>
731 <path action="A">a</path>
732 </paths>
732 </paths>
733 </logentry>
733 </logentry>
734 </log>
734 </log>
735
735
736 $ hg log --debug --style xml
736 $ hg log --debug --style xml
737 <?xml version="1.0"?>
737 <?xml version="1.0"?>
738 <log>
738 <log>
739 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
739 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
740 <tag>tip</tag>
740 <tag>tip</tag>
741 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
741 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
742 <parent revision="-1" node="0000000000000000000000000000000000000000" />
742 <parent revision="-1" node="0000000000000000000000000000000000000000" />
743 <author email="test">test</author>
743 <author email="test">test</author>
744 <date>2020-01-01T10:01:00+00:00</date>
744 <date>2020-01-01T10:01:00+00:00</date>
745 <msg xml:space="preserve">third</msg>
745 <msg xml:space="preserve">third</msg>
746 <paths>
746 <paths>
747 <path action="A">fourth</path>
747 <path action="A">fourth</path>
748 <path action="A">third</path>
748 <path action="A">third</path>
749 <path action="R">second</path>
749 <path action="R">second</path>
750 </paths>
750 </paths>
751 <copies>
751 <copies>
752 <copy source="second">fourth</copy>
752 <copy source="second">fourth</copy>
753 </copies>
753 </copies>
754 <extra key="branch">default</extra>
754 <extra key="branch">default</extra>
755 </logentry>
755 </logentry>
756 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
756 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
757 <parent revision="-1" node="0000000000000000000000000000000000000000" />
757 <parent revision="-1" node="0000000000000000000000000000000000000000" />
758 <parent revision="-1" node="0000000000000000000000000000000000000000" />
758 <parent revision="-1" node="0000000000000000000000000000000000000000" />
759 <author email="user@hostname">User Name</author>
759 <author email="user@hostname">User Name</author>
760 <date>1970-01-12T13:46:40+00:00</date>
760 <date>1970-01-12T13:46:40+00:00</date>
761 <msg xml:space="preserve">second</msg>
761 <msg xml:space="preserve">second</msg>
762 <paths>
762 <paths>
763 <path action="A">second</path>
763 <path action="A">second</path>
764 </paths>
764 </paths>
765 <extra key="branch">default</extra>
765 <extra key="branch">default</extra>
766 </logentry>
766 </logentry>
767 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
767 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
768 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
768 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
769 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
769 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
770 <author email="person">person</author>
770 <author email="person">person</author>
771 <date>1970-01-18T08:40:01+00:00</date>
771 <date>1970-01-18T08:40:01+00:00</date>
772 <msg xml:space="preserve">merge</msg>
772 <msg xml:space="preserve">merge</msg>
773 <paths>
773 <paths>
774 </paths>
774 </paths>
775 <extra key="branch">default</extra>
775 <extra key="branch">default</extra>
776 </logentry>
776 </logentry>
777 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
777 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
778 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
778 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
779 <parent revision="-1" node="0000000000000000000000000000000000000000" />
779 <parent revision="-1" node="0000000000000000000000000000000000000000" />
780 <author email="person">person</author>
780 <author email="person">person</author>
781 <date>1970-01-18T08:40:00+00:00</date>
781 <date>1970-01-18T08:40:00+00:00</date>
782 <msg xml:space="preserve">new head</msg>
782 <msg xml:space="preserve">new head</msg>
783 <paths>
783 <paths>
784 <path action="A">d</path>
784 <path action="A">d</path>
785 </paths>
785 </paths>
786 <extra key="branch">default</extra>
786 <extra key="branch">default</extra>
787 </logentry>
787 </logentry>
788 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
788 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
789 <branch>foo</branch>
789 <branch>foo</branch>
790 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
790 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
791 <parent revision="-1" node="0000000000000000000000000000000000000000" />
791 <parent revision="-1" node="0000000000000000000000000000000000000000" />
792 <author email="person">person</author>
792 <author email="person">person</author>
793 <date>1970-01-17T04:53:20+00:00</date>
793 <date>1970-01-17T04:53:20+00:00</date>
794 <msg xml:space="preserve">new branch</msg>
794 <msg xml:space="preserve">new branch</msg>
795 <paths>
795 <paths>
796 </paths>
796 </paths>
797 <extra key="branch">foo</extra>
797 <extra key="branch">foo</extra>
798 </logentry>
798 </logentry>
799 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
799 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
800 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
800 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
801 <parent revision="-1" node="0000000000000000000000000000000000000000" />
801 <parent revision="-1" node="0000000000000000000000000000000000000000" />
802 <author email="person">person</author>
802 <author email="person">person</author>
803 <date>1970-01-16T01:06:40+00:00</date>
803 <date>1970-01-16T01:06:40+00:00</date>
804 <msg xml:space="preserve">no user, no domain</msg>
804 <msg xml:space="preserve">no user, no domain</msg>
805 <paths>
805 <paths>
806 <path action="M">c</path>
806 <path action="M">c</path>
807 </paths>
807 </paths>
808 <extra key="branch">default</extra>
808 <extra key="branch">default</extra>
809 </logentry>
809 </logentry>
810 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
810 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
811 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
811 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
812 <parent revision="-1" node="0000000000000000000000000000000000000000" />
812 <parent revision="-1" node="0000000000000000000000000000000000000000" />
813 <author email="other@place">other</author>
813 <author email="other@place">other</author>
814 <date>1970-01-14T21:20:00+00:00</date>
814 <date>1970-01-14T21:20:00+00:00</date>
815 <msg xml:space="preserve">no person</msg>
815 <msg xml:space="preserve">no person</msg>
816 <paths>
816 <paths>
817 <path action="A">c</path>
817 <path action="A">c</path>
818 </paths>
818 </paths>
819 <extra key="branch">default</extra>
819 <extra key="branch">default</extra>
820 </logentry>
820 </logentry>
821 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
821 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
822 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
822 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
823 <parent revision="-1" node="0000000000000000000000000000000000000000" />
823 <parent revision="-1" node="0000000000000000000000000000000000000000" />
824 <author email="other@place">A. N. Other</author>
824 <author email="other@place">A. N. Other</author>
825 <date>1970-01-13T17:33:20+00:00</date>
825 <date>1970-01-13T17:33:20+00:00</date>
826 <msg xml:space="preserve">other 1
826 <msg xml:space="preserve">other 1
827 other 2
827 other 2
828
828
829 other 3</msg>
829 other 3</msg>
830 <paths>
830 <paths>
831 <path action="A">b</path>
831 <path action="A">b</path>
832 </paths>
832 </paths>
833 <extra key="branch">default</extra>
833 <extra key="branch">default</extra>
834 </logentry>
834 </logentry>
835 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
835 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
836 <parent revision="-1" node="0000000000000000000000000000000000000000" />
836 <parent revision="-1" node="0000000000000000000000000000000000000000" />
837 <parent revision="-1" node="0000000000000000000000000000000000000000" />
837 <parent revision="-1" node="0000000000000000000000000000000000000000" />
838 <author email="user@hostname">User Name</author>
838 <author email="user@hostname">User Name</author>
839 <date>1970-01-12T13:46:40+00:00</date>
839 <date>1970-01-12T13:46:40+00:00</date>
840 <msg xml:space="preserve">line 1
840 <msg xml:space="preserve">line 1
841 line 2</msg>
841 line 2</msg>
842 <paths>
842 <paths>
843 <path action="A">a</path>
843 <path action="A">a</path>
844 </paths>
844 </paths>
845 <extra key="branch">default</extra>
845 <extra key="branch">default</extra>
846 </logentry>
846 </logentry>
847 </log>
847 </log>
848
848
849
849
850 Test JSON style:
850 Test JSON style:
851
851
852 $ hg log -k nosuch -Tjson
852 $ hg log -k nosuch -Tjson
853 []
853 []
854
854
855 $ hg log -qr . -Tjson
855 $ hg log -qr . -Tjson
856 [
856 [
857 {
857 {
858 "rev": 8,
858 "rev": 8,
859 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
859 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
860 }
860 }
861 ]
861 ]
862
862
863 $ hg log -vpr . -Tjson --stat
863 $ hg log -vpr . -Tjson --stat
864 [
864 [
865 {
865 {
866 "rev": 8,
866 "rev": 8,
867 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
867 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
868 "branch": "default",
868 "branch": "default",
869 "phase": "draft",
869 "phase": "draft",
870 "user": "test",
870 "user": "test",
871 "date": [1577872860, 0],
871 "date": [1577872860, 0],
872 "desc": "third",
872 "desc": "third",
873 "bookmarks": [],
873 "bookmarks": [],
874 "tags": ["tip"],
874 "tags": ["tip"],
875 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
875 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
876 "files": ["fourth", "second", "third"],
876 "files": ["fourth", "second", "third"],
877 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
877 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
878 "diff": "diff -r 29114dbae42b -r 95c24699272e fourth\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/fourth\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+second\ndiff -r 29114dbae42b -r 95c24699272e second\n--- a/second\tMon Jan 12 13:46:40 1970 +0000\n+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,1 +0,0 @@\n-second\ndiff -r 29114dbae42b -r 95c24699272e third\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/third\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+third\n"
878 "diff": "diff -r 29114dbae42b -r 95c24699272e fourth\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/fourth\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+second\ndiff -r 29114dbae42b -r 95c24699272e second\n--- a/second\tMon Jan 12 13:46:40 1970 +0000\n+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,1 +0,0 @@\n-second\ndiff -r 29114dbae42b -r 95c24699272e third\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/third\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+third\n"
879 }
879 }
880 ]
880 ]
881
881
882 honor --git but not format-breaking diffopts
882 honor --git but not format-breaking diffopts
883 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
883 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
884 [
884 [
885 {
885 {
886 "rev": 8,
886 "rev": 8,
887 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
887 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
888 "branch": "default",
888 "branch": "default",
889 "phase": "draft",
889 "phase": "draft",
890 "user": "test",
890 "user": "test",
891 "date": [1577872860, 0],
891 "date": [1577872860, 0],
892 "desc": "third",
892 "desc": "third",
893 "bookmarks": [],
893 "bookmarks": [],
894 "tags": ["tip"],
894 "tags": ["tip"],
895 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
895 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
896 "files": ["fourth", "second", "third"],
896 "files": ["fourth", "second", "third"],
897 "diff": "diff --git a/second b/fourth\nrename from second\nrename to fourth\ndiff --git a/third b/third\nnew file mode 100644\n--- /dev/null\n+++ b/third\n@@ -0,0 +1,1 @@\n+third\n"
897 "diff": "diff --git a/second b/fourth\nrename from second\nrename to fourth\ndiff --git a/third b/third\nnew file mode 100644\n--- /dev/null\n+++ b/third\n@@ -0,0 +1,1 @@\n+third\n"
898 }
898 }
899 ]
899 ]
900
900
901 $ hg log -T json
901 $ hg log -T json
902 [
902 [
903 {
903 {
904 "rev": 8,
904 "rev": 8,
905 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
905 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
906 "branch": "default",
906 "branch": "default",
907 "phase": "draft",
907 "phase": "draft",
908 "user": "test",
908 "user": "test",
909 "date": [1577872860, 0],
909 "date": [1577872860, 0],
910 "desc": "third",
910 "desc": "third",
911 "bookmarks": [],
911 "bookmarks": [],
912 "tags": ["tip"],
912 "tags": ["tip"],
913 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
913 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
914 },
914 },
915 {
915 {
916 "rev": 7,
916 "rev": 7,
917 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
917 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
918 "branch": "default",
918 "branch": "default",
919 "phase": "draft",
919 "phase": "draft",
920 "user": "User Name <user@hostname>",
920 "user": "User Name <user@hostname>",
921 "date": [1000000, 0],
921 "date": [1000000, 0],
922 "desc": "second",
922 "desc": "second",
923 "bookmarks": [],
923 "bookmarks": [],
924 "tags": [],
924 "tags": [],
925 "parents": ["0000000000000000000000000000000000000000"]
925 "parents": ["0000000000000000000000000000000000000000"]
926 },
926 },
927 {
927 {
928 "rev": 6,
928 "rev": 6,
929 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
929 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
930 "branch": "default",
930 "branch": "default",
931 "phase": "draft",
931 "phase": "draft",
932 "user": "person",
932 "user": "person",
933 "date": [1500001, 0],
933 "date": [1500001, 0],
934 "desc": "merge",
934 "desc": "merge",
935 "bookmarks": [],
935 "bookmarks": [],
936 "tags": [],
936 "tags": [],
937 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
937 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
938 },
938 },
939 {
939 {
940 "rev": 5,
940 "rev": 5,
941 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
941 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
942 "branch": "default",
942 "branch": "default",
943 "phase": "draft",
943 "phase": "draft",
944 "user": "person",
944 "user": "person",
945 "date": [1500000, 0],
945 "date": [1500000, 0],
946 "desc": "new head",
946 "desc": "new head",
947 "bookmarks": [],
947 "bookmarks": [],
948 "tags": [],
948 "tags": [],
949 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
949 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
950 },
950 },
951 {
951 {
952 "rev": 4,
952 "rev": 4,
953 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
953 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
954 "branch": "foo",
954 "branch": "foo",
955 "phase": "draft",
955 "phase": "draft",
956 "user": "person",
956 "user": "person",
957 "date": [1400000, 0],
957 "date": [1400000, 0],
958 "desc": "new branch",
958 "desc": "new branch",
959 "bookmarks": [],
959 "bookmarks": [],
960 "tags": [],
960 "tags": [],
961 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
961 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
962 },
962 },
963 {
963 {
964 "rev": 3,
964 "rev": 3,
965 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
965 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
966 "branch": "default",
966 "branch": "default",
967 "phase": "draft",
967 "phase": "draft",
968 "user": "person",
968 "user": "person",
969 "date": [1300000, 0],
969 "date": [1300000, 0],
970 "desc": "no user, no domain",
970 "desc": "no user, no domain",
971 "bookmarks": [],
971 "bookmarks": [],
972 "tags": [],
972 "tags": [],
973 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
973 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
974 },
974 },
975 {
975 {
976 "rev": 2,
976 "rev": 2,
977 "node": "97054abb4ab824450e9164180baf491ae0078465",
977 "node": "97054abb4ab824450e9164180baf491ae0078465",
978 "branch": "default",
978 "branch": "default",
979 "phase": "draft",
979 "phase": "draft",
980 "user": "other@place",
980 "user": "other@place",
981 "date": [1200000, 0],
981 "date": [1200000, 0],
982 "desc": "no person",
982 "desc": "no person",
983 "bookmarks": [],
983 "bookmarks": [],
984 "tags": [],
984 "tags": [],
985 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
985 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
986 },
986 },
987 {
987 {
988 "rev": 1,
988 "rev": 1,
989 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
989 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
990 "branch": "default",
990 "branch": "default",
991 "phase": "draft",
991 "phase": "draft",
992 "user": "A. N. Other <other@place>",
992 "user": "A. N. Other <other@place>",
993 "date": [1100000, 0],
993 "date": [1100000, 0],
994 "desc": "other 1\nother 2\n\nother 3",
994 "desc": "other 1\nother 2\n\nother 3",
995 "bookmarks": [],
995 "bookmarks": [],
996 "tags": [],
996 "tags": [],
997 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
997 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
998 },
998 },
999 {
999 {
1000 "rev": 0,
1000 "rev": 0,
1001 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1001 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1002 "branch": "default",
1002 "branch": "default",
1003 "phase": "draft",
1003 "phase": "draft",
1004 "user": "User Name <user@hostname>",
1004 "user": "User Name <user@hostname>",
1005 "date": [1000000, 0],
1005 "date": [1000000, 0],
1006 "desc": "line 1\nline 2",
1006 "desc": "line 1\nline 2",
1007 "bookmarks": [],
1007 "bookmarks": [],
1008 "tags": [],
1008 "tags": [],
1009 "parents": ["0000000000000000000000000000000000000000"]
1009 "parents": ["0000000000000000000000000000000000000000"]
1010 }
1010 }
1011 ]
1011 ]
1012
1012
1013 $ hg heads -v -Tjson
1013 $ hg heads -v -Tjson
1014 [
1014 [
1015 {
1015 {
1016 "rev": 8,
1016 "rev": 8,
1017 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1017 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1018 "branch": "default",
1018 "branch": "default",
1019 "phase": "draft",
1019 "phase": "draft",
1020 "user": "test",
1020 "user": "test",
1021 "date": [1577872860, 0],
1021 "date": [1577872860, 0],
1022 "desc": "third",
1022 "desc": "third",
1023 "bookmarks": [],
1023 "bookmarks": [],
1024 "tags": ["tip"],
1024 "tags": ["tip"],
1025 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1025 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1026 "files": ["fourth", "second", "third"]
1026 "files": ["fourth", "second", "third"]
1027 },
1027 },
1028 {
1028 {
1029 "rev": 6,
1029 "rev": 6,
1030 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1030 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1031 "branch": "default",
1031 "branch": "default",
1032 "phase": "draft",
1032 "phase": "draft",
1033 "user": "person",
1033 "user": "person",
1034 "date": [1500001, 0],
1034 "date": [1500001, 0],
1035 "desc": "merge",
1035 "desc": "merge",
1036 "bookmarks": [],
1036 "bookmarks": [],
1037 "tags": [],
1037 "tags": [],
1038 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1038 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1039 "files": []
1039 "files": []
1040 },
1040 },
1041 {
1041 {
1042 "rev": 4,
1042 "rev": 4,
1043 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1043 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1044 "branch": "foo",
1044 "branch": "foo",
1045 "phase": "draft",
1045 "phase": "draft",
1046 "user": "person",
1046 "user": "person",
1047 "date": [1400000, 0],
1047 "date": [1400000, 0],
1048 "desc": "new branch",
1048 "desc": "new branch",
1049 "bookmarks": [],
1049 "bookmarks": [],
1050 "tags": [],
1050 "tags": [],
1051 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1051 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1052 "files": []
1052 "files": []
1053 }
1053 }
1054 ]
1054 ]
1055
1055
1056 $ hg log --debug -Tjson
1056 $ hg log --debug -Tjson
1057 [
1057 [
1058 {
1058 {
1059 "rev": 8,
1059 "rev": 8,
1060 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1060 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1061 "branch": "default",
1061 "branch": "default",
1062 "phase": "draft",
1062 "phase": "draft",
1063 "user": "test",
1063 "user": "test",
1064 "date": [1577872860, 0],
1064 "date": [1577872860, 0],
1065 "desc": "third",
1065 "desc": "third",
1066 "bookmarks": [],
1066 "bookmarks": [],
1067 "tags": ["tip"],
1067 "tags": ["tip"],
1068 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1068 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1069 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
1069 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
1070 "extra": {"branch": "default"},
1070 "extra": {"branch": "default"},
1071 "modified": [],
1071 "modified": [],
1072 "added": ["fourth", "third"],
1072 "added": ["fourth", "third"],
1073 "removed": ["second"]
1073 "removed": ["second"]
1074 },
1074 },
1075 {
1075 {
1076 "rev": 7,
1076 "rev": 7,
1077 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
1077 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
1078 "branch": "default",
1078 "branch": "default",
1079 "phase": "draft",
1079 "phase": "draft",
1080 "user": "User Name <user@hostname>",
1080 "user": "User Name <user@hostname>",
1081 "date": [1000000, 0],
1081 "date": [1000000, 0],
1082 "desc": "second",
1082 "desc": "second",
1083 "bookmarks": [],
1083 "bookmarks": [],
1084 "tags": [],
1084 "tags": [],
1085 "parents": ["0000000000000000000000000000000000000000"],
1085 "parents": ["0000000000000000000000000000000000000000"],
1086 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
1086 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
1087 "extra": {"branch": "default"},
1087 "extra": {"branch": "default"},
1088 "modified": [],
1088 "modified": [],
1089 "added": ["second"],
1089 "added": ["second"],
1090 "removed": []
1090 "removed": []
1091 },
1091 },
1092 {
1092 {
1093 "rev": 6,
1093 "rev": 6,
1094 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1094 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1095 "branch": "default",
1095 "branch": "default",
1096 "phase": "draft",
1096 "phase": "draft",
1097 "user": "person",
1097 "user": "person",
1098 "date": [1500001, 0],
1098 "date": [1500001, 0],
1099 "desc": "merge",
1099 "desc": "merge",
1100 "bookmarks": [],
1100 "bookmarks": [],
1101 "tags": [],
1101 "tags": [],
1102 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1102 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1103 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1103 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1104 "extra": {"branch": "default"},
1104 "extra": {"branch": "default"},
1105 "modified": [],
1105 "modified": [],
1106 "added": [],
1106 "added": [],
1107 "removed": []
1107 "removed": []
1108 },
1108 },
1109 {
1109 {
1110 "rev": 5,
1110 "rev": 5,
1111 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
1111 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
1112 "branch": "default",
1112 "branch": "default",
1113 "phase": "draft",
1113 "phase": "draft",
1114 "user": "person",
1114 "user": "person",
1115 "date": [1500000, 0],
1115 "date": [1500000, 0],
1116 "desc": "new head",
1116 "desc": "new head",
1117 "bookmarks": [],
1117 "bookmarks": [],
1118 "tags": [],
1118 "tags": [],
1119 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1119 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1120 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1120 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1121 "extra": {"branch": "default"},
1121 "extra": {"branch": "default"},
1122 "modified": [],
1122 "modified": [],
1123 "added": ["d"],
1123 "added": ["d"],
1124 "removed": []
1124 "removed": []
1125 },
1125 },
1126 {
1126 {
1127 "rev": 4,
1127 "rev": 4,
1128 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1128 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1129 "branch": "foo",
1129 "branch": "foo",
1130 "phase": "draft",
1130 "phase": "draft",
1131 "user": "person",
1131 "user": "person",
1132 "date": [1400000, 0],
1132 "date": [1400000, 0],
1133 "desc": "new branch",
1133 "desc": "new branch",
1134 "bookmarks": [],
1134 "bookmarks": [],
1135 "tags": [],
1135 "tags": [],
1136 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1136 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1137 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1137 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1138 "extra": {"branch": "foo"},
1138 "extra": {"branch": "foo"},
1139 "modified": [],
1139 "modified": [],
1140 "added": [],
1140 "added": [],
1141 "removed": []
1141 "removed": []
1142 },
1142 },
1143 {
1143 {
1144 "rev": 3,
1144 "rev": 3,
1145 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
1145 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
1146 "branch": "default",
1146 "branch": "default",
1147 "phase": "draft",
1147 "phase": "draft",
1148 "user": "person",
1148 "user": "person",
1149 "date": [1300000, 0],
1149 "date": [1300000, 0],
1150 "desc": "no user, no domain",
1150 "desc": "no user, no domain",
1151 "bookmarks": [],
1151 "bookmarks": [],
1152 "tags": [],
1152 "tags": [],
1153 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
1153 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
1154 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1154 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1155 "extra": {"branch": "default"},
1155 "extra": {"branch": "default"},
1156 "modified": ["c"],
1156 "modified": ["c"],
1157 "added": [],
1157 "added": [],
1158 "removed": []
1158 "removed": []
1159 },
1159 },
1160 {
1160 {
1161 "rev": 2,
1161 "rev": 2,
1162 "node": "97054abb4ab824450e9164180baf491ae0078465",
1162 "node": "97054abb4ab824450e9164180baf491ae0078465",
1163 "branch": "default",
1163 "branch": "default",
1164 "phase": "draft",
1164 "phase": "draft",
1165 "user": "other@place",
1165 "user": "other@place",
1166 "date": [1200000, 0],
1166 "date": [1200000, 0],
1167 "desc": "no person",
1167 "desc": "no person",
1168 "bookmarks": [],
1168 "bookmarks": [],
1169 "tags": [],
1169 "tags": [],
1170 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
1170 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
1171 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
1171 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
1172 "extra": {"branch": "default"},
1172 "extra": {"branch": "default"},
1173 "modified": [],
1173 "modified": [],
1174 "added": ["c"],
1174 "added": ["c"],
1175 "removed": []
1175 "removed": []
1176 },
1176 },
1177 {
1177 {
1178 "rev": 1,
1178 "rev": 1,
1179 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
1179 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
1180 "branch": "default",
1180 "branch": "default",
1181 "phase": "draft",
1181 "phase": "draft",
1182 "user": "A. N. Other <other@place>",
1182 "user": "A. N. Other <other@place>",
1183 "date": [1100000, 0],
1183 "date": [1100000, 0],
1184 "desc": "other 1\nother 2\n\nother 3",
1184 "desc": "other 1\nother 2\n\nother 3",
1185 "bookmarks": [],
1185 "bookmarks": [],
1186 "tags": [],
1186 "tags": [],
1187 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
1187 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
1188 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
1188 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
1189 "extra": {"branch": "default"},
1189 "extra": {"branch": "default"},
1190 "modified": [],
1190 "modified": [],
1191 "added": ["b"],
1191 "added": ["b"],
1192 "removed": []
1192 "removed": []
1193 },
1193 },
1194 {
1194 {
1195 "rev": 0,
1195 "rev": 0,
1196 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1196 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1197 "branch": "default",
1197 "branch": "default",
1198 "phase": "draft",
1198 "phase": "draft",
1199 "user": "User Name <user@hostname>",
1199 "user": "User Name <user@hostname>",
1200 "date": [1000000, 0],
1200 "date": [1000000, 0],
1201 "desc": "line 1\nline 2",
1201 "desc": "line 1\nline 2",
1202 "bookmarks": [],
1202 "bookmarks": [],
1203 "tags": [],
1203 "tags": [],
1204 "parents": ["0000000000000000000000000000000000000000"],
1204 "parents": ["0000000000000000000000000000000000000000"],
1205 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
1205 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
1206 "extra": {"branch": "default"},
1206 "extra": {"branch": "default"},
1207 "modified": [],
1207 "modified": [],
1208 "added": ["a"],
1208 "added": ["a"],
1209 "removed": []
1209 "removed": []
1210 }
1210 }
1211 ]
1211 ]
1212
1212
1213 Error if style not readable:
1213 Error if style not readable:
1214
1214
1215 #if unix-permissions no-root
1215 #if unix-permissions no-root
1216 $ touch q
1216 $ touch q
1217 $ chmod 0 q
1217 $ chmod 0 q
1218 $ hg log --style ./q
1218 $ hg log --style ./q
1219 abort: Permission denied: ./q
1219 abort: Permission denied: ./q
1220 [255]
1220 [255]
1221 #endif
1221 #endif
1222
1222
1223 Error if no style:
1223 Error if no style:
1224
1224
1225 $ hg log --style notexist
1225 $ hg log --style notexist
1226 abort: style 'notexist' not found
1226 abort: style 'notexist' not found
1227 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
1227 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
1228 [255]
1228 [255]
1229
1229
1230 $ hg log -T list
1230 $ hg log -T list
1231 available styles: bisect, changelog, compact, default, phases, show, status, xml
1231 available styles: bisect, changelog, compact, default, phases, show, status, xml
1232 abort: specify a template
1232 abort: specify a template
1233 [255]
1233 [255]
1234
1234
1235 Error if style missing key:
1235 Error if style missing key:
1236
1236
1237 $ echo 'q = q' > t
1237 $ echo 'q = q' > t
1238 $ hg log --style ./t
1238 $ hg log --style ./t
1239 abort: "changeset" not in template map
1239 abort: "changeset" not in template map
1240 [255]
1240 [255]
1241
1241
1242 Error if style missing value:
1242 Error if style missing value:
1243
1243
1244 $ echo 'changeset =' > t
1244 $ echo 'changeset =' > t
1245 $ hg log --style t
1245 $ hg log --style t
1246 hg: parse error at t:1: missing value
1246 hg: parse error at t:1: missing value
1247 [255]
1247 [255]
1248
1248
1249 Error if include fails:
1249 Error if include fails:
1250
1250
1251 $ echo 'changeset = q' >> t
1251 $ echo 'changeset = q' >> t
1252 #if unix-permissions no-root
1252 #if unix-permissions no-root
1253 $ hg log --style ./t
1253 $ hg log --style ./t
1254 abort: template file ./q: Permission denied
1254 abort: template file ./q: Permission denied
1255 [255]
1255 [255]
1256 $ rm -f q
1256 $ rm -f q
1257 #endif
1257 #endif
1258
1258
1259 Include works:
1259 Include works:
1260
1260
1261 $ echo '{rev}' > q
1261 $ echo '{rev}' > q
1262 $ hg log --style ./t
1262 $ hg log --style ./t
1263 8
1263 8
1264 7
1264 7
1265 6
1265 6
1266 5
1266 5
1267 4
1267 4
1268 3
1268 3
1269 2
1269 2
1270 1
1270 1
1271 0
1271 0
1272
1272
1273 Check that recursive reference does not fall into RuntimeError (issue4758):
1273 Check that recursive reference does not fall into RuntimeError (issue4758):
1274
1274
1275 common mistake:
1275 common mistake:
1276
1276
1277 $ cat << EOF > issue4758
1277 $ cat << EOF > issue4758
1278 > changeset = '{changeset}\n'
1278 > changeset = '{changeset}\n'
1279 > EOF
1279 > EOF
1280 $ hg log --style ./issue4758
1280 $ hg log --style ./issue4758
1281 abort: recursive reference 'changeset' in template
1281 abort: recursive reference 'changeset' in template
1282 [255]
1282 [255]
1283
1283
1284 circular reference:
1284 circular reference:
1285
1285
1286 $ cat << EOF > issue4758
1286 $ cat << EOF > issue4758
1287 > changeset = '{foo}'
1287 > changeset = '{foo}'
1288 > foo = '{changeset}'
1288 > foo = '{changeset}'
1289 > EOF
1289 > EOF
1290 $ hg log --style ./issue4758
1290 $ hg log --style ./issue4758
1291 abort: recursive reference 'foo' in template
1291 abort: recursive reference 'foo' in template
1292 [255]
1292 [255]
1293
1293
1294 buildmap() -> gettemplate(), where no thunk was made:
1294 buildmap() -> gettemplate(), where no thunk was made:
1295
1295
1296 $ cat << EOF > issue4758
1296 $ cat << EOF > issue4758
1297 > changeset = '{files % changeset}\n'
1297 > changeset = '{files % changeset}\n'
1298 > EOF
1298 > EOF
1299 $ hg log --style ./issue4758
1299 $ hg log --style ./issue4758
1300 abort: recursive reference 'changeset' in template
1300 abort: recursive reference 'changeset' in template
1301 [255]
1301 [255]
1302
1302
1303 not a recursion if a keyword of the same name exists:
1303 not a recursion if a keyword of the same name exists:
1304
1304
1305 $ cat << EOF > issue4758
1305 $ cat << EOF > issue4758
1306 > changeset = '{tags % rev}'
1306 > changeset = '{tags % rev}'
1307 > rev = '{rev} {tag}\n'
1307 > rev = '{rev} {tag}\n'
1308 > EOF
1308 > EOF
1309 $ hg log --style ./issue4758 -r tip
1309 $ hg log --style ./issue4758 -r tip
1310 8 tip
1310 8 tip
1311
1311
1312 Check that {phase} works correctly on parents:
1312 Check that {phase} works correctly on parents:
1313
1313
1314 $ cat << EOF > parentphase
1314 $ cat << EOF > parentphase
1315 > changeset_debug = '{rev} ({phase}):{parents}\n'
1315 > changeset_debug = '{rev} ({phase}):{parents}\n'
1316 > parent = ' {rev} ({phase})'
1316 > parent = ' {rev} ({phase})'
1317 > EOF
1317 > EOF
1318 $ hg phase -r 5 --public
1318 $ hg phase -r 5 --public
1319 $ hg phase -r 7 --secret --force
1319 $ hg phase -r 7 --secret --force
1320 $ hg log --debug -G --style ./parentphase
1320 $ hg log --debug -G --style ./parentphase
1321 @ 8 (secret): 7 (secret) -1 (public)
1321 @ 8 (secret): 7 (secret) -1 (public)
1322 |
1322 |
1323 o 7 (secret): -1 (public) -1 (public)
1323 o 7 (secret): -1 (public) -1 (public)
1324
1324
1325 o 6 (draft): 5 (public) 4 (draft)
1325 o 6 (draft): 5 (public) 4 (draft)
1326 |\
1326 |\
1327 | o 5 (public): 3 (public) -1 (public)
1327 | o 5 (public): 3 (public) -1 (public)
1328 | |
1328 | |
1329 o | 4 (draft): 3 (public) -1 (public)
1329 o | 4 (draft): 3 (public) -1 (public)
1330 |/
1330 |/
1331 o 3 (public): 2 (public) -1 (public)
1331 o 3 (public): 2 (public) -1 (public)
1332 |
1332 |
1333 o 2 (public): 1 (public) -1 (public)
1333 o 2 (public): 1 (public) -1 (public)
1334 |
1334 |
1335 o 1 (public): 0 (public) -1 (public)
1335 o 1 (public): 0 (public) -1 (public)
1336 |
1336 |
1337 o 0 (public): -1 (public) -1 (public)
1337 o 0 (public): -1 (public) -1 (public)
1338
1338
1339
1339
1340 Missing non-standard names give no error (backward compatibility):
1340 Missing non-standard names give no error (backward compatibility):
1341
1341
1342 $ echo "changeset = '{c}'" > t
1342 $ echo "changeset = '{c}'" > t
1343 $ hg log --style ./t
1343 $ hg log --style ./t
1344
1344
1345 Defining non-standard name works:
1345 Defining non-standard name works:
1346
1346
1347 $ cat <<EOF > t
1347 $ cat <<EOF > t
1348 > changeset = '{c}'
1348 > changeset = '{c}'
1349 > c = q
1349 > c = q
1350 > EOF
1350 > EOF
1351 $ hg log --style ./t
1351 $ hg log --style ./t
1352 8
1352 8
1353 7
1353 7
1354 6
1354 6
1355 5
1355 5
1356 4
1356 4
1357 3
1357 3
1358 2
1358 2
1359 1
1359 1
1360 0
1360 0
1361
1361
1362 ui.style works:
1362 ui.style works:
1363
1363
1364 $ echo '[ui]' > .hg/hgrc
1364 $ echo '[ui]' > .hg/hgrc
1365 $ echo 'style = t' >> .hg/hgrc
1365 $ echo 'style = t' >> .hg/hgrc
1366 $ hg log
1366 $ hg log
1367 8
1367 8
1368 7
1368 7
1369 6
1369 6
1370 5
1370 5
1371 4
1371 4
1372 3
1372 3
1373 2
1373 2
1374 1
1374 1
1375 0
1375 0
1376
1376
1377
1377
1378 Issue338:
1378 Issue338:
1379
1379
1380 $ hg log --style=changelog > changelog
1380 $ hg log --style=changelog > changelog
1381
1381
1382 $ cat changelog
1382 $ cat changelog
1383 2020-01-01 test <test>
1383 2020-01-01 test <test>
1384
1384
1385 * fourth, second, third:
1385 * fourth, second, third:
1386 third
1386 third
1387 [95c24699272e] [tip]
1387 [95c24699272e] [tip]
1388
1388
1389 1970-01-12 User Name <user@hostname>
1389 1970-01-12 User Name <user@hostname>
1390
1390
1391 * second:
1391 * second:
1392 second
1392 second
1393 [29114dbae42b]
1393 [29114dbae42b]
1394
1394
1395 1970-01-18 person <person>
1395 1970-01-18 person <person>
1396
1396
1397 * merge
1397 * merge
1398 [d41e714fe50d]
1398 [d41e714fe50d]
1399
1399
1400 * d:
1400 * d:
1401 new head
1401 new head
1402 [13207e5a10d9]
1402 [13207e5a10d9]
1403
1403
1404 1970-01-17 person <person>
1404 1970-01-17 person <person>
1405
1405
1406 * new branch
1406 * new branch
1407 [bbe44766e73d] <foo>
1407 [bbe44766e73d] <foo>
1408
1408
1409 1970-01-16 person <person>
1409 1970-01-16 person <person>
1410
1410
1411 * c:
1411 * c:
1412 no user, no domain
1412 no user, no domain
1413 [10e46f2dcbf4]
1413 [10e46f2dcbf4]
1414
1414
1415 1970-01-14 other <other@place>
1415 1970-01-14 other <other@place>
1416
1416
1417 * c:
1417 * c:
1418 no person
1418 no person
1419 [97054abb4ab8]
1419 [97054abb4ab8]
1420
1420
1421 1970-01-13 A. N. Other <other@place>
1421 1970-01-13 A. N. Other <other@place>
1422
1422
1423 * b:
1423 * b:
1424 other 1 other 2
1424 other 1 other 2
1425
1425
1426 other 3
1426 other 3
1427 [b608e9d1a3f0]
1427 [b608e9d1a3f0]
1428
1428
1429 1970-01-12 User Name <user@hostname>
1429 1970-01-12 User Name <user@hostname>
1430
1430
1431 * a:
1431 * a:
1432 line 1 line 2
1432 line 1 line 2
1433 [1e4e1b8f71e0]
1433 [1e4e1b8f71e0]
1434
1434
1435
1435
1436 Issue2130: xml output for 'hg heads' is malformed
1436 Issue2130: xml output for 'hg heads' is malformed
1437
1437
1438 $ hg heads --style changelog
1438 $ hg heads --style changelog
1439 2020-01-01 test <test>
1439 2020-01-01 test <test>
1440
1440
1441 * fourth, second, third:
1441 * fourth, second, third:
1442 third
1442 third
1443 [95c24699272e] [tip]
1443 [95c24699272e] [tip]
1444
1444
1445 1970-01-18 person <person>
1445 1970-01-18 person <person>
1446
1446
1447 * merge
1447 * merge
1448 [d41e714fe50d]
1448 [d41e714fe50d]
1449
1449
1450 1970-01-17 person <person>
1450 1970-01-17 person <person>
1451
1451
1452 * new branch
1452 * new branch
1453 [bbe44766e73d] <foo>
1453 [bbe44766e73d] <foo>
1454
1454
1455
1455
1456 Keys work:
1456 Keys work:
1457
1457
1458 $ for key in author branch branches date desc file_adds file_dels file_mods \
1458 $ for key in author branch branches date desc file_adds file_dels file_mods \
1459 > file_copies file_copies_switch files \
1459 > file_copies file_copies_switch files \
1460 > manifest node parents rev tags diffstat extras \
1460 > manifest node parents rev tags diffstat extras \
1461 > p1rev p2rev p1node p2node; do
1461 > p1rev p2rev p1node p2node; do
1462 > for mode in '' --verbose --debug; do
1462 > for mode in '' --verbose --debug; do
1463 > hg log $mode --template "$key$mode: {$key}\n"
1463 > hg log $mode --template "$key$mode: {$key}\n"
1464 > done
1464 > done
1465 > done
1465 > done
1466 author: test
1466 author: test
1467 author: User Name <user@hostname>
1467 author: User Name <user@hostname>
1468 author: person
1468 author: person
1469 author: person
1469 author: person
1470 author: person
1470 author: person
1471 author: person
1471 author: person
1472 author: other@place
1472 author: other@place
1473 author: A. N. Other <other@place>
1473 author: A. N. Other <other@place>
1474 author: User Name <user@hostname>
1474 author: User Name <user@hostname>
1475 author--verbose: test
1475 author--verbose: test
1476 author--verbose: User Name <user@hostname>
1476 author--verbose: User Name <user@hostname>
1477 author--verbose: person
1477 author--verbose: person
1478 author--verbose: person
1478 author--verbose: person
1479 author--verbose: person
1479 author--verbose: person
1480 author--verbose: person
1480 author--verbose: person
1481 author--verbose: other@place
1481 author--verbose: other@place
1482 author--verbose: A. N. Other <other@place>
1482 author--verbose: A. N. Other <other@place>
1483 author--verbose: User Name <user@hostname>
1483 author--verbose: User Name <user@hostname>
1484 author--debug: test
1484 author--debug: test
1485 author--debug: User Name <user@hostname>
1485 author--debug: User Name <user@hostname>
1486 author--debug: person
1486 author--debug: person
1487 author--debug: person
1487 author--debug: person
1488 author--debug: person
1488 author--debug: person
1489 author--debug: person
1489 author--debug: person
1490 author--debug: other@place
1490 author--debug: other@place
1491 author--debug: A. N. Other <other@place>
1491 author--debug: A. N. Other <other@place>
1492 author--debug: User Name <user@hostname>
1492 author--debug: User Name <user@hostname>
1493 branch: default
1493 branch: default
1494 branch: default
1494 branch: default
1495 branch: default
1495 branch: default
1496 branch: default
1496 branch: default
1497 branch: foo
1497 branch: foo
1498 branch: default
1498 branch: default
1499 branch: default
1499 branch: default
1500 branch: default
1500 branch: default
1501 branch: default
1501 branch: default
1502 branch--verbose: default
1502 branch--verbose: default
1503 branch--verbose: default
1503 branch--verbose: default
1504 branch--verbose: default
1504 branch--verbose: default
1505 branch--verbose: default
1505 branch--verbose: default
1506 branch--verbose: foo
1506 branch--verbose: foo
1507 branch--verbose: default
1507 branch--verbose: default
1508 branch--verbose: default
1508 branch--verbose: default
1509 branch--verbose: default
1509 branch--verbose: default
1510 branch--verbose: default
1510 branch--verbose: default
1511 branch--debug: default
1511 branch--debug: default
1512 branch--debug: default
1512 branch--debug: default
1513 branch--debug: default
1513 branch--debug: default
1514 branch--debug: default
1514 branch--debug: default
1515 branch--debug: foo
1515 branch--debug: foo
1516 branch--debug: default
1516 branch--debug: default
1517 branch--debug: default
1517 branch--debug: default
1518 branch--debug: default
1518 branch--debug: default
1519 branch--debug: default
1519 branch--debug: default
1520 branches:
1520 branches:
1521 branches:
1521 branches:
1522 branches:
1522 branches:
1523 branches:
1523 branches:
1524 branches: foo
1524 branches: foo
1525 branches:
1525 branches:
1526 branches:
1526 branches:
1527 branches:
1527 branches:
1528 branches:
1528 branches:
1529 branches--verbose:
1529 branches--verbose:
1530 branches--verbose:
1530 branches--verbose:
1531 branches--verbose:
1531 branches--verbose:
1532 branches--verbose:
1532 branches--verbose:
1533 branches--verbose: foo
1533 branches--verbose: foo
1534 branches--verbose:
1534 branches--verbose:
1535 branches--verbose:
1535 branches--verbose:
1536 branches--verbose:
1536 branches--verbose:
1537 branches--verbose:
1537 branches--verbose:
1538 branches--debug:
1538 branches--debug:
1539 branches--debug:
1539 branches--debug:
1540 branches--debug:
1540 branches--debug:
1541 branches--debug:
1541 branches--debug:
1542 branches--debug: foo
1542 branches--debug: foo
1543 branches--debug:
1543 branches--debug:
1544 branches--debug:
1544 branches--debug:
1545 branches--debug:
1545 branches--debug:
1546 branches--debug:
1546 branches--debug:
1547 date: 1577872860.00
1547 date: 1577872860.00
1548 date: 1000000.00
1548 date: 1000000.00
1549 date: 1500001.00
1549 date: 1500001.00
1550 date: 1500000.00
1550 date: 1500000.00
1551 date: 1400000.00
1551 date: 1400000.00
1552 date: 1300000.00
1552 date: 1300000.00
1553 date: 1200000.00
1553 date: 1200000.00
1554 date: 1100000.00
1554 date: 1100000.00
1555 date: 1000000.00
1555 date: 1000000.00
1556 date--verbose: 1577872860.00
1556 date--verbose: 1577872860.00
1557 date--verbose: 1000000.00
1557 date--verbose: 1000000.00
1558 date--verbose: 1500001.00
1558 date--verbose: 1500001.00
1559 date--verbose: 1500000.00
1559 date--verbose: 1500000.00
1560 date--verbose: 1400000.00
1560 date--verbose: 1400000.00
1561 date--verbose: 1300000.00
1561 date--verbose: 1300000.00
1562 date--verbose: 1200000.00
1562 date--verbose: 1200000.00
1563 date--verbose: 1100000.00
1563 date--verbose: 1100000.00
1564 date--verbose: 1000000.00
1564 date--verbose: 1000000.00
1565 date--debug: 1577872860.00
1565 date--debug: 1577872860.00
1566 date--debug: 1000000.00
1566 date--debug: 1000000.00
1567 date--debug: 1500001.00
1567 date--debug: 1500001.00
1568 date--debug: 1500000.00
1568 date--debug: 1500000.00
1569 date--debug: 1400000.00
1569 date--debug: 1400000.00
1570 date--debug: 1300000.00
1570 date--debug: 1300000.00
1571 date--debug: 1200000.00
1571 date--debug: 1200000.00
1572 date--debug: 1100000.00
1572 date--debug: 1100000.00
1573 date--debug: 1000000.00
1573 date--debug: 1000000.00
1574 desc: third
1574 desc: third
1575 desc: second
1575 desc: second
1576 desc: merge
1576 desc: merge
1577 desc: new head
1577 desc: new head
1578 desc: new branch
1578 desc: new branch
1579 desc: no user, no domain
1579 desc: no user, no domain
1580 desc: no person
1580 desc: no person
1581 desc: other 1
1581 desc: other 1
1582 other 2
1582 other 2
1583
1583
1584 other 3
1584 other 3
1585 desc: line 1
1585 desc: line 1
1586 line 2
1586 line 2
1587 desc--verbose: third
1587 desc--verbose: third
1588 desc--verbose: second
1588 desc--verbose: second
1589 desc--verbose: merge
1589 desc--verbose: merge
1590 desc--verbose: new head
1590 desc--verbose: new head
1591 desc--verbose: new branch
1591 desc--verbose: new branch
1592 desc--verbose: no user, no domain
1592 desc--verbose: no user, no domain
1593 desc--verbose: no person
1593 desc--verbose: no person
1594 desc--verbose: other 1
1594 desc--verbose: other 1
1595 other 2
1595 other 2
1596
1596
1597 other 3
1597 other 3
1598 desc--verbose: line 1
1598 desc--verbose: line 1
1599 line 2
1599 line 2
1600 desc--debug: third
1600 desc--debug: third
1601 desc--debug: second
1601 desc--debug: second
1602 desc--debug: merge
1602 desc--debug: merge
1603 desc--debug: new head
1603 desc--debug: new head
1604 desc--debug: new branch
1604 desc--debug: new branch
1605 desc--debug: no user, no domain
1605 desc--debug: no user, no domain
1606 desc--debug: no person
1606 desc--debug: no person
1607 desc--debug: other 1
1607 desc--debug: other 1
1608 other 2
1608 other 2
1609
1609
1610 other 3
1610 other 3
1611 desc--debug: line 1
1611 desc--debug: line 1
1612 line 2
1612 line 2
1613 file_adds: fourth third
1613 file_adds: fourth third
1614 file_adds: second
1614 file_adds: second
1615 file_adds:
1615 file_adds:
1616 file_adds: d
1616 file_adds: d
1617 file_adds:
1617 file_adds:
1618 file_adds:
1618 file_adds:
1619 file_adds: c
1619 file_adds: c
1620 file_adds: b
1620 file_adds: b
1621 file_adds: a
1621 file_adds: a
1622 file_adds--verbose: fourth third
1622 file_adds--verbose: fourth third
1623 file_adds--verbose: second
1623 file_adds--verbose: second
1624 file_adds--verbose:
1624 file_adds--verbose:
1625 file_adds--verbose: d
1625 file_adds--verbose: d
1626 file_adds--verbose:
1626 file_adds--verbose:
1627 file_adds--verbose:
1627 file_adds--verbose:
1628 file_adds--verbose: c
1628 file_adds--verbose: c
1629 file_adds--verbose: b
1629 file_adds--verbose: b
1630 file_adds--verbose: a
1630 file_adds--verbose: a
1631 file_adds--debug: fourth third
1631 file_adds--debug: fourth third
1632 file_adds--debug: second
1632 file_adds--debug: second
1633 file_adds--debug:
1633 file_adds--debug:
1634 file_adds--debug: d
1634 file_adds--debug: d
1635 file_adds--debug:
1635 file_adds--debug:
1636 file_adds--debug:
1636 file_adds--debug:
1637 file_adds--debug: c
1637 file_adds--debug: c
1638 file_adds--debug: b
1638 file_adds--debug: b
1639 file_adds--debug: a
1639 file_adds--debug: a
1640 file_dels: second
1640 file_dels: second
1641 file_dels:
1641 file_dels:
1642 file_dels:
1642 file_dels:
1643 file_dels:
1643 file_dels:
1644 file_dels:
1644 file_dels:
1645 file_dels:
1645 file_dels:
1646 file_dels:
1646 file_dels:
1647 file_dels:
1647 file_dels:
1648 file_dels:
1648 file_dels:
1649 file_dels--verbose: second
1649 file_dels--verbose: second
1650 file_dels--verbose:
1650 file_dels--verbose:
1651 file_dels--verbose:
1651 file_dels--verbose:
1652 file_dels--verbose:
1652 file_dels--verbose:
1653 file_dels--verbose:
1653 file_dels--verbose:
1654 file_dels--verbose:
1654 file_dels--verbose:
1655 file_dels--verbose:
1655 file_dels--verbose:
1656 file_dels--verbose:
1656 file_dels--verbose:
1657 file_dels--verbose:
1657 file_dels--verbose:
1658 file_dels--debug: second
1658 file_dels--debug: second
1659 file_dels--debug:
1659 file_dels--debug:
1660 file_dels--debug:
1660 file_dels--debug:
1661 file_dels--debug:
1661 file_dels--debug:
1662 file_dels--debug:
1662 file_dels--debug:
1663 file_dels--debug:
1663 file_dels--debug:
1664 file_dels--debug:
1664 file_dels--debug:
1665 file_dels--debug:
1665 file_dels--debug:
1666 file_dels--debug:
1666 file_dels--debug:
1667 file_mods:
1667 file_mods:
1668 file_mods:
1668 file_mods:
1669 file_mods:
1669 file_mods:
1670 file_mods:
1670 file_mods:
1671 file_mods:
1671 file_mods:
1672 file_mods: c
1672 file_mods: c
1673 file_mods:
1673 file_mods:
1674 file_mods:
1674 file_mods:
1675 file_mods:
1675 file_mods:
1676 file_mods--verbose:
1676 file_mods--verbose:
1677 file_mods--verbose:
1677 file_mods--verbose:
1678 file_mods--verbose:
1678 file_mods--verbose:
1679 file_mods--verbose:
1679 file_mods--verbose:
1680 file_mods--verbose:
1680 file_mods--verbose:
1681 file_mods--verbose: c
1681 file_mods--verbose: c
1682 file_mods--verbose:
1682 file_mods--verbose:
1683 file_mods--verbose:
1683 file_mods--verbose:
1684 file_mods--verbose:
1684 file_mods--verbose:
1685 file_mods--debug:
1685 file_mods--debug:
1686 file_mods--debug:
1686 file_mods--debug:
1687 file_mods--debug:
1687 file_mods--debug:
1688 file_mods--debug:
1688 file_mods--debug:
1689 file_mods--debug:
1689 file_mods--debug:
1690 file_mods--debug: c
1690 file_mods--debug: c
1691 file_mods--debug:
1691 file_mods--debug:
1692 file_mods--debug:
1692 file_mods--debug:
1693 file_mods--debug:
1693 file_mods--debug:
1694 file_copies: fourth (second)
1694 file_copies: fourth (second)
1695 file_copies:
1695 file_copies:
1696 file_copies:
1696 file_copies:
1697 file_copies:
1697 file_copies:
1698 file_copies:
1698 file_copies:
1699 file_copies:
1699 file_copies:
1700 file_copies:
1700 file_copies:
1701 file_copies:
1701 file_copies:
1702 file_copies:
1702 file_copies:
1703 file_copies--verbose: fourth (second)
1703 file_copies--verbose: fourth (second)
1704 file_copies--verbose:
1704 file_copies--verbose:
1705 file_copies--verbose:
1705 file_copies--verbose:
1706 file_copies--verbose:
1706 file_copies--verbose:
1707 file_copies--verbose:
1707 file_copies--verbose:
1708 file_copies--verbose:
1708 file_copies--verbose:
1709 file_copies--verbose:
1709 file_copies--verbose:
1710 file_copies--verbose:
1710 file_copies--verbose:
1711 file_copies--verbose:
1711 file_copies--verbose:
1712 file_copies--debug: fourth (second)
1712 file_copies--debug: fourth (second)
1713 file_copies--debug:
1713 file_copies--debug:
1714 file_copies--debug:
1714 file_copies--debug:
1715 file_copies--debug:
1715 file_copies--debug:
1716 file_copies--debug:
1716 file_copies--debug:
1717 file_copies--debug:
1717 file_copies--debug:
1718 file_copies--debug:
1718 file_copies--debug:
1719 file_copies--debug:
1719 file_copies--debug:
1720 file_copies--debug:
1720 file_copies--debug:
1721 file_copies_switch:
1721 file_copies_switch:
1722 file_copies_switch:
1722 file_copies_switch:
1723 file_copies_switch:
1723 file_copies_switch:
1724 file_copies_switch:
1724 file_copies_switch:
1725 file_copies_switch:
1725 file_copies_switch:
1726 file_copies_switch:
1726 file_copies_switch:
1727 file_copies_switch:
1727 file_copies_switch:
1728 file_copies_switch:
1728 file_copies_switch:
1729 file_copies_switch:
1729 file_copies_switch:
1730 file_copies_switch--verbose:
1730 file_copies_switch--verbose:
1731 file_copies_switch--verbose:
1731 file_copies_switch--verbose:
1732 file_copies_switch--verbose:
1732 file_copies_switch--verbose:
1733 file_copies_switch--verbose:
1733 file_copies_switch--verbose:
1734 file_copies_switch--verbose:
1734 file_copies_switch--verbose:
1735 file_copies_switch--verbose:
1735 file_copies_switch--verbose:
1736 file_copies_switch--verbose:
1736 file_copies_switch--verbose:
1737 file_copies_switch--verbose:
1737 file_copies_switch--verbose:
1738 file_copies_switch--verbose:
1738 file_copies_switch--verbose:
1739 file_copies_switch--debug:
1739 file_copies_switch--debug:
1740 file_copies_switch--debug:
1740 file_copies_switch--debug:
1741 file_copies_switch--debug:
1741 file_copies_switch--debug:
1742 file_copies_switch--debug:
1742 file_copies_switch--debug:
1743 file_copies_switch--debug:
1743 file_copies_switch--debug:
1744 file_copies_switch--debug:
1744 file_copies_switch--debug:
1745 file_copies_switch--debug:
1745 file_copies_switch--debug:
1746 file_copies_switch--debug:
1746 file_copies_switch--debug:
1747 file_copies_switch--debug:
1747 file_copies_switch--debug:
1748 files: fourth second third
1748 files: fourth second third
1749 files: second
1749 files: second
1750 files:
1750 files:
1751 files: d
1751 files: d
1752 files:
1752 files:
1753 files: c
1753 files: c
1754 files: c
1754 files: c
1755 files: b
1755 files: b
1756 files: a
1756 files: a
1757 files--verbose: fourth second third
1757 files--verbose: fourth second third
1758 files--verbose: second
1758 files--verbose: second
1759 files--verbose:
1759 files--verbose:
1760 files--verbose: d
1760 files--verbose: d
1761 files--verbose:
1761 files--verbose:
1762 files--verbose: c
1762 files--verbose: c
1763 files--verbose: c
1763 files--verbose: c
1764 files--verbose: b
1764 files--verbose: b
1765 files--verbose: a
1765 files--verbose: a
1766 files--debug: fourth second third
1766 files--debug: fourth second third
1767 files--debug: second
1767 files--debug: second
1768 files--debug:
1768 files--debug:
1769 files--debug: d
1769 files--debug: d
1770 files--debug:
1770 files--debug:
1771 files--debug: c
1771 files--debug: c
1772 files--debug: c
1772 files--debug: c
1773 files--debug: b
1773 files--debug: b
1774 files--debug: a
1774 files--debug: a
1775 manifest: 6:94961b75a2da
1775 manifest: 6:94961b75a2da
1776 manifest: 5:f2dbc354b94e
1776 manifest: 5:f2dbc354b94e
1777 manifest: 4:4dc3def4f9b4
1777 manifest: 4:4dc3def4f9b4
1778 manifest: 4:4dc3def4f9b4
1778 manifest: 4:4dc3def4f9b4
1779 manifest: 3:cb5a1327723b
1779 manifest: 3:cb5a1327723b
1780 manifest: 3:cb5a1327723b
1780 manifest: 3:cb5a1327723b
1781 manifest: 2:6e0e82995c35
1781 manifest: 2:6e0e82995c35
1782 manifest: 1:4e8d705b1e53
1782 manifest: 1:4e8d705b1e53
1783 manifest: 0:a0c8bcbbb45c
1783 manifest: 0:a0c8bcbbb45c
1784 manifest--verbose: 6:94961b75a2da
1784 manifest--verbose: 6:94961b75a2da
1785 manifest--verbose: 5:f2dbc354b94e
1785 manifest--verbose: 5:f2dbc354b94e
1786 manifest--verbose: 4:4dc3def4f9b4
1786 manifest--verbose: 4:4dc3def4f9b4
1787 manifest--verbose: 4:4dc3def4f9b4
1787 manifest--verbose: 4:4dc3def4f9b4
1788 manifest--verbose: 3:cb5a1327723b
1788 manifest--verbose: 3:cb5a1327723b
1789 manifest--verbose: 3:cb5a1327723b
1789 manifest--verbose: 3:cb5a1327723b
1790 manifest--verbose: 2:6e0e82995c35
1790 manifest--verbose: 2:6e0e82995c35
1791 manifest--verbose: 1:4e8d705b1e53
1791 manifest--verbose: 1:4e8d705b1e53
1792 manifest--verbose: 0:a0c8bcbbb45c
1792 manifest--verbose: 0:a0c8bcbbb45c
1793 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1793 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1794 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1794 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1795 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1795 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1796 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1796 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1797 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1797 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1798 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1798 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1799 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1799 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1800 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1800 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1801 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1801 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1802 node: 95c24699272ef57d062b8bccc32c878bf841784a
1802 node: 95c24699272ef57d062b8bccc32c878bf841784a
1803 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1803 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1804 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1804 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1805 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1805 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1806 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1806 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1807 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1807 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1808 node: 97054abb4ab824450e9164180baf491ae0078465
1808 node: 97054abb4ab824450e9164180baf491ae0078465
1809 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1809 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1810 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1810 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1811 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1811 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1812 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1812 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1813 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1813 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1814 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1814 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1815 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1815 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1816 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1816 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1817 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1817 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1818 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1818 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1819 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1819 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1820 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1820 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1821 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1821 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1822 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1822 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1823 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1823 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1824 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1824 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1825 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1825 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1826 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1826 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1827 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1827 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1828 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1828 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1829 parents:
1829 parents:
1830 parents: -1:000000000000
1830 parents: -1:000000000000
1831 parents: 5:13207e5a10d9 4:bbe44766e73d
1831 parents: 5:13207e5a10d9 4:bbe44766e73d
1832 parents: 3:10e46f2dcbf4
1832 parents: 3:10e46f2dcbf4
1833 parents:
1833 parents:
1834 parents:
1834 parents:
1835 parents:
1835 parents:
1836 parents:
1836 parents:
1837 parents:
1837 parents:
1838 parents--verbose:
1838 parents--verbose:
1839 parents--verbose: -1:000000000000
1839 parents--verbose: -1:000000000000
1840 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1840 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1841 parents--verbose: 3:10e46f2dcbf4
1841 parents--verbose: 3:10e46f2dcbf4
1842 parents--verbose:
1842 parents--verbose:
1843 parents--verbose:
1843 parents--verbose:
1844 parents--verbose:
1844 parents--verbose:
1845 parents--verbose:
1845 parents--verbose:
1846 parents--verbose:
1846 parents--verbose:
1847 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1847 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1848 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1848 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1849 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1849 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1850 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1850 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1851 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1851 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1852 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1852 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1853 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1853 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1854 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1854 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1855 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1855 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1856 rev: 8
1856 rev: 8
1857 rev: 7
1857 rev: 7
1858 rev: 6
1858 rev: 6
1859 rev: 5
1859 rev: 5
1860 rev: 4
1860 rev: 4
1861 rev: 3
1861 rev: 3
1862 rev: 2
1862 rev: 2
1863 rev: 1
1863 rev: 1
1864 rev: 0
1864 rev: 0
1865 rev--verbose: 8
1865 rev--verbose: 8
1866 rev--verbose: 7
1866 rev--verbose: 7
1867 rev--verbose: 6
1867 rev--verbose: 6
1868 rev--verbose: 5
1868 rev--verbose: 5
1869 rev--verbose: 4
1869 rev--verbose: 4
1870 rev--verbose: 3
1870 rev--verbose: 3
1871 rev--verbose: 2
1871 rev--verbose: 2
1872 rev--verbose: 1
1872 rev--verbose: 1
1873 rev--verbose: 0
1873 rev--verbose: 0
1874 rev--debug: 8
1874 rev--debug: 8
1875 rev--debug: 7
1875 rev--debug: 7
1876 rev--debug: 6
1876 rev--debug: 6
1877 rev--debug: 5
1877 rev--debug: 5
1878 rev--debug: 4
1878 rev--debug: 4
1879 rev--debug: 3
1879 rev--debug: 3
1880 rev--debug: 2
1880 rev--debug: 2
1881 rev--debug: 1
1881 rev--debug: 1
1882 rev--debug: 0
1882 rev--debug: 0
1883 tags: tip
1883 tags: tip
1884 tags:
1884 tags:
1885 tags:
1885 tags:
1886 tags:
1886 tags:
1887 tags:
1887 tags:
1888 tags:
1888 tags:
1889 tags:
1889 tags:
1890 tags:
1890 tags:
1891 tags:
1891 tags:
1892 tags--verbose: tip
1892 tags--verbose: tip
1893 tags--verbose:
1893 tags--verbose:
1894 tags--verbose:
1894 tags--verbose:
1895 tags--verbose:
1895 tags--verbose:
1896 tags--verbose:
1896 tags--verbose:
1897 tags--verbose:
1897 tags--verbose:
1898 tags--verbose:
1898 tags--verbose:
1899 tags--verbose:
1899 tags--verbose:
1900 tags--verbose:
1900 tags--verbose:
1901 tags--debug: tip
1901 tags--debug: tip
1902 tags--debug:
1902 tags--debug:
1903 tags--debug:
1903 tags--debug:
1904 tags--debug:
1904 tags--debug:
1905 tags--debug:
1905 tags--debug:
1906 tags--debug:
1906 tags--debug:
1907 tags--debug:
1907 tags--debug:
1908 tags--debug:
1908 tags--debug:
1909 tags--debug:
1909 tags--debug:
1910 diffstat: 3: +2/-1
1910 diffstat: 3: +2/-1
1911 diffstat: 1: +1/-0
1911 diffstat: 1: +1/-0
1912 diffstat: 0: +0/-0
1912 diffstat: 0: +0/-0
1913 diffstat: 1: +1/-0
1913 diffstat: 1: +1/-0
1914 diffstat: 0: +0/-0
1914 diffstat: 0: +0/-0
1915 diffstat: 1: +1/-0
1915 diffstat: 1: +1/-0
1916 diffstat: 1: +4/-0
1916 diffstat: 1: +4/-0
1917 diffstat: 1: +2/-0
1917 diffstat: 1: +2/-0
1918 diffstat: 1: +1/-0
1918 diffstat: 1: +1/-0
1919 diffstat--verbose: 3: +2/-1
1919 diffstat--verbose: 3: +2/-1
1920 diffstat--verbose: 1: +1/-0
1920 diffstat--verbose: 1: +1/-0
1921 diffstat--verbose: 0: +0/-0
1921 diffstat--verbose: 0: +0/-0
1922 diffstat--verbose: 1: +1/-0
1922 diffstat--verbose: 1: +1/-0
1923 diffstat--verbose: 0: +0/-0
1923 diffstat--verbose: 0: +0/-0
1924 diffstat--verbose: 1: +1/-0
1924 diffstat--verbose: 1: +1/-0
1925 diffstat--verbose: 1: +4/-0
1925 diffstat--verbose: 1: +4/-0
1926 diffstat--verbose: 1: +2/-0
1926 diffstat--verbose: 1: +2/-0
1927 diffstat--verbose: 1: +1/-0
1927 diffstat--verbose: 1: +1/-0
1928 diffstat--debug: 3: +2/-1
1928 diffstat--debug: 3: +2/-1
1929 diffstat--debug: 1: +1/-0
1929 diffstat--debug: 1: +1/-0
1930 diffstat--debug: 0: +0/-0
1930 diffstat--debug: 0: +0/-0
1931 diffstat--debug: 1: +1/-0
1931 diffstat--debug: 1: +1/-0
1932 diffstat--debug: 0: +0/-0
1932 diffstat--debug: 0: +0/-0
1933 diffstat--debug: 1: +1/-0
1933 diffstat--debug: 1: +1/-0
1934 diffstat--debug: 1: +4/-0
1934 diffstat--debug: 1: +4/-0
1935 diffstat--debug: 1: +2/-0
1935 diffstat--debug: 1: +2/-0
1936 diffstat--debug: 1: +1/-0
1936 diffstat--debug: 1: +1/-0
1937 extras: branch=default
1937 extras: branch=default
1938 extras: branch=default
1938 extras: branch=default
1939 extras: branch=default
1939 extras: branch=default
1940 extras: branch=default
1940 extras: branch=default
1941 extras: branch=foo
1941 extras: branch=foo
1942 extras: branch=default
1942 extras: branch=default
1943 extras: branch=default
1943 extras: branch=default
1944 extras: branch=default
1944 extras: branch=default
1945 extras: branch=default
1945 extras: branch=default
1946 extras--verbose: branch=default
1946 extras--verbose: branch=default
1947 extras--verbose: branch=default
1947 extras--verbose: branch=default
1948 extras--verbose: branch=default
1948 extras--verbose: branch=default
1949 extras--verbose: branch=default
1949 extras--verbose: branch=default
1950 extras--verbose: branch=foo
1950 extras--verbose: branch=foo
1951 extras--verbose: branch=default
1951 extras--verbose: branch=default
1952 extras--verbose: branch=default
1952 extras--verbose: branch=default
1953 extras--verbose: branch=default
1953 extras--verbose: branch=default
1954 extras--verbose: branch=default
1954 extras--verbose: branch=default
1955 extras--debug: branch=default
1955 extras--debug: branch=default
1956 extras--debug: branch=default
1956 extras--debug: branch=default
1957 extras--debug: branch=default
1957 extras--debug: branch=default
1958 extras--debug: branch=default
1958 extras--debug: branch=default
1959 extras--debug: branch=foo
1959 extras--debug: branch=foo
1960 extras--debug: branch=default
1960 extras--debug: branch=default
1961 extras--debug: branch=default
1961 extras--debug: branch=default
1962 extras--debug: branch=default
1962 extras--debug: branch=default
1963 extras--debug: branch=default
1963 extras--debug: branch=default
1964 p1rev: 7
1964 p1rev: 7
1965 p1rev: -1
1965 p1rev: -1
1966 p1rev: 5
1966 p1rev: 5
1967 p1rev: 3
1967 p1rev: 3
1968 p1rev: 3
1968 p1rev: 3
1969 p1rev: 2
1969 p1rev: 2
1970 p1rev: 1
1970 p1rev: 1
1971 p1rev: 0
1971 p1rev: 0
1972 p1rev: -1
1972 p1rev: -1
1973 p1rev--verbose: 7
1973 p1rev--verbose: 7
1974 p1rev--verbose: -1
1974 p1rev--verbose: -1
1975 p1rev--verbose: 5
1975 p1rev--verbose: 5
1976 p1rev--verbose: 3
1976 p1rev--verbose: 3
1977 p1rev--verbose: 3
1977 p1rev--verbose: 3
1978 p1rev--verbose: 2
1978 p1rev--verbose: 2
1979 p1rev--verbose: 1
1979 p1rev--verbose: 1
1980 p1rev--verbose: 0
1980 p1rev--verbose: 0
1981 p1rev--verbose: -1
1981 p1rev--verbose: -1
1982 p1rev--debug: 7
1982 p1rev--debug: 7
1983 p1rev--debug: -1
1983 p1rev--debug: -1
1984 p1rev--debug: 5
1984 p1rev--debug: 5
1985 p1rev--debug: 3
1985 p1rev--debug: 3
1986 p1rev--debug: 3
1986 p1rev--debug: 3
1987 p1rev--debug: 2
1987 p1rev--debug: 2
1988 p1rev--debug: 1
1988 p1rev--debug: 1
1989 p1rev--debug: 0
1989 p1rev--debug: 0
1990 p1rev--debug: -1
1990 p1rev--debug: -1
1991 p2rev: -1
1991 p2rev: -1
1992 p2rev: -1
1992 p2rev: -1
1993 p2rev: 4
1993 p2rev: 4
1994 p2rev: -1
1994 p2rev: -1
1995 p2rev: -1
1995 p2rev: -1
1996 p2rev: -1
1996 p2rev: -1
1997 p2rev: -1
1997 p2rev: -1
1998 p2rev: -1
1998 p2rev: -1
1999 p2rev: -1
1999 p2rev: -1
2000 p2rev--verbose: -1
2000 p2rev--verbose: -1
2001 p2rev--verbose: -1
2001 p2rev--verbose: -1
2002 p2rev--verbose: 4
2002 p2rev--verbose: 4
2003 p2rev--verbose: -1
2003 p2rev--verbose: -1
2004 p2rev--verbose: -1
2004 p2rev--verbose: -1
2005 p2rev--verbose: -1
2005 p2rev--verbose: -1
2006 p2rev--verbose: -1
2006 p2rev--verbose: -1
2007 p2rev--verbose: -1
2007 p2rev--verbose: -1
2008 p2rev--verbose: -1
2008 p2rev--verbose: -1
2009 p2rev--debug: -1
2009 p2rev--debug: -1
2010 p2rev--debug: -1
2010 p2rev--debug: -1
2011 p2rev--debug: 4
2011 p2rev--debug: 4
2012 p2rev--debug: -1
2012 p2rev--debug: -1
2013 p2rev--debug: -1
2013 p2rev--debug: -1
2014 p2rev--debug: -1
2014 p2rev--debug: -1
2015 p2rev--debug: -1
2015 p2rev--debug: -1
2016 p2rev--debug: -1
2016 p2rev--debug: -1
2017 p2rev--debug: -1
2017 p2rev--debug: -1
2018 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2018 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2019 p1node: 0000000000000000000000000000000000000000
2019 p1node: 0000000000000000000000000000000000000000
2020 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
2020 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
2021 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2021 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2022 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2022 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2023 p1node: 97054abb4ab824450e9164180baf491ae0078465
2023 p1node: 97054abb4ab824450e9164180baf491ae0078465
2024 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2024 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2025 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
2025 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
2026 p1node: 0000000000000000000000000000000000000000
2026 p1node: 0000000000000000000000000000000000000000
2027 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2027 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2028 p1node--verbose: 0000000000000000000000000000000000000000
2028 p1node--verbose: 0000000000000000000000000000000000000000
2029 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
2029 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
2030 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2030 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2031 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2031 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2032 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
2032 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
2033 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2033 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2034 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
2034 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
2035 p1node--verbose: 0000000000000000000000000000000000000000
2035 p1node--verbose: 0000000000000000000000000000000000000000
2036 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2036 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2037 p1node--debug: 0000000000000000000000000000000000000000
2037 p1node--debug: 0000000000000000000000000000000000000000
2038 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
2038 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
2039 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2039 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2040 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2040 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2041 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
2041 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
2042 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2042 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2043 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
2043 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
2044 p1node--debug: 0000000000000000000000000000000000000000
2044 p1node--debug: 0000000000000000000000000000000000000000
2045 p2node: 0000000000000000000000000000000000000000
2045 p2node: 0000000000000000000000000000000000000000
2046 p2node: 0000000000000000000000000000000000000000
2046 p2node: 0000000000000000000000000000000000000000
2047 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2047 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2048 p2node: 0000000000000000000000000000000000000000
2048 p2node: 0000000000000000000000000000000000000000
2049 p2node: 0000000000000000000000000000000000000000
2049 p2node: 0000000000000000000000000000000000000000
2050 p2node: 0000000000000000000000000000000000000000
2050 p2node: 0000000000000000000000000000000000000000
2051 p2node: 0000000000000000000000000000000000000000
2051 p2node: 0000000000000000000000000000000000000000
2052 p2node: 0000000000000000000000000000000000000000
2052 p2node: 0000000000000000000000000000000000000000
2053 p2node: 0000000000000000000000000000000000000000
2053 p2node: 0000000000000000000000000000000000000000
2054 p2node--verbose: 0000000000000000000000000000000000000000
2054 p2node--verbose: 0000000000000000000000000000000000000000
2055 p2node--verbose: 0000000000000000000000000000000000000000
2055 p2node--verbose: 0000000000000000000000000000000000000000
2056 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2056 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2057 p2node--verbose: 0000000000000000000000000000000000000000
2057 p2node--verbose: 0000000000000000000000000000000000000000
2058 p2node--verbose: 0000000000000000000000000000000000000000
2058 p2node--verbose: 0000000000000000000000000000000000000000
2059 p2node--verbose: 0000000000000000000000000000000000000000
2059 p2node--verbose: 0000000000000000000000000000000000000000
2060 p2node--verbose: 0000000000000000000000000000000000000000
2060 p2node--verbose: 0000000000000000000000000000000000000000
2061 p2node--verbose: 0000000000000000000000000000000000000000
2061 p2node--verbose: 0000000000000000000000000000000000000000
2062 p2node--verbose: 0000000000000000000000000000000000000000
2062 p2node--verbose: 0000000000000000000000000000000000000000
2063 p2node--debug: 0000000000000000000000000000000000000000
2063 p2node--debug: 0000000000000000000000000000000000000000
2064 p2node--debug: 0000000000000000000000000000000000000000
2064 p2node--debug: 0000000000000000000000000000000000000000
2065 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2065 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2066 p2node--debug: 0000000000000000000000000000000000000000
2066 p2node--debug: 0000000000000000000000000000000000000000
2067 p2node--debug: 0000000000000000000000000000000000000000
2067 p2node--debug: 0000000000000000000000000000000000000000
2068 p2node--debug: 0000000000000000000000000000000000000000
2068 p2node--debug: 0000000000000000000000000000000000000000
2069 p2node--debug: 0000000000000000000000000000000000000000
2069 p2node--debug: 0000000000000000000000000000000000000000
2070 p2node--debug: 0000000000000000000000000000000000000000
2070 p2node--debug: 0000000000000000000000000000000000000000
2071 p2node--debug: 0000000000000000000000000000000000000000
2071 p2node--debug: 0000000000000000000000000000000000000000
2072
2072
2073 Filters work:
2073 Filters work:
2074
2074
2075 $ hg log --template '{author|domain}\n'
2075 $ hg log --template '{author|domain}\n'
2076
2076
2077 hostname
2077 hostname
2078
2078
2079
2079
2080
2080
2081
2081
2082 place
2082 place
2083 place
2083 place
2084 hostname
2084 hostname
2085
2085
2086 $ hg log --template '{author|person}\n'
2086 $ hg log --template '{author|person}\n'
2087 test
2087 test
2088 User Name
2088 User Name
2089 person
2089 person
2090 person
2090 person
2091 person
2091 person
2092 person
2092 person
2093 other
2093 other
2094 A. N. Other
2094 A. N. Other
2095 User Name
2095 User Name
2096
2096
2097 $ hg log --template '{author|user}\n'
2097 $ hg log --template '{author|user}\n'
2098 test
2098 test
2099 user
2099 user
2100 person
2100 person
2101 person
2101 person
2102 person
2102 person
2103 person
2103 person
2104 other
2104 other
2105 other
2105 other
2106 user
2106 user
2107
2107
2108 $ hg log --template '{date|date}\n'
2108 $ hg log --template '{date|date}\n'
2109 Wed Jan 01 10:01:00 2020 +0000
2109 Wed Jan 01 10:01:00 2020 +0000
2110 Mon Jan 12 13:46:40 1970 +0000
2110 Mon Jan 12 13:46:40 1970 +0000
2111 Sun Jan 18 08:40:01 1970 +0000
2111 Sun Jan 18 08:40:01 1970 +0000
2112 Sun Jan 18 08:40:00 1970 +0000
2112 Sun Jan 18 08:40:00 1970 +0000
2113 Sat Jan 17 04:53:20 1970 +0000
2113 Sat Jan 17 04:53:20 1970 +0000
2114 Fri Jan 16 01:06:40 1970 +0000
2114 Fri Jan 16 01:06:40 1970 +0000
2115 Wed Jan 14 21:20:00 1970 +0000
2115 Wed Jan 14 21:20:00 1970 +0000
2116 Tue Jan 13 17:33:20 1970 +0000
2116 Tue Jan 13 17:33:20 1970 +0000
2117 Mon Jan 12 13:46:40 1970 +0000
2117 Mon Jan 12 13:46:40 1970 +0000
2118
2118
2119 $ hg log --template '{date|isodate}\n'
2119 $ hg log --template '{date|isodate}\n'
2120 2020-01-01 10:01 +0000
2120 2020-01-01 10:01 +0000
2121 1970-01-12 13:46 +0000
2121 1970-01-12 13:46 +0000
2122 1970-01-18 08:40 +0000
2122 1970-01-18 08:40 +0000
2123 1970-01-18 08:40 +0000
2123 1970-01-18 08:40 +0000
2124 1970-01-17 04:53 +0000
2124 1970-01-17 04:53 +0000
2125 1970-01-16 01:06 +0000
2125 1970-01-16 01:06 +0000
2126 1970-01-14 21:20 +0000
2126 1970-01-14 21:20 +0000
2127 1970-01-13 17:33 +0000
2127 1970-01-13 17:33 +0000
2128 1970-01-12 13:46 +0000
2128 1970-01-12 13:46 +0000
2129
2129
2130 $ hg log --template '{date|isodatesec}\n'
2130 $ hg log --template '{date|isodatesec}\n'
2131 2020-01-01 10:01:00 +0000
2131 2020-01-01 10:01:00 +0000
2132 1970-01-12 13:46:40 +0000
2132 1970-01-12 13:46:40 +0000
2133 1970-01-18 08:40:01 +0000
2133 1970-01-18 08:40:01 +0000
2134 1970-01-18 08:40:00 +0000
2134 1970-01-18 08:40:00 +0000
2135 1970-01-17 04:53:20 +0000
2135 1970-01-17 04:53:20 +0000
2136 1970-01-16 01:06:40 +0000
2136 1970-01-16 01:06:40 +0000
2137 1970-01-14 21:20:00 +0000
2137 1970-01-14 21:20:00 +0000
2138 1970-01-13 17:33:20 +0000
2138 1970-01-13 17:33:20 +0000
2139 1970-01-12 13:46:40 +0000
2139 1970-01-12 13:46:40 +0000
2140
2140
2141 $ hg log --template '{date|rfc822date}\n'
2141 $ hg log --template '{date|rfc822date}\n'
2142 Wed, 01 Jan 2020 10:01:00 +0000
2142 Wed, 01 Jan 2020 10:01:00 +0000
2143 Mon, 12 Jan 1970 13:46:40 +0000
2143 Mon, 12 Jan 1970 13:46:40 +0000
2144 Sun, 18 Jan 1970 08:40:01 +0000
2144 Sun, 18 Jan 1970 08:40:01 +0000
2145 Sun, 18 Jan 1970 08:40:00 +0000
2145 Sun, 18 Jan 1970 08:40:00 +0000
2146 Sat, 17 Jan 1970 04:53:20 +0000
2146 Sat, 17 Jan 1970 04:53:20 +0000
2147 Fri, 16 Jan 1970 01:06:40 +0000
2147 Fri, 16 Jan 1970 01:06:40 +0000
2148 Wed, 14 Jan 1970 21:20:00 +0000
2148 Wed, 14 Jan 1970 21:20:00 +0000
2149 Tue, 13 Jan 1970 17:33:20 +0000
2149 Tue, 13 Jan 1970 17:33:20 +0000
2150 Mon, 12 Jan 1970 13:46:40 +0000
2150 Mon, 12 Jan 1970 13:46:40 +0000
2151
2151
2152 $ hg log --template '{desc|firstline}\n'
2152 $ hg log --template '{desc|firstline}\n'
2153 third
2153 third
2154 second
2154 second
2155 merge
2155 merge
2156 new head
2156 new head
2157 new branch
2157 new branch
2158 no user, no domain
2158 no user, no domain
2159 no person
2159 no person
2160 other 1
2160 other 1
2161 line 1
2161 line 1
2162
2162
2163 $ hg log --template '{node|short}\n'
2163 $ hg log --template '{node|short}\n'
2164 95c24699272e
2164 95c24699272e
2165 29114dbae42b
2165 29114dbae42b
2166 d41e714fe50d
2166 d41e714fe50d
2167 13207e5a10d9
2167 13207e5a10d9
2168 bbe44766e73d
2168 bbe44766e73d
2169 10e46f2dcbf4
2169 10e46f2dcbf4
2170 97054abb4ab8
2170 97054abb4ab8
2171 b608e9d1a3f0
2171 b608e9d1a3f0
2172 1e4e1b8f71e0
2172 1e4e1b8f71e0
2173
2173
2174 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
2174 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
2175 <changeset author="test"/>
2175 <changeset author="test"/>
2176 <changeset author="User Name &lt;user@hostname&gt;"/>
2176 <changeset author="User Name &lt;user@hostname&gt;"/>
2177 <changeset author="person"/>
2177 <changeset author="person"/>
2178 <changeset author="person"/>
2178 <changeset author="person"/>
2179 <changeset author="person"/>
2179 <changeset author="person"/>
2180 <changeset author="person"/>
2180 <changeset author="person"/>
2181 <changeset author="other@place"/>
2181 <changeset author="other@place"/>
2182 <changeset author="A. N. Other &lt;other@place&gt;"/>
2182 <changeset author="A. N. Other &lt;other@place&gt;"/>
2183 <changeset author="User Name &lt;user@hostname&gt;"/>
2183 <changeset author="User Name &lt;user@hostname&gt;"/>
2184
2184
2185 $ hg log --template '{rev}: {children}\n'
2185 $ hg log --template '{rev}: {children}\n'
2186 8:
2186 8:
2187 7: 8:95c24699272e
2187 7: 8:95c24699272e
2188 6:
2188 6:
2189 5: 6:d41e714fe50d
2189 5: 6:d41e714fe50d
2190 4: 6:d41e714fe50d
2190 4: 6:d41e714fe50d
2191 3: 4:bbe44766e73d 5:13207e5a10d9
2191 3: 4:bbe44766e73d 5:13207e5a10d9
2192 2: 3:10e46f2dcbf4
2192 2: 3:10e46f2dcbf4
2193 1: 2:97054abb4ab8
2193 1: 2:97054abb4ab8
2194 0: 1:b608e9d1a3f0
2194 0: 1:b608e9d1a3f0
2195
2195
2196 Formatnode filter works:
2196 Formatnode filter works:
2197
2197
2198 $ hg -q log -r 0 --template '{node|formatnode}\n'
2198 $ hg -q log -r 0 --template '{node|formatnode}\n'
2199 1e4e1b8f71e0
2199 1e4e1b8f71e0
2200
2200
2201 $ hg log -r 0 --template '{node|formatnode}\n'
2201 $ hg log -r 0 --template '{node|formatnode}\n'
2202 1e4e1b8f71e0
2202 1e4e1b8f71e0
2203
2203
2204 $ hg -v log -r 0 --template '{node|formatnode}\n'
2204 $ hg -v log -r 0 --template '{node|formatnode}\n'
2205 1e4e1b8f71e0
2205 1e4e1b8f71e0
2206
2206
2207 $ hg --debug log -r 0 --template '{node|formatnode}\n'
2207 $ hg --debug log -r 0 --template '{node|formatnode}\n'
2208 1e4e1b8f71e05681d422154f5421e385fec3454f
2208 1e4e1b8f71e05681d422154f5421e385fec3454f
2209
2209
2210 Age filter:
2210 Age filter:
2211
2211
2212 $ hg init unstable-hash
2212 $ hg init unstable-hash
2213 $ cd unstable-hash
2213 $ cd unstable-hash
2214 $ hg log --template '{date|age}\n' > /dev/null || exit 1
2214 $ hg log --template '{date|age}\n' > /dev/null || exit 1
2215
2215
2216 >>> from __future__ import absolute_import
2216 >>> from __future__ import absolute_import
2217 >>> import datetime
2217 >>> import datetime
2218 >>> fp = open('a', 'w')
2218 >>> fp = open('a', 'w')
2219 >>> n = datetime.datetime.now() + datetime.timedelta(366 * 7)
2219 >>> n = datetime.datetime.now() + datetime.timedelta(366 * 7)
2220 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
2220 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
2221 >>> fp.close()
2221 >>> fp.close()
2222 $ hg add a
2222 $ hg add a
2223 $ hg commit -m future -d "`cat a`"
2223 $ hg commit -m future -d "`cat a`"
2224
2224
2225 $ hg log -l1 --template '{date|age}\n'
2225 $ hg log -l1 --template '{date|age}\n'
2226 7 years from now
2226 7 years from now
2227
2227
2228 $ cd ..
2228 $ cd ..
2229 $ rm -rf unstable-hash
2229 $ rm -rf unstable-hash
2230
2230
2231 Add a dummy commit to make up for the instability of the above:
2231 Add a dummy commit to make up for the instability of the above:
2232
2232
2233 $ echo a > a
2233 $ echo a > a
2234 $ hg add a
2234 $ hg add a
2235 $ hg ci -m future
2235 $ hg ci -m future
2236
2236
2237 Count filter:
2237 Count filter:
2238
2238
2239 $ hg log -l1 --template '{node|count} {node|short|count}\n'
2239 $ hg log -l1 --template '{node|count} {node|short|count}\n'
2240 40 12
2240 40 12
2241
2241
2242 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
2242 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
2243 0 1 4
2243 0 1 4
2244
2244
2245 $ hg log -G --template '{rev}: children: {children|count}, \
2245 $ hg log -G --template '{rev}: children: {children|count}, \
2246 > tags: {tags|count}, file_adds: {file_adds|count}, \
2246 > tags: {tags|count}, file_adds: {file_adds|count}, \
2247 > ancestors: {revset("ancestors(%s)", rev)|count}'
2247 > ancestors: {revset("ancestors(%s)", rev)|count}'
2248 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
2248 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
2249 |
2249 |
2250 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
2250 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
2251 |
2251 |
2252 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
2252 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
2253
2253
2254 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
2254 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
2255 |\
2255 |\
2256 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
2256 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
2257 | |
2257 | |
2258 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
2258 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
2259 |/
2259 |/
2260 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
2260 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
2261 |
2261 |
2262 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
2262 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
2263 |
2263 |
2264 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
2264 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
2265 |
2265 |
2266 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
2266 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
2267
2267
2268
2268
2269 Upper/lower filters:
2269 Upper/lower filters:
2270
2270
2271 $ hg log -r0 --template '{branch|upper}\n'
2271 $ hg log -r0 --template '{branch|upper}\n'
2272 DEFAULT
2272 DEFAULT
2273 $ hg log -r0 --template '{author|lower}\n'
2273 $ hg log -r0 --template '{author|lower}\n'
2274 user name <user@hostname>
2274 user name <user@hostname>
2275 $ hg log -r0 --template '{date|upper}\n'
2275 $ hg log -r0 --template '{date|upper}\n'
2276 abort: template filter 'upper' is not compatible with keyword 'date'
2276 abort: template filter 'upper' is not compatible with keyword 'date'
2277 [255]
2277 [255]
2278
2278
2279 Add a commit that does all possible modifications at once
2279 Add a commit that does all possible modifications at once
2280
2280
2281 $ echo modify >> third
2281 $ echo modify >> third
2282 $ touch b
2282 $ touch b
2283 $ hg add b
2283 $ hg add b
2284 $ hg mv fourth fifth
2284 $ hg mv fourth fifth
2285 $ hg rm a
2285 $ hg rm a
2286 $ hg ci -m "Modify, add, remove, rename"
2286 $ hg ci -m "Modify, add, remove, rename"
2287
2287
2288 Check the status template
2288 Check the status template
2289
2289
2290 $ cat <<EOF >> $HGRCPATH
2290 $ cat <<EOF >> $HGRCPATH
2291 > [extensions]
2291 > [extensions]
2292 > color=
2292 > color=
2293 > EOF
2293 > EOF
2294
2294
2295 $ hg log -T status -r 10
2295 $ hg log -T status -r 10
2296 changeset: 10:0f9759ec227a
2296 changeset: 10:0f9759ec227a
2297 tag: tip
2297 tag: tip
2298 user: test
2298 user: test
2299 date: Thu Jan 01 00:00:00 1970 +0000
2299 date: Thu Jan 01 00:00:00 1970 +0000
2300 summary: Modify, add, remove, rename
2300 summary: Modify, add, remove, rename
2301 files:
2301 files:
2302 M third
2302 M third
2303 A b
2303 A b
2304 A fifth
2304 A fifth
2305 R a
2305 R a
2306 R fourth
2306 R fourth
2307
2307
2308 $ hg log -T status -C -r 10
2308 $ hg log -T status -C -r 10
2309 changeset: 10:0f9759ec227a
2309 changeset: 10:0f9759ec227a
2310 tag: tip
2310 tag: tip
2311 user: test
2311 user: test
2312 date: Thu Jan 01 00:00:00 1970 +0000
2312 date: Thu Jan 01 00:00:00 1970 +0000
2313 summary: Modify, add, remove, rename
2313 summary: Modify, add, remove, rename
2314 files:
2314 files:
2315 M third
2315 M third
2316 A b
2316 A b
2317 A fifth
2317 A fifth
2318 fourth
2318 fourth
2319 R a
2319 R a
2320 R fourth
2320 R fourth
2321
2321
2322 $ hg log -T status -C -r 10 -v
2322 $ hg log -T status -C -r 10 -v
2323 changeset: 10:0f9759ec227a
2323 changeset: 10:0f9759ec227a
2324 tag: tip
2324 tag: tip
2325 user: test
2325 user: test
2326 date: Thu Jan 01 00:00:00 1970 +0000
2326 date: Thu Jan 01 00:00:00 1970 +0000
2327 description:
2327 description:
2328 Modify, add, remove, rename
2328 Modify, add, remove, rename
2329
2329
2330 files:
2330 files:
2331 M third
2331 M third
2332 A b
2332 A b
2333 A fifth
2333 A fifth
2334 fourth
2334 fourth
2335 R a
2335 R a
2336 R fourth
2336 R fourth
2337
2337
2338 $ hg log -T status -C -r 10 --debug
2338 $ hg log -T status -C -r 10 --debug
2339 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2339 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2340 tag: tip
2340 tag: tip
2341 phase: secret
2341 phase: secret
2342 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2342 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2343 parent: -1:0000000000000000000000000000000000000000
2343 parent: -1:0000000000000000000000000000000000000000
2344 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2344 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2345 user: test
2345 user: test
2346 date: Thu Jan 01 00:00:00 1970 +0000
2346 date: Thu Jan 01 00:00:00 1970 +0000
2347 extra: branch=default
2347 extra: branch=default
2348 description:
2348 description:
2349 Modify, add, remove, rename
2349 Modify, add, remove, rename
2350
2350
2351 files:
2351 files:
2352 M third
2352 M third
2353 A b
2353 A b
2354 A fifth
2354 A fifth
2355 fourth
2355 fourth
2356 R a
2356 R a
2357 R fourth
2357 R fourth
2358
2358
2359 $ hg log -T status -C -r 10 --quiet
2359 $ hg log -T status -C -r 10 --quiet
2360 10:0f9759ec227a
2360 10:0f9759ec227a
2361 $ hg --color=debug log -T status -r 10
2361 $ hg --color=debug log -T status -r 10
2362 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2362 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2363 [log.tag|tag: tip]
2363 [log.tag|tag: tip]
2364 [log.user|user: test]
2364 [log.user|user: test]
2365 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2365 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2366 [log.summary|summary: Modify, add, remove, rename]
2366 [log.summary|summary: Modify, add, remove, rename]
2367 [ui.note log.files|files:]
2367 [ui.note log.files|files:]
2368 [status.modified|M third]
2368 [status.modified|M third]
2369 [status.added|A b]
2369 [status.added|A b]
2370 [status.added|A fifth]
2370 [status.added|A fifth]
2371 [status.removed|R a]
2371 [status.removed|R a]
2372 [status.removed|R fourth]
2372 [status.removed|R fourth]
2373
2373
2374 $ hg --color=debug log -T status -C -r 10
2374 $ hg --color=debug log -T status -C -r 10
2375 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2375 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2376 [log.tag|tag: tip]
2376 [log.tag|tag: tip]
2377 [log.user|user: test]
2377 [log.user|user: test]
2378 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2378 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2379 [log.summary|summary: Modify, add, remove, rename]
2379 [log.summary|summary: Modify, add, remove, rename]
2380 [ui.note log.files|files:]
2380 [ui.note log.files|files:]
2381 [status.modified|M third]
2381 [status.modified|M third]
2382 [status.added|A b]
2382 [status.added|A b]
2383 [status.added|A fifth]
2383 [status.added|A fifth]
2384 [status.copied| fourth]
2384 [status.copied| fourth]
2385 [status.removed|R a]
2385 [status.removed|R a]
2386 [status.removed|R fourth]
2386 [status.removed|R fourth]
2387
2387
2388 $ hg --color=debug log -T status -C -r 10 -v
2388 $ hg --color=debug log -T status -C -r 10 -v
2389 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2389 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2390 [log.tag|tag: tip]
2390 [log.tag|tag: tip]
2391 [log.user|user: test]
2391 [log.user|user: test]
2392 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2392 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2393 [ui.note log.description|description:]
2393 [ui.note log.description|description:]
2394 [ui.note log.description|Modify, add, remove, rename]
2394 [ui.note log.description|Modify, add, remove, rename]
2395
2395
2396 [ui.note log.files|files:]
2396 [ui.note log.files|files:]
2397 [status.modified|M third]
2397 [status.modified|M third]
2398 [status.added|A b]
2398 [status.added|A b]
2399 [status.added|A fifth]
2399 [status.added|A fifth]
2400 [status.copied| fourth]
2400 [status.copied| fourth]
2401 [status.removed|R a]
2401 [status.removed|R a]
2402 [status.removed|R fourth]
2402 [status.removed|R fourth]
2403
2403
2404 $ hg --color=debug log -T status -C -r 10 --debug
2404 $ hg --color=debug log -T status -C -r 10 --debug
2405 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2405 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2406 [log.tag|tag: tip]
2406 [log.tag|tag: tip]
2407 [log.phase|phase: secret]
2407 [log.phase|phase: secret]
2408 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2408 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2409 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2409 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2410 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2410 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2411 [log.user|user: test]
2411 [log.user|user: test]
2412 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2412 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2413 [ui.debug log.extra|extra: branch=default]
2413 [ui.debug log.extra|extra: branch=default]
2414 [ui.note log.description|description:]
2414 [ui.note log.description|description:]
2415 [ui.note log.description|Modify, add, remove, rename]
2415 [ui.note log.description|Modify, add, remove, rename]
2416
2416
2417 [ui.note log.files|files:]
2417 [ui.note log.files|files:]
2418 [status.modified|M third]
2418 [status.modified|M third]
2419 [status.added|A b]
2419 [status.added|A b]
2420 [status.added|A fifth]
2420 [status.added|A fifth]
2421 [status.copied| fourth]
2421 [status.copied| fourth]
2422 [status.removed|R a]
2422 [status.removed|R a]
2423 [status.removed|R fourth]
2423 [status.removed|R fourth]
2424
2424
2425 $ hg --color=debug log -T status -C -r 10 --quiet
2425 $ hg --color=debug log -T status -C -r 10 --quiet
2426 [log.node|10:0f9759ec227a]
2426 [log.node|10:0f9759ec227a]
2427
2427
2428 Check the bisect template
2428 Check the bisect template
2429
2429
2430 $ hg bisect -g 1
2430 $ hg bisect -g 1
2431 $ hg bisect -b 3 --noupdate
2431 $ hg bisect -b 3 --noupdate
2432 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2432 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2433 $ hg log -T bisect -r 0:4
2433 $ hg log -T bisect -r 0:4
2434 changeset: 0:1e4e1b8f71e0
2434 changeset: 0:1e4e1b8f71e0
2435 bisect: good (implicit)
2435 bisect: good (implicit)
2436 user: User Name <user@hostname>
2436 user: User Name <user@hostname>
2437 date: Mon Jan 12 13:46:40 1970 +0000
2437 date: Mon Jan 12 13:46:40 1970 +0000
2438 summary: line 1
2438 summary: line 1
2439
2439
2440 changeset: 1:b608e9d1a3f0
2440 changeset: 1:b608e9d1a3f0
2441 bisect: good
2441 bisect: good
2442 user: A. N. Other <other@place>
2442 user: A. N. Other <other@place>
2443 date: Tue Jan 13 17:33:20 1970 +0000
2443 date: Tue Jan 13 17:33:20 1970 +0000
2444 summary: other 1
2444 summary: other 1
2445
2445
2446 changeset: 2:97054abb4ab8
2446 changeset: 2:97054abb4ab8
2447 bisect: untested
2447 bisect: untested
2448 user: other@place
2448 user: other@place
2449 date: Wed Jan 14 21:20:00 1970 +0000
2449 date: Wed Jan 14 21:20:00 1970 +0000
2450 summary: no person
2450 summary: no person
2451
2451
2452 changeset: 3:10e46f2dcbf4
2452 changeset: 3:10e46f2dcbf4
2453 bisect: bad
2453 bisect: bad
2454 user: person
2454 user: person
2455 date: Fri Jan 16 01:06:40 1970 +0000
2455 date: Fri Jan 16 01:06:40 1970 +0000
2456 summary: no user, no domain
2456 summary: no user, no domain
2457
2457
2458 changeset: 4:bbe44766e73d
2458 changeset: 4:bbe44766e73d
2459 bisect: bad (implicit)
2459 bisect: bad (implicit)
2460 branch: foo
2460 branch: foo
2461 user: person
2461 user: person
2462 date: Sat Jan 17 04:53:20 1970 +0000
2462 date: Sat Jan 17 04:53:20 1970 +0000
2463 summary: new branch
2463 summary: new branch
2464
2464
2465 $ hg log --debug -T bisect -r 0:4
2465 $ hg log --debug -T bisect -r 0:4
2466 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2466 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2467 bisect: good (implicit)
2467 bisect: good (implicit)
2468 phase: public
2468 phase: public
2469 parent: -1:0000000000000000000000000000000000000000
2469 parent: -1:0000000000000000000000000000000000000000
2470 parent: -1:0000000000000000000000000000000000000000
2470 parent: -1:0000000000000000000000000000000000000000
2471 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2471 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2472 user: User Name <user@hostname>
2472 user: User Name <user@hostname>
2473 date: Mon Jan 12 13:46:40 1970 +0000
2473 date: Mon Jan 12 13:46:40 1970 +0000
2474 files+: a
2474 files+: a
2475 extra: branch=default
2475 extra: branch=default
2476 description:
2476 description:
2477 line 1
2477 line 1
2478 line 2
2478 line 2
2479
2479
2480
2480
2481 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2481 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2482 bisect: good
2482 bisect: good
2483 phase: public
2483 phase: public
2484 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2484 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2485 parent: -1:0000000000000000000000000000000000000000
2485 parent: -1:0000000000000000000000000000000000000000
2486 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2486 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2487 user: A. N. Other <other@place>
2487 user: A. N. Other <other@place>
2488 date: Tue Jan 13 17:33:20 1970 +0000
2488 date: Tue Jan 13 17:33:20 1970 +0000
2489 files+: b
2489 files+: b
2490 extra: branch=default
2490 extra: branch=default
2491 description:
2491 description:
2492 other 1
2492 other 1
2493 other 2
2493 other 2
2494
2494
2495 other 3
2495 other 3
2496
2496
2497
2497
2498 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2498 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2499 bisect: untested
2499 bisect: untested
2500 phase: public
2500 phase: public
2501 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2501 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2502 parent: -1:0000000000000000000000000000000000000000
2502 parent: -1:0000000000000000000000000000000000000000
2503 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2503 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2504 user: other@place
2504 user: other@place
2505 date: Wed Jan 14 21:20:00 1970 +0000
2505 date: Wed Jan 14 21:20:00 1970 +0000
2506 files+: c
2506 files+: c
2507 extra: branch=default
2507 extra: branch=default
2508 description:
2508 description:
2509 no person
2509 no person
2510
2510
2511
2511
2512 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2512 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2513 bisect: bad
2513 bisect: bad
2514 phase: public
2514 phase: public
2515 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2515 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2516 parent: -1:0000000000000000000000000000000000000000
2516 parent: -1:0000000000000000000000000000000000000000
2517 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2517 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2518 user: person
2518 user: person
2519 date: Fri Jan 16 01:06:40 1970 +0000
2519 date: Fri Jan 16 01:06:40 1970 +0000
2520 files: c
2520 files: c
2521 extra: branch=default
2521 extra: branch=default
2522 description:
2522 description:
2523 no user, no domain
2523 no user, no domain
2524
2524
2525
2525
2526 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2526 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2527 bisect: bad (implicit)
2527 bisect: bad (implicit)
2528 branch: foo
2528 branch: foo
2529 phase: draft
2529 phase: draft
2530 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2530 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2531 parent: -1:0000000000000000000000000000000000000000
2531 parent: -1:0000000000000000000000000000000000000000
2532 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2532 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2533 user: person
2533 user: person
2534 date: Sat Jan 17 04:53:20 1970 +0000
2534 date: Sat Jan 17 04:53:20 1970 +0000
2535 extra: branch=foo
2535 extra: branch=foo
2536 description:
2536 description:
2537 new branch
2537 new branch
2538
2538
2539
2539
2540 $ hg log -v -T bisect -r 0:4
2540 $ hg log -v -T bisect -r 0:4
2541 changeset: 0:1e4e1b8f71e0
2541 changeset: 0:1e4e1b8f71e0
2542 bisect: good (implicit)
2542 bisect: good (implicit)
2543 user: User Name <user@hostname>
2543 user: User Name <user@hostname>
2544 date: Mon Jan 12 13:46:40 1970 +0000
2544 date: Mon Jan 12 13:46:40 1970 +0000
2545 files: a
2545 files: a
2546 description:
2546 description:
2547 line 1
2547 line 1
2548 line 2
2548 line 2
2549
2549
2550
2550
2551 changeset: 1:b608e9d1a3f0
2551 changeset: 1:b608e9d1a3f0
2552 bisect: good
2552 bisect: good
2553 user: A. N. Other <other@place>
2553 user: A. N. Other <other@place>
2554 date: Tue Jan 13 17:33:20 1970 +0000
2554 date: Tue Jan 13 17:33:20 1970 +0000
2555 files: b
2555 files: b
2556 description:
2556 description:
2557 other 1
2557 other 1
2558 other 2
2558 other 2
2559
2559
2560 other 3
2560 other 3
2561
2561
2562
2562
2563 changeset: 2:97054abb4ab8
2563 changeset: 2:97054abb4ab8
2564 bisect: untested
2564 bisect: untested
2565 user: other@place
2565 user: other@place
2566 date: Wed Jan 14 21:20:00 1970 +0000
2566 date: Wed Jan 14 21:20:00 1970 +0000
2567 files: c
2567 files: c
2568 description:
2568 description:
2569 no person
2569 no person
2570
2570
2571
2571
2572 changeset: 3:10e46f2dcbf4
2572 changeset: 3:10e46f2dcbf4
2573 bisect: bad
2573 bisect: bad
2574 user: person
2574 user: person
2575 date: Fri Jan 16 01:06:40 1970 +0000
2575 date: Fri Jan 16 01:06:40 1970 +0000
2576 files: c
2576 files: c
2577 description:
2577 description:
2578 no user, no domain
2578 no user, no domain
2579
2579
2580
2580
2581 changeset: 4:bbe44766e73d
2581 changeset: 4:bbe44766e73d
2582 bisect: bad (implicit)
2582 bisect: bad (implicit)
2583 branch: foo
2583 branch: foo
2584 user: person
2584 user: person
2585 date: Sat Jan 17 04:53:20 1970 +0000
2585 date: Sat Jan 17 04:53:20 1970 +0000
2586 description:
2586 description:
2587 new branch
2587 new branch
2588
2588
2589
2589
2590 $ hg --color=debug log -T bisect -r 0:4
2590 $ hg --color=debug log -T bisect -r 0:4
2591 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2591 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2592 [log.bisect bisect.good|bisect: good (implicit)]
2592 [log.bisect bisect.good|bisect: good (implicit)]
2593 [log.user|user: User Name <user@hostname>]
2593 [log.user|user: User Name <user@hostname>]
2594 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2594 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2595 [log.summary|summary: line 1]
2595 [log.summary|summary: line 1]
2596
2596
2597 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2597 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2598 [log.bisect bisect.good|bisect: good]
2598 [log.bisect bisect.good|bisect: good]
2599 [log.user|user: A. N. Other <other@place>]
2599 [log.user|user: A. N. Other <other@place>]
2600 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2600 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2601 [log.summary|summary: other 1]
2601 [log.summary|summary: other 1]
2602
2602
2603 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2603 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2604 [log.bisect bisect.untested|bisect: untested]
2604 [log.bisect bisect.untested|bisect: untested]
2605 [log.user|user: other@place]
2605 [log.user|user: other@place]
2606 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2606 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2607 [log.summary|summary: no person]
2607 [log.summary|summary: no person]
2608
2608
2609 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2609 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2610 [log.bisect bisect.bad|bisect: bad]
2610 [log.bisect bisect.bad|bisect: bad]
2611 [log.user|user: person]
2611 [log.user|user: person]
2612 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2612 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2613 [log.summary|summary: no user, no domain]
2613 [log.summary|summary: no user, no domain]
2614
2614
2615 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2615 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2616 [log.bisect bisect.bad|bisect: bad (implicit)]
2616 [log.bisect bisect.bad|bisect: bad (implicit)]
2617 [log.branch|branch: foo]
2617 [log.branch|branch: foo]
2618 [log.user|user: person]
2618 [log.user|user: person]
2619 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2619 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2620 [log.summary|summary: new branch]
2620 [log.summary|summary: new branch]
2621
2621
2622 $ hg --color=debug log --debug -T bisect -r 0:4
2622 $ hg --color=debug log --debug -T bisect -r 0:4
2623 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2623 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2624 [log.bisect bisect.good|bisect: good (implicit)]
2624 [log.bisect bisect.good|bisect: good (implicit)]
2625 [log.phase|phase: public]
2625 [log.phase|phase: public]
2626 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2626 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2627 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2627 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2628 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2628 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2629 [log.user|user: User Name <user@hostname>]
2629 [log.user|user: User Name <user@hostname>]
2630 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2630 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2631 [ui.debug log.files|files+: a]
2631 [ui.debug log.files|files+: a]
2632 [ui.debug log.extra|extra: branch=default]
2632 [ui.debug log.extra|extra: branch=default]
2633 [ui.note log.description|description:]
2633 [ui.note log.description|description:]
2634 [ui.note log.description|line 1
2634 [ui.note log.description|line 1
2635 line 2]
2635 line 2]
2636
2636
2637
2637
2638 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2638 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2639 [log.bisect bisect.good|bisect: good]
2639 [log.bisect bisect.good|bisect: good]
2640 [log.phase|phase: public]
2640 [log.phase|phase: public]
2641 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2641 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2642 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2642 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2643 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2643 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2644 [log.user|user: A. N. Other <other@place>]
2644 [log.user|user: A. N. Other <other@place>]
2645 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2645 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2646 [ui.debug log.files|files+: b]
2646 [ui.debug log.files|files+: b]
2647 [ui.debug log.extra|extra: branch=default]
2647 [ui.debug log.extra|extra: branch=default]
2648 [ui.note log.description|description:]
2648 [ui.note log.description|description:]
2649 [ui.note log.description|other 1
2649 [ui.note log.description|other 1
2650 other 2
2650 other 2
2651
2651
2652 other 3]
2652 other 3]
2653
2653
2654
2654
2655 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2655 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2656 [log.bisect bisect.untested|bisect: untested]
2656 [log.bisect bisect.untested|bisect: untested]
2657 [log.phase|phase: public]
2657 [log.phase|phase: public]
2658 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2658 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2659 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2659 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2660 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2660 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2661 [log.user|user: other@place]
2661 [log.user|user: other@place]
2662 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2662 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2663 [ui.debug log.files|files+: c]
2663 [ui.debug log.files|files+: c]
2664 [ui.debug log.extra|extra: branch=default]
2664 [ui.debug log.extra|extra: branch=default]
2665 [ui.note log.description|description:]
2665 [ui.note log.description|description:]
2666 [ui.note log.description|no person]
2666 [ui.note log.description|no person]
2667
2667
2668
2668
2669 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2669 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2670 [log.bisect bisect.bad|bisect: bad]
2670 [log.bisect bisect.bad|bisect: bad]
2671 [log.phase|phase: public]
2671 [log.phase|phase: public]
2672 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2672 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2673 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2673 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2674 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2674 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2675 [log.user|user: person]
2675 [log.user|user: person]
2676 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2676 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2677 [ui.debug log.files|files: c]
2677 [ui.debug log.files|files: c]
2678 [ui.debug log.extra|extra: branch=default]
2678 [ui.debug log.extra|extra: branch=default]
2679 [ui.note log.description|description:]
2679 [ui.note log.description|description:]
2680 [ui.note log.description|no user, no domain]
2680 [ui.note log.description|no user, no domain]
2681
2681
2682
2682
2683 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2683 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2684 [log.bisect bisect.bad|bisect: bad (implicit)]
2684 [log.bisect bisect.bad|bisect: bad (implicit)]
2685 [log.branch|branch: foo]
2685 [log.branch|branch: foo]
2686 [log.phase|phase: draft]
2686 [log.phase|phase: draft]
2687 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2687 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2688 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2688 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2689 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2689 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2690 [log.user|user: person]
2690 [log.user|user: person]
2691 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2691 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2692 [ui.debug log.extra|extra: branch=foo]
2692 [ui.debug log.extra|extra: branch=foo]
2693 [ui.note log.description|description:]
2693 [ui.note log.description|description:]
2694 [ui.note log.description|new branch]
2694 [ui.note log.description|new branch]
2695
2695
2696
2696
2697 $ hg --color=debug log -v -T bisect -r 0:4
2697 $ hg --color=debug log -v -T bisect -r 0:4
2698 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2698 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2699 [log.bisect bisect.good|bisect: good (implicit)]
2699 [log.bisect bisect.good|bisect: good (implicit)]
2700 [log.user|user: User Name <user@hostname>]
2700 [log.user|user: User Name <user@hostname>]
2701 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2701 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2702 [ui.note log.files|files: a]
2702 [ui.note log.files|files: a]
2703 [ui.note log.description|description:]
2703 [ui.note log.description|description:]
2704 [ui.note log.description|line 1
2704 [ui.note log.description|line 1
2705 line 2]
2705 line 2]
2706
2706
2707
2707
2708 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2708 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2709 [log.bisect bisect.good|bisect: good]
2709 [log.bisect bisect.good|bisect: good]
2710 [log.user|user: A. N. Other <other@place>]
2710 [log.user|user: A. N. Other <other@place>]
2711 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2711 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2712 [ui.note log.files|files: b]
2712 [ui.note log.files|files: b]
2713 [ui.note log.description|description:]
2713 [ui.note log.description|description:]
2714 [ui.note log.description|other 1
2714 [ui.note log.description|other 1
2715 other 2
2715 other 2
2716
2716
2717 other 3]
2717 other 3]
2718
2718
2719
2719
2720 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2720 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2721 [log.bisect bisect.untested|bisect: untested]
2721 [log.bisect bisect.untested|bisect: untested]
2722 [log.user|user: other@place]
2722 [log.user|user: other@place]
2723 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2723 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2724 [ui.note log.files|files: c]
2724 [ui.note log.files|files: c]
2725 [ui.note log.description|description:]
2725 [ui.note log.description|description:]
2726 [ui.note log.description|no person]
2726 [ui.note log.description|no person]
2727
2727
2728
2728
2729 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2729 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2730 [log.bisect bisect.bad|bisect: bad]
2730 [log.bisect bisect.bad|bisect: bad]
2731 [log.user|user: person]
2731 [log.user|user: person]
2732 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2732 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2733 [ui.note log.files|files: c]
2733 [ui.note log.files|files: c]
2734 [ui.note log.description|description:]
2734 [ui.note log.description|description:]
2735 [ui.note log.description|no user, no domain]
2735 [ui.note log.description|no user, no domain]
2736
2736
2737
2737
2738 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2738 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2739 [log.bisect bisect.bad|bisect: bad (implicit)]
2739 [log.bisect bisect.bad|bisect: bad (implicit)]
2740 [log.branch|branch: foo]
2740 [log.branch|branch: foo]
2741 [log.user|user: person]
2741 [log.user|user: person]
2742 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2742 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2743 [ui.note log.description|description:]
2743 [ui.note log.description|description:]
2744 [ui.note log.description|new branch]
2744 [ui.note log.description|new branch]
2745
2745
2746
2746
2747 $ hg bisect --reset
2747 $ hg bisect --reset
2748
2748
2749 Error on syntax:
2749 Error on syntax:
2750
2750
2751 $ echo 'x = "f' >> t
2751 $ echo 'x = "f' >> t
2752 $ hg log
2752 $ hg log
2753 hg: parse error at t:3: unmatched quotes
2753 hg: parse error at t:3: unmatched quotes
2754 [255]
2754 [255]
2755
2755
2756 $ hg log -T '{date'
2756 $ hg log -T '{date'
2757 hg: parse error at 1: unterminated template expansion
2757 hg: parse error at 1: unterminated template expansion
2758 [255]
2758 [255]
2759
2759
2760 Behind the scenes, this will throw TypeError
2760 Behind the scenes, this will throw TypeError
2761
2761
2762 $ hg log -l 3 --template '{date|obfuscate}\n'
2762 $ hg log -l 3 --template '{date|obfuscate}\n'
2763 abort: template filter 'obfuscate' is not compatible with keyword 'date'
2763 abort: template filter 'obfuscate' is not compatible with keyword 'date'
2764 [255]
2764 [255]
2765
2765
2766 Behind the scenes, this will throw a ValueError
2766 Behind the scenes, this will throw a ValueError
2767
2767
2768 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2768 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2769 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2769 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2770 [255]
2770 [255]
2771
2771
2772 Behind the scenes, this will throw AttributeError
2772 Behind the scenes, this will throw AttributeError
2773
2773
2774 $ hg log -l 3 --template 'line: {date|escape}\n'
2774 $ hg log -l 3 --template 'line: {date|escape}\n'
2775 abort: template filter 'escape' is not compatible with keyword 'date'
2775 abort: template filter 'escape' is not compatible with keyword 'date'
2776 [255]
2776 [255]
2777
2777
2778 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2778 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2779 hg: parse error: localdate expects a date information
2779 hg: parse error: localdate expects a date information
2780 [255]
2780 [255]
2781
2781
2782 Behind the scenes, this will throw ValueError
2782 Behind the scenes, this will throw ValueError
2783
2783
2784 $ hg tip --template '{author|email|date}\n'
2784 $ hg tip --template '{author|email|date}\n'
2785 hg: parse error: date expects a date information
2785 hg: parse error: date expects a date information
2786 [255]
2786 [255]
2787
2787
2788 $ hg tip -T '{author|email|shortdate}\n'
2788 $ hg tip -T '{author|email|shortdate}\n'
2789 abort: template filter 'shortdate' is not compatible with keyword 'author'
2789 abort: template filter 'shortdate' is not compatible with keyword 'author'
2790 [255]
2790 [255]
2791
2791
2792 $ hg tip -T '{get(extras, "branch")|shortdate}\n'
2792 $ hg tip -T '{get(extras, "branch")|shortdate}\n'
2793 abort: incompatible use of template filter 'shortdate'
2793 abort: incompatible use of template filter 'shortdate'
2794 [255]
2794 [255]
2795
2795
2796 Error in nested template:
2796 Error in nested template:
2797
2797
2798 $ hg log -T '{"date'
2798 $ hg log -T '{"date'
2799 hg: parse error at 2: unterminated string
2799 hg: parse error at 2: unterminated string
2800 [255]
2800 [255]
2801
2801
2802 $ hg log -T '{"foo{date|?}"}'
2802 $ hg log -T '{"foo{date|?}"}'
2803 hg: parse error at 11: syntax error
2803 hg: parse error at 11: syntax error
2804 [255]
2804 [255]
2805
2805
2806 Thrown an error if a template function doesn't exist
2806 Thrown an error if a template function doesn't exist
2807
2807
2808 $ hg tip --template '{foo()}\n'
2808 $ hg tip --template '{foo()}\n'
2809 hg: parse error: unknown function 'foo'
2809 hg: parse error: unknown function 'foo'
2810 [255]
2810 [255]
2811
2811
2812 Pass generator object created by template function to filter
2812 Pass generator object created by template function to filter
2813
2813
2814 $ hg log -l 1 --template '{if(author, author)|user}\n'
2814 $ hg log -l 1 --template '{if(author, author)|user}\n'
2815 test
2815 test
2816
2816
2817 Test index keyword:
2817 Test index keyword:
2818
2818
2819 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
2819 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
2820 10 0:a 1:b 2:fifth 3:fourth 4:third
2820 10 0:a 1:b 2:fifth 3:fourth 4:third
2821 11 0:a
2821 11 0:a
2822
2822
2823 $ hg branches -T '{index} {branch}\n'
2823 $ hg branches -T '{index} {branch}\n'
2824 0 default
2824 0 default
2825 1 foo
2825 1 foo
2826
2826
2827 Test diff function:
2827 Test diff function:
2828
2828
2829 $ hg diff -c 8
2829 $ hg diff -c 8
2830 diff -r 29114dbae42b -r 95c24699272e fourth
2830 diff -r 29114dbae42b -r 95c24699272e fourth
2831 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2831 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2832 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2832 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2833 @@ -0,0 +1,1 @@
2833 @@ -0,0 +1,1 @@
2834 +second
2834 +second
2835 diff -r 29114dbae42b -r 95c24699272e second
2835 diff -r 29114dbae42b -r 95c24699272e second
2836 --- a/second Mon Jan 12 13:46:40 1970 +0000
2836 --- a/second Mon Jan 12 13:46:40 1970 +0000
2837 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2837 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2838 @@ -1,1 +0,0 @@
2838 @@ -1,1 +0,0 @@
2839 -second
2839 -second
2840 diff -r 29114dbae42b -r 95c24699272e third
2840 diff -r 29114dbae42b -r 95c24699272e third
2841 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2841 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2842 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2842 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2843 @@ -0,0 +1,1 @@
2843 @@ -0,0 +1,1 @@
2844 +third
2844 +third
2845
2845
2846 $ hg log -r 8 -T "{diff()}"
2846 $ hg log -r 8 -T "{diff()}"
2847 diff -r 29114dbae42b -r 95c24699272e fourth
2847 diff -r 29114dbae42b -r 95c24699272e fourth
2848 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2848 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2849 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2849 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2850 @@ -0,0 +1,1 @@
2850 @@ -0,0 +1,1 @@
2851 +second
2851 +second
2852 diff -r 29114dbae42b -r 95c24699272e second
2852 diff -r 29114dbae42b -r 95c24699272e second
2853 --- a/second Mon Jan 12 13:46:40 1970 +0000
2853 --- a/second Mon Jan 12 13:46:40 1970 +0000
2854 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2854 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2855 @@ -1,1 +0,0 @@
2855 @@ -1,1 +0,0 @@
2856 -second
2856 -second
2857 diff -r 29114dbae42b -r 95c24699272e third
2857 diff -r 29114dbae42b -r 95c24699272e third
2858 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2858 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2859 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2859 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2860 @@ -0,0 +1,1 @@
2860 @@ -0,0 +1,1 @@
2861 +third
2861 +third
2862
2862
2863 $ hg log -r 8 -T "{diff('glob:f*')}"
2863 $ hg log -r 8 -T "{diff('glob:f*')}"
2864 diff -r 29114dbae42b -r 95c24699272e fourth
2864 diff -r 29114dbae42b -r 95c24699272e fourth
2865 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2865 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2866 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2866 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2867 @@ -0,0 +1,1 @@
2867 @@ -0,0 +1,1 @@
2868 +second
2868 +second
2869
2869
2870 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2870 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2871 diff -r 29114dbae42b -r 95c24699272e second
2871 diff -r 29114dbae42b -r 95c24699272e second
2872 --- a/second Mon Jan 12 13:46:40 1970 +0000
2872 --- a/second Mon Jan 12 13:46:40 1970 +0000
2873 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2873 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2874 @@ -1,1 +0,0 @@
2874 @@ -1,1 +0,0 @@
2875 -second
2875 -second
2876 diff -r 29114dbae42b -r 95c24699272e third
2876 diff -r 29114dbae42b -r 95c24699272e third
2877 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2877 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2878 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2878 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2879 @@ -0,0 +1,1 @@
2879 @@ -0,0 +1,1 @@
2880 +third
2880 +third
2881
2881
2882 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2882 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2883 diff -r 29114dbae42b -r 95c24699272e fourth
2883 diff -r 29114dbae42b -r 95c24699272e fourth
2884 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2884 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2885 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2885 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2886 @@ -0,0 +1,1 @@
2886 @@ -0,0 +1,1 @@
2887 +second
2887 +second
2888
2888
2889 ui verbosity:
2889 ui verbosity:
2890
2890
2891 $ hg log -l1 -T '{verbosity}\n'
2891 $ hg log -l1 -T '{verbosity}\n'
2892
2892
2893 $ hg log -l1 -T '{verbosity}\n' --debug
2893 $ hg log -l1 -T '{verbosity}\n' --debug
2894 debug
2894 debug
2895 $ hg log -l1 -T '{verbosity}\n' --quiet
2895 $ hg log -l1 -T '{verbosity}\n' --quiet
2896 quiet
2896 quiet
2897 $ hg log -l1 -T '{verbosity}\n' --verbose
2897 $ hg log -l1 -T '{verbosity}\n' --verbose
2898 verbose
2898 verbose
2899
2899
2900 $ cd ..
2900 $ cd ..
2901
2901
2902
2902
2903 latesttag:
2903 latesttag:
2904
2904
2905 $ hg init latesttag
2905 $ hg init latesttag
2906 $ cd latesttag
2906 $ cd latesttag
2907
2907
2908 $ echo a > file
2908 $ echo a > file
2909 $ hg ci -Am a -d '0 0'
2909 $ hg ci -Am a -d '0 0'
2910 adding file
2910 adding file
2911
2911
2912 $ echo b >> file
2912 $ echo b >> file
2913 $ hg ci -m b -d '1 0'
2913 $ hg ci -m b -d '1 0'
2914
2914
2915 $ echo c >> head1
2915 $ echo c >> head1
2916 $ hg ci -Am h1c -d '2 0'
2916 $ hg ci -Am h1c -d '2 0'
2917 adding head1
2917 adding head1
2918
2918
2919 $ hg update -q 1
2919 $ hg update -q 1
2920 $ echo d >> head2
2920 $ echo d >> head2
2921 $ hg ci -Am h2d -d '3 0'
2921 $ hg ci -Am h2d -d '3 0'
2922 adding head2
2922 adding head2
2923 created new head
2923 created new head
2924
2924
2925 $ echo e >> head2
2925 $ echo e >> head2
2926 $ hg ci -m h2e -d '4 0'
2926 $ hg ci -m h2e -d '4 0'
2927
2927
2928 $ hg merge -q
2928 $ hg merge -q
2929 $ hg ci -m merge -d '5 -3600'
2929 $ hg ci -m merge -d '5 -3600'
2930
2930
2931 No tag set:
2931 No tag set:
2932
2932
2933 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2933 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2934 @ 5: null+5
2934 @ 5: null+5
2935 |\
2935 |\
2936 | o 4: null+4
2936 | o 4: null+4
2937 | |
2937 | |
2938 | o 3: null+3
2938 | o 3: null+3
2939 | |
2939 | |
2940 o | 2: null+3
2940 o | 2: null+3
2941 |/
2941 |/
2942 o 1: null+2
2942 o 1: null+2
2943 |
2943 |
2944 o 0: null+1
2944 o 0: null+1
2945
2945
2946
2946
2947 One common tag: longest path wins for {latesttagdistance}:
2947 One common tag: longest path wins for {latesttagdistance}:
2948
2948
2949 $ hg tag -r 1 -m t1 -d '6 0' t1
2949 $ hg tag -r 1 -m t1 -d '6 0' t1
2950 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2950 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2951 @ 6: t1+4
2951 @ 6: t1+4
2952 |
2952 |
2953 o 5: t1+3
2953 o 5: t1+3
2954 |\
2954 |\
2955 | o 4: t1+2
2955 | o 4: t1+2
2956 | |
2956 | |
2957 | o 3: t1+1
2957 | o 3: t1+1
2958 | |
2958 | |
2959 o | 2: t1+1
2959 o | 2: t1+1
2960 |/
2960 |/
2961 o 1: t1+0
2961 o 1: t1+0
2962 |
2962 |
2963 o 0: null+1
2963 o 0: null+1
2964
2964
2965
2965
2966 One ancestor tag: closest wins:
2966 One ancestor tag: closest wins:
2967
2967
2968 $ hg tag -r 2 -m t2 -d '7 0' t2
2968 $ hg tag -r 2 -m t2 -d '7 0' t2
2969 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2969 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2970 @ 7: t2+3
2970 @ 7: t2+3
2971 |
2971 |
2972 o 6: t2+2
2972 o 6: t2+2
2973 |
2973 |
2974 o 5: t2+1
2974 o 5: t2+1
2975 |\
2975 |\
2976 | o 4: t1+2
2976 | o 4: t1+2
2977 | |
2977 | |
2978 | o 3: t1+1
2978 | o 3: t1+1
2979 | |
2979 | |
2980 o | 2: t2+0
2980 o | 2: t2+0
2981 |/
2981 |/
2982 o 1: t1+0
2982 o 1: t1+0
2983 |
2983 |
2984 o 0: null+1
2984 o 0: null+1
2985
2985
2986
2986
2987 Two branch tags: more recent wins if same number of changes:
2987 Two branch tags: more recent wins if same number of changes:
2988
2988
2989 $ hg tag -r 3 -m t3 -d '8 0' t3
2989 $ hg tag -r 3 -m t3 -d '8 0' t3
2990 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2990 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2991 @ 8: t3+5
2991 @ 8: t3+5
2992 |
2992 |
2993 o 7: t3+4
2993 o 7: t3+4
2994 |
2994 |
2995 o 6: t3+3
2995 o 6: t3+3
2996 |
2996 |
2997 o 5: t3+2
2997 o 5: t3+2
2998 |\
2998 |\
2999 | o 4: t3+1
2999 | o 4: t3+1
3000 | |
3000 | |
3001 | o 3: t3+0
3001 | o 3: t3+0
3002 | |
3002 | |
3003 o | 2: t2+0
3003 o | 2: t2+0
3004 |/
3004 |/
3005 o 1: t1+0
3005 o 1: t1+0
3006 |
3006 |
3007 o 0: null+1
3007 o 0: null+1
3008
3008
3009
3009
3010 Two branch tags: fewest changes wins:
3010 Two branch tags: fewest changes wins:
3011
3011
3012 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
3012 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
3013 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3013 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3014 @ 9: t4+5,6
3014 @ 9: t4+5,6
3015 |
3015 |
3016 o 8: t4+4,5
3016 o 8: t4+4,5
3017 |
3017 |
3018 o 7: t4+3,4
3018 o 7: t4+3,4
3019 |
3019 |
3020 o 6: t4+2,3
3020 o 6: t4+2,3
3021 |
3021 |
3022 o 5: t4+1,2
3022 o 5: t4+1,2
3023 |\
3023 |\
3024 | o 4: t4+0,0
3024 | o 4: t4+0,0
3025 | |
3025 | |
3026 | o 3: t3+0,0
3026 | o 3: t3+0,0
3027 | |
3027 | |
3028 o | 2: t2+0,0
3028 o | 2: t2+0,0
3029 |/
3029 |/
3030 o 1: t1+0,0
3030 o 1: t1+0,0
3031 |
3031 |
3032 o 0: null+1,1
3032 o 0: null+1,1
3033
3033
3034
3034
3035 Merged tag overrides:
3035 Merged tag overrides:
3036
3036
3037 $ hg tag -r 5 -m t5 -d '9 0' t5
3037 $ hg tag -r 5 -m t5 -d '9 0' t5
3038 $ hg tag -r 3 -m at3 -d '10 0' at3
3038 $ hg tag -r 3 -m at3 -d '10 0' at3
3039 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3039 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3040 @ 11: t5+6
3040 @ 11: t5+6
3041 |
3041 |
3042 o 10: t5+5
3042 o 10: t5+5
3043 |
3043 |
3044 o 9: t5+4
3044 o 9: t5+4
3045 |
3045 |
3046 o 8: t5+3
3046 o 8: t5+3
3047 |
3047 |
3048 o 7: t5+2
3048 o 7: t5+2
3049 |
3049 |
3050 o 6: t5+1
3050 o 6: t5+1
3051 |
3051 |
3052 o 5: t5+0
3052 o 5: t5+0
3053 |\
3053 |\
3054 | o 4: t4+0
3054 | o 4: t4+0
3055 | |
3055 | |
3056 | o 3: at3:t3+0
3056 | o 3: at3:t3+0
3057 | |
3057 | |
3058 o | 2: t2+0
3058 o | 2: t2+0
3059 |/
3059 |/
3060 o 1: t1+0
3060 o 1: t1+0
3061 |
3061 |
3062 o 0: null+1
3062 o 0: null+1
3063
3063
3064
3064
3065 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3065 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3066 @ 11: t5+6,6
3066 @ 11: t5+6,6
3067 |
3067 |
3068 o 10: t5+5,5
3068 o 10: t5+5,5
3069 |
3069 |
3070 o 9: t5+4,4
3070 o 9: t5+4,4
3071 |
3071 |
3072 o 8: t5+3,3
3072 o 8: t5+3,3
3073 |
3073 |
3074 o 7: t5+2,2
3074 o 7: t5+2,2
3075 |
3075 |
3076 o 6: t5+1,1
3076 o 6: t5+1,1
3077 |
3077 |
3078 o 5: t5+0,0
3078 o 5: t5+0,0
3079 |\
3079 |\
3080 | o 4: t4+0,0
3080 | o 4: t4+0,0
3081 | |
3081 | |
3082 | o 3: at3+0,0 t3+0,0
3082 | o 3: at3+0,0 t3+0,0
3083 | |
3083 | |
3084 o | 2: t2+0,0
3084 o | 2: t2+0,0
3085 |/
3085 |/
3086 o 1: t1+0,0
3086 o 1: t1+0,0
3087 |
3087 |
3088 o 0: null+1,1
3088 o 0: null+1,1
3089
3089
3090
3090
3091 $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
3091 $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
3092 @ 11: t3, C: 9, D: 8
3092 @ 11: t3, C: 9, D: 8
3093 |
3093 |
3094 o 10: t3, C: 8, D: 7
3094 o 10: t3, C: 8, D: 7
3095 |
3095 |
3096 o 9: t3, C: 7, D: 6
3096 o 9: t3, C: 7, D: 6
3097 |
3097 |
3098 o 8: t3, C: 6, D: 5
3098 o 8: t3, C: 6, D: 5
3099 |
3099 |
3100 o 7: t3, C: 5, D: 4
3100 o 7: t3, C: 5, D: 4
3101 |
3101 |
3102 o 6: t3, C: 4, D: 3
3102 o 6: t3, C: 4, D: 3
3103 |
3103 |
3104 o 5: t3, C: 3, D: 2
3104 o 5: t3, C: 3, D: 2
3105 |\
3105 |\
3106 | o 4: t3, C: 1, D: 1
3106 | o 4: t3, C: 1, D: 1
3107 | |
3107 | |
3108 | o 3: t3, C: 0, D: 0
3108 | o 3: t3, C: 0, D: 0
3109 | |
3109 | |
3110 o | 2: t1, C: 1, D: 1
3110 o | 2: t1, C: 1, D: 1
3111 |/
3111 |/
3112 o 1: t1, C: 0, D: 0
3112 o 1: t1, C: 0, D: 0
3113 |
3113 |
3114 o 0: null, C: 1, D: 1
3114 o 0: null, C: 1, D: 1
3115
3115
3116
3116
3117 $ cd ..
3117 $ cd ..
3118
3118
3119
3119
3120 Style path expansion: issue1948 - ui.style option doesn't work on OSX
3120 Style path expansion: issue1948 - ui.style option doesn't work on OSX
3121 if it is a relative path
3121 if it is a relative path
3122
3122
3123 $ mkdir -p home/styles
3123 $ mkdir -p home/styles
3124
3124
3125 $ cat > home/styles/teststyle <<EOF
3125 $ cat > home/styles/teststyle <<EOF
3126 > changeset = 'test {rev}:{node|short}\n'
3126 > changeset = 'test {rev}:{node|short}\n'
3127 > EOF
3127 > EOF
3128
3128
3129 $ HOME=`pwd`/home; export HOME
3129 $ HOME=`pwd`/home; export HOME
3130
3130
3131 $ cat > latesttag/.hg/hgrc <<EOF
3131 $ cat > latesttag/.hg/hgrc <<EOF
3132 > [ui]
3132 > [ui]
3133 > style = ~/styles/teststyle
3133 > style = ~/styles/teststyle
3134 > EOF
3134 > EOF
3135
3135
3136 $ hg -R latesttag tip
3136 $ hg -R latesttag tip
3137 test 11:97e5943b523a
3137 test 11:97e5943b523a
3138
3138
3139 Test recursive showlist template (issue1989):
3139 Test recursive showlist template (issue1989):
3140
3140
3141 $ cat > style1989 <<EOF
3141 $ cat > style1989 <<EOF
3142 > changeset = '{file_mods}{manifest}{extras}'
3142 > changeset = '{file_mods}{manifest}{extras}'
3143 > file_mod = 'M|{author|person}\n'
3143 > file_mod = 'M|{author|person}\n'
3144 > manifest = '{rev},{author}\n'
3144 > manifest = '{rev},{author}\n'
3145 > extra = '{key}: {author}\n'
3145 > extra = '{key}: {author}\n'
3146 > EOF
3146 > EOF
3147
3147
3148 $ hg -R latesttag log -r tip --style=style1989
3148 $ hg -R latesttag log -r tip --style=style1989
3149 M|test
3149 M|test
3150 11,test
3150 11,test
3151 branch: test
3151 branch: test
3152
3152
3153 Test new-style inline templating:
3153 Test new-style inline templating:
3154
3154
3155 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
3155 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
3156 modified files: .hgtags
3156 modified files: .hgtags
3157
3157
3158
3158
3159 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
3159 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
3160 hg: parse error: keyword 'rev' is not iterable
3160 hg: parse error: keyword 'rev' is not iterable
3161 [255]
3161 [255]
3162 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
3162 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
3163 hg: parse error: None is not iterable
3163 hg: parse error: None is not iterable
3164 [255]
3164 [255]
3165
3165
3166 Test new-style inline templating of non-list/dict type:
3166 Test new-style inline templating of non-list/dict type:
3167
3167
3168 $ hg log -R latesttag -r tip -T '{manifest}\n'
3168 $ hg log -R latesttag -r tip -T '{manifest}\n'
3169 11:2bc6e9006ce2
3169 11:2bc6e9006ce2
3170 $ hg log -R latesttag -r tip -T 'string length: {manifest|count}\n'
3170 $ hg log -R latesttag -r tip -T 'string length: {manifest|count}\n'
3171 string length: 15
3171 string length: 15
3172 $ hg log -R latesttag -r tip -T '{manifest % "{rev}:{node}"}\n'
3172 $ hg log -R latesttag -r tip -T '{manifest % "{rev}:{node}"}\n'
3173 11:2bc6e9006ce29882383a22d39fd1f4e66dd3e2fc
3173 11:2bc6e9006ce29882383a22d39fd1f4e66dd3e2fc
3174
3174
3175 $ hg log -R latesttag -r tip -T '{get(extras, "branch") % "{key}: {value}\n"}'
3175 $ hg log -R latesttag -r tip -T '{get(extras, "branch") % "{key}: {value}\n"}'
3176 branch: default
3176 branch: default
3177 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "{key}\n"}'
3177 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "{key}\n"}'
3178 hg: parse error: None is not iterable
3178 hg: parse error: None is not iterable
3179 [255]
3179 [255]
3180 $ hg log -R latesttag -r tip -T '{min(extras) % "{key}: {value}\n"}'
3180 $ hg log -R latesttag -r tip -T '{min(extras) % "{key}: {value}\n"}'
3181 branch: default
3181 branch: default
3182 $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}'
3182 $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}'
3183 0:ce3cec86e6c2
3183 0:ce3cec86e6c2
3184 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
3184 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
3185 9:fbc7cd862e9c
3185 9:fbc7cd862e9c
3186
3186
3187 Test manifest/get() can be join()-ed as before, though it's silly:
3187 Test manifest/get() can be join()-ed as before, though it's silly:
3188
3188
3189 $ hg log -R latesttag -r tip -T '{join(manifest, "")}\n'
3189 $ hg log -R latesttag -r tip -T '{join(manifest, "")}\n'
3190 11:2bc6e9006ce2
3190 11:2bc6e9006ce2
3191 $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), "")}\n'
3191 $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), "")}\n'
3192 default
3192 default
3193
3193
3194 Test min/max of integers
3194 Test min/max of integers
3195
3195
3196 $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'
3196 $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'
3197 9
3197 9
3198 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
3198 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
3199 10
3199 10
3200
3200
3201 Test dot operator precedence:
3201 Test dot operator precedence:
3202
3202
3203 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
3203 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
3204 (template
3204 (template
3205 (|
3205 (|
3206 (.
3206 (.
3207 (symbol 'manifest')
3207 (symbol 'manifest')
3208 (symbol 'node'))
3208 (symbol 'node'))
3209 (symbol 'short'))
3209 (symbol 'short'))
3210 (string '\n'))
3210 (string '\n'))
3211 89f4071fec70
3211 89f4071fec70
3212
3212
3213 (the following examples are invalid, but seem natural in parsing POV)
3213 (the following examples are invalid, but seem natural in parsing POV)
3214
3214
3215 $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null
3215 $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null
3216 (template
3216 (template
3217 (|
3217 (|
3218 (symbol 'foo')
3218 (symbol 'foo')
3219 (.
3219 (.
3220 (symbol 'bar')
3220 (symbol 'bar')
3221 (symbol 'baz')))
3221 (symbol 'baz')))
3222 (string '\n'))
3222 (string '\n'))
3223 [255]
3223 [255]
3224 $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null
3224 $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null
3225 (template
3225 (template
3226 (.
3226 (.
3227 (symbol 'foo')
3227 (symbol 'foo')
3228 (func
3228 (func
3229 (symbol 'bar')
3229 (symbol 'bar')
3230 None))
3230 None))
3231 (string '\n'))
3231 (string '\n'))
3232 [255]
3232 [255]
3233
3233
3234 Test evaluation of dot operator:
3234 Test evaluation of dot operator:
3235
3235
3236 $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n'
3236 $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n'
3237 ce3cec86e6c26bd9bdfc590a6b92abc9680f1796
3237 ce3cec86e6c26bd9bdfc590a6b92abc9680f1796
3238 $ hg log -R latesttag -r0 -T '{extras.branch}\n'
3238 $ hg log -R latesttag -r0 -T '{extras.branch}\n'
3239 default
3239 default
3240
3240
3241 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
3241 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
3242 hg: parse error: keyword 'author' has no member
3242 hg: parse error: keyword 'author' has no member
3243 [255]
3243 [255]
3244 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
3244 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
3245 hg: parse error: 'a' has no member
3245 hg: parse error: 'a' has no member
3246 [255]
3246 [255]
3247
3247
3248 Test the sub function of templating for expansion:
3248 Test the sub function of templating for expansion:
3249
3249
3250 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
3250 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
3251 xx
3251 xx
3252
3252
3253 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
3253 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
3254 hg: parse error: sub got an invalid pattern: [
3254 hg: parse error: sub got an invalid pattern: [
3255 [255]
3255 [255]
3256 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
3256 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
3257 hg: parse error: sub got an invalid replacement: \1
3257 hg: parse error: sub got an invalid replacement: \1
3258 [255]
3258 [255]
3259
3259
3260 Test the strip function with chars specified:
3260 Test the strip function with chars specified:
3261
3261
3262 $ hg log -R latesttag --template '{desc}\n'
3262 $ hg log -R latesttag --template '{desc}\n'
3263 at3
3263 at3
3264 t5
3264 t5
3265 t4
3265 t4
3266 t3
3266 t3
3267 t2
3267 t2
3268 t1
3268 t1
3269 merge
3269 merge
3270 h2e
3270 h2e
3271 h2d
3271 h2d
3272 h1c
3272 h1c
3273 b
3273 b
3274 a
3274 a
3275
3275
3276 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
3276 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
3277 at3
3277 at3
3278 5
3278 5
3279 4
3279 4
3280 3
3280 3
3281 2
3281 2
3282 1
3282 1
3283 merg
3283 merg
3284 h2
3284 h2
3285 h2d
3285 h2d
3286 h1c
3286 h1c
3287 b
3287 b
3288 a
3288 a
3289
3289
3290 Test date format:
3290 Test date format:
3291
3291
3292 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
3292 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
3293 date: 70 01 01 10 +0000
3293 date: 70 01 01 10 +0000
3294 date: 70 01 01 09 +0000
3294 date: 70 01 01 09 +0000
3295 date: 70 01 01 04 +0000
3295 date: 70 01 01 04 +0000
3296 date: 70 01 01 08 +0000
3296 date: 70 01 01 08 +0000
3297 date: 70 01 01 07 +0000
3297 date: 70 01 01 07 +0000
3298 date: 70 01 01 06 +0000
3298 date: 70 01 01 06 +0000
3299 date: 70 01 01 05 +0100
3299 date: 70 01 01 05 +0100
3300 date: 70 01 01 04 +0000
3300 date: 70 01 01 04 +0000
3301 date: 70 01 01 03 +0000
3301 date: 70 01 01 03 +0000
3302 date: 70 01 01 02 +0000
3302 date: 70 01 01 02 +0000
3303 date: 70 01 01 01 +0000
3303 date: 70 01 01 01 +0000
3304 date: 70 01 01 00 +0000
3304 date: 70 01 01 00 +0000
3305
3305
3306 Test invalid date:
3306 Test invalid date:
3307
3307
3308 $ hg log -R latesttag -T '{date(rev)}\n'
3308 $ hg log -R latesttag -T '{date(rev)}\n'
3309 hg: parse error: date expects a date information
3309 hg: parse error: date expects a date information
3310 [255]
3310 [255]
3311
3311
3312 Test integer literal:
3312 Test integer literal:
3313
3313
3314 $ hg debugtemplate -v '{(0)}\n'
3314 $ hg debugtemplate -v '{(0)}\n'
3315 (template
3315 (template
3316 (group
3316 (group
3317 (integer '0'))
3317 (integer '0'))
3318 (string '\n'))
3318 (string '\n'))
3319 0
3319 0
3320 $ hg debugtemplate -v '{(123)}\n'
3320 $ hg debugtemplate -v '{(123)}\n'
3321 (template
3321 (template
3322 (group
3322 (group
3323 (integer '123'))
3323 (integer '123'))
3324 (string '\n'))
3324 (string '\n'))
3325 123
3325 123
3326 $ hg debugtemplate -v '{(-4)}\n'
3326 $ hg debugtemplate -v '{(-4)}\n'
3327 (template
3327 (template
3328 (group
3328 (group
3329 (negate
3329 (negate
3330 (integer '4')))
3330 (integer '4')))
3331 (string '\n'))
3331 (string '\n'))
3332 -4
3332 -4
3333 $ hg debugtemplate '{(-)}\n'
3333 $ hg debugtemplate '{(-)}\n'
3334 hg: parse error at 3: not a prefix: )
3334 hg: parse error at 3: not a prefix: )
3335 [255]
3335 [255]
3336 $ hg debugtemplate '{(-a)}\n'
3336 $ hg debugtemplate '{(-a)}\n'
3337 hg: parse error: negation needs an integer argument
3337 hg: parse error: negation needs an integer argument
3338 [255]
3338 [255]
3339
3339
3340 top-level integer literal is interpreted as symbol (i.e. variable name):
3340 top-level integer literal is interpreted as symbol (i.e. variable name):
3341
3341
3342 $ hg debugtemplate -D 1=one -v '{1}\n'
3342 $ hg debugtemplate -D 1=one -v '{1}\n'
3343 (template
3343 (template
3344 (integer '1')
3344 (integer '1')
3345 (string '\n'))
3345 (string '\n'))
3346 one
3346 one
3347 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
3347 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
3348 (template
3348 (template
3349 (func
3349 (func
3350 (symbol 'if')
3350 (symbol 'if')
3351 (list
3351 (list
3352 (string 't')
3352 (string 't')
3353 (template
3353 (template
3354 (integer '1'))))
3354 (integer '1'))))
3355 (string '\n'))
3355 (string '\n'))
3356 one
3356 one
3357 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
3357 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
3358 (template
3358 (template
3359 (|
3359 (|
3360 (integer '1')
3360 (integer '1')
3361 (symbol 'stringify'))
3361 (symbol 'stringify'))
3362 (string '\n'))
3362 (string '\n'))
3363 one
3363 one
3364
3364
3365 unless explicit symbol is expected:
3365 unless explicit symbol is expected:
3366
3366
3367 $ hg log -Ra -r0 -T '{desc|1}\n'
3367 $ hg log -Ra -r0 -T '{desc|1}\n'
3368 hg: parse error: expected a symbol, got 'integer'
3368 hg: parse error: expected a symbol, got 'integer'
3369 [255]
3369 [255]
3370 $ hg log -Ra -r0 -T '{1()}\n'
3370 $ hg log -Ra -r0 -T '{1()}\n'
3371 hg: parse error: expected a symbol, got 'integer'
3371 hg: parse error: expected a symbol, got 'integer'
3372 [255]
3372 [255]
3373
3373
3374 Test string literal:
3374 Test string literal:
3375
3375
3376 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
3376 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
3377 (template
3377 (template
3378 (string 'string with no template fragment')
3378 (string 'string with no template fragment')
3379 (string '\n'))
3379 (string '\n'))
3380 string with no template fragment
3380 string with no template fragment
3381 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
3381 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
3382 (template
3382 (template
3383 (template
3383 (template
3384 (string 'template: ')
3384 (string 'template: ')
3385 (symbol 'rev'))
3385 (symbol 'rev'))
3386 (string '\n'))
3386 (string '\n'))
3387 template: 0
3387 template: 0
3388 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
3388 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
3389 (template
3389 (template
3390 (string 'rawstring: {rev}')
3390 (string 'rawstring: {rev}')
3391 (string '\n'))
3391 (string '\n'))
3392 rawstring: {rev}
3392 rawstring: {rev}
3393 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
3393 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
3394 (template
3394 (template
3395 (%
3395 (%
3396 (symbol 'files')
3396 (symbol 'files')
3397 (string 'rawstring: {file}'))
3397 (string 'rawstring: {file}'))
3398 (string '\n'))
3398 (string '\n'))
3399 rawstring: {file}
3399 rawstring: {file}
3400
3400
3401 Test string escaping:
3401 Test string escaping:
3402
3402
3403 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3403 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3404 >
3404 >
3405 <>\n<[>
3405 <>\n<[>
3406 <>\n<]>
3406 <>\n<]>
3407 <>\n<
3407 <>\n<
3408
3408
3409 $ hg log -R latesttag -r 0 \
3409 $ hg log -R latesttag -r 0 \
3410 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3410 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3411 >
3411 >
3412 <>\n<[>
3412 <>\n<[>
3413 <>\n<]>
3413 <>\n<]>
3414 <>\n<
3414 <>\n<
3415
3415
3416 $ hg log -R latesttag -r 0 -T esc \
3416 $ hg log -R latesttag -r 0 -T esc \
3417 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3417 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3418 >
3418 >
3419 <>\n<[>
3419 <>\n<[>
3420 <>\n<]>
3420 <>\n<]>
3421 <>\n<
3421 <>\n<
3422
3422
3423 $ cat <<'EOF' > esctmpl
3423 $ cat <<'EOF' > esctmpl
3424 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3424 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3425 > EOF
3425 > EOF
3426 $ hg log -R latesttag -r 0 --style ./esctmpl
3426 $ hg log -R latesttag -r 0 --style ./esctmpl
3427 >
3427 >
3428 <>\n<[>
3428 <>\n<[>
3429 <>\n<]>
3429 <>\n<]>
3430 <>\n<
3430 <>\n<
3431
3431
3432 Test string escaping of quotes:
3432 Test string escaping of quotes:
3433
3433
3434 $ hg log -Ra -r0 -T '{"\""}\n'
3434 $ hg log -Ra -r0 -T '{"\""}\n'
3435 "
3435 "
3436 $ hg log -Ra -r0 -T '{"\\\""}\n'
3436 $ hg log -Ra -r0 -T '{"\\\""}\n'
3437 \"
3437 \"
3438 $ hg log -Ra -r0 -T '{r"\""}\n'
3438 $ hg log -Ra -r0 -T '{r"\""}\n'
3439 \"
3439 \"
3440 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3440 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3441 \\\"
3441 \\\"
3442
3442
3443
3443
3444 $ hg log -Ra -r0 -T '{"\""}\n'
3444 $ hg log -Ra -r0 -T '{"\""}\n'
3445 "
3445 "
3446 $ hg log -Ra -r0 -T '{"\\\""}\n'
3446 $ hg log -Ra -r0 -T '{"\\\""}\n'
3447 \"
3447 \"
3448 $ hg log -Ra -r0 -T '{r"\""}\n'
3448 $ hg log -Ra -r0 -T '{r"\""}\n'
3449 \"
3449 \"
3450 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3450 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3451 \\\"
3451 \\\"
3452
3452
3453 Test exception in quoted template. single backslash before quotation mark is
3453 Test exception in quoted template. single backslash before quotation mark is
3454 stripped before parsing:
3454 stripped before parsing:
3455
3455
3456 $ cat <<'EOF' > escquotetmpl
3456 $ cat <<'EOF' > escquotetmpl
3457 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
3457 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
3458 > EOF
3458 > EOF
3459 $ cd latesttag
3459 $ cd latesttag
3460 $ hg log -r 2 --style ../escquotetmpl
3460 $ hg log -r 2 --style ../escquotetmpl
3461 " \" \" \\" head1
3461 " \" \" \\" head1
3462
3462
3463 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
3463 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
3464 valid
3464 valid
3465 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
3465 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
3466 valid
3466 valid
3467
3467
3468 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
3468 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
3469 _evalifliteral() templates (issue4733):
3469 _evalifliteral() templates (issue4733):
3470
3470
3471 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
3471 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
3472 "2
3472 "2
3473 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
3473 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
3474 "2
3474 "2
3475 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
3475 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
3476 "2
3476 "2
3477
3477
3478 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
3478 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
3479 \"
3479 \"
3480 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
3480 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
3481 \"
3481 \"
3482 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3482 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3483 \"
3483 \"
3484
3484
3485 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
3485 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
3486 \\\"
3486 \\\"
3487 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
3487 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
3488 \\\"
3488 \\\"
3489 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3489 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3490 \\\"
3490 \\\"
3491
3491
3492 escaped single quotes and errors:
3492 escaped single quotes and errors:
3493
3493
3494 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
3494 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
3495 foo
3495 foo
3496 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
3496 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
3497 foo
3497 foo
3498 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3498 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3499 hg: parse error at 21: unterminated string
3499 hg: parse error at 21: unterminated string
3500 [255]
3500 [255]
3501 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3501 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3502 hg: parse error: trailing \ in string
3502 hg: parse error: trailing \ in string
3503 [255]
3503 [255]
3504 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3504 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3505 hg: parse error: trailing \ in string
3505 hg: parse error: trailing \ in string
3506 [255]
3506 [255]
3507
3507
3508 $ cd ..
3508 $ cd ..
3509
3509
3510 Test leading backslashes:
3510 Test leading backslashes:
3511
3511
3512 $ cd latesttag
3512 $ cd latesttag
3513 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3513 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3514 {rev} {file}
3514 {rev} {file}
3515 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3515 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3516 \2 \head1
3516 \2 \head1
3517 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3517 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3518 \{rev} \{file}
3518 \{rev} \{file}
3519 $ cd ..
3519 $ cd ..
3520
3520
3521 Test leading backslashes in "if" expression (issue4714):
3521 Test leading backslashes in "if" expression (issue4714):
3522
3522
3523 $ cd latesttag
3523 $ cd latesttag
3524 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3524 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3525 {rev} \{rev}
3525 {rev} \{rev}
3526 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3526 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3527 \2 \\{rev}
3527 \2 \\{rev}
3528 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3528 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3529 \{rev} \\\{rev}
3529 \{rev} \\\{rev}
3530 $ cd ..
3530 $ cd ..
3531
3531
3532 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3532 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3533
3533
3534 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3534 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3535 \x6e
3535 \x6e
3536 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3536 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3537 \x5c\x786e
3537 \x5c\x786e
3538 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3538 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3539 \x6e
3539 \x6e
3540 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3540 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3541 \x5c\x786e
3541 \x5c\x786e
3542
3542
3543 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3543 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3544 \x6e
3544 \x6e
3545 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3545 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3546 \x5c\x786e
3546 \x5c\x786e
3547 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3547 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3548 \x6e
3548 \x6e
3549 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3549 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3550 \x5c\x786e
3550 \x5c\x786e
3551
3551
3552 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3552 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3553 fourth
3553 fourth
3554 second
3554 second
3555 third
3555 third
3556 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3556 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3557 fourth\nsecond\nthird
3557 fourth\nsecond\nthird
3558
3558
3559 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3559 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3560 <p>
3560 <p>
3561 1st
3561 1st
3562 </p>
3562 </p>
3563 <p>
3563 <p>
3564 2nd
3564 2nd
3565 </p>
3565 </p>
3566 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3566 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3567 <p>
3567 <p>
3568 1st\n\n2nd
3568 1st\n\n2nd
3569 </p>
3569 </p>
3570 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3570 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3571 1st
3571 1st
3572
3572
3573 2nd
3573 2nd
3574
3574
3575 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3575 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3576 o perso
3576 o perso
3577 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3577 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3578 no person
3578 no person
3579 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3579 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3580 o perso
3580 o perso
3581 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3581 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3582 no perso
3582 no perso
3583
3583
3584 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3584 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3585 -o perso-
3585 -o perso-
3586 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3586 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3587 no person
3587 no person
3588 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3588 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3589 \x2do perso\x2d
3589 \x2do perso\x2d
3590 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3590 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3591 -o perso-
3591 -o perso-
3592 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3592 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3593 \x2do perso\x6e
3593 \x2do perso\x6e
3594
3594
3595 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3595 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3596 fourth
3596 fourth
3597 second
3597 second
3598 third
3598 third
3599
3599
3600 Test string escaping in nested expression:
3600 Test string escaping in nested expression:
3601
3601
3602 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3602 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3603 fourth\x6esecond\x6ethird
3603 fourth\x6esecond\x6ethird
3604 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3604 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3605 fourth\x6esecond\x6ethird
3605 fourth\x6esecond\x6ethird
3606
3606
3607 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3607 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3608 fourth\x6esecond\x6ethird
3608 fourth\x6esecond\x6ethird
3609 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3609 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3610 fourth\x5c\x786esecond\x5c\x786ethird
3610 fourth\x5c\x786esecond\x5c\x786ethird
3611
3611
3612 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3612 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3613 3:\x6eo user, \x6eo domai\x6e
3613 3:\x6eo user, \x6eo domai\x6e
3614 4:\x5c\x786eew bra\x5c\x786ech
3614 4:\x5c\x786eew bra\x5c\x786ech
3615
3615
3616 Test quotes in nested expression are evaluated just like a $(command)
3616 Test quotes in nested expression are evaluated just like a $(command)
3617 substitution in POSIX shells:
3617 substitution in POSIX shells:
3618
3618
3619 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3619 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3620 8:95c24699272e
3620 8:95c24699272e
3621 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3621 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3622 {8} "95c24699272e"
3622 {8} "95c24699272e"
3623
3623
3624 Test recursive evaluation:
3624 Test recursive evaluation:
3625
3625
3626 $ hg init r
3626 $ hg init r
3627 $ cd r
3627 $ cd r
3628 $ echo a > a
3628 $ echo a > a
3629 $ hg ci -Am '{rev}'
3629 $ hg ci -Am '{rev}'
3630 adding a
3630 adding a
3631 $ hg log -r 0 --template '{if(rev, desc)}\n'
3631 $ hg log -r 0 --template '{if(rev, desc)}\n'
3632 {rev}
3632 {rev}
3633 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3633 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3634 test 0
3634 test 0
3635
3635
3636 $ hg branch -q 'text.{rev}'
3636 $ hg branch -q 'text.{rev}'
3637 $ echo aa >> aa
3637 $ echo aa >> aa
3638 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3638 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3639
3639
3640 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3640 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3641 {node|short}desc to
3641 {node|short}desc to
3642 text.{rev}be wrapped
3642 text.{rev}be wrapped
3643 text.{rev}desc to be
3643 text.{rev}desc to be
3644 text.{rev}wrapped (no-eol)
3644 text.{rev}wrapped (no-eol)
3645 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3645 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3646 bcc7ff960b8e:desc to
3646 bcc7ff960b8e:desc to
3647 text.1:be wrapped
3647 text.1:be wrapped
3648 text.1:desc to be
3648 text.1:desc to be
3649 text.1:wrapped (no-eol)
3649 text.1:wrapped (no-eol)
3650 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3650 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3651 hg: parse error: fill expects an integer width
3651 hg: parse error: fill expects an integer width
3652 [255]
3652 [255]
3653
3653
3654 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
3654 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
3655 bcc7ff960b8e:desc to be
3655 bcc7ff960b8e:desc to be
3656 termwidth.1:wrapped desc
3656 termwidth.1:wrapped desc
3657 termwidth.1:to be wrapped (no-eol)
3657 termwidth.1:to be wrapped (no-eol)
3658
3658
3659 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3659 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3660 {node|short} (no-eol)
3660 {node|short} (no-eol)
3661 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3661 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3662 bcc-ff---b-e (no-eol)
3662 bcc-ff---b-e (no-eol)
3663
3663
3664 $ cat >> .hg/hgrc <<EOF
3664 $ cat >> .hg/hgrc <<EOF
3665 > [extensions]
3665 > [extensions]
3666 > color=
3666 > color=
3667 > [color]
3667 > [color]
3668 > mode=ansi
3668 > mode=ansi
3669 > text.{rev} = red
3669 > text.{rev} = red
3670 > text.1 = green
3670 > text.1 = green
3671 > EOF
3671 > EOF
3672 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3672 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3673 \x1b[0;31mtext\x1b[0m (esc)
3673 \x1b[0;31mtext\x1b[0m (esc)
3674 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3674 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3675 \x1b[0;32mtext\x1b[0m (esc)
3675 \x1b[0;32mtext\x1b[0m (esc)
3676
3676
3677 color effect can be specified without quoting:
3677 color effect can be specified without quoting:
3678
3678
3679 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
3679 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
3680 \x1b[0;31mtext\x1b[0m (esc)
3680 \x1b[0;31mtext\x1b[0m (esc)
3681
3681
3682 color effects can be nested (issue5413)
3682 color effects can be nested (issue5413)
3683
3683
3684 $ hg debugtemplate --color=always \
3684 $ hg debugtemplate --color=always \
3685 > '{label(red, "red{label(magenta, "ma{label(cyan, "cyan")}{label(yellow, "yellow")}genta")}")}\n'
3685 > '{label(red, "red{label(magenta, "ma{label(cyan, "cyan")}{label(yellow, "yellow")}genta")}")}\n'
3686 \x1b[0;31mred\x1b[0;35mma\x1b[0;36mcyan\x1b[0m\x1b[0;31m\x1b[0;35m\x1b[0;33myellow\x1b[0m\x1b[0;31m\x1b[0;35mgenta\x1b[0m (esc)
3686 \x1b[0;31mred\x1b[0;35mma\x1b[0;36mcyan\x1b[0m\x1b[0;31m\x1b[0;35m\x1b[0;33myellow\x1b[0m\x1b[0;31m\x1b[0;35mgenta\x1b[0m (esc)
3687
3687
3688 pad() should interact well with color codes (issue5416)
3688 pad() should interact well with color codes (issue5416)
3689
3689
3690 $ hg debugtemplate --color=always \
3690 $ hg debugtemplate --color=always \
3691 > '{pad(label(red, "red"), 5, label(cyan, "-"))}\n'
3691 > '{pad(label(red, "red"), 5, label(cyan, "-"))}\n'
3692 \x1b[0;31mred\x1b[0m\x1b[0;36m-\x1b[0m\x1b[0;36m-\x1b[0m (esc)
3692 \x1b[0;31mred\x1b[0m\x1b[0;36m-\x1b[0m\x1b[0;36m-\x1b[0m (esc)
3693
3693
3694 label should be no-op if color is disabled:
3694 label should be no-op if color is disabled:
3695
3695
3696 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
3696 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
3697 text
3697 text
3698 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
3698 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
3699 text
3699 text
3700
3700
3701 Test branches inside if statement:
3701 Test branches inside if statement:
3702
3702
3703 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3703 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3704 no
3704 no
3705
3705
3706 Test dict constructor:
3706 Test dict constructor:
3707
3707
3708 $ hg log -r 0 -T '{dict(y=node|short, x=rev)}\n'
3708 $ hg log -r 0 -T '{dict(y=node|short, x=rev)}\n'
3709 y=f7769ec2ab97 x=0
3709 y=f7769ec2ab97 x=0
3710 $ hg log -r 0 -T '{dict(x=rev, y=node|short) % "{key}={value}\n"}'
3710 $ hg log -r 0 -T '{dict(x=rev, y=node|short) % "{key}={value}\n"}'
3711 x=0
3711 x=0
3712 y=f7769ec2ab97
3712 y=f7769ec2ab97
3713 $ hg log -r 0 -T '{dict(x=rev, y=node|short)|json}\n'
3713 $ hg log -r 0 -T '{dict(x=rev, y=node|short)|json}\n'
3714 {"x": 0, "y": "f7769ec2ab97"}
3714 {"x": 0, "y": "f7769ec2ab97"}
3715 $ hg log -r 0 -T '{dict()|json}\n'
3715 $ hg log -r 0 -T '{dict()|json}\n'
3716 {}
3716 {}
3717
3717
3718 $ hg log -r 0 -T '{dict(rev, node=node|short)}\n'
3718 $ hg log -r 0 -T '{dict(rev, node=node|short)}\n'
3719 rev=0 node=f7769ec2ab97
3719 rev=0 node=f7769ec2ab97
3720 $ hg log -r 0 -T '{dict(rev, node|short)}\n'
3720 $ hg log -r 0 -T '{dict(rev, node|short)}\n'
3721 rev=0 node=f7769ec2ab97
3721 rev=0 node=f7769ec2ab97
3722
3722
3723 $ hg log -r 0 -T '{dict(rev, rev=rev)}\n'
3723 $ hg log -r 0 -T '{dict(rev, rev=rev)}\n'
3724 hg: parse error: duplicated dict key 'rev' inferred
3724 hg: parse error: duplicated dict key 'rev' inferred
3725 [255]
3725 [255]
3726 $ hg log -r 0 -T '{dict(node, node|short)}\n'
3726 $ hg log -r 0 -T '{dict(node, node|short)}\n'
3727 hg: parse error: duplicated dict key 'node' inferred
3727 hg: parse error: duplicated dict key 'node' inferred
3728 [255]
3728 [255]
3729 $ hg log -r 0 -T '{dict(1 + 2)}'
3729 $ hg log -r 0 -T '{dict(1 + 2)}'
3730 hg: parse error: dict key cannot be inferred
3730 hg: parse error: dict key cannot be inferred
3731 [255]
3731 [255]
3732
3732
3733 $ hg log -r 0 -T '{dict(x=rev, x=node)}'
3733 $ hg log -r 0 -T '{dict(x=rev, x=node)}'
3734 hg: parse error: dict got multiple values for keyword argument 'x'
3734 hg: parse error: dict got multiple values for keyword argument 'x'
3735 [255]
3735 [255]
3736
3736
3737 Test get function:
3737 Test get function:
3738
3738
3739 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3739 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3740 default
3740 default
3741 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3741 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3742 default
3742 default
3743 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3743 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3744 hg: parse error: get() expects a dict as first argument
3744 hg: parse error: get() expects a dict as first argument
3745 [255]
3745 [255]
3746
3746
3747 Test json filter applied to hybrid object:
3747 Test json filter applied to hybrid object:
3748
3748
3749 $ hg log -r0 -T '{files|json}\n'
3749 $ hg log -r0 -T '{files|json}\n'
3750 ["a"]
3750 ["a"]
3751 $ hg log -r0 -T '{extras|json}\n'
3751 $ hg log -r0 -T '{extras|json}\n'
3752 {"branch": "default"}
3752 {"branch": "default"}
3753
3753
3754 Test localdate(date, tz) function:
3754 Test localdate(date, tz) function:
3755
3755
3756 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3756 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3757 1970-01-01 09:00 +0900
3757 1970-01-01 09:00 +0900
3758 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3758 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3759 1970-01-01 00:00 +0000
3759 1970-01-01 00:00 +0000
3760 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "blahUTC")|isodate}\n'
3760 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "blahUTC")|isodate}\n'
3761 hg: parse error: localdate expects a timezone
3761 hg: parse error: localdate expects a timezone
3762 [255]
3762 [255]
3763 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3763 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3764 1970-01-01 02:00 +0200
3764 1970-01-01 02:00 +0200
3765 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3765 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3766 1970-01-01 00:00 +0000
3766 1970-01-01 00:00 +0000
3767 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3767 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3768 1970-01-01 00:00 +0000
3768 1970-01-01 00:00 +0000
3769 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3769 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3770 hg: parse error: localdate expects a timezone
3770 hg: parse error: localdate expects a timezone
3771 [255]
3771 [255]
3772 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3772 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3773 hg: parse error: localdate expects a timezone
3773 hg: parse error: localdate expects a timezone
3774 [255]
3774 [255]
3775
3775
3776 Test shortest(node) function:
3776 Test shortest(node) function:
3777
3777
3778 $ echo b > b
3778 $ echo b > b
3779 $ hg ci -qAm b
3779 $ hg ci -qAm b
3780 $ hg log --template '{shortest(node)}\n'
3780 $ hg log --template '{shortest(node)}\n'
3781 e777
3781 e777
3782 bcc7
3782 bcc7
3783 f776
3783 f776
3784 $ hg log --template '{shortest(node, 10)}\n'
3784 $ hg log --template '{shortest(node, 10)}\n'
3785 e777603221
3785 e777603221
3786 bcc7ff960b
3786 bcc7ff960b
3787 f7769ec2ab
3787 f7769ec2ab
3788 $ hg log --template '{node|shortest}\n' -l1
3788 $ hg log --template '{node|shortest}\n' -l1
3789 e777
3789 e777
3790
3790
3791 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
3791 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
3792 f7769ec2ab
3792 f7769ec2ab
3793 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
3793 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
3794 hg: parse error: shortest() expects an integer minlength
3794 hg: parse error: shortest() expects an integer minlength
3795 [255]
3795 [255]
3796
3796
3797 $ hg log -r 'wdir()' -T '{node|shortest}\n'
3797 $ hg log -r 'wdir()' -T '{node|shortest}\n'
3798 ffff
3798 ffff
3799
3799
3800 $ cd ..
3800 $ cd ..
3801
3801
3802 Test shortest(node) with the repo having short hash collision:
3802 Test shortest(node) with the repo having short hash collision:
3803
3803
3804 $ hg init hashcollision
3804 $ hg init hashcollision
3805 $ cd hashcollision
3805 $ cd hashcollision
3806 $ cat <<EOF >> .hg/hgrc
3806 $ cat <<EOF >> .hg/hgrc
3807 > [experimental]
3807 > [experimental]
3808 > evolution.createmarkers=True
3808 > evolution.createmarkers=True
3809 > EOF
3809 > EOF
3810 $ echo 0 > a
3810 $ echo 0 > a
3811 $ hg ci -qAm 0
3811 $ hg ci -qAm 0
3812 $ for i in 17 129 248 242 480 580 617 1057 2857 4025; do
3812 $ for i in 17 129 248 242 480 580 617 1057 2857 4025; do
3813 > hg up -q 0
3813 > hg up -q 0
3814 > echo $i > a
3814 > echo $i > a
3815 > hg ci -qm $i
3815 > hg ci -qm $i
3816 > done
3816 > done
3817 $ hg up -q null
3817 $ hg up -q null
3818 $ hg log -r0: -T '{rev}:{node}\n'
3818 $ hg log -r0: -T '{rev}:{node}\n'
3819 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
3819 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
3820 1:11424df6dc1dd4ea255eae2b58eaca7831973bbc
3820 1:11424df6dc1dd4ea255eae2b58eaca7831973bbc
3821 2:11407b3f1b9c3e76a79c1ec5373924df096f0499
3821 2:11407b3f1b9c3e76a79c1ec5373924df096f0499
3822 3:11dd92fe0f39dfdaacdaa5f3997edc533875cfc4
3822 3:11dd92fe0f39dfdaacdaa5f3997edc533875cfc4
3823 4:10776689e627b465361ad5c296a20a487e153ca4
3823 4:10776689e627b465361ad5c296a20a487e153ca4
3824 5:a00be79088084cb3aff086ab799f8790e01a976b
3824 5:a00be79088084cb3aff086ab799f8790e01a976b
3825 6:a0b0acd79b4498d0052993d35a6a748dd51d13e6
3825 6:a0b0acd79b4498d0052993d35a6a748dd51d13e6
3826 7:a0457b3450b8e1b778f1163b31a435802987fe5d
3826 7:a0457b3450b8e1b778f1163b31a435802987fe5d
3827 8:c56256a09cd28e5764f32e8e2810d0f01e2e357a
3827 8:c56256a09cd28e5764f32e8e2810d0f01e2e357a
3828 9:c5623987d205cd6d9d8389bfc40fff9dbb670b48
3828 9:c5623987d205cd6d9d8389bfc40fff9dbb670b48
3829 10:c562ddd9c94164376c20b86b0b4991636a3bf84f
3829 10:c562ddd9c94164376c20b86b0b4991636a3bf84f
3830 $ hg debugobsolete a00be79088084cb3aff086ab799f8790e01a976b
3830 $ hg debugobsolete a00be79088084cb3aff086ab799f8790e01a976b
3831 obsoleted 1 changesets
3831 obsoleted 1 changesets
3832 $ hg debugobsolete c5623987d205cd6d9d8389bfc40fff9dbb670b48
3832 $ hg debugobsolete c5623987d205cd6d9d8389bfc40fff9dbb670b48
3833 obsoleted 1 changesets
3833 obsoleted 1 changesets
3834 $ hg debugobsolete c562ddd9c94164376c20b86b0b4991636a3bf84f
3834 $ hg debugobsolete c562ddd9c94164376c20b86b0b4991636a3bf84f
3835 obsoleted 1 changesets
3835 obsoleted 1 changesets
3836
3836
3837 nodes starting with '11' (we don't have the revision number '11' though)
3837 nodes starting with '11' (we don't have the revision number '11' though)
3838
3838
3839 $ hg log -r 1:3 -T '{rev}:{shortest(node, 0)}\n'
3839 $ hg log -r 1:3 -T '{rev}:{shortest(node, 0)}\n'
3840 1:1142
3840 1:1142
3841 2:1140
3841 2:1140
3842 3:11d
3842 3:11d
3843
3843
3844 '5:a00' is hidden, but still we have two nodes starting with 'a0'
3844 '5:a00' is hidden, but still we have two nodes starting with 'a0'
3845
3845
3846 $ hg log -r 6:7 -T '{rev}:{shortest(node, 0)}\n'
3846 $ hg log -r 6:7 -T '{rev}:{shortest(node, 0)}\n'
3847 6:a0b
3847 6:a0b
3848 7:a04
3848 7:a04
3849
3849
3850 node '10' conflicts with the revision number '10' even if it is hidden
3850 node '10' conflicts with the revision number '10' even if it is hidden
3851 (we could exclude hidden revision numbers, but currently we don't)
3851 (we could exclude hidden revision numbers, but currently we don't)
3852
3852
3853 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n'
3853 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n'
3854 4:107
3854 4:107
3855 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden
3855 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden
3856 4:107
3856 4:107
3857
3857
3858 node 'c562' should be unique if the other 'c562' nodes are hidden
3858 node 'c562' should be unique if the other 'c562' nodes are hidden
3859 (but we don't try the slow path to filter out hidden nodes for now)
3859 (but we don't try the slow path to filter out hidden nodes for now)
3860
3860
3861 $ hg log -r 8 -T '{rev}:{node|shortest}\n'
3861 $ hg log -r 8 -T '{rev}:{node|shortest}\n'
3862 8:c5625
3862 8:c5625
3863 $ hg log -r 8:10 -T '{rev}:{node|shortest}\n' --hidden
3863 $ hg log -r 8:10 -T '{rev}:{node|shortest}\n' --hidden
3864 8:c5625
3864 8:c5625
3865 9:c5623
3865 9:c5623
3866 10:c562d
3866 10:c562d
3867
3867
3868 $ cd ..
3868 $ cd ..
3869
3869
3870 Test pad function
3870 Test pad function
3871
3871
3872 $ cd r
3872 $ cd r
3873
3873
3874 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3874 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3875 2 test
3875 2 test
3876 1 {node|short}
3876 1 {node|short}
3877 0 test
3877 0 test
3878
3878
3879 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3879 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3880 2 test
3880 2 test
3881 1 {node|short}
3881 1 {node|short}
3882 0 test
3882 0 test
3883
3883
3884 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3884 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3885 2------------------- test
3885 2------------------- test
3886 1------------------- {node|short}
3886 1------------------- {node|short}
3887 0------------------- test
3887 0------------------- test
3888
3888
3889 Test template string in pad function
3889 Test template string in pad function
3890
3890
3891 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3891 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3892 {0} test
3892 {0} test
3893
3893
3894 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3894 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3895 \{rev} test
3895 \{rev} test
3896
3896
3897 Test width argument passed to pad function
3897 Test width argument passed to pad function
3898
3898
3899 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
3899 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
3900 0 test
3900 0 test
3901 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
3901 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
3902 hg: parse error: pad() expects an integer width
3902 hg: parse error: pad() expects an integer width
3903 [255]
3903 [255]
3904
3904
3905 Test invalid fillchar passed to pad function
3905 Test invalid fillchar passed to pad function
3906
3906
3907 $ hg log -r 0 -T '{pad(rev, 10, "")}\n'
3907 $ hg log -r 0 -T '{pad(rev, 10, "")}\n'
3908 hg: parse error: pad() expects a single fill character
3908 hg: parse error: pad() expects a single fill character
3909 [255]
3909 [255]
3910 $ hg log -r 0 -T '{pad(rev, 10, "--")}\n'
3910 $ hg log -r 0 -T '{pad(rev, 10, "--")}\n'
3911 hg: parse error: pad() expects a single fill character
3911 hg: parse error: pad() expects a single fill character
3912 [255]
3912 [255]
3913
3913
3914 Test boolean argument passed to pad function
3914 Test boolean argument passed to pad function
3915
3915
3916 no crash
3916 no crash
3917
3917
3918 $ hg log -r 0 -T '{pad(rev, 10, "-", "f{"oo"}")}\n'
3918 $ hg log -r 0 -T '{pad(rev, 10, "-", "f{"oo"}")}\n'
3919 ---------0
3919 ---------0
3920
3920
3921 string/literal
3921 string/literal
3922
3922
3923 $ hg log -r 0 -T '{pad(rev, 10, "-", "false")}\n'
3923 $ hg log -r 0 -T '{pad(rev, 10, "-", "false")}\n'
3924 ---------0
3924 ---------0
3925 $ hg log -r 0 -T '{pad(rev, 10, "-", false)}\n'
3925 $ hg log -r 0 -T '{pad(rev, 10, "-", false)}\n'
3926 0---------
3926 0---------
3927 $ hg log -r 0 -T '{pad(rev, 10, "-", "")}\n'
3927 $ hg log -r 0 -T '{pad(rev, 10, "-", "")}\n'
3928 0---------
3928 0---------
3929
3929
3930 unknown keyword is evaluated to ''
3930 unknown keyword is evaluated to ''
3931
3931
3932 $ hg log -r 0 -T '{pad(rev, 10, "-", unknownkeyword)}\n'
3932 $ hg log -r 0 -T '{pad(rev, 10, "-", unknownkeyword)}\n'
3933 0---------
3933 0---------
3934
3934
3935 Test separate function
3935 Test separate function
3936
3936
3937 $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
3937 $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
3938 a-b-c
3938 a-b-c
3939 $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
3939 $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
3940 0:f7769ec2ab97 test default
3940 0:f7769ec2ab97 test default
3941 $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
3941 $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
3942 a \x1b[0;31mb\x1b[0m c d (esc)
3942 a \x1b[0;31mb\x1b[0m c d (esc)
3943
3943
3944 Test boolean expression/literal passed to if function
3944 Test boolean expression/literal passed to if function
3945
3945
3946 $ hg log -r 0 -T '{if(rev, "rev 0 is True")}\n'
3946 $ hg log -r 0 -T '{if(rev, "rev 0 is True")}\n'
3947 rev 0 is True
3947 rev 0 is True
3948 $ hg log -r 0 -T '{if(0, "literal 0 is True as well")}\n'
3948 $ hg log -r 0 -T '{if(0, "literal 0 is True as well")}\n'
3949 literal 0 is True as well
3949 literal 0 is True as well
3950 $ hg log -r 0 -T '{if("", "", "empty string is False")}\n'
3950 $ hg log -r 0 -T '{if("", "", "empty string is False")}\n'
3951 empty string is False
3951 empty string is False
3952 $ hg log -r 0 -T '{if(revset(r"0 - 0"), "", "empty list is False")}\n'
3952 $ hg log -r 0 -T '{if(revset(r"0 - 0"), "", "empty list is False")}\n'
3953 empty list is False
3953 empty list is False
3954 $ hg log -r 0 -T '{if(true, "true is True")}\n'
3954 $ hg log -r 0 -T '{if(true, "true is True")}\n'
3955 true is True
3955 true is True
3956 $ hg log -r 0 -T '{if(false, "", "false is False")}\n'
3956 $ hg log -r 0 -T '{if(false, "", "false is False")}\n'
3957 false is False
3957 false is False
3958 $ hg log -r 0 -T '{if("false", "non-empty string is True")}\n'
3958 $ hg log -r 0 -T '{if("false", "non-empty string is True")}\n'
3959 non-empty string is True
3959 non-empty string is True
3960
3960
3961 Test ifcontains function
3961 Test ifcontains function
3962
3962
3963 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
3963 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
3964 2 is in the string
3964 2 is in the string
3965 1 is not
3965 1 is not
3966 0 is in the string
3966 0 is in the string
3967
3967
3968 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
3968 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
3969 2 is in the string
3969 2 is in the string
3970 1 is not
3970 1 is not
3971 0 is in the string
3971 0 is in the string
3972
3972
3973 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
3973 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
3974 2 did not add a
3974 2 did not add a
3975 1 did not add a
3975 1 did not add a
3976 0 added a
3976 0 added a
3977
3977
3978 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
3978 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
3979 2 is parent of 1
3979 2 is parent of 1
3980 1
3980 1
3981 0
3981 0
3982
3982
3983 Test revset function
3983 Test revset function
3984
3984
3985 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
3985 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
3986 2 current rev
3986 2 current rev
3987 1 not current rev
3987 1 not current rev
3988 0 not current rev
3988 0 not current rev
3989
3989
3990 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
3990 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
3991 2 match rev
3991 2 match rev
3992 1 match rev
3992 1 match rev
3993 0 not match rev
3993 0 not match rev
3994
3994
3995 $ hg log -T '{ifcontains(desc, revset(":"), "", "type not match")}\n' -l1
3995 $ hg log -T '{ifcontains(desc, revset(":"), "", "type not match")}\n' -l1
3996 type not match
3996 type not match
3997
3997
3998 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
3998 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
3999 2 Parents: 1
3999 2 Parents: 1
4000 1 Parents: 0
4000 1 Parents: 0
4001 0 Parents:
4001 0 Parents:
4002
4002
4003 $ cat >> .hg/hgrc <<EOF
4003 $ cat >> .hg/hgrc <<EOF
4004 > [revsetalias]
4004 > [revsetalias]
4005 > myparents(\$1) = parents(\$1)
4005 > myparents(\$1) = parents(\$1)
4006 > EOF
4006 > EOF
4007 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
4007 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
4008 2 Parents: 1
4008 2 Parents: 1
4009 1 Parents: 0
4009 1 Parents: 0
4010 0 Parents:
4010 0 Parents:
4011
4011
4012 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
4012 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
4013 Rev: 2
4013 Rev: 2
4014 Ancestor: 0
4014 Ancestor: 0
4015 Ancestor: 1
4015 Ancestor: 1
4016 Ancestor: 2
4016 Ancestor: 2
4017
4017
4018 Rev: 1
4018 Rev: 1
4019 Ancestor: 0
4019 Ancestor: 0
4020 Ancestor: 1
4020 Ancestor: 1
4021
4021
4022 Rev: 0
4022 Rev: 0
4023 Ancestor: 0
4023 Ancestor: 0
4024
4024
4025 $ hg log --template '{revset("TIP"|lower)}\n' -l1
4025 $ hg log --template '{revset("TIP"|lower)}\n' -l1
4026 2
4026 2
4027
4027
4028 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
4028 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
4029 2
4029 2
4030
4030
4031 a list template is evaluated for each item of revset/parents
4031 a list template is evaluated for each item of revset/parents
4032
4032
4033 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
4033 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
4034 2 p: 1:bcc7ff960b8e
4034 2 p: 1:bcc7ff960b8e
4035 1 p: 0:f7769ec2ab97
4035 1 p: 0:f7769ec2ab97
4036 0 p:
4036 0 p:
4037
4037
4038 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
4038 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
4039 2 p: 1:bcc7ff960b8e -1:000000000000
4039 2 p: 1:bcc7ff960b8e -1:000000000000
4040 1 p: 0:f7769ec2ab97 -1:000000000000
4040 1 p: 0:f7769ec2ab97 -1:000000000000
4041 0 p: -1:000000000000 -1:000000000000
4041 0 p: -1:000000000000 -1:000000000000
4042
4042
4043 therefore, 'revcache' should be recreated for each rev
4043 therefore, 'revcache' should be recreated for each rev
4044
4044
4045 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
4045 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
4046 2 aa b
4046 2 aa b
4047 p
4047 p
4048 1
4048 1
4049 p a
4049 p a
4050 0 a
4050 0 a
4051 p
4051 p
4052
4052
4053 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
4053 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
4054 2 aa b
4054 2 aa b
4055 p
4055 p
4056 1
4056 1
4057 p a
4057 p a
4058 0 a
4058 0 a
4059 p
4059 p
4060
4060
4061 a revset item must be evaluated as an integer revision, not an offset from tip
4061 a revset item must be evaluated as an integer revision, not an offset from tip
4062
4062
4063 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
4063 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
4064 -1:000000000000
4064 -1:000000000000
4065 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
4065 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
4066 -1:000000000000
4066 -1:000000000000
4067
4067
4068 join() should pick '{rev}' from revset items:
4068 join() should pick '{rev}' from revset items:
4069
4069
4070 $ hg log -R ../a -T '{join(revset("parents(%d)", rev), ", ")}\n' -r6
4070 $ hg log -R ../a -T '{join(revset("parents(%d)", rev), ", ")}\n' -r6
4071 4, 5
4071 4, 5
4072
4072
4073 on the other hand, parents are formatted as '{rev}:{node|formatnode}' by
4073 on the other hand, parents are formatted as '{rev}:{node|formatnode}' by
4074 default. join() should agree with the default formatting:
4074 default. join() should agree with the default formatting:
4075
4075
4076 $ hg log -R ../a -T '{join(parents, ", ")}\n' -r6
4076 $ hg log -R ../a -T '{join(parents, ", ")}\n' -r6
4077 5:13207e5a10d9, 4:bbe44766e73d
4077 5:13207e5a10d9, 4:bbe44766e73d
4078
4078
4079 $ hg log -R ../a -T '{join(parents, ",\n")}\n' -r6 --debug
4079 $ hg log -R ../a -T '{join(parents, ",\n")}\n' -r6 --debug
4080 5:13207e5a10d9fd28ec424934298e176197f2c67f,
4080 5:13207e5a10d9fd28ec424934298e176197f2c67f,
4081 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
4081 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
4082
4082
4083 Invalid arguments passed to revset()
4084
4085 $ hg log -T '{revset("%whatever", 0)}\n'
4086 hg: parse error: unexpected revspec format character w
4087 [255]
4088
4083 Test files function
4089 Test files function
4084
4090
4085 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
4091 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
4086 2
4092 2
4087 a
4093 a
4088 aa
4094 aa
4089 b
4095 b
4090 1
4096 1
4091 a
4097 a
4092 0
4098 0
4093 a
4099 a
4094
4100
4095 $ hg log -T "{rev}\n{join(files('aa'), '\n')}\n"
4101 $ hg log -T "{rev}\n{join(files('aa'), '\n')}\n"
4096 2
4102 2
4097 aa
4103 aa
4098 1
4104 1
4099
4105
4100 0
4106 0
4101
4107
4102
4108
4103 Test relpath function
4109 Test relpath function
4104
4110
4105 $ hg log -r0 -T '{files % "{file|relpath}\n"}'
4111 $ hg log -r0 -T '{files % "{file|relpath}\n"}'
4106 a
4112 a
4107 $ cd ..
4113 $ cd ..
4108 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
4114 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
4109 r/a
4115 r/a
4110 $ cd r
4116 $ cd r
4111
4117
4112 Test active bookmark templating
4118 Test active bookmark templating
4113
4119
4114 $ hg book foo
4120 $ hg book foo
4115 $ hg book bar
4121 $ hg book bar
4116 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
4122 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
4117 2 bar* foo
4123 2 bar* foo
4118 1
4124 1
4119 0
4125 0
4120 $ hg log --template "{rev} {activebookmark}\n"
4126 $ hg log --template "{rev} {activebookmark}\n"
4121 2 bar
4127 2 bar
4122 1
4128 1
4123 0
4129 0
4124 $ hg bookmarks --inactive bar
4130 $ hg bookmarks --inactive bar
4125 $ hg log --template "{rev} {activebookmark}\n"
4131 $ hg log --template "{rev} {activebookmark}\n"
4126 2
4132 2
4127 1
4133 1
4128 0
4134 0
4129 $ hg book -r1 baz
4135 $ hg book -r1 baz
4130 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
4136 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
4131 2 bar foo
4137 2 bar foo
4132 1 baz
4138 1 baz
4133 0
4139 0
4134 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
4140 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
4135 2 t
4141 2 t
4136 1 f
4142 1 f
4137 0 f
4143 0 f
4138
4144
4139 Test namespaces dict
4145 Test namespaces dict
4140
4146
4141 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
4147 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
4142 2
4148 2
4143 bookmarks color=bookmark builtin=True
4149 bookmarks color=bookmark builtin=True
4144 bar,foo
4150 bar,foo
4145 tags color=tag builtin=True
4151 tags color=tag builtin=True
4146 tip
4152 tip
4147 branches color=branch builtin=True
4153 branches color=branch builtin=True
4148 text.{rev}
4154 text.{rev}
4149 revnames color=revname builtin=False
4155 revnames color=revname builtin=False
4150 r2
4156 r2
4151
4157
4152 1
4158 1
4153 bookmarks color=bookmark builtin=True
4159 bookmarks color=bookmark builtin=True
4154 baz
4160 baz
4155 tags color=tag builtin=True
4161 tags color=tag builtin=True
4156
4162
4157 branches color=branch builtin=True
4163 branches color=branch builtin=True
4158 text.{rev}
4164 text.{rev}
4159 revnames color=revname builtin=False
4165 revnames color=revname builtin=False
4160 r1
4166 r1
4161
4167
4162 0
4168 0
4163 bookmarks color=bookmark builtin=True
4169 bookmarks color=bookmark builtin=True
4164
4170
4165 tags color=tag builtin=True
4171 tags color=tag builtin=True
4166
4172
4167 branches color=branch builtin=True
4173 branches color=branch builtin=True
4168 default
4174 default
4169 revnames color=revname builtin=False
4175 revnames color=revname builtin=False
4170 r0
4176 r0
4171
4177
4172 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
4178 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
4173 bookmarks: bar foo
4179 bookmarks: bar foo
4174 tags: tip
4180 tags: tip
4175 branches: text.{rev}
4181 branches: text.{rev}
4176 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
4182 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
4177 bookmarks:
4183 bookmarks:
4178 bar
4184 bar
4179 foo
4185 foo
4180 tags:
4186 tags:
4181 tip
4187 tip
4182 branches:
4188 branches:
4183 text.{rev}
4189 text.{rev}
4184 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
4190 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
4185 bar
4191 bar
4186 foo
4192 foo
4187 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
4193 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
4188 bar
4194 bar
4189 foo
4195 foo
4190
4196
4191 Test stringify on sub expressions
4197 Test stringify on sub expressions
4192
4198
4193 $ cd ..
4199 $ cd ..
4194 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
4200 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
4195 fourth, second, third
4201 fourth, second, third
4196 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
4202 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
4197 abc
4203 abc
4198
4204
4199 Test splitlines
4205 Test splitlines
4200
4206
4201 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
4207 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
4202 @ foo Modify, add, remove, rename
4208 @ foo Modify, add, remove, rename
4203 |
4209 |
4204 o foo future
4210 o foo future
4205 |
4211 |
4206 o foo third
4212 o foo third
4207 |
4213 |
4208 o foo second
4214 o foo second
4209
4215
4210 o foo merge
4216 o foo merge
4211 |\
4217 |\
4212 | o foo new head
4218 | o foo new head
4213 | |
4219 | |
4214 o | foo new branch
4220 o | foo new branch
4215 |/
4221 |/
4216 o foo no user, no domain
4222 o foo no user, no domain
4217 |
4223 |
4218 o foo no person
4224 o foo no person
4219 |
4225 |
4220 o foo other 1
4226 o foo other 1
4221 | foo other 2
4227 | foo other 2
4222 | foo
4228 | foo
4223 | foo other 3
4229 | foo other 3
4224 o foo line 1
4230 o foo line 1
4225 foo line 2
4231 foo line 2
4226
4232
4227 $ hg log -R a -r0 -T '{desc|splitlines}\n'
4233 $ hg log -R a -r0 -T '{desc|splitlines}\n'
4228 line 1 line 2
4234 line 1 line 2
4229 $ hg log -R a -r0 -T '{join(desc|splitlines, "|")}\n'
4235 $ hg log -R a -r0 -T '{join(desc|splitlines, "|")}\n'
4230 line 1|line 2
4236 line 1|line 2
4231
4237
4232 Test startswith
4238 Test startswith
4233 $ hg log -Gv -R a --template "{startswith(desc)}"
4239 $ hg log -Gv -R a --template "{startswith(desc)}"
4234 hg: parse error: startswith expects two arguments
4240 hg: parse error: startswith expects two arguments
4235 [255]
4241 [255]
4236
4242
4237 $ hg log -Gv -R a --template "{startswith('line', desc)}"
4243 $ hg log -Gv -R a --template "{startswith('line', desc)}"
4238 @
4244 @
4239 |
4245 |
4240 o
4246 o
4241 |
4247 |
4242 o
4248 o
4243 |
4249 |
4244 o
4250 o
4245
4251
4246 o
4252 o
4247 |\
4253 |\
4248 | o
4254 | o
4249 | |
4255 | |
4250 o |
4256 o |
4251 |/
4257 |/
4252 o
4258 o
4253 |
4259 |
4254 o
4260 o
4255 |
4261 |
4256 o
4262 o
4257 |
4263 |
4258 o line 1
4264 o line 1
4259 line 2
4265 line 2
4260
4266
4261 Test bad template with better error message
4267 Test bad template with better error message
4262
4268
4263 $ hg log -Gv -R a --template '{desc|user()}'
4269 $ hg log -Gv -R a --template '{desc|user()}'
4264 hg: parse error: expected a symbol, got 'func'
4270 hg: parse error: expected a symbol, got 'func'
4265 [255]
4271 [255]
4266
4272
4267 Test word function (including index out of bounds graceful failure)
4273 Test word function (including index out of bounds graceful failure)
4268
4274
4269 $ hg log -Gv -R a --template "{word('1', desc)}"
4275 $ hg log -Gv -R a --template "{word('1', desc)}"
4270 @ add,
4276 @ add,
4271 |
4277 |
4272 o
4278 o
4273 |
4279 |
4274 o
4280 o
4275 |
4281 |
4276 o
4282 o
4277
4283
4278 o
4284 o
4279 |\
4285 |\
4280 | o head
4286 | o head
4281 | |
4287 | |
4282 o | branch
4288 o | branch
4283 |/
4289 |/
4284 o user,
4290 o user,
4285 |
4291 |
4286 o person
4292 o person
4287 |
4293 |
4288 o 1
4294 o 1
4289 |
4295 |
4290 o 1
4296 o 1
4291
4297
4292
4298
4293 Test word third parameter used as splitter
4299 Test word third parameter used as splitter
4294
4300
4295 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
4301 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
4296 @ M
4302 @ M
4297 |
4303 |
4298 o future
4304 o future
4299 |
4305 |
4300 o third
4306 o third
4301 |
4307 |
4302 o sec
4308 o sec
4303
4309
4304 o merge
4310 o merge
4305 |\
4311 |\
4306 | o new head
4312 | o new head
4307 | |
4313 | |
4308 o | new branch
4314 o | new branch
4309 |/
4315 |/
4310 o n
4316 o n
4311 |
4317 |
4312 o n
4318 o n
4313 |
4319 |
4314 o
4320 o
4315 |
4321 |
4316 o line 1
4322 o line 1
4317 line 2
4323 line 2
4318
4324
4319 Test word error messages for not enough and too many arguments
4325 Test word error messages for not enough and too many arguments
4320
4326
4321 $ hg log -Gv -R a --template "{word('0')}"
4327 $ hg log -Gv -R a --template "{word('0')}"
4322 hg: parse error: word expects two or three arguments, got 1
4328 hg: parse error: word expects two or three arguments, got 1
4323 [255]
4329 [255]
4324
4330
4325 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
4331 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
4326 hg: parse error: word expects two or three arguments, got 7
4332 hg: parse error: word expects two or three arguments, got 7
4327 [255]
4333 [255]
4328
4334
4329 Test word for integer literal
4335 Test word for integer literal
4330
4336
4331 $ hg log -R a --template "{word(2, desc)}\n" -r0
4337 $ hg log -R a --template "{word(2, desc)}\n" -r0
4332 line
4338 line
4333
4339
4334 Test word for invalid numbers
4340 Test word for invalid numbers
4335
4341
4336 $ hg log -Gv -R a --template "{word('a', desc)}"
4342 $ hg log -Gv -R a --template "{word('a', desc)}"
4337 hg: parse error: word expects an integer index
4343 hg: parse error: word expects an integer index
4338 [255]
4344 [255]
4339
4345
4340 Test word for out of range
4346 Test word for out of range
4341
4347
4342 $ hg log -R a --template "{word(10000, desc)}"
4348 $ hg log -R a --template "{word(10000, desc)}"
4343 $ hg log -R a --template "{word(-10000, desc)}"
4349 $ hg log -R a --template "{word(-10000, desc)}"
4344
4350
4345 Test indent and not adding to empty lines
4351 Test indent and not adding to empty lines
4346
4352
4347 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
4353 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
4348 -----
4354 -----
4349 > line 1
4355 > line 1
4350 >> line 2
4356 >> line 2
4351 -----
4357 -----
4352 > other 1
4358 > other 1
4353 >> other 2
4359 >> other 2
4354
4360
4355 >> other 3
4361 >> other 3
4356
4362
4357 Test with non-strings like dates
4363 Test with non-strings like dates
4358
4364
4359 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
4365 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
4360 1200000.00
4366 1200000.00
4361 1300000.00
4367 1300000.00
4362
4368
4363 Test broken string escapes:
4369 Test broken string escapes:
4364
4370
4365 $ hg log -T "bogus\\" -R a
4371 $ hg log -T "bogus\\" -R a
4366 hg: parse error: trailing \ in string
4372 hg: parse error: trailing \ in string
4367 [255]
4373 [255]
4368 $ hg log -T "\\xy" -R a
4374 $ hg log -T "\\xy" -R a
4369 hg: parse error: invalid \x escape
4375 hg: parse error: invalid \x escape
4370 [255]
4376 [255]
4371
4377
4372 json filter should escape HTML tags so that the output can be embedded in hgweb:
4378 json filter should escape HTML tags so that the output can be embedded in hgweb:
4373
4379
4374 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
4380 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
4375 "\u003cfoo@example.org\u003e"
4381 "\u003cfoo@example.org\u003e"
4376
4382
4377 Templater supports aliases of symbol and func() styles:
4383 Templater supports aliases of symbol and func() styles:
4378
4384
4379 $ hg clone -q a aliases
4385 $ hg clone -q a aliases
4380 $ cd aliases
4386 $ cd aliases
4381 $ cat <<EOF >> .hg/hgrc
4387 $ cat <<EOF >> .hg/hgrc
4382 > [templatealias]
4388 > [templatealias]
4383 > r = rev
4389 > r = rev
4384 > rn = "{r}:{node|short}"
4390 > rn = "{r}:{node|short}"
4385 > status(c, files) = files % "{c} {file}\n"
4391 > status(c, files) = files % "{c} {file}\n"
4386 > utcdate(d) = localdate(d, "UTC")
4392 > utcdate(d) = localdate(d, "UTC")
4387 > EOF
4393 > EOF
4388
4394
4389 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
4395 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
4390 (template
4396 (template
4391 (symbol 'rn')
4397 (symbol 'rn')
4392 (string ' ')
4398 (string ' ')
4393 (|
4399 (|
4394 (func
4400 (func
4395 (symbol 'utcdate')
4401 (symbol 'utcdate')
4396 (symbol 'date'))
4402 (symbol 'date'))
4397 (symbol 'isodate'))
4403 (symbol 'isodate'))
4398 (string '\n'))
4404 (string '\n'))
4399 * expanded:
4405 * expanded:
4400 (template
4406 (template
4401 (template
4407 (template
4402 (symbol 'rev')
4408 (symbol 'rev')
4403 (string ':')
4409 (string ':')
4404 (|
4410 (|
4405 (symbol 'node')
4411 (symbol 'node')
4406 (symbol 'short')))
4412 (symbol 'short')))
4407 (string ' ')
4413 (string ' ')
4408 (|
4414 (|
4409 (func
4415 (func
4410 (symbol 'localdate')
4416 (symbol 'localdate')
4411 (list
4417 (list
4412 (symbol 'date')
4418 (symbol 'date')
4413 (string 'UTC')))
4419 (string 'UTC')))
4414 (symbol 'isodate'))
4420 (symbol 'isodate'))
4415 (string '\n'))
4421 (string '\n'))
4416 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4422 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4417
4423
4418 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
4424 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
4419 (template
4425 (template
4420 (func
4426 (func
4421 (symbol 'status')
4427 (symbol 'status')
4422 (list
4428 (list
4423 (string 'A')
4429 (string 'A')
4424 (symbol 'file_adds'))))
4430 (symbol 'file_adds'))))
4425 * expanded:
4431 * expanded:
4426 (template
4432 (template
4427 (%
4433 (%
4428 (symbol 'file_adds')
4434 (symbol 'file_adds')
4429 (template
4435 (template
4430 (string 'A')
4436 (string 'A')
4431 (string ' ')
4437 (string ' ')
4432 (symbol 'file')
4438 (symbol 'file')
4433 (string '\n'))))
4439 (string '\n'))))
4434 A a
4440 A a
4435
4441
4436 A unary function alias can be called as a filter:
4442 A unary function alias can be called as a filter:
4437
4443
4438 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
4444 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
4439 (template
4445 (template
4440 (|
4446 (|
4441 (|
4447 (|
4442 (symbol 'date')
4448 (symbol 'date')
4443 (symbol 'utcdate'))
4449 (symbol 'utcdate'))
4444 (symbol 'isodate'))
4450 (symbol 'isodate'))
4445 (string '\n'))
4451 (string '\n'))
4446 * expanded:
4452 * expanded:
4447 (template
4453 (template
4448 (|
4454 (|
4449 (func
4455 (func
4450 (symbol 'localdate')
4456 (symbol 'localdate')
4451 (list
4457 (list
4452 (symbol 'date')
4458 (symbol 'date')
4453 (string 'UTC')))
4459 (string 'UTC')))
4454 (symbol 'isodate'))
4460 (symbol 'isodate'))
4455 (string '\n'))
4461 (string '\n'))
4456 1970-01-12 13:46 +0000
4462 1970-01-12 13:46 +0000
4457
4463
4458 Aliases should be applied only to command arguments and templates in hgrc.
4464 Aliases should be applied only to command arguments and templates in hgrc.
4459 Otherwise, our stock styles and web templates could be corrupted:
4465 Otherwise, our stock styles and web templates could be corrupted:
4460
4466
4461 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
4467 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
4462 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4468 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4463
4469
4464 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
4470 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
4465 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4471 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4466
4472
4467 $ cat <<EOF > tmpl
4473 $ cat <<EOF > tmpl
4468 > changeset = 'nothing expanded:{rn}\n'
4474 > changeset = 'nothing expanded:{rn}\n'
4469 > EOF
4475 > EOF
4470 $ hg log -r0 --style ./tmpl
4476 $ hg log -r0 --style ./tmpl
4471 nothing expanded:
4477 nothing expanded:
4472
4478
4473 Aliases in formatter:
4479 Aliases in formatter:
4474
4480
4475 $ hg branches -T '{pad(branch, 7)} {rn}\n'
4481 $ hg branches -T '{pad(branch, 7)} {rn}\n'
4476 default 6:d41e714fe50d
4482 default 6:d41e714fe50d
4477 foo 4:bbe44766e73d
4483 foo 4:bbe44766e73d
4478
4484
4479 Aliases should honor HGPLAIN:
4485 Aliases should honor HGPLAIN:
4480
4486
4481 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
4487 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
4482 nothing expanded:
4488 nothing expanded:
4483 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
4489 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
4484 0:1e4e1b8f71e0
4490 0:1e4e1b8f71e0
4485
4491
4486 Unparsable alias:
4492 Unparsable alias:
4487
4493
4488 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
4494 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
4489 (template
4495 (template
4490 (symbol 'bad'))
4496 (symbol 'bad'))
4491 abort: bad definition of template alias "bad": at 2: not a prefix: end
4497 abort: bad definition of template alias "bad": at 2: not a prefix: end
4492 [255]
4498 [255]
4493 $ hg log --config templatealias.bad='x(' -T '{bad}'
4499 $ hg log --config templatealias.bad='x(' -T '{bad}'
4494 abort: bad definition of template alias "bad": at 2: not a prefix: end
4500 abort: bad definition of template alias "bad": at 2: not a prefix: end
4495 [255]
4501 [255]
4496
4502
4497 $ cd ..
4503 $ cd ..
4498
4504
4499 Set up repository for non-ascii encoding tests:
4505 Set up repository for non-ascii encoding tests:
4500
4506
4501 $ hg init nonascii
4507 $ hg init nonascii
4502 $ cd nonascii
4508 $ cd nonascii
4503 $ $PYTHON <<EOF
4509 $ $PYTHON <<EOF
4504 > open('latin1', 'w').write('\xe9')
4510 > open('latin1', 'w').write('\xe9')
4505 > open('utf-8', 'w').write('\xc3\xa9')
4511 > open('utf-8', 'w').write('\xc3\xa9')
4506 > EOF
4512 > EOF
4507 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
4513 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
4508 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
4514 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
4509
4515
4510 json filter should try round-trip conversion to utf-8:
4516 json filter should try round-trip conversion to utf-8:
4511
4517
4512 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
4518 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
4513 "\u00e9"
4519 "\u00e9"
4514 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
4520 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
4515 "non-ascii branch: \u00e9"
4521 "non-ascii branch: \u00e9"
4516
4522
4517 json filter takes input as utf-8b:
4523 json filter takes input as utf-8b:
4518
4524
4519 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
4525 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
4520 "\u00e9"
4526 "\u00e9"
4521 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
4527 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
4522 "\udce9"
4528 "\udce9"
4523
4529
4524 utf8 filter:
4530 utf8 filter:
4525
4531
4526 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
4532 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
4527 round-trip: c3a9
4533 round-trip: c3a9
4528 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
4534 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
4529 decoded: c3a9
4535 decoded: c3a9
4530 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
4536 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
4531 abort: decoding near * (glob)
4537 abort: decoding near * (glob)
4532 [255]
4538 [255]
4533 $ hg log -T "invalid type: {rev|utf8}\n" -r0
4539 $ hg log -T "invalid type: {rev|utf8}\n" -r0
4534 abort: template filter 'utf8' is not compatible with keyword 'rev'
4540 abort: template filter 'utf8' is not compatible with keyword 'rev'
4535 [255]
4541 [255]
4536
4542
4537 pad width:
4543 pad width:
4538
4544
4539 $ HGENCODING=utf-8 hg debugtemplate "{pad('`cat utf-8`', 2, '-')}\n"
4545 $ HGENCODING=utf-8 hg debugtemplate "{pad('`cat utf-8`', 2, '-')}\n"
4540 \xc3\xa9- (esc)
4546 \xc3\xa9- (esc)
4541
4547
4542 $ cd ..
4548 $ cd ..
4543
4549
4544 Test that template function in extension is registered as expected
4550 Test that template function in extension is registered as expected
4545
4551
4546 $ cd a
4552 $ cd a
4547
4553
4548 $ cat <<EOF > $TESTTMP/customfunc.py
4554 $ cat <<EOF > $TESTTMP/customfunc.py
4549 > from mercurial import registrar
4555 > from mercurial import registrar
4550 >
4556 >
4551 > templatefunc = registrar.templatefunc()
4557 > templatefunc = registrar.templatefunc()
4552 >
4558 >
4553 > @templatefunc('custom()')
4559 > @templatefunc('custom()')
4554 > def custom(context, mapping, args):
4560 > def custom(context, mapping, args):
4555 > return 'custom'
4561 > return 'custom'
4556 > EOF
4562 > EOF
4557 $ cat <<EOF > .hg/hgrc
4563 $ cat <<EOF > .hg/hgrc
4558 > [extensions]
4564 > [extensions]
4559 > customfunc = $TESTTMP/customfunc.py
4565 > customfunc = $TESTTMP/customfunc.py
4560 > EOF
4566 > EOF
4561
4567
4562 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
4568 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
4563 custom
4569 custom
4564
4570
4565 $ cd ..
4571 $ cd ..
4566
4572
4567 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
4573 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
4568 printed graphwidths 3, 5, 7, etc. should all line up in their respective
4574 printed graphwidths 3, 5, 7, etc. should all line up in their respective
4569 columns. We don't care about other aspects of the graph rendering here.
4575 columns. We don't care about other aspects of the graph rendering here.
4570
4576
4571 $ hg init graphwidth
4577 $ hg init graphwidth
4572 $ cd graphwidth
4578 $ cd graphwidth
4573
4579
4574 $ wrappabletext="a a a a a a a a a a a a"
4580 $ wrappabletext="a a a a a a a a a a a a"
4575
4581
4576 $ printf "first\n" > file
4582 $ printf "first\n" > file
4577 $ hg add file
4583 $ hg add file
4578 $ hg commit -m "$wrappabletext"
4584 $ hg commit -m "$wrappabletext"
4579
4585
4580 $ printf "first\nsecond\n" > file
4586 $ printf "first\nsecond\n" > file
4581 $ hg commit -m "$wrappabletext"
4587 $ hg commit -m "$wrappabletext"
4582
4588
4583 $ hg checkout 0
4589 $ hg checkout 0
4584 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4590 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4585 $ printf "third\nfirst\n" > file
4591 $ printf "third\nfirst\n" > file
4586 $ hg commit -m "$wrappabletext"
4592 $ hg commit -m "$wrappabletext"
4587 created new head
4593 created new head
4588
4594
4589 $ hg merge
4595 $ hg merge
4590 merging file
4596 merging file
4591 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
4597 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
4592 (branch merge, don't forget to commit)
4598 (branch merge, don't forget to commit)
4593
4599
4594 $ hg log --graph -T "{graphwidth}"
4600 $ hg log --graph -T "{graphwidth}"
4595 @ 3
4601 @ 3
4596 |
4602 |
4597 | @ 5
4603 | @ 5
4598 |/
4604 |/
4599 o 3
4605 o 3
4600
4606
4601 $ hg commit -m "$wrappabletext"
4607 $ hg commit -m "$wrappabletext"
4602
4608
4603 $ hg log --graph -T "{graphwidth}"
4609 $ hg log --graph -T "{graphwidth}"
4604 @ 5
4610 @ 5
4605 |\
4611 |\
4606 | o 5
4612 | o 5
4607 | |
4613 | |
4608 o | 5
4614 o | 5
4609 |/
4615 |/
4610 o 3
4616 o 3
4611
4617
4612
4618
4613 $ hg checkout 0
4619 $ hg checkout 0
4614 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4620 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4615 $ printf "third\nfirst\nsecond\n" > file
4621 $ printf "third\nfirst\nsecond\n" > file
4616 $ hg commit -m "$wrappabletext"
4622 $ hg commit -m "$wrappabletext"
4617 created new head
4623 created new head
4618
4624
4619 $ hg log --graph -T "{graphwidth}"
4625 $ hg log --graph -T "{graphwidth}"
4620 @ 3
4626 @ 3
4621 |
4627 |
4622 | o 7
4628 | o 7
4623 | |\
4629 | |\
4624 +---o 7
4630 +---o 7
4625 | |
4631 | |
4626 | o 5
4632 | o 5
4627 |/
4633 |/
4628 o 3
4634 o 3
4629
4635
4630
4636
4631 $ hg log --graph -T "{graphwidth}" -r 3
4637 $ hg log --graph -T "{graphwidth}" -r 3
4632 o 5
4638 o 5
4633 |\
4639 |\
4634 ~ ~
4640 ~ ~
4635
4641
4636 $ hg log --graph -T "{graphwidth}" -r 1
4642 $ hg log --graph -T "{graphwidth}" -r 1
4637 o 3
4643 o 3
4638 |
4644 |
4639 ~
4645 ~
4640
4646
4641 $ hg merge
4647 $ hg merge
4642 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4648 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4643 (branch merge, don't forget to commit)
4649 (branch merge, don't forget to commit)
4644 $ hg commit -m "$wrappabletext"
4650 $ hg commit -m "$wrappabletext"
4645
4651
4646 $ printf "seventh\n" >> file
4652 $ printf "seventh\n" >> file
4647 $ hg commit -m "$wrappabletext"
4653 $ hg commit -m "$wrappabletext"
4648
4654
4649 $ hg log --graph -T "{graphwidth}"
4655 $ hg log --graph -T "{graphwidth}"
4650 @ 3
4656 @ 3
4651 |
4657 |
4652 o 5
4658 o 5
4653 |\
4659 |\
4654 | o 5
4660 | o 5
4655 | |
4661 | |
4656 o | 7
4662 o | 7
4657 |\ \
4663 |\ \
4658 | o | 7
4664 | o | 7
4659 | |/
4665 | |/
4660 o / 5
4666 o / 5
4661 |/
4667 |/
4662 o 3
4668 o 3
4663
4669
4664
4670
4665 The point of graphwidth is to allow wrapping that accounts for the space taken
4671 The point of graphwidth is to allow wrapping that accounts for the space taken
4666 by the graph.
4672 by the graph.
4667
4673
4668 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
4674 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
4669 @ a a a a
4675 @ a a a a
4670 | a a a a
4676 | a a a a
4671 | a a a a
4677 | a a a a
4672 o a a a
4678 o a a a
4673 |\ a a a
4679 |\ a a a
4674 | | a a a
4680 | | a a a
4675 | | a a a
4681 | | a a a
4676 | o a a a
4682 | o a a a
4677 | | a a a
4683 | | a a a
4678 | | a a a
4684 | | a a a
4679 | | a a a
4685 | | a a a
4680 o | a a
4686 o | a a
4681 |\ \ a a
4687 |\ \ a a
4682 | | | a a
4688 | | | a a
4683 | | | a a
4689 | | | a a
4684 | | | a a
4690 | | | a a
4685 | | | a a
4691 | | | a a
4686 | o | a a
4692 | o | a a
4687 | |/ a a
4693 | |/ a a
4688 | | a a
4694 | | a a
4689 | | a a
4695 | | a a
4690 | | a a
4696 | | a a
4691 | | a a
4697 | | a a
4692 o | a a a
4698 o | a a a
4693 |/ a a a
4699 |/ a a a
4694 | a a a
4700 | a a a
4695 | a a a
4701 | a a a
4696 o a a a a
4702 o a a a a
4697 a a a a
4703 a a a a
4698 a a a a
4704 a a a a
4699
4705
4700 Something tricky happens when there are elided nodes; the next drawn row of
4706 Something tricky happens when there are elided nodes; the next drawn row of
4701 edges can be more than one column wider, but the graph width only increases by
4707 edges can be more than one column wider, but the graph width only increases by
4702 one column. The remaining columns are added in between the nodes.
4708 one column. The remaining columns are added in between the nodes.
4703
4709
4704 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
4710 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
4705 o 5
4711 o 5
4706 |\
4712 |\
4707 | \
4713 | \
4708 | :\
4714 | :\
4709 o : : 7
4715 o : : 7
4710 :/ /
4716 :/ /
4711 : o 5
4717 : o 5
4712 :/
4718 :/
4713 o 3
4719 o 3
4714
4720
4715
4721
4716 $ cd ..
4722 $ cd ..
4717
4723
General Comments 0
You need to be logged in to leave comments. Login now