##// END OF EJS Templates
templater: create string unescape helper (issue4798)...
Matt Mackall -
r26215:72aad184 default
parent child Browse files
Show More
@@ -1,959 +1,962 b''
1 # templater.py - template expansion for output
1 # templater.py - template expansion for output
2 #
2 #
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005, 2006 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 os
10 import os
11 import re
11 import re
12 import types
12 import types
13
13
14 from .i18n import _
14 from .i18n import _
15 from . import (
15 from . import (
16 config,
16 config,
17 error,
17 error,
18 minirst,
18 minirst,
19 parser,
19 parser,
20 revset as revsetmod,
20 revset as revsetmod,
21 templatefilters,
21 templatefilters,
22 templatekw,
22 templatekw,
23 util,
23 util,
24 )
24 )
25
25
26 # template parsing
26 # template parsing
27
27
28 elements = {
28 elements = {
29 # token-type: binding-strength, primary, prefix, infix, suffix
29 # token-type: binding-strength, primary, prefix, infix, suffix
30 "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None),
30 "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None),
31 ",": (2, None, None, ("list", 2), None),
31 ",": (2, None, None, ("list", 2), None),
32 "|": (5, None, None, ("|", 5), None),
32 "|": (5, None, None, ("|", 5), None),
33 "%": (6, None, None, ("%", 6), None),
33 "%": (6, None, None, ("%", 6), None),
34 ")": (0, None, None, None, None),
34 ")": (0, None, None, None, None),
35 "integer": (0, "integer", None, None, None),
35 "integer": (0, "integer", None, None, None),
36 "symbol": (0, "symbol", None, None, None),
36 "symbol": (0, "symbol", None, None, None),
37 "string": (0, "string", None, None, None),
37 "string": (0, "string", None, None, None),
38 "template": (0, "template", None, None, None),
38 "template": (0, "template", None, None, None),
39 "end": (0, None, None, None, None),
39 "end": (0, None, None, None, None),
40 }
40 }
41
41
42 def _unescape(s):
43 try:
44 return s.decode("string_escape")
45 except ValueError as e:
46 # mangle Python's exception into our format
47 raise error.ParseError(str(e).lower())
48
42 def tokenize(program, start, end):
49 def tokenize(program, start, end):
43 pos = start
50 pos = start
44 while pos < end:
51 while pos < end:
45 c = program[pos]
52 c = program[pos]
46 if c.isspace(): # skip inter-token whitespace
53 if c.isspace(): # skip inter-token whitespace
47 pass
54 pass
48 elif c in "(,)%|": # handle simple operators
55 elif c in "(,)%|": # handle simple operators
49 yield (c, None, pos)
56 yield (c, None, pos)
50 elif c in '"\'': # handle quoted templates
57 elif c in '"\'': # handle quoted templates
51 s = pos + 1
58 s = pos + 1
52 data, pos = _parsetemplate(program, s, end, c)
59 data, pos = _parsetemplate(program, s, end, c)
53 yield ('template', data, s)
60 yield ('template', data, s)
54 pos -= 1
61 pos -= 1
55 elif c == 'r' and program[pos:pos + 2] in ("r'", 'r"'):
62 elif c == 'r' and program[pos:pos + 2] in ("r'", 'r"'):
56 # handle quoted strings
63 # handle quoted strings
57 c = program[pos + 1]
64 c = program[pos + 1]
58 s = pos = pos + 2
65 s = pos = pos + 2
59 while pos < end: # find closing quote
66 while pos < end: # find closing quote
60 d = program[pos]
67 d = program[pos]
61 if d == '\\': # skip over escaped characters
68 if d == '\\': # skip over escaped characters
62 pos += 2
69 pos += 2
63 continue
70 continue
64 if d == c:
71 if d == c:
65 yield ('string', program[s:pos], s)
72 yield ('string', program[s:pos], s)
66 break
73 break
67 pos += 1
74 pos += 1
68 else:
75 else:
69 raise error.ParseError(_("unterminated string"), s)
76 raise error.ParseError(_("unterminated string"), s)
70 elif c.isdigit() or c == '-':
77 elif c.isdigit() or c == '-':
71 s = pos
78 s = pos
72 if c == '-': # simply take negate operator as part of integer
79 if c == '-': # simply take negate operator as part of integer
73 pos += 1
80 pos += 1
74 if pos >= end or not program[pos].isdigit():
81 if pos >= end or not program[pos].isdigit():
75 raise error.ParseError(_("integer literal without digits"), s)
82 raise error.ParseError(_("integer literal without digits"), s)
76 pos += 1
83 pos += 1
77 while pos < end:
84 while pos < end:
78 d = program[pos]
85 d = program[pos]
79 if not d.isdigit():
86 if not d.isdigit():
80 break
87 break
81 pos += 1
88 pos += 1
82 yield ('integer', program[s:pos], s)
89 yield ('integer', program[s:pos], s)
83 pos -= 1
90 pos -= 1
84 elif (c == '\\' and program[pos:pos + 2] in (r"\'", r'\"')
91 elif (c == '\\' and program[pos:pos + 2] in (r"\'", r'\"')
85 or c == 'r' and program[pos:pos + 3] in (r"r\'", r'r\"')):
92 or c == 'r' and program[pos:pos + 3] in (r"r\'", r'r\"')):
86 # handle escaped quoted strings for compatibility with 2.9.2-3.4,
93 # handle escaped quoted strings for compatibility with 2.9.2-3.4,
87 # where some of nested templates were preprocessed as strings and
94 # where some of nested templates were preprocessed as strings and
88 # then compiled. therefore, \"...\" was allowed. (issue4733)
95 # then compiled. therefore, \"...\" was allowed. (issue4733)
89 #
96 #
90 # processing flow of _evalifliteral() at 5ab28a2e9962:
97 # processing flow of _evalifliteral() at 5ab28a2e9962:
91 # outer template string -> stringify() -> compiletemplate()
98 # outer template string -> stringify() -> compiletemplate()
92 # ------------------------ ------------ ------------------
99 # ------------------------ ------------ ------------------
93 # {f("\\\\ {g(\"\\\"\")}"} \\ {g("\"")} [r'\\', {g("\"")}]
100 # {f("\\\\ {g(\"\\\"\")}"} \\ {g("\"")} [r'\\', {g("\"")}]
94 # ~~~~~~~~
101 # ~~~~~~~~
95 # escaped quoted string
102 # escaped quoted string
96 if c == 'r':
103 if c == 'r':
97 pos += 1
104 pos += 1
98 token = 'string'
105 token = 'string'
99 else:
106 else:
100 token = 'template'
107 token = 'template'
101 quote = program[pos:pos + 2]
108 quote = program[pos:pos + 2]
102 s = pos = pos + 2
109 s = pos = pos + 2
103 while pos < end: # find closing escaped quote
110 while pos < end: # find closing escaped quote
104 if program.startswith('\\\\\\', pos, end):
111 if program.startswith('\\\\\\', pos, end):
105 pos += 4 # skip over double escaped characters
112 pos += 4 # skip over double escaped characters
106 continue
113 continue
107 if program.startswith(quote, pos, end):
114 if program.startswith(quote, pos, end):
108 try:
109 # interpret as if it were a part of an outer string
115 # interpret as if it were a part of an outer string
110 data = program[s:pos].decode('string-escape')
116 data = _unescape(program[s:pos])
111 except ValueError: # unbalanced escapes
112 raise error.ParseError(_("syntax error"), s)
113 if token == 'template':
117 if token == 'template':
114 data = _parsetemplate(data, 0, len(data))[0]
118 data = _parsetemplate(data, 0, len(data))[0]
115 yield (token, data, s)
119 yield (token, data, s)
116 pos += 1
120 pos += 1
117 break
121 break
118 pos += 1
122 pos += 1
119 else:
123 else:
120 raise error.ParseError(_("unterminated string"), s)
124 raise error.ParseError(_("unterminated string"), s)
121 elif c.isalnum() or c in '_':
125 elif c.isalnum() or c in '_':
122 s = pos
126 s = pos
123 pos += 1
127 pos += 1
124 while pos < end: # find end of symbol
128 while pos < end: # find end of symbol
125 d = program[pos]
129 d = program[pos]
126 if not (d.isalnum() or d == "_"):
130 if not (d.isalnum() or d == "_"):
127 break
131 break
128 pos += 1
132 pos += 1
129 sym = program[s:pos]
133 sym = program[s:pos]
130 yield ('symbol', sym, s)
134 yield ('symbol', sym, s)
131 pos -= 1
135 pos -= 1
132 elif c == '}':
136 elif c == '}':
133 yield ('end', None, pos + 1)
137 yield ('end', None, pos + 1)
134 return
138 return
135 else:
139 else:
136 raise error.ParseError(_("syntax error"), pos)
140 raise error.ParseError(_("syntax error"), pos)
137 pos += 1
141 pos += 1
138 raise error.ParseError(_("unterminated template expansion"), start)
142 raise error.ParseError(_("unterminated template expansion"), start)
139
143
140 def _parsetemplate(tmpl, start, stop, quote=''):
144 def _parsetemplate(tmpl, start, stop, quote=''):
141 r"""
145 r"""
142 >>> _parsetemplate('foo{bar}"baz', 0, 12)
146 >>> _parsetemplate('foo{bar}"baz', 0, 12)
143 ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12)
147 ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12)
144 >>> _parsetemplate('foo{bar}"baz', 0, 12, quote='"')
148 >>> _parsetemplate('foo{bar}"baz', 0, 12, quote='"')
145 ([('string', 'foo'), ('symbol', 'bar')], 9)
149 ([('string', 'foo'), ('symbol', 'bar')], 9)
146 >>> _parsetemplate('foo"{bar}', 0, 9, quote='"')
150 >>> _parsetemplate('foo"{bar}', 0, 9, quote='"')
147 ([('string', 'foo')], 4)
151 ([('string', 'foo')], 4)
148 >>> _parsetemplate(r'foo\"bar"baz', 0, 12, quote='"')
152 >>> _parsetemplate(r'foo\"bar"baz', 0, 12, quote='"')
149 ([('string', 'foo"'), ('string', 'bar')], 9)
153 ([('string', 'foo"'), ('string', 'bar')], 9)
150 >>> _parsetemplate(r'foo\\"bar', 0, 10, quote='"')
154 >>> _parsetemplate(r'foo\\"bar', 0, 10, quote='"')
151 ([('string', 'foo\\')], 6)
155 ([('string', 'foo\\')], 6)
152 """
156 """
153 parsed = []
157 parsed = []
154 sepchars = '{' + quote
158 sepchars = '{' + quote
155 pos = start
159 pos = start
156 p = parser.parser(elements)
160 p = parser.parser(elements)
157 while pos < stop:
161 while pos < stop:
158 n = min((tmpl.find(c, pos, stop) for c in sepchars),
162 n = min((tmpl.find(c, pos, stop) for c in sepchars),
159 key=lambda n: (n < 0, n))
163 key=lambda n: (n < 0, n))
160 if n < 0:
164 if n < 0:
161 parsed.append(('string', tmpl[pos:stop].decode('string-escape')))
165 parsed.append(('string', _unescape(tmpl[pos:stop])))
162 pos = stop
166 pos = stop
163 break
167 break
164 c = tmpl[n]
168 c = tmpl[n]
165 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
169 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
166 if bs % 2 == 1:
170 if bs % 2 == 1:
167 # escaped (e.g. '\{', '\\\{', but not '\\{')
171 # escaped (e.g. '\{', '\\\{', but not '\\{')
168 parsed.append(('string',
172 parsed.append(('string', _unescape(tmpl[pos:n - 1]) + c))
169 tmpl[pos:n - 1].decode('string-escape') + c))
170 pos = n + 1
173 pos = n + 1
171 continue
174 continue
172 if n > pos:
175 if n > pos:
173 parsed.append(('string', tmpl[pos:n].decode('string-escape')))
176 parsed.append(('string', _unescape(tmpl[pos:n])))
174 if c == quote:
177 if c == quote:
175 return parsed, n + 1
178 return parsed, n + 1
176
179
177 parseres, pos = p.parse(tokenize(tmpl, n + 1, stop))
180 parseres, pos = p.parse(tokenize(tmpl, n + 1, stop))
178 parsed.append(parseres)
181 parsed.append(parseres)
179
182
180 if quote:
183 if quote:
181 raise error.ParseError(_("unterminated string"), start)
184 raise error.ParseError(_("unterminated string"), start)
182 return parsed, pos
185 return parsed, pos
183
186
184 def compiletemplate(tmpl, context):
187 def compiletemplate(tmpl, context):
185 parsed, pos = _parsetemplate(tmpl, 0, len(tmpl))
188 parsed, pos = _parsetemplate(tmpl, 0, len(tmpl))
186 return [compileexp(e, context, methods) for e in parsed]
189 return [compileexp(e, context, methods) for e in parsed]
187
190
188 def compileexp(exp, context, curmethods):
191 def compileexp(exp, context, curmethods):
189 t = exp[0]
192 t = exp[0]
190 if t in curmethods:
193 if t in curmethods:
191 return curmethods[t](exp, context)
194 return curmethods[t](exp, context)
192 raise error.ParseError(_("unknown method '%s'") % t)
195 raise error.ParseError(_("unknown method '%s'") % t)
193
196
194 # template evaluation
197 # template evaluation
195
198
196 def getsymbol(exp):
199 def getsymbol(exp):
197 if exp[0] == 'symbol':
200 if exp[0] == 'symbol':
198 return exp[1]
201 return exp[1]
199 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
202 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
200
203
201 def getlist(x):
204 def getlist(x):
202 if not x:
205 if not x:
203 return []
206 return []
204 if x[0] == 'list':
207 if x[0] == 'list':
205 return getlist(x[1]) + [x[2]]
208 return getlist(x[1]) + [x[2]]
206 return [x]
209 return [x]
207
210
208 def gettemplate(exp, context):
211 def gettemplate(exp, context):
209 if exp[0] == 'template':
212 if exp[0] == 'template':
210 return [compileexp(e, context, methods) for e in exp[1]]
213 return [compileexp(e, context, methods) for e in exp[1]]
211 if exp[0] == 'symbol':
214 if exp[0] == 'symbol':
212 # unlike runsymbol(), here 'symbol' is always taken as template name
215 # unlike runsymbol(), here 'symbol' is always taken as template name
213 # even if it exists in mapping. this allows us to override mapping
216 # even if it exists in mapping. this allows us to override mapping
214 # by web templates, e.g. 'changelogtag' is redefined in map file.
217 # by web templates, e.g. 'changelogtag' is redefined in map file.
215 return context._load(exp[1])
218 return context._load(exp[1])
216 raise error.ParseError(_("expected template specifier"))
219 raise error.ParseError(_("expected template specifier"))
217
220
218 def evalfuncarg(context, mapping, arg):
221 def evalfuncarg(context, mapping, arg):
219 func, data = arg
222 func, data = arg
220 # func() may return string, generator of strings or arbitrary object such
223 # func() may return string, generator of strings or arbitrary object such
221 # as date tuple, but filter does not want generator.
224 # as date tuple, but filter does not want generator.
222 thing = func(context, mapping, data)
225 thing = func(context, mapping, data)
223 if isinstance(thing, types.GeneratorType):
226 if isinstance(thing, types.GeneratorType):
224 thing = stringify(thing)
227 thing = stringify(thing)
225 return thing
228 return thing
226
229
227 def runinteger(context, mapping, data):
230 def runinteger(context, mapping, data):
228 return int(data)
231 return int(data)
229
232
230 def runstring(context, mapping, data):
233 def runstring(context, mapping, data):
231 return data
234 return data
232
235
233 def runsymbol(context, mapping, key):
236 def runsymbol(context, mapping, key):
234 v = mapping.get(key)
237 v = mapping.get(key)
235 if v is None:
238 if v is None:
236 v = context._defaults.get(key)
239 v = context._defaults.get(key)
237 if v is None:
240 if v is None:
238 try:
241 try:
239 v = context.process(key, mapping)
242 v = context.process(key, mapping)
240 except TemplateNotFound:
243 except TemplateNotFound:
241 v = ''
244 v = ''
242 if callable(v):
245 if callable(v):
243 return v(**mapping)
246 return v(**mapping)
244 if isinstance(v, types.GeneratorType):
247 if isinstance(v, types.GeneratorType):
245 v = list(v)
248 v = list(v)
246 return v
249 return v
247
250
248 def buildtemplate(exp, context):
251 def buildtemplate(exp, context):
249 ctmpl = [compileexp(e, context, methods) for e in exp[1]]
252 ctmpl = [compileexp(e, context, methods) for e in exp[1]]
250 if len(ctmpl) == 1:
253 if len(ctmpl) == 1:
251 return ctmpl[0] # fast path for string with no template fragment
254 return ctmpl[0] # fast path for string with no template fragment
252 return (runtemplate, ctmpl)
255 return (runtemplate, ctmpl)
253
256
254 def runtemplate(context, mapping, template):
257 def runtemplate(context, mapping, template):
255 for func, data in template:
258 for func, data in template:
256 yield func(context, mapping, data)
259 yield func(context, mapping, data)
257
260
258 def buildfilter(exp, context):
261 def buildfilter(exp, context):
259 arg = compileexp(exp[1], context, methods)
262 arg = compileexp(exp[1], context, methods)
260 n = getsymbol(exp[2])
263 n = getsymbol(exp[2])
261 if n in context._filters:
264 if n in context._filters:
262 filt = context._filters[n]
265 filt = context._filters[n]
263 return (runfilter, (arg, filt))
266 return (runfilter, (arg, filt))
264 if n in funcs:
267 if n in funcs:
265 f = funcs[n]
268 f = funcs[n]
266 return (f, [arg])
269 return (f, [arg])
267 raise error.ParseError(_("unknown function '%s'") % n)
270 raise error.ParseError(_("unknown function '%s'") % n)
268
271
269 def runfilter(context, mapping, data):
272 def runfilter(context, mapping, data):
270 arg, filt = data
273 arg, filt = data
271 thing = evalfuncarg(context, mapping, arg)
274 thing = evalfuncarg(context, mapping, arg)
272 try:
275 try:
273 return filt(thing)
276 return filt(thing)
274 except (ValueError, AttributeError, TypeError):
277 except (ValueError, AttributeError, TypeError):
275 if isinstance(arg[1], tuple):
278 if isinstance(arg[1], tuple):
276 dt = arg[1][1]
279 dt = arg[1][1]
277 else:
280 else:
278 dt = arg[1]
281 dt = arg[1]
279 raise util.Abort(_("template filter '%s' is not compatible with "
282 raise util.Abort(_("template filter '%s' is not compatible with "
280 "keyword '%s'") % (filt.func_name, dt))
283 "keyword '%s'") % (filt.func_name, dt))
281
284
282 def buildmap(exp, context):
285 def buildmap(exp, context):
283 func, data = compileexp(exp[1], context, methods)
286 func, data = compileexp(exp[1], context, methods)
284 ctmpl = gettemplate(exp[2], context)
287 ctmpl = gettemplate(exp[2], context)
285 return (runmap, (func, data, ctmpl))
288 return (runmap, (func, data, ctmpl))
286
289
287 def runmap(context, mapping, data):
290 def runmap(context, mapping, data):
288 func, data, ctmpl = data
291 func, data, ctmpl = data
289 d = func(context, mapping, data)
292 d = func(context, mapping, data)
290 if callable(d):
293 if callable(d):
291 d = d()
294 d = d()
292
295
293 lm = mapping.copy()
296 lm = mapping.copy()
294
297
295 for i in d:
298 for i in d:
296 if isinstance(i, dict):
299 if isinstance(i, dict):
297 lm.update(i)
300 lm.update(i)
298 lm['originalnode'] = mapping.get('node')
301 lm['originalnode'] = mapping.get('node')
299 yield runtemplate(context, lm, ctmpl)
302 yield runtemplate(context, lm, ctmpl)
300 else:
303 else:
301 # v is not an iterable of dicts, this happen when 'key'
304 # v is not an iterable of dicts, this happen when 'key'
302 # has been fully expanded already and format is useless.
305 # has been fully expanded already and format is useless.
303 # If so, return the expanded value.
306 # If so, return the expanded value.
304 yield i
307 yield i
305
308
306 def buildfunc(exp, context):
309 def buildfunc(exp, context):
307 n = getsymbol(exp[1])
310 n = getsymbol(exp[1])
308 args = [compileexp(x, context, exprmethods) for x in getlist(exp[2])]
311 args = [compileexp(x, context, exprmethods) for x in getlist(exp[2])]
309 if n in funcs:
312 if n in funcs:
310 f = funcs[n]
313 f = funcs[n]
311 return (f, args)
314 return (f, args)
312 if n in context._filters:
315 if n in context._filters:
313 if len(args) != 1:
316 if len(args) != 1:
314 raise error.ParseError(_("filter %s expects one argument") % n)
317 raise error.ParseError(_("filter %s expects one argument") % n)
315 f = context._filters[n]
318 f = context._filters[n]
316 return (runfilter, (args[0], f))
319 return (runfilter, (args[0], f))
317 raise error.ParseError(_("unknown function '%s'") % n)
320 raise error.ParseError(_("unknown function '%s'") % n)
318
321
319 def date(context, mapping, args):
322 def date(context, mapping, args):
320 """:date(date[, fmt]): Format a date. See :hg:`help dates` for formatting
323 """:date(date[, fmt]): Format a date. See :hg:`help dates` for formatting
321 strings. The default is a Unix date format, including the timezone:
324 strings. The default is a Unix date format, including the timezone:
322 "Mon Sep 04 15:13:13 2006 0700"."""
325 "Mon Sep 04 15:13:13 2006 0700"."""
323 if not (1 <= len(args) <= 2):
326 if not (1 <= len(args) <= 2):
324 # i18n: "date" is a keyword
327 # i18n: "date" is a keyword
325 raise error.ParseError(_("date expects one or two arguments"))
328 raise error.ParseError(_("date expects one or two arguments"))
326
329
327 date = args[0][0](context, mapping, args[0][1])
330 date = args[0][0](context, mapping, args[0][1])
328 fmt = None
331 fmt = None
329 if len(args) == 2:
332 if len(args) == 2:
330 fmt = stringify(args[1][0](context, mapping, args[1][1]))
333 fmt = stringify(args[1][0](context, mapping, args[1][1]))
331 try:
334 try:
332 if fmt is None:
335 if fmt is None:
333 return util.datestr(date)
336 return util.datestr(date)
334 else:
337 else:
335 return util.datestr(date, fmt)
338 return util.datestr(date, fmt)
336 except (TypeError, ValueError):
339 except (TypeError, ValueError):
337 # i18n: "date" is a keyword
340 # i18n: "date" is a keyword
338 raise error.ParseError(_("date expects a date information"))
341 raise error.ParseError(_("date expects a date information"))
339
342
340 def diff(context, mapping, args):
343 def diff(context, mapping, args):
341 """:diff([includepattern [, excludepattern]]): Show a diff, optionally
344 """:diff([includepattern [, excludepattern]]): Show a diff, optionally
342 specifying files to include or exclude."""
345 specifying files to include or exclude."""
343 if len(args) > 2:
346 if len(args) > 2:
344 # i18n: "diff" is a keyword
347 # i18n: "diff" is a keyword
345 raise error.ParseError(_("diff expects one, two or no arguments"))
348 raise error.ParseError(_("diff expects one, two or no arguments"))
346
349
347 def getpatterns(i):
350 def getpatterns(i):
348 if i < len(args):
351 if i < len(args):
349 s = stringify(args[i][0](context, mapping, args[i][1])).strip()
352 s = stringify(args[i][0](context, mapping, args[i][1])).strip()
350 if s:
353 if s:
351 return [s]
354 return [s]
352 return []
355 return []
353
356
354 ctx = mapping['ctx']
357 ctx = mapping['ctx']
355 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
358 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
356
359
357 return ''.join(chunks)
360 return ''.join(chunks)
358
361
359 def fill(context, mapping, args):
362 def fill(context, mapping, args):
360 """:fill(text[, width[, initialident[, hangindent]]]): Fill many
363 """:fill(text[, width[, initialident[, hangindent]]]): Fill many
361 paragraphs with optional indentation. See the "fill" filter."""
364 paragraphs with optional indentation. See the "fill" filter."""
362 if not (1 <= len(args) <= 4):
365 if not (1 <= len(args) <= 4):
363 # i18n: "fill" is a keyword
366 # i18n: "fill" is a keyword
364 raise error.ParseError(_("fill expects one to four arguments"))
367 raise error.ParseError(_("fill expects one to four arguments"))
365
368
366 text = stringify(args[0][0](context, mapping, args[0][1]))
369 text = stringify(args[0][0](context, mapping, args[0][1]))
367 width = 76
370 width = 76
368 initindent = ''
371 initindent = ''
369 hangindent = ''
372 hangindent = ''
370 if 2 <= len(args) <= 4:
373 if 2 <= len(args) <= 4:
371 try:
374 try:
372 width = int(stringify(args[1][0](context, mapping, args[1][1])))
375 width = int(stringify(args[1][0](context, mapping, args[1][1])))
373 except ValueError:
376 except ValueError:
374 # i18n: "fill" is a keyword
377 # i18n: "fill" is a keyword
375 raise error.ParseError(_("fill expects an integer width"))
378 raise error.ParseError(_("fill expects an integer width"))
376 try:
379 try:
377 initindent = stringify(args[2][0](context, mapping, args[2][1]))
380 initindent = stringify(args[2][0](context, mapping, args[2][1]))
378 hangindent = stringify(args[3][0](context, mapping, args[3][1]))
381 hangindent = stringify(args[3][0](context, mapping, args[3][1]))
379 except IndexError:
382 except IndexError:
380 pass
383 pass
381
384
382 return templatefilters.fill(text, width, initindent, hangindent)
385 return templatefilters.fill(text, width, initindent, hangindent)
383
386
384 def pad(context, mapping, args):
387 def pad(context, mapping, args):
385 """:pad(text, width[, fillchar=' '[, right=False]]): Pad text with a
388 """:pad(text, width[, fillchar=' '[, right=False]]): Pad text with a
386 fill character."""
389 fill character."""
387 if not (2 <= len(args) <= 4):
390 if not (2 <= len(args) <= 4):
388 # i18n: "pad" is a keyword
391 # i18n: "pad" is a keyword
389 raise error.ParseError(_("pad() expects two to four arguments"))
392 raise error.ParseError(_("pad() expects two to four arguments"))
390
393
391 width = int(args[1][1])
394 width = int(args[1][1])
392
395
393 text = stringify(args[0][0](context, mapping, args[0][1]))
396 text = stringify(args[0][0](context, mapping, args[0][1]))
394
397
395 right = False
398 right = False
396 fillchar = ' '
399 fillchar = ' '
397 if len(args) > 2:
400 if len(args) > 2:
398 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
401 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
399 if len(args) > 3:
402 if len(args) > 3:
400 right = util.parsebool(args[3][1])
403 right = util.parsebool(args[3][1])
401
404
402 if right:
405 if right:
403 return text.rjust(width, fillchar)
406 return text.rjust(width, fillchar)
404 else:
407 else:
405 return text.ljust(width, fillchar)
408 return text.ljust(width, fillchar)
406
409
407 def indent(context, mapping, args):
410 def indent(context, mapping, args):
408 """:indent(text, indentchars[, firstline]): Indents all non-empty lines
411 """:indent(text, indentchars[, firstline]): Indents all non-empty lines
409 with the characters given in the indentchars string. An optional
412 with the characters given in the indentchars string. An optional
410 third parameter will override the indent for the first line only
413 third parameter will override the indent for the first line only
411 if present."""
414 if present."""
412 if not (2 <= len(args) <= 3):
415 if not (2 <= len(args) <= 3):
413 # i18n: "indent" is a keyword
416 # i18n: "indent" is a keyword
414 raise error.ParseError(_("indent() expects two or three arguments"))
417 raise error.ParseError(_("indent() expects two or three arguments"))
415
418
416 text = stringify(args[0][0](context, mapping, args[0][1]))
419 text = stringify(args[0][0](context, mapping, args[0][1]))
417 indent = stringify(args[1][0](context, mapping, args[1][1]))
420 indent = stringify(args[1][0](context, mapping, args[1][1]))
418
421
419 if len(args) == 3:
422 if len(args) == 3:
420 firstline = stringify(args[2][0](context, mapping, args[2][1]))
423 firstline = stringify(args[2][0](context, mapping, args[2][1]))
421 else:
424 else:
422 firstline = indent
425 firstline = indent
423
426
424 # the indent function doesn't indent the first line, so we do it here
427 # the indent function doesn't indent the first line, so we do it here
425 return templatefilters.indent(firstline + text, indent)
428 return templatefilters.indent(firstline + text, indent)
426
429
427 def get(context, mapping, args):
430 def get(context, mapping, args):
428 """:get(dict, key): Get an attribute/key from an object. Some keywords
431 """:get(dict, key): Get an attribute/key from an object. Some keywords
429 are complex types. This function allows you to obtain the value of an
432 are complex types. This function allows you to obtain the value of an
430 attribute on these types."""
433 attribute on these types."""
431 if len(args) != 2:
434 if len(args) != 2:
432 # i18n: "get" is a keyword
435 # i18n: "get" is a keyword
433 raise error.ParseError(_("get() expects two arguments"))
436 raise error.ParseError(_("get() expects two arguments"))
434
437
435 dictarg = args[0][0](context, mapping, args[0][1])
438 dictarg = args[0][0](context, mapping, args[0][1])
436 if not util.safehasattr(dictarg, 'get'):
439 if not util.safehasattr(dictarg, 'get'):
437 # i18n: "get" is a keyword
440 # i18n: "get" is a keyword
438 raise error.ParseError(_("get() expects a dict as first argument"))
441 raise error.ParseError(_("get() expects a dict as first argument"))
439
442
440 key = args[1][0](context, mapping, args[1][1])
443 key = args[1][0](context, mapping, args[1][1])
441 yield dictarg.get(key)
444 yield dictarg.get(key)
442
445
443 def if_(context, mapping, args):
446 def if_(context, mapping, args):
444 """:if(expr, then[, else]): Conditionally execute based on the result of
447 """:if(expr, then[, else]): Conditionally execute based on the result of
445 an expression."""
448 an expression."""
446 if not (2 <= len(args) <= 3):
449 if not (2 <= len(args) <= 3):
447 # i18n: "if" is a keyword
450 # i18n: "if" is a keyword
448 raise error.ParseError(_("if expects two or three arguments"))
451 raise error.ParseError(_("if expects two or three arguments"))
449
452
450 test = stringify(args[0][0](context, mapping, args[0][1]))
453 test = stringify(args[0][0](context, mapping, args[0][1]))
451 if test:
454 if test:
452 yield args[1][0](context, mapping, args[1][1])
455 yield args[1][0](context, mapping, args[1][1])
453 elif len(args) == 3:
456 elif len(args) == 3:
454 yield args[2][0](context, mapping, args[2][1])
457 yield args[2][0](context, mapping, args[2][1])
455
458
456 def ifcontains(context, mapping, args):
459 def ifcontains(context, mapping, args):
457 """:ifcontains(search, thing, then[, else]): Conditionally execute based
460 """:ifcontains(search, thing, then[, else]): Conditionally execute based
458 on whether the item "search" is in "thing"."""
461 on whether the item "search" is in "thing"."""
459 if not (3 <= len(args) <= 4):
462 if not (3 <= len(args) <= 4):
460 # i18n: "ifcontains" is a keyword
463 # i18n: "ifcontains" is a keyword
461 raise error.ParseError(_("ifcontains expects three or four arguments"))
464 raise error.ParseError(_("ifcontains expects three or four arguments"))
462
465
463 item = stringify(args[0][0](context, mapping, args[0][1]))
466 item = stringify(args[0][0](context, mapping, args[0][1]))
464 items = args[1][0](context, mapping, args[1][1])
467 items = args[1][0](context, mapping, args[1][1])
465
468
466 if item in items:
469 if item in items:
467 yield args[2][0](context, mapping, args[2][1])
470 yield args[2][0](context, mapping, args[2][1])
468 elif len(args) == 4:
471 elif len(args) == 4:
469 yield args[3][0](context, mapping, args[3][1])
472 yield args[3][0](context, mapping, args[3][1])
470
473
471 def ifeq(context, mapping, args):
474 def ifeq(context, mapping, args):
472 """:ifeq(expr1, expr2, then[, else]): Conditionally execute based on
475 """:ifeq(expr1, expr2, then[, else]): Conditionally execute based on
473 whether 2 items are equivalent."""
476 whether 2 items are equivalent."""
474 if not (3 <= len(args) <= 4):
477 if not (3 <= len(args) <= 4):
475 # i18n: "ifeq" is a keyword
478 # i18n: "ifeq" is a keyword
476 raise error.ParseError(_("ifeq expects three or four arguments"))
479 raise error.ParseError(_("ifeq expects three or four arguments"))
477
480
478 test = stringify(args[0][0](context, mapping, args[0][1]))
481 test = stringify(args[0][0](context, mapping, args[0][1]))
479 match = stringify(args[1][0](context, mapping, args[1][1]))
482 match = stringify(args[1][0](context, mapping, args[1][1]))
480 if test == match:
483 if test == match:
481 yield args[2][0](context, mapping, args[2][1])
484 yield args[2][0](context, mapping, args[2][1])
482 elif len(args) == 4:
485 elif len(args) == 4:
483 yield args[3][0](context, mapping, args[3][1])
486 yield args[3][0](context, mapping, args[3][1])
484
487
485 def join(context, mapping, args):
488 def join(context, mapping, args):
486 """:join(list, sep): Join items in a list with a delimiter."""
489 """:join(list, sep): Join items in a list with a delimiter."""
487 if not (1 <= len(args) <= 2):
490 if not (1 <= len(args) <= 2):
488 # i18n: "join" is a keyword
491 # i18n: "join" is a keyword
489 raise error.ParseError(_("join expects one or two arguments"))
492 raise error.ParseError(_("join expects one or two arguments"))
490
493
491 joinset = args[0][0](context, mapping, args[0][1])
494 joinset = args[0][0](context, mapping, args[0][1])
492 if callable(joinset):
495 if callable(joinset):
493 jf = joinset.joinfmt
496 jf = joinset.joinfmt
494 joinset = [jf(x) for x in joinset()]
497 joinset = [jf(x) for x in joinset()]
495
498
496 joiner = " "
499 joiner = " "
497 if len(args) > 1:
500 if len(args) > 1:
498 joiner = stringify(args[1][0](context, mapping, args[1][1]))
501 joiner = stringify(args[1][0](context, mapping, args[1][1]))
499
502
500 first = True
503 first = True
501 for x in joinset:
504 for x in joinset:
502 if first:
505 if first:
503 first = False
506 first = False
504 else:
507 else:
505 yield joiner
508 yield joiner
506 yield x
509 yield x
507
510
508 def label(context, mapping, args):
511 def label(context, mapping, args):
509 """:label(label, expr): Apply a label to generated content. Content with
512 """:label(label, expr): Apply a label to generated content. Content with
510 a label applied can result in additional post-processing, such as
513 a label applied can result in additional post-processing, such as
511 automatic colorization."""
514 automatic colorization."""
512 if len(args) != 2:
515 if len(args) != 2:
513 # i18n: "label" is a keyword
516 # i18n: "label" is a keyword
514 raise error.ParseError(_("label expects two arguments"))
517 raise error.ParseError(_("label expects two arguments"))
515
518
516 # ignore args[0] (the label string) since this is supposed to be a a no-op
519 # ignore args[0] (the label string) since this is supposed to be a a no-op
517 yield args[1][0](context, mapping, args[1][1])
520 yield args[1][0](context, mapping, args[1][1])
518
521
519 def localdate(context, mapping, args):
522 def localdate(context, mapping, args):
520 """:localdate(date[, tz]): Converts a date to the specified timezone.
523 """:localdate(date[, tz]): Converts a date to the specified timezone.
521 The default is local date."""
524 The default is local date."""
522 if not (1 <= len(args) <= 2):
525 if not (1 <= len(args) <= 2):
523 # i18n: "localdate" is a keyword
526 # i18n: "localdate" is a keyword
524 raise error.ParseError(_("localdate expects one or two arguments"))
527 raise error.ParseError(_("localdate expects one or two arguments"))
525
528
526 date = evalfuncarg(context, mapping, args[0])
529 date = evalfuncarg(context, mapping, args[0])
527 try:
530 try:
528 date = util.parsedate(date)
531 date = util.parsedate(date)
529 except AttributeError: # not str nor date tuple
532 except AttributeError: # not str nor date tuple
530 # i18n: "localdate" is a keyword
533 # i18n: "localdate" is a keyword
531 raise error.ParseError(_("localdate expects a date information"))
534 raise error.ParseError(_("localdate expects a date information"))
532 if len(args) >= 2:
535 if len(args) >= 2:
533 tzoffset = None
536 tzoffset = None
534 tz = evalfuncarg(context, mapping, args[1])
537 tz = evalfuncarg(context, mapping, args[1])
535 if isinstance(tz, str):
538 if isinstance(tz, str):
536 tzoffset = util.parsetimezone(tz)
539 tzoffset = util.parsetimezone(tz)
537 if tzoffset is None:
540 if tzoffset is None:
538 try:
541 try:
539 tzoffset = int(tz)
542 tzoffset = int(tz)
540 except (TypeError, ValueError):
543 except (TypeError, ValueError):
541 # i18n: "localdate" is a keyword
544 # i18n: "localdate" is a keyword
542 raise error.ParseError(_("localdate expects a timezone"))
545 raise error.ParseError(_("localdate expects a timezone"))
543 else:
546 else:
544 tzoffset = util.makedate()[1]
547 tzoffset = util.makedate()[1]
545 return (date[0], tzoffset)
548 return (date[0], tzoffset)
546
549
547 def revset(context, mapping, args):
550 def revset(context, mapping, args):
548 """:revset(query[, formatargs...]): Execute a revision set query. See
551 """:revset(query[, formatargs...]): Execute a revision set query. See
549 :hg:`help revset`."""
552 :hg:`help revset`."""
550 if not len(args) > 0:
553 if not len(args) > 0:
551 # i18n: "revset" is a keyword
554 # i18n: "revset" is a keyword
552 raise error.ParseError(_("revset expects one or more arguments"))
555 raise error.ParseError(_("revset expects one or more arguments"))
553
556
554 raw = stringify(args[0][0](context, mapping, args[0][1]))
557 raw = stringify(args[0][0](context, mapping, args[0][1]))
555 ctx = mapping['ctx']
558 ctx = mapping['ctx']
556 repo = ctx.repo()
559 repo = ctx.repo()
557
560
558 def query(expr):
561 def query(expr):
559 m = revsetmod.match(repo.ui, expr)
562 m = revsetmod.match(repo.ui, expr)
560 return m(repo)
563 return m(repo)
561
564
562 if len(args) > 1:
565 if len(args) > 1:
563 formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
566 formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
564 revs = query(revsetmod.formatspec(raw, *formatargs))
567 revs = query(revsetmod.formatspec(raw, *formatargs))
565 revs = list([str(r) for r in revs])
568 revs = list([str(r) for r in revs])
566 else:
569 else:
567 revsetcache = mapping['cache'].setdefault("revsetcache", {})
570 revsetcache = mapping['cache'].setdefault("revsetcache", {})
568 if raw in revsetcache:
571 if raw in revsetcache:
569 revs = revsetcache[raw]
572 revs = revsetcache[raw]
570 else:
573 else:
571 revs = query(raw)
574 revs = query(raw)
572 revs = list([str(r) for r in revs])
575 revs = list([str(r) for r in revs])
573 revsetcache[raw] = revs
576 revsetcache[raw] = revs
574
577
575 return templatekw.showlist("revision", revs, **mapping)
578 return templatekw.showlist("revision", revs, **mapping)
576
579
577 def rstdoc(context, mapping, args):
580 def rstdoc(context, mapping, args):
578 """:rstdoc(text, style): Format ReStructuredText."""
581 """:rstdoc(text, style): Format ReStructuredText."""
579 if len(args) != 2:
582 if len(args) != 2:
580 # i18n: "rstdoc" is a keyword
583 # i18n: "rstdoc" is a keyword
581 raise error.ParseError(_("rstdoc expects two arguments"))
584 raise error.ParseError(_("rstdoc expects two arguments"))
582
585
583 text = stringify(args[0][0](context, mapping, args[0][1]))
586 text = stringify(args[0][0](context, mapping, args[0][1]))
584 style = stringify(args[1][0](context, mapping, args[1][1]))
587 style = stringify(args[1][0](context, mapping, args[1][1]))
585
588
586 return minirst.format(text, style=style, keep=['verbose'])
589 return minirst.format(text, style=style, keep=['verbose'])
587
590
588 def shortest(context, mapping, args):
591 def shortest(context, mapping, args):
589 """:shortest(node, minlength=4): Obtain the shortest representation of
592 """:shortest(node, minlength=4): Obtain the shortest representation of
590 a node."""
593 a node."""
591 if not (1 <= len(args) <= 2):
594 if not (1 <= len(args) <= 2):
592 # i18n: "shortest" is a keyword
595 # i18n: "shortest" is a keyword
593 raise error.ParseError(_("shortest() expects one or two arguments"))
596 raise error.ParseError(_("shortest() expects one or two arguments"))
594
597
595 node = stringify(args[0][0](context, mapping, args[0][1]))
598 node = stringify(args[0][0](context, mapping, args[0][1]))
596
599
597 minlength = 4
600 minlength = 4
598 if len(args) > 1:
601 if len(args) > 1:
599 minlength = int(args[1][1])
602 minlength = int(args[1][1])
600
603
601 cl = mapping['ctx']._repo.changelog
604 cl = mapping['ctx']._repo.changelog
602 def isvalid(test):
605 def isvalid(test):
603 try:
606 try:
604 try:
607 try:
605 cl.index.partialmatch(test)
608 cl.index.partialmatch(test)
606 except AttributeError:
609 except AttributeError:
607 # Pure mercurial doesn't support partialmatch on the index.
610 # Pure mercurial doesn't support partialmatch on the index.
608 # Fallback to the slow way.
611 # Fallback to the slow way.
609 if cl._partialmatch(test) is None:
612 if cl._partialmatch(test) is None:
610 return False
613 return False
611
614
612 try:
615 try:
613 i = int(test)
616 i = int(test)
614 # if we are a pure int, then starting with zero will not be
617 # if we are a pure int, then starting with zero will not be
615 # confused as a rev; or, obviously, if the int is larger than
618 # confused as a rev; or, obviously, if the int is larger than
616 # the value of the tip rev
619 # the value of the tip rev
617 if test[0] == '0' or i > len(cl):
620 if test[0] == '0' or i > len(cl):
618 return True
621 return True
619 return False
622 return False
620 except ValueError:
623 except ValueError:
621 return True
624 return True
622 except error.RevlogError:
625 except error.RevlogError:
623 return False
626 return False
624
627
625 shortest = node
628 shortest = node
626 startlength = max(6, minlength)
629 startlength = max(6, minlength)
627 length = startlength
630 length = startlength
628 while True:
631 while True:
629 test = node[:length]
632 test = node[:length]
630 if isvalid(test):
633 if isvalid(test):
631 shortest = test
634 shortest = test
632 if length == minlength or length > startlength:
635 if length == minlength or length > startlength:
633 return shortest
636 return shortest
634 length -= 1
637 length -= 1
635 else:
638 else:
636 length += 1
639 length += 1
637 if len(shortest) <= length:
640 if len(shortest) <= length:
638 return shortest
641 return shortest
639
642
640 def strip(context, mapping, args):
643 def strip(context, mapping, args):
641 """:strip(text[, chars]): Strip characters from a string. By default,
644 """:strip(text[, chars]): Strip characters from a string. By default,
642 strips all leading and trailing whitespace."""
645 strips all leading and trailing whitespace."""
643 if not (1 <= len(args) <= 2):
646 if not (1 <= len(args) <= 2):
644 # i18n: "strip" is a keyword
647 # i18n: "strip" is a keyword
645 raise error.ParseError(_("strip expects one or two arguments"))
648 raise error.ParseError(_("strip expects one or two arguments"))
646
649
647 text = stringify(args[0][0](context, mapping, args[0][1]))
650 text = stringify(args[0][0](context, mapping, args[0][1]))
648 if len(args) == 2:
651 if len(args) == 2:
649 chars = stringify(args[1][0](context, mapping, args[1][1]))
652 chars = stringify(args[1][0](context, mapping, args[1][1]))
650 return text.strip(chars)
653 return text.strip(chars)
651 return text.strip()
654 return text.strip()
652
655
653 def sub(context, mapping, args):
656 def sub(context, mapping, args):
654 """:sub(pattern, replacement, expression): Perform text substitution
657 """:sub(pattern, replacement, expression): Perform text substitution
655 using regular expressions."""
658 using regular expressions."""
656 if len(args) != 3:
659 if len(args) != 3:
657 # i18n: "sub" is a keyword
660 # i18n: "sub" is a keyword
658 raise error.ParseError(_("sub expects three arguments"))
661 raise error.ParseError(_("sub expects three arguments"))
659
662
660 pat = stringify(args[0][0](context, mapping, args[0][1]))
663 pat = stringify(args[0][0](context, mapping, args[0][1]))
661 rpl = stringify(args[1][0](context, mapping, args[1][1]))
664 rpl = stringify(args[1][0](context, mapping, args[1][1]))
662 src = stringify(args[2][0](context, mapping, args[2][1]))
665 src = stringify(args[2][0](context, mapping, args[2][1]))
663 try:
666 try:
664 patre = re.compile(pat)
667 patre = re.compile(pat)
665 except re.error:
668 except re.error:
666 # i18n: "sub" is a keyword
669 # i18n: "sub" is a keyword
667 raise error.ParseError(_("sub got an invalid pattern: %s") % pat)
670 raise error.ParseError(_("sub got an invalid pattern: %s") % pat)
668 try:
671 try:
669 yield patre.sub(rpl, src)
672 yield patre.sub(rpl, src)
670 except re.error:
673 except re.error:
671 # i18n: "sub" is a keyword
674 # i18n: "sub" is a keyword
672 raise error.ParseError(_("sub got an invalid replacement: %s") % rpl)
675 raise error.ParseError(_("sub got an invalid replacement: %s") % rpl)
673
676
674 def startswith(context, mapping, args):
677 def startswith(context, mapping, args):
675 """:startswith(pattern, text): Returns the value from the "text" argument
678 """:startswith(pattern, text): Returns the value from the "text" argument
676 if it begins with the content from the "pattern" argument."""
679 if it begins with the content from the "pattern" argument."""
677 if len(args) != 2:
680 if len(args) != 2:
678 # i18n: "startswith" is a keyword
681 # i18n: "startswith" is a keyword
679 raise error.ParseError(_("startswith expects two arguments"))
682 raise error.ParseError(_("startswith expects two arguments"))
680
683
681 patn = stringify(args[0][0](context, mapping, args[0][1]))
684 patn = stringify(args[0][0](context, mapping, args[0][1]))
682 text = stringify(args[1][0](context, mapping, args[1][1]))
685 text = stringify(args[1][0](context, mapping, args[1][1]))
683 if text.startswith(patn):
686 if text.startswith(patn):
684 return text
687 return text
685 return ''
688 return ''
686
689
687
690
688 def word(context, mapping, args):
691 def word(context, mapping, args):
689 """:word(number, text[, separator]): Return the nth word from a string."""
692 """:word(number, text[, separator]): Return the nth word from a string."""
690 if not (2 <= len(args) <= 3):
693 if not (2 <= len(args) <= 3):
691 # i18n: "word" is a keyword
694 # i18n: "word" is a keyword
692 raise error.ParseError(_("word expects two or three arguments, got %d")
695 raise error.ParseError(_("word expects two or three arguments, got %d")
693 % len(args))
696 % len(args))
694
697
695 try:
698 try:
696 num = int(stringify(args[0][0](context, mapping, args[0][1])))
699 num = int(stringify(args[0][0](context, mapping, args[0][1])))
697 except ValueError:
700 except ValueError:
698 # i18n: "word" is a keyword
701 # i18n: "word" is a keyword
699 raise error.ParseError(_("word expects an integer index"))
702 raise error.ParseError(_("word expects an integer index"))
700 text = stringify(args[1][0](context, mapping, args[1][1]))
703 text = stringify(args[1][0](context, mapping, args[1][1]))
701 if len(args) == 3:
704 if len(args) == 3:
702 splitter = stringify(args[2][0](context, mapping, args[2][1]))
705 splitter = stringify(args[2][0](context, mapping, args[2][1]))
703 else:
706 else:
704 splitter = None
707 splitter = None
705
708
706 tokens = text.split(splitter)
709 tokens = text.split(splitter)
707 if num >= len(tokens):
710 if num >= len(tokens):
708 return ''
711 return ''
709 else:
712 else:
710 return tokens[num]
713 return tokens[num]
711
714
712 # methods to interpret function arguments or inner expressions (e.g. {_(x)})
715 # methods to interpret function arguments or inner expressions (e.g. {_(x)})
713 exprmethods = {
716 exprmethods = {
714 "integer": lambda e, c: (runinteger, e[1]),
717 "integer": lambda e, c: (runinteger, e[1]),
715 "string": lambda e, c: (runstring, e[1]),
718 "string": lambda e, c: (runstring, e[1]),
716 "symbol": lambda e, c: (runsymbol, e[1]),
719 "symbol": lambda e, c: (runsymbol, e[1]),
717 "template": buildtemplate,
720 "template": buildtemplate,
718 "group": lambda e, c: compileexp(e[1], c, exprmethods),
721 "group": lambda e, c: compileexp(e[1], c, exprmethods),
719 # ".": buildmember,
722 # ".": buildmember,
720 "|": buildfilter,
723 "|": buildfilter,
721 "%": buildmap,
724 "%": buildmap,
722 "func": buildfunc,
725 "func": buildfunc,
723 }
726 }
724
727
725 # methods to interpret top-level template (e.g. {x}, {x|_}, {x % "y"})
728 # methods to interpret top-level template (e.g. {x}, {x|_}, {x % "y"})
726 methods = exprmethods.copy()
729 methods = exprmethods.copy()
727 methods["integer"] = exprmethods["symbol"] # '{1}' as variable
730 methods["integer"] = exprmethods["symbol"] # '{1}' as variable
728
731
729 funcs = {
732 funcs = {
730 "date": date,
733 "date": date,
731 "diff": diff,
734 "diff": diff,
732 "fill": fill,
735 "fill": fill,
733 "get": get,
736 "get": get,
734 "if": if_,
737 "if": if_,
735 "ifcontains": ifcontains,
738 "ifcontains": ifcontains,
736 "ifeq": ifeq,
739 "ifeq": ifeq,
737 "indent": indent,
740 "indent": indent,
738 "join": join,
741 "join": join,
739 "label": label,
742 "label": label,
740 "localdate": localdate,
743 "localdate": localdate,
741 "pad": pad,
744 "pad": pad,
742 "revset": revset,
745 "revset": revset,
743 "rstdoc": rstdoc,
746 "rstdoc": rstdoc,
744 "shortest": shortest,
747 "shortest": shortest,
745 "startswith": startswith,
748 "startswith": startswith,
746 "strip": strip,
749 "strip": strip,
747 "sub": sub,
750 "sub": sub,
748 "word": word,
751 "word": word,
749 }
752 }
750
753
751 # template engine
754 # template engine
752
755
753 stringify = templatefilters.stringify
756 stringify = templatefilters.stringify
754
757
755 def _flatten(thing):
758 def _flatten(thing):
756 '''yield a single stream from a possibly nested set of iterators'''
759 '''yield a single stream from a possibly nested set of iterators'''
757 if isinstance(thing, str):
760 if isinstance(thing, str):
758 yield thing
761 yield thing
759 elif not util.safehasattr(thing, '__iter__'):
762 elif not util.safehasattr(thing, '__iter__'):
760 if thing is not None:
763 if thing is not None:
761 yield str(thing)
764 yield str(thing)
762 else:
765 else:
763 for i in thing:
766 for i in thing:
764 if isinstance(i, str):
767 if isinstance(i, str):
765 yield i
768 yield i
766 elif not util.safehasattr(i, '__iter__'):
769 elif not util.safehasattr(i, '__iter__'):
767 if i is not None:
770 if i is not None:
768 yield str(i)
771 yield str(i)
769 elif i is not None:
772 elif i is not None:
770 for j in _flatten(i):
773 for j in _flatten(i):
771 yield j
774 yield j
772
775
773 def unquotestring(s):
776 def unquotestring(s):
774 '''unwrap quotes'''
777 '''unwrap quotes'''
775 if len(s) < 2 or s[0] != s[-1]:
778 if len(s) < 2 or s[0] != s[-1]:
776 raise SyntaxError(_('unmatched quotes'))
779 raise SyntaxError(_('unmatched quotes'))
777 return s[1:-1]
780 return s[1:-1]
778
781
779 class engine(object):
782 class engine(object):
780 '''template expansion engine.
783 '''template expansion engine.
781
784
782 template expansion works like this. a map file contains key=value
785 template expansion works like this. a map file contains key=value
783 pairs. if value is quoted, it is treated as string. otherwise, it
786 pairs. if value is quoted, it is treated as string. otherwise, it
784 is treated as name of template file.
787 is treated as name of template file.
785
788
786 templater is asked to expand a key in map. it looks up key, and
789 templater is asked to expand a key in map. it looks up key, and
787 looks for strings like this: {foo}. it expands {foo} by looking up
790 looks for strings like this: {foo}. it expands {foo} by looking up
788 foo in map, and substituting it. expansion is recursive: it stops
791 foo in map, and substituting it. expansion is recursive: it stops
789 when there is no more {foo} to replace.
792 when there is no more {foo} to replace.
790
793
791 expansion also allows formatting and filtering.
794 expansion also allows formatting and filtering.
792
795
793 format uses key to expand each item in list. syntax is
796 format uses key to expand each item in list. syntax is
794 {key%format}.
797 {key%format}.
795
798
796 filter uses function to transform value. syntax is
799 filter uses function to transform value. syntax is
797 {key|filter1|filter2|...}.'''
800 {key|filter1|filter2|...}.'''
798
801
799 def __init__(self, loader, filters={}, defaults={}):
802 def __init__(self, loader, filters={}, defaults={}):
800 self._loader = loader
803 self._loader = loader
801 self._filters = filters
804 self._filters = filters
802 self._defaults = defaults
805 self._defaults = defaults
803 self._cache = {}
806 self._cache = {}
804
807
805 def _load(self, t):
808 def _load(self, t):
806 '''load, parse, and cache a template'''
809 '''load, parse, and cache a template'''
807 if t not in self._cache:
810 if t not in self._cache:
808 self._cache[t] = compiletemplate(self._loader(t), self)
811 self._cache[t] = compiletemplate(self._loader(t), self)
809 return self._cache[t]
812 return self._cache[t]
810
813
811 def process(self, t, mapping):
814 def process(self, t, mapping):
812 '''Perform expansion. t is name of map element to expand.
815 '''Perform expansion. t is name of map element to expand.
813 mapping contains added elements for use during expansion. Is a
816 mapping contains added elements for use during expansion. Is a
814 generator.'''
817 generator.'''
815 return _flatten(runtemplate(self, mapping, self._load(t)))
818 return _flatten(runtemplate(self, mapping, self._load(t)))
816
819
817 engines = {'default': engine}
820 engines = {'default': engine}
818
821
819 def stylelist():
822 def stylelist():
820 paths = templatepaths()
823 paths = templatepaths()
821 if not paths:
824 if not paths:
822 return _('no templates found, try `hg debuginstall` for more info')
825 return _('no templates found, try `hg debuginstall` for more info')
823 dirlist = os.listdir(paths[0])
826 dirlist = os.listdir(paths[0])
824 stylelist = []
827 stylelist = []
825 for file in dirlist:
828 for file in dirlist:
826 split = file.split(".")
829 split = file.split(".")
827 if split[0] == "map-cmdline":
830 if split[0] == "map-cmdline":
828 stylelist.append(split[1])
831 stylelist.append(split[1])
829 return ", ".join(sorted(stylelist))
832 return ", ".join(sorted(stylelist))
830
833
831 class TemplateNotFound(util.Abort):
834 class TemplateNotFound(util.Abort):
832 pass
835 pass
833
836
834 class templater(object):
837 class templater(object):
835
838
836 def __init__(self, mapfile, filters={}, defaults={}, cache={},
839 def __init__(self, mapfile, filters={}, defaults={}, cache={},
837 minchunk=1024, maxchunk=65536):
840 minchunk=1024, maxchunk=65536):
838 '''set up template engine.
841 '''set up template engine.
839 mapfile is name of file to read map definitions from.
842 mapfile is name of file to read map definitions from.
840 filters is dict of functions. each transforms a value into another.
843 filters is dict of functions. each transforms a value into another.
841 defaults is dict of default map definitions.'''
844 defaults is dict of default map definitions.'''
842 self.mapfile = mapfile or 'template'
845 self.mapfile = mapfile or 'template'
843 self.cache = cache.copy()
846 self.cache = cache.copy()
844 self.map = {}
847 self.map = {}
845 if mapfile:
848 if mapfile:
846 self.base = os.path.dirname(mapfile)
849 self.base = os.path.dirname(mapfile)
847 else:
850 else:
848 self.base = ''
851 self.base = ''
849 self.filters = templatefilters.filters.copy()
852 self.filters = templatefilters.filters.copy()
850 self.filters.update(filters)
853 self.filters.update(filters)
851 self.defaults = defaults
854 self.defaults = defaults
852 self.minchunk, self.maxchunk = minchunk, maxchunk
855 self.minchunk, self.maxchunk = minchunk, maxchunk
853 self.ecache = {}
856 self.ecache = {}
854
857
855 if not mapfile:
858 if not mapfile:
856 return
859 return
857 if not os.path.exists(mapfile):
860 if not os.path.exists(mapfile):
858 raise util.Abort(_("style '%s' not found") % mapfile,
861 raise util.Abort(_("style '%s' not found") % mapfile,
859 hint=_("available styles: %s") % stylelist())
862 hint=_("available styles: %s") % stylelist())
860
863
861 conf = config.config(includepaths=templatepaths())
864 conf = config.config(includepaths=templatepaths())
862 conf.read(mapfile)
865 conf.read(mapfile)
863
866
864 for key, val in conf[''].items():
867 for key, val in conf[''].items():
865 if not val:
868 if not val:
866 raise SyntaxError(_('%s: missing value') % conf.source('', key))
869 raise SyntaxError(_('%s: missing value') % conf.source('', key))
867 if val[0] in "'\"":
870 if val[0] in "'\"":
868 try:
871 try:
869 self.cache[key] = unquotestring(val)
872 self.cache[key] = unquotestring(val)
870 except SyntaxError as inst:
873 except SyntaxError as inst:
871 raise SyntaxError('%s: %s' %
874 raise SyntaxError('%s: %s' %
872 (conf.source('', key), inst.args[0]))
875 (conf.source('', key), inst.args[0]))
873 else:
876 else:
874 val = 'default', val
877 val = 'default', val
875 if ':' in val[1]:
878 if ':' in val[1]:
876 val = val[1].split(':', 1)
879 val = val[1].split(':', 1)
877 self.map[key] = val[0], os.path.join(self.base, val[1])
880 self.map[key] = val[0], os.path.join(self.base, val[1])
878
881
879 def __contains__(self, key):
882 def __contains__(self, key):
880 return key in self.cache or key in self.map
883 return key in self.cache or key in self.map
881
884
882 def load(self, t):
885 def load(self, t):
883 '''Get the template for the given template name. Use a local cache.'''
886 '''Get the template for the given template name. Use a local cache.'''
884 if t not in self.cache:
887 if t not in self.cache:
885 try:
888 try:
886 self.cache[t] = util.readfile(self.map[t][1])
889 self.cache[t] = util.readfile(self.map[t][1])
887 except KeyError as inst:
890 except KeyError as inst:
888 raise TemplateNotFound(_('"%s" not in template map') %
891 raise TemplateNotFound(_('"%s" not in template map') %
889 inst.args[0])
892 inst.args[0])
890 except IOError as inst:
893 except IOError as inst:
891 raise IOError(inst.args[0], _('template file %s: %s') %
894 raise IOError(inst.args[0], _('template file %s: %s') %
892 (self.map[t][1], inst.args[1]))
895 (self.map[t][1], inst.args[1]))
893 return self.cache[t]
896 return self.cache[t]
894
897
895 def __call__(self, t, **mapping):
898 def __call__(self, t, **mapping):
896 ttype = t in self.map and self.map[t][0] or 'default'
899 ttype = t in self.map and self.map[t][0] or 'default'
897 if ttype not in self.ecache:
900 if ttype not in self.ecache:
898 self.ecache[ttype] = engines[ttype](self.load,
901 self.ecache[ttype] = engines[ttype](self.load,
899 self.filters, self.defaults)
902 self.filters, self.defaults)
900 proc = self.ecache[ttype]
903 proc = self.ecache[ttype]
901
904
902 stream = proc.process(t, mapping)
905 stream = proc.process(t, mapping)
903 if self.minchunk:
906 if self.minchunk:
904 stream = util.increasingchunks(stream, min=self.minchunk,
907 stream = util.increasingchunks(stream, min=self.minchunk,
905 max=self.maxchunk)
908 max=self.maxchunk)
906 return stream
909 return stream
907
910
908 def templatepaths():
911 def templatepaths():
909 '''return locations used for template files.'''
912 '''return locations used for template files.'''
910 pathsrel = ['templates']
913 pathsrel = ['templates']
911 paths = [os.path.normpath(os.path.join(util.datapath, f))
914 paths = [os.path.normpath(os.path.join(util.datapath, f))
912 for f in pathsrel]
915 for f in pathsrel]
913 return [p for p in paths if os.path.isdir(p)]
916 return [p for p in paths if os.path.isdir(p)]
914
917
915 def templatepath(name):
918 def templatepath(name):
916 '''return location of template file. returns None if not found.'''
919 '''return location of template file. returns None if not found.'''
917 for p in templatepaths():
920 for p in templatepaths():
918 f = os.path.join(p, name)
921 f = os.path.join(p, name)
919 if os.path.exists(f):
922 if os.path.exists(f):
920 return f
923 return f
921 return None
924 return None
922
925
923 def stylemap(styles, paths=None):
926 def stylemap(styles, paths=None):
924 """Return path to mapfile for a given style.
927 """Return path to mapfile for a given style.
925
928
926 Searches mapfile in the following locations:
929 Searches mapfile in the following locations:
927 1. templatepath/style/map
930 1. templatepath/style/map
928 2. templatepath/map-style
931 2. templatepath/map-style
929 3. templatepath/map
932 3. templatepath/map
930 """
933 """
931
934
932 if paths is None:
935 if paths is None:
933 paths = templatepaths()
936 paths = templatepaths()
934 elif isinstance(paths, str):
937 elif isinstance(paths, str):
935 paths = [paths]
938 paths = [paths]
936
939
937 if isinstance(styles, str):
940 if isinstance(styles, str):
938 styles = [styles]
941 styles = [styles]
939
942
940 for style in styles:
943 for style in styles:
941 # only plain name is allowed to honor template paths
944 # only plain name is allowed to honor template paths
942 if (not style
945 if (not style
943 or style in (os.curdir, os.pardir)
946 or style in (os.curdir, os.pardir)
944 or os.sep in style
947 or os.sep in style
945 or os.altsep and os.altsep in style):
948 or os.altsep and os.altsep in style):
946 continue
949 continue
947 locations = [os.path.join(style, 'map'), 'map-' + style]
950 locations = [os.path.join(style, 'map'), 'map-' + style]
948 locations.append('map')
951 locations.append('map')
949
952
950 for path in paths:
953 for path in paths:
951 for location in locations:
954 for location in locations:
952 mapfile = os.path.join(path, location)
955 mapfile = os.path.join(path, location)
953 if os.path.isfile(mapfile):
956 if os.path.isfile(mapfile):
954 return style, mapfile
957 return style, mapfile
955
958
956 raise RuntimeError("No hgweb templates found in %r" % paths)
959 raise RuntimeError("No hgweb templates found in %r" % paths)
957
960
958 # tell hggettext to extract docstrings from these functions:
961 # tell hggettext to extract docstrings from these functions:
959 i18nfunctions = funcs.values()
962 i18nfunctions = funcs.values()
@@ -1,3419 +1,3428 b''
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 Second branch starting at nullrev:
32 Second branch starting at nullrev:
33
33
34 $ hg update null
34 $ hg update null
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
36 $ echo second > second
36 $ echo second > second
37 $ hg add second
37 $ hg add second
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
39 created new head
39 created new head
40
40
41 $ echo third > third
41 $ echo third > third
42 $ hg add third
42 $ hg add third
43 $ hg mv second fourth
43 $ hg mv second fourth
44 $ hg commit -m third -d "2020-01-01 10:01"
44 $ hg commit -m third -d "2020-01-01 10:01"
45
45
46 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
46 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
47 fourth (second)
47 fourth (second)
48 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
48 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
49 second -> fourth
49 second -> fourth
50 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
50 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
51 8 t
51 8 t
52 7 f
52 7 f
53
53
54 Working-directory revision has special identifiers, though they are still
54 Working-directory revision has special identifiers, though they are still
55 experimental:
55 experimental:
56
56
57 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
57 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
58 2147483647:ffffffffffffffffffffffffffffffffffffffff
58 2147483647:ffffffffffffffffffffffffffffffffffffffff
59
59
60 Some keywords are invalid for working-directory revision, but they should
60 Some keywords are invalid for working-directory revision, but they should
61 never cause crash:
61 never cause crash:
62
62
63 $ hg log -r 'wdir()' -T '{manifest}\n'
63 $ hg log -r 'wdir()' -T '{manifest}\n'
64
64
65
65
66 Quoting for ui.logtemplate
66 Quoting for ui.logtemplate
67
67
68 $ hg tip --config "ui.logtemplate={rev}\n"
68 $ hg tip --config "ui.logtemplate={rev}\n"
69 8
69 8
70 $ hg tip --config "ui.logtemplate='{rev}\n'"
70 $ hg tip --config "ui.logtemplate='{rev}\n'"
71 8
71 8
72 $ hg tip --config 'ui.logtemplate="{rev}\n"'
72 $ hg tip --config 'ui.logtemplate="{rev}\n"'
73 8
73 8
74
74
75 Make sure user/global hgrc does not affect tests
75 Make sure user/global hgrc does not affect tests
76
76
77 $ echo '[ui]' > .hg/hgrc
77 $ echo '[ui]' > .hg/hgrc
78 $ echo 'logtemplate =' >> .hg/hgrc
78 $ echo 'logtemplate =' >> .hg/hgrc
79 $ echo 'style =' >> .hg/hgrc
79 $ echo 'style =' >> .hg/hgrc
80
80
81 Add some simple styles to settings
81 Add some simple styles to settings
82
82
83 $ echo '[templates]' >> .hg/hgrc
83 $ echo '[templates]' >> .hg/hgrc
84 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
84 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
85 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
85 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
86
86
87 $ hg log -l1 -Tsimple
87 $ hg log -l1 -Tsimple
88 8
88 8
89 $ hg log -l1 -Tsimple2
89 $ hg log -l1 -Tsimple2
90 8
90 8
91
91
92 Test templates and style maps in files:
92 Test templates and style maps in files:
93
93
94 $ echo "{rev}" > tmpl
94 $ echo "{rev}" > tmpl
95 $ hg log -l1 -T./tmpl
95 $ hg log -l1 -T./tmpl
96 8
96 8
97 $ hg log -l1 -Tblah/blah
97 $ hg log -l1 -Tblah/blah
98 blah/blah (no-eol)
98 blah/blah (no-eol)
99
99
100 $ printf 'changeset = "{rev}\\n"\n' > map-simple
100 $ printf 'changeset = "{rev}\\n"\n' > map-simple
101 $ hg log -l1 -T./map-simple
101 $ hg log -l1 -T./map-simple
102 8
102 8
103
103
104 Template should precede style option
104 Template should precede style option
105
105
106 $ hg log -l1 --style default -T '{rev}\n'
106 $ hg log -l1 --style default -T '{rev}\n'
107 8
107 8
108
108
109 Add a commit with empty description, to ensure that the templates
109 Add a commit with empty description, to ensure that the templates
110 below will omit the description line.
110 below will omit the description line.
111
111
112 $ echo c >> c
112 $ echo c >> c
113 $ hg add c
113 $ hg add c
114 $ hg commit -qm ' '
114 $ hg commit -qm ' '
115
115
116 Default style is like normal output. Phases style should be the same
116 Default style is like normal output. Phases style should be the same
117 as default style, except for extra phase lines.
117 as default style, except for extra phase lines.
118
118
119 $ hg log > log.out
119 $ hg log > log.out
120 $ hg log --style default > style.out
120 $ hg log --style default > style.out
121 $ cmp log.out style.out || diff -u log.out style.out
121 $ cmp log.out style.out || diff -u log.out style.out
122 $ hg log -T phases > phases.out
122 $ hg log -T phases > phases.out
123 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
123 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
124 +phase: draft
124 +phase: draft
125 +phase: draft
125 +phase: draft
126 +phase: draft
126 +phase: draft
127 +phase: draft
127 +phase: draft
128 +phase: draft
128 +phase: draft
129 +phase: draft
129 +phase: draft
130 +phase: draft
130 +phase: draft
131 +phase: draft
131 +phase: draft
132 +phase: draft
132 +phase: draft
133 +phase: draft
133 +phase: draft
134
134
135 $ hg log -v > log.out
135 $ hg log -v > log.out
136 $ hg log -v --style default > style.out
136 $ hg log -v --style default > style.out
137 $ cmp log.out style.out || diff -u log.out style.out
137 $ cmp log.out style.out || diff -u log.out style.out
138 $ hg log -v -T phases > phases.out
138 $ hg log -v -T phases > phases.out
139 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
139 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
140 +phase: draft
140 +phase: draft
141 +phase: draft
141 +phase: draft
142 +phase: draft
142 +phase: draft
143 +phase: draft
143 +phase: draft
144 +phase: draft
144 +phase: draft
145 +phase: draft
145 +phase: draft
146 +phase: draft
146 +phase: draft
147 +phase: draft
147 +phase: draft
148 +phase: draft
148 +phase: draft
149 +phase: draft
149 +phase: draft
150
150
151 $ hg log -q > log.out
151 $ hg log -q > log.out
152 $ hg log -q --style default > style.out
152 $ hg log -q --style default > style.out
153 $ cmp log.out style.out || diff -u log.out style.out
153 $ cmp log.out style.out || diff -u log.out style.out
154 $ hg log -q -T phases > phases.out
154 $ hg log -q -T phases > phases.out
155 $ cmp log.out phases.out || diff -u log.out phases.out
155 $ cmp log.out phases.out || diff -u log.out phases.out
156
156
157 $ hg log --debug > log.out
157 $ hg log --debug > log.out
158 $ hg log --debug --style default > style.out
158 $ hg log --debug --style default > style.out
159 $ cmp log.out style.out || diff -u log.out style.out
159 $ cmp log.out style.out || diff -u log.out style.out
160 $ hg log --debug -T phases > phases.out
160 $ hg log --debug -T phases > phases.out
161 $ cmp log.out phases.out || diff -u log.out phases.out
161 $ cmp log.out phases.out || diff -u log.out phases.out
162
162
163 Default style of working-directory revision should also be the same (but
163 Default style of working-directory revision should also be the same (but
164 date may change while running tests):
164 date may change while running tests):
165
165
166 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
166 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
167 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
167 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
168 $ cmp log.out style.out || diff -u log.out style.out
168 $ cmp log.out style.out || diff -u log.out style.out
169
169
170 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
170 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
171 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
171 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
172 $ cmp log.out style.out || diff -u log.out style.out
172 $ cmp log.out style.out || diff -u log.out style.out
173
173
174 $ hg log -r 'wdir()' -q > log.out
174 $ hg log -r 'wdir()' -q > log.out
175 $ hg log -r 'wdir()' -q --style default > style.out
175 $ hg log -r 'wdir()' -q --style default > style.out
176 $ cmp log.out style.out || diff -u log.out style.out
176 $ cmp log.out style.out || diff -u log.out style.out
177
177
178 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
178 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
179 $ hg log -r 'wdir()' --debug --style default \
179 $ hg log -r 'wdir()' --debug --style default \
180 > | sed 's|^date:.*|date:|' > style.out
180 > | sed 's|^date:.*|date:|' > style.out
181 $ cmp log.out style.out || diff -u log.out style.out
181 $ cmp log.out style.out || diff -u log.out style.out
182
182
183 Default style should also preserve color information (issue2866):
183 Default style should also preserve color information (issue2866):
184
184
185 $ cp $HGRCPATH $HGRCPATH-bak
185 $ cp $HGRCPATH $HGRCPATH-bak
186 $ cat <<EOF >> $HGRCPATH
186 $ cat <<EOF >> $HGRCPATH
187 > [extensions]
187 > [extensions]
188 > color=
188 > color=
189 > EOF
189 > EOF
190
190
191 $ hg --color=debug log > log.out
191 $ hg --color=debug log > log.out
192 $ hg --color=debug log --style default > style.out
192 $ hg --color=debug log --style default > style.out
193 $ cmp log.out style.out || diff -u log.out style.out
193 $ cmp log.out style.out || diff -u log.out style.out
194 $ hg --color=debug log -T phases > phases.out
194 $ hg --color=debug log -T phases > phases.out
195 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
195 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
196 +[log.phase|phase: draft]
196 +[log.phase|phase: draft]
197 +[log.phase|phase: draft]
197 +[log.phase|phase: draft]
198 +[log.phase|phase: draft]
198 +[log.phase|phase: draft]
199 +[log.phase|phase: draft]
199 +[log.phase|phase: draft]
200 +[log.phase|phase: draft]
200 +[log.phase|phase: draft]
201 +[log.phase|phase: draft]
201 +[log.phase|phase: draft]
202 +[log.phase|phase: draft]
202 +[log.phase|phase: draft]
203 +[log.phase|phase: draft]
203 +[log.phase|phase: draft]
204 +[log.phase|phase: draft]
204 +[log.phase|phase: draft]
205 +[log.phase|phase: draft]
205 +[log.phase|phase: draft]
206
206
207 $ hg --color=debug -v log > log.out
207 $ hg --color=debug -v log > log.out
208 $ hg --color=debug -v log --style default > style.out
208 $ hg --color=debug -v log --style default > style.out
209 $ cmp log.out style.out || diff -u log.out style.out
209 $ cmp log.out style.out || diff -u log.out style.out
210 $ hg --color=debug -v log -T phases > phases.out
210 $ hg --color=debug -v log -T phases > phases.out
211 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
211 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
212 +[log.phase|phase: draft]
212 +[log.phase|phase: draft]
213 +[log.phase|phase: draft]
213 +[log.phase|phase: draft]
214 +[log.phase|phase: draft]
214 +[log.phase|phase: draft]
215 +[log.phase|phase: draft]
215 +[log.phase|phase: draft]
216 +[log.phase|phase: draft]
216 +[log.phase|phase: draft]
217 +[log.phase|phase: draft]
217 +[log.phase|phase: draft]
218 +[log.phase|phase: draft]
218 +[log.phase|phase: draft]
219 +[log.phase|phase: draft]
219 +[log.phase|phase: draft]
220 +[log.phase|phase: draft]
220 +[log.phase|phase: draft]
221 +[log.phase|phase: draft]
221 +[log.phase|phase: draft]
222
222
223 $ hg --color=debug -q log > log.out
223 $ hg --color=debug -q log > log.out
224 $ hg --color=debug -q log --style default > style.out
224 $ hg --color=debug -q log --style default > style.out
225 $ cmp log.out style.out || diff -u log.out style.out
225 $ cmp log.out style.out || diff -u log.out style.out
226 $ hg --color=debug -q log -T phases > phases.out
226 $ hg --color=debug -q log -T phases > phases.out
227 $ cmp log.out phases.out || diff -u log.out phases.out
227 $ cmp log.out phases.out || diff -u log.out phases.out
228
228
229 $ hg --color=debug --debug log > log.out
229 $ hg --color=debug --debug log > log.out
230 $ hg --color=debug --debug log --style default > style.out
230 $ hg --color=debug --debug log --style default > style.out
231 $ cmp log.out style.out || diff -u log.out style.out
231 $ cmp log.out style.out || diff -u log.out style.out
232 $ hg --color=debug --debug log -T phases > phases.out
232 $ hg --color=debug --debug log -T phases > phases.out
233 $ cmp log.out phases.out || diff -u log.out phases.out
233 $ cmp log.out phases.out || diff -u log.out phases.out
234
234
235 $ mv $HGRCPATH-bak $HGRCPATH
235 $ mv $HGRCPATH-bak $HGRCPATH
236
236
237 Remove commit with empty commit message, so as to not pollute further
237 Remove commit with empty commit message, so as to not pollute further
238 tests.
238 tests.
239
239
240 $ hg --config extensions.strip= strip -q .
240 $ hg --config extensions.strip= strip -q .
241
241
242 Revision with no copies (used to print a traceback):
242 Revision with no copies (used to print a traceback):
243
243
244 $ hg tip -v --template '\n'
244 $ hg tip -v --template '\n'
245
245
246
246
247 Compact style works:
247 Compact style works:
248
248
249 $ hg log -Tcompact
249 $ hg log -Tcompact
250 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
250 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
251 third
251 third
252
252
253 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
253 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
254 second
254 second
255
255
256 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
256 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
257 merge
257 merge
258
258
259 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
259 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
260 new head
260 new head
261
261
262 4 bbe44766e73d 1970-01-17 04:53 +0000 person
262 4 bbe44766e73d 1970-01-17 04:53 +0000 person
263 new branch
263 new branch
264
264
265 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
265 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
266 no user, no domain
266 no user, no domain
267
267
268 2 97054abb4ab8 1970-01-14 21:20 +0000 other
268 2 97054abb4ab8 1970-01-14 21:20 +0000 other
269 no person
269 no person
270
270
271 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
271 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
272 other 1
272 other 1
273
273
274 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
274 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
275 line 1
275 line 1
276
276
277
277
278 $ hg log -v --style compact
278 $ hg log -v --style compact
279 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
279 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
280 third
280 third
281
281
282 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
282 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
283 second
283 second
284
284
285 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
285 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
286 merge
286 merge
287
287
288 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
288 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
289 new head
289 new head
290
290
291 4 bbe44766e73d 1970-01-17 04:53 +0000 person
291 4 bbe44766e73d 1970-01-17 04:53 +0000 person
292 new branch
292 new branch
293
293
294 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
294 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
295 no user, no domain
295 no user, no domain
296
296
297 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
297 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
298 no person
298 no person
299
299
300 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
300 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
301 other 1
301 other 1
302 other 2
302 other 2
303
303
304 other 3
304 other 3
305
305
306 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
306 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
307 line 1
307 line 1
308 line 2
308 line 2
309
309
310
310
311 $ hg log --debug --style compact
311 $ hg log --debug --style compact
312 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
312 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
313 third
313 third
314
314
315 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
315 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
316 second
316 second
317
317
318 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
318 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
319 merge
319 merge
320
320
321 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
321 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
322 new head
322 new head
323
323
324 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
324 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
325 new branch
325 new branch
326
326
327 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
327 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
328 no user, no domain
328 no user, no domain
329
329
330 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
330 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
331 no person
331 no person
332
332
333 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
333 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
334 other 1
334 other 1
335 other 2
335 other 2
336
336
337 other 3
337 other 3
338
338
339 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
339 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
340 line 1
340 line 1
341 line 2
341 line 2
342
342
343
343
344 Test xml styles:
344 Test xml styles:
345
345
346 $ hg log --style xml
346 $ hg log --style xml
347 <?xml version="1.0"?>
347 <?xml version="1.0"?>
348 <log>
348 <log>
349 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
349 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
350 <tag>tip</tag>
350 <tag>tip</tag>
351 <author email="test">test</author>
351 <author email="test">test</author>
352 <date>2020-01-01T10:01:00+00:00</date>
352 <date>2020-01-01T10:01:00+00:00</date>
353 <msg xml:space="preserve">third</msg>
353 <msg xml:space="preserve">third</msg>
354 </logentry>
354 </logentry>
355 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
355 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
356 <parent revision="-1" node="0000000000000000000000000000000000000000" />
356 <parent revision="-1" node="0000000000000000000000000000000000000000" />
357 <author email="user@hostname">User Name</author>
357 <author email="user@hostname">User Name</author>
358 <date>1970-01-12T13:46:40+00:00</date>
358 <date>1970-01-12T13:46:40+00:00</date>
359 <msg xml:space="preserve">second</msg>
359 <msg xml:space="preserve">second</msg>
360 </logentry>
360 </logentry>
361 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
361 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
362 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
362 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
363 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
363 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
364 <author email="person">person</author>
364 <author email="person">person</author>
365 <date>1970-01-18T08:40:01+00:00</date>
365 <date>1970-01-18T08:40:01+00:00</date>
366 <msg xml:space="preserve">merge</msg>
366 <msg xml:space="preserve">merge</msg>
367 </logentry>
367 </logentry>
368 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
368 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
369 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
369 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
370 <author email="person">person</author>
370 <author email="person">person</author>
371 <date>1970-01-18T08:40:00+00:00</date>
371 <date>1970-01-18T08:40:00+00:00</date>
372 <msg xml:space="preserve">new head</msg>
372 <msg xml:space="preserve">new head</msg>
373 </logentry>
373 </logentry>
374 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
374 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
375 <branch>foo</branch>
375 <branch>foo</branch>
376 <author email="person">person</author>
376 <author email="person">person</author>
377 <date>1970-01-17T04:53:20+00:00</date>
377 <date>1970-01-17T04:53:20+00:00</date>
378 <msg xml:space="preserve">new branch</msg>
378 <msg xml:space="preserve">new branch</msg>
379 </logentry>
379 </logentry>
380 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
380 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
381 <author email="person">person</author>
381 <author email="person">person</author>
382 <date>1970-01-16T01:06:40+00:00</date>
382 <date>1970-01-16T01:06:40+00:00</date>
383 <msg xml:space="preserve">no user, no domain</msg>
383 <msg xml:space="preserve">no user, no domain</msg>
384 </logentry>
384 </logentry>
385 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
385 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
386 <author email="other@place">other</author>
386 <author email="other@place">other</author>
387 <date>1970-01-14T21:20:00+00:00</date>
387 <date>1970-01-14T21:20:00+00:00</date>
388 <msg xml:space="preserve">no person</msg>
388 <msg xml:space="preserve">no person</msg>
389 </logentry>
389 </logentry>
390 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
390 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
391 <author email="other@place">A. N. Other</author>
391 <author email="other@place">A. N. Other</author>
392 <date>1970-01-13T17:33:20+00:00</date>
392 <date>1970-01-13T17:33:20+00:00</date>
393 <msg xml:space="preserve">other 1
393 <msg xml:space="preserve">other 1
394 other 2
394 other 2
395
395
396 other 3</msg>
396 other 3</msg>
397 </logentry>
397 </logentry>
398 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
398 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
399 <author email="user@hostname">User Name</author>
399 <author email="user@hostname">User Name</author>
400 <date>1970-01-12T13:46:40+00:00</date>
400 <date>1970-01-12T13:46:40+00:00</date>
401 <msg xml:space="preserve">line 1
401 <msg xml:space="preserve">line 1
402 line 2</msg>
402 line 2</msg>
403 </logentry>
403 </logentry>
404 </log>
404 </log>
405
405
406 $ hg log -v --style xml
406 $ hg log -v --style xml
407 <?xml version="1.0"?>
407 <?xml version="1.0"?>
408 <log>
408 <log>
409 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
409 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
410 <tag>tip</tag>
410 <tag>tip</tag>
411 <author email="test">test</author>
411 <author email="test">test</author>
412 <date>2020-01-01T10:01:00+00:00</date>
412 <date>2020-01-01T10:01:00+00:00</date>
413 <msg xml:space="preserve">third</msg>
413 <msg xml:space="preserve">third</msg>
414 <paths>
414 <paths>
415 <path action="A">fourth</path>
415 <path action="A">fourth</path>
416 <path action="A">third</path>
416 <path action="A">third</path>
417 <path action="R">second</path>
417 <path action="R">second</path>
418 </paths>
418 </paths>
419 <copies>
419 <copies>
420 <copy source="second">fourth</copy>
420 <copy source="second">fourth</copy>
421 </copies>
421 </copies>
422 </logentry>
422 </logentry>
423 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
423 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
424 <parent revision="-1" node="0000000000000000000000000000000000000000" />
424 <parent revision="-1" node="0000000000000000000000000000000000000000" />
425 <author email="user@hostname">User Name</author>
425 <author email="user@hostname">User Name</author>
426 <date>1970-01-12T13:46:40+00:00</date>
426 <date>1970-01-12T13:46:40+00:00</date>
427 <msg xml:space="preserve">second</msg>
427 <msg xml:space="preserve">second</msg>
428 <paths>
428 <paths>
429 <path action="A">second</path>
429 <path action="A">second</path>
430 </paths>
430 </paths>
431 </logentry>
431 </logentry>
432 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
432 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
433 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
433 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
434 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
434 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
435 <author email="person">person</author>
435 <author email="person">person</author>
436 <date>1970-01-18T08:40:01+00:00</date>
436 <date>1970-01-18T08:40:01+00:00</date>
437 <msg xml:space="preserve">merge</msg>
437 <msg xml:space="preserve">merge</msg>
438 <paths>
438 <paths>
439 </paths>
439 </paths>
440 </logentry>
440 </logentry>
441 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
441 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
442 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
442 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
443 <author email="person">person</author>
443 <author email="person">person</author>
444 <date>1970-01-18T08:40:00+00:00</date>
444 <date>1970-01-18T08:40:00+00:00</date>
445 <msg xml:space="preserve">new head</msg>
445 <msg xml:space="preserve">new head</msg>
446 <paths>
446 <paths>
447 <path action="A">d</path>
447 <path action="A">d</path>
448 </paths>
448 </paths>
449 </logentry>
449 </logentry>
450 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
450 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
451 <branch>foo</branch>
451 <branch>foo</branch>
452 <author email="person">person</author>
452 <author email="person">person</author>
453 <date>1970-01-17T04:53:20+00:00</date>
453 <date>1970-01-17T04:53:20+00:00</date>
454 <msg xml:space="preserve">new branch</msg>
454 <msg xml:space="preserve">new branch</msg>
455 <paths>
455 <paths>
456 </paths>
456 </paths>
457 </logentry>
457 </logentry>
458 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
458 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
459 <author email="person">person</author>
459 <author email="person">person</author>
460 <date>1970-01-16T01:06:40+00:00</date>
460 <date>1970-01-16T01:06:40+00:00</date>
461 <msg xml:space="preserve">no user, no domain</msg>
461 <msg xml:space="preserve">no user, no domain</msg>
462 <paths>
462 <paths>
463 <path action="M">c</path>
463 <path action="M">c</path>
464 </paths>
464 </paths>
465 </logentry>
465 </logentry>
466 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
466 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
467 <author email="other@place">other</author>
467 <author email="other@place">other</author>
468 <date>1970-01-14T21:20:00+00:00</date>
468 <date>1970-01-14T21:20:00+00:00</date>
469 <msg xml:space="preserve">no person</msg>
469 <msg xml:space="preserve">no person</msg>
470 <paths>
470 <paths>
471 <path action="A">c</path>
471 <path action="A">c</path>
472 </paths>
472 </paths>
473 </logentry>
473 </logentry>
474 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
474 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
475 <author email="other@place">A. N. Other</author>
475 <author email="other@place">A. N. Other</author>
476 <date>1970-01-13T17:33:20+00:00</date>
476 <date>1970-01-13T17:33:20+00:00</date>
477 <msg xml:space="preserve">other 1
477 <msg xml:space="preserve">other 1
478 other 2
478 other 2
479
479
480 other 3</msg>
480 other 3</msg>
481 <paths>
481 <paths>
482 <path action="A">b</path>
482 <path action="A">b</path>
483 </paths>
483 </paths>
484 </logentry>
484 </logentry>
485 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
485 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
486 <author email="user@hostname">User Name</author>
486 <author email="user@hostname">User Name</author>
487 <date>1970-01-12T13:46:40+00:00</date>
487 <date>1970-01-12T13:46:40+00:00</date>
488 <msg xml:space="preserve">line 1
488 <msg xml:space="preserve">line 1
489 line 2</msg>
489 line 2</msg>
490 <paths>
490 <paths>
491 <path action="A">a</path>
491 <path action="A">a</path>
492 </paths>
492 </paths>
493 </logentry>
493 </logentry>
494 </log>
494 </log>
495
495
496 $ hg log --debug --style xml
496 $ hg log --debug --style xml
497 <?xml version="1.0"?>
497 <?xml version="1.0"?>
498 <log>
498 <log>
499 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
499 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
500 <tag>tip</tag>
500 <tag>tip</tag>
501 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
501 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
502 <parent revision="-1" node="0000000000000000000000000000000000000000" />
502 <parent revision="-1" node="0000000000000000000000000000000000000000" />
503 <author email="test">test</author>
503 <author email="test">test</author>
504 <date>2020-01-01T10:01:00+00:00</date>
504 <date>2020-01-01T10:01:00+00:00</date>
505 <msg xml:space="preserve">third</msg>
505 <msg xml:space="preserve">third</msg>
506 <paths>
506 <paths>
507 <path action="A">fourth</path>
507 <path action="A">fourth</path>
508 <path action="A">third</path>
508 <path action="A">third</path>
509 <path action="R">second</path>
509 <path action="R">second</path>
510 </paths>
510 </paths>
511 <copies>
511 <copies>
512 <copy source="second">fourth</copy>
512 <copy source="second">fourth</copy>
513 </copies>
513 </copies>
514 <extra key="branch">default</extra>
514 <extra key="branch">default</extra>
515 </logentry>
515 </logentry>
516 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
516 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
517 <parent revision="-1" node="0000000000000000000000000000000000000000" />
517 <parent revision="-1" node="0000000000000000000000000000000000000000" />
518 <parent revision="-1" node="0000000000000000000000000000000000000000" />
518 <parent revision="-1" node="0000000000000000000000000000000000000000" />
519 <author email="user@hostname">User Name</author>
519 <author email="user@hostname">User Name</author>
520 <date>1970-01-12T13:46:40+00:00</date>
520 <date>1970-01-12T13:46:40+00:00</date>
521 <msg xml:space="preserve">second</msg>
521 <msg xml:space="preserve">second</msg>
522 <paths>
522 <paths>
523 <path action="A">second</path>
523 <path action="A">second</path>
524 </paths>
524 </paths>
525 <extra key="branch">default</extra>
525 <extra key="branch">default</extra>
526 </logentry>
526 </logentry>
527 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
527 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
528 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
528 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
529 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
529 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
530 <author email="person">person</author>
530 <author email="person">person</author>
531 <date>1970-01-18T08:40:01+00:00</date>
531 <date>1970-01-18T08:40:01+00:00</date>
532 <msg xml:space="preserve">merge</msg>
532 <msg xml:space="preserve">merge</msg>
533 <paths>
533 <paths>
534 </paths>
534 </paths>
535 <extra key="branch">default</extra>
535 <extra key="branch">default</extra>
536 </logentry>
536 </logentry>
537 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
537 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
538 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
538 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
539 <parent revision="-1" node="0000000000000000000000000000000000000000" />
539 <parent revision="-1" node="0000000000000000000000000000000000000000" />
540 <author email="person">person</author>
540 <author email="person">person</author>
541 <date>1970-01-18T08:40:00+00:00</date>
541 <date>1970-01-18T08:40:00+00:00</date>
542 <msg xml:space="preserve">new head</msg>
542 <msg xml:space="preserve">new head</msg>
543 <paths>
543 <paths>
544 <path action="A">d</path>
544 <path action="A">d</path>
545 </paths>
545 </paths>
546 <extra key="branch">default</extra>
546 <extra key="branch">default</extra>
547 </logentry>
547 </logentry>
548 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
548 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
549 <branch>foo</branch>
549 <branch>foo</branch>
550 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
550 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
551 <parent revision="-1" node="0000000000000000000000000000000000000000" />
551 <parent revision="-1" node="0000000000000000000000000000000000000000" />
552 <author email="person">person</author>
552 <author email="person">person</author>
553 <date>1970-01-17T04:53:20+00:00</date>
553 <date>1970-01-17T04:53:20+00:00</date>
554 <msg xml:space="preserve">new branch</msg>
554 <msg xml:space="preserve">new branch</msg>
555 <paths>
555 <paths>
556 </paths>
556 </paths>
557 <extra key="branch">foo</extra>
557 <extra key="branch">foo</extra>
558 </logentry>
558 </logentry>
559 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
559 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
560 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
560 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
561 <parent revision="-1" node="0000000000000000000000000000000000000000" />
561 <parent revision="-1" node="0000000000000000000000000000000000000000" />
562 <author email="person">person</author>
562 <author email="person">person</author>
563 <date>1970-01-16T01:06:40+00:00</date>
563 <date>1970-01-16T01:06:40+00:00</date>
564 <msg xml:space="preserve">no user, no domain</msg>
564 <msg xml:space="preserve">no user, no domain</msg>
565 <paths>
565 <paths>
566 <path action="M">c</path>
566 <path action="M">c</path>
567 </paths>
567 </paths>
568 <extra key="branch">default</extra>
568 <extra key="branch">default</extra>
569 </logentry>
569 </logentry>
570 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
570 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
571 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
571 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
572 <parent revision="-1" node="0000000000000000000000000000000000000000" />
572 <parent revision="-1" node="0000000000000000000000000000000000000000" />
573 <author email="other@place">other</author>
573 <author email="other@place">other</author>
574 <date>1970-01-14T21:20:00+00:00</date>
574 <date>1970-01-14T21:20:00+00:00</date>
575 <msg xml:space="preserve">no person</msg>
575 <msg xml:space="preserve">no person</msg>
576 <paths>
576 <paths>
577 <path action="A">c</path>
577 <path action="A">c</path>
578 </paths>
578 </paths>
579 <extra key="branch">default</extra>
579 <extra key="branch">default</extra>
580 </logentry>
580 </logentry>
581 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
581 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
582 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
582 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
583 <parent revision="-1" node="0000000000000000000000000000000000000000" />
583 <parent revision="-1" node="0000000000000000000000000000000000000000" />
584 <author email="other@place">A. N. Other</author>
584 <author email="other@place">A. N. Other</author>
585 <date>1970-01-13T17:33:20+00:00</date>
585 <date>1970-01-13T17:33:20+00:00</date>
586 <msg xml:space="preserve">other 1
586 <msg xml:space="preserve">other 1
587 other 2
587 other 2
588
588
589 other 3</msg>
589 other 3</msg>
590 <paths>
590 <paths>
591 <path action="A">b</path>
591 <path action="A">b</path>
592 </paths>
592 </paths>
593 <extra key="branch">default</extra>
593 <extra key="branch">default</extra>
594 </logentry>
594 </logentry>
595 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
595 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
596 <parent revision="-1" node="0000000000000000000000000000000000000000" />
596 <parent revision="-1" node="0000000000000000000000000000000000000000" />
597 <parent revision="-1" node="0000000000000000000000000000000000000000" />
597 <parent revision="-1" node="0000000000000000000000000000000000000000" />
598 <author email="user@hostname">User Name</author>
598 <author email="user@hostname">User Name</author>
599 <date>1970-01-12T13:46:40+00:00</date>
599 <date>1970-01-12T13:46:40+00:00</date>
600 <msg xml:space="preserve">line 1
600 <msg xml:space="preserve">line 1
601 line 2</msg>
601 line 2</msg>
602 <paths>
602 <paths>
603 <path action="A">a</path>
603 <path action="A">a</path>
604 </paths>
604 </paths>
605 <extra key="branch">default</extra>
605 <extra key="branch">default</extra>
606 </logentry>
606 </logentry>
607 </log>
607 </log>
608
608
609
609
610 Test JSON style:
610 Test JSON style:
611
611
612 $ hg log -k nosuch -Tjson
612 $ hg log -k nosuch -Tjson
613 []
613 []
614
614
615 $ hg log -qr . -Tjson
615 $ hg log -qr . -Tjson
616 [
616 [
617 {
617 {
618 "rev": 8,
618 "rev": 8,
619 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
619 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
620 }
620 }
621 ]
621 ]
622
622
623 $ hg log -vpr . -Tjson --stat
623 $ hg log -vpr . -Tjson --stat
624 [
624 [
625 {
625 {
626 "rev": 8,
626 "rev": 8,
627 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
627 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
628 "branch": "default",
628 "branch": "default",
629 "phase": "draft",
629 "phase": "draft",
630 "user": "test",
630 "user": "test",
631 "date": [1577872860, 0],
631 "date": [1577872860, 0],
632 "desc": "third",
632 "desc": "third",
633 "bookmarks": [],
633 "bookmarks": [],
634 "tags": ["tip"],
634 "tags": ["tip"],
635 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
635 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
636 "files": ["fourth", "second", "third"],
636 "files": ["fourth", "second", "third"],
637 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
637 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
638 "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"
638 "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"
639 }
639 }
640 ]
640 ]
641
641
642 honor --git but not format-breaking diffopts
642 honor --git but not format-breaking diffopts
643 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
643 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
644 [
644 [
645 {
645 {
646 "rev": 8,
646 "rev": 8,
647 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
647 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
648 "branch": "default",
648 "branch": "default",
649 "phase": "draft",
649 "phase": "draft",
650 "user": "test",
650 "user": "test",
651 "date": [1577872860, 0],
651 "date": [1577872860, 0],
652 "desc": "third",
652 "desc": "third",
653 "bookmarks": [],
653 "bookmarks": [],
654 "tags": ["tip"],
654 "tags": ["tip"],
655 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
655 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
656 "files": ["fourth", "second", "third"],
656 "files": ["fourth", "second", "third"],
657 "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"
657 "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"
658 }
658 }
659 ]
659 ]
660
660
661 $ hg log -T json
661 $ hg log -T json
662 [
662 [
663 {
663 {
664 "rev": 8,
664 "rev": 8,
665 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
665 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
666 "branch": "default",
666 "branch": "default",
667 "phase": "draft",
667 "phase": "draft",
668 "user": "test",
668 "user": "test",
669 "date": [1577872860, 0],
669 "date": [1577872860, 0],
670 "desc": "third",
670 "desc": "third",
671 "bookmarks": [],
671 "bookmarks": [],
672 "tags": ["tip"],
672 "tags": ["tip"],
673 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
673 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
674 },
674 },
675 {
675 {
676 "rev": 7,
676 "rev": 7,
677 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
677 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
678 "branch": "default",
678 "branch": "default",
679 "phase": "draft",
679 "phase": "draft",
680 "user": "User Name <user@hostname>",
680 "user": "User Name <user@hostname>",
681 "date": [1000000, 0],
681 "date": [1000000, 0],
682 "desc": "second",
682 "desc": "second",
683 "bookmarks": [],
683 "bookmarks": [],
684 "tags": [],
684 "tags": [],
685 "parents": ["0000000000000000000000000000000000000000"]
685 "parents": ["0000000000000000000000000000000000000000"]
686 },
686 },
687 {
687 {
688 "rev": 6,
688 "rev": 6,
689 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
689 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
690 "branch": "default",
690 "branch": "default",
691 "phase": "draft",
691 "phase": "draft",
692 "user": "person",
692 "user": "person",
693 "date": [1500001, 0],
693 "date": [1500001, 0],
694 "desc": "merge",
694 "desc": "merge",
695 "bookmarks": [],
695 "bookmarks": [],
696 "tags": [],
696 "tags": [],
697 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
697 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
698 },
698 },
699 {
699 {
700 "rev": 5,
700 "rev": 5,
701 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
701 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
702 "branch": "default",
702 "branch": "default",
703 "phase": "draft",
703 "phase": "draft",
704 "user": "person",
704 "user": "person",
705 "date": [1500000, 0],
705 "date": [1500000, 0],
706 "desc": "new head",
706 "desc": "new head",
707 "bookmarks": [],
707 "bookmarks": [],
708 "tags": [],
708 "tags": [],
709 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
709 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
710 },
710 },
711 {
711 {
712 "rev": 4,
712 "rev": 4,
713 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
713 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
714 "branch": "foo",
714 "branch": "foo",
715 "phase": "draft",
715 "phase": "draft",
716 "user": "person",
716 "user": "person",
717 "date": [1400000, 0],
717 "date": [1400000, 0],
718 "desc": "new branch",
718 "desc": "new branch",
719 "bookmarks": [],
719 "bookmarks": [],
720 "tags": [],
720 "tags": [],
721 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
721 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
722 },
722 },
723 {
723 {
724 "rev": 3,
724 "rev": 3,
725 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
725 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
726 "branch": "default",
726 "branch": "default",
727 "phase": "draft",
727 "phase": "draft",
728 "user": "person",
728 "user": "person",
729 "date": [1300000, 0],
729 "date": [1300000, 0],
730 "desc": "no user, no domain",
730 "desc": "no user, no domain",
731 "bookmarks": [],
731 "bookmarks": [],
732 "tags": [],
732 "tags": [],
733 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
733 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
734 },
734 },
735 {
735 {
736 "rev": 2,
736 "rev": 2,
737 "node": "97054abb4ab824450e9164180baf491ae0078465",
737 "node": "97054abb4ab824450e9164180baf491ae0078465",
738 "branch": "default",
738 "branch": "default",
739 "phase": "draft",
739 "phase": "draft",
740 "user": "other@place",
740 "user": "other@place",
741 "date": [1200000, 0],
741 "date": [1200000, 0],
742 "desc": "no person",
742 "desc": "no person",
743 "bookmarks": [],
743 "bookmarks": [],
744 "tags": [],
744 "tags": [],
745 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
745 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
746 },
746 },
747 {
747 {
748 "rev": 1,
748 "rev": 1,
749 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
749 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
750 "branch": "default",
750 "branch": "default",
751 "phase": "draft",
751 "phase": "draft",
752 "user": "A. N. Other <other@place>",
752 "user": "A. N. Other <other@place>",
753 "date": [1100000, 0],
753 "date": [1100000, 0],
754 "desc": "other 1\nother 2\n\nother 3",
754 "desc": "other 1\nother 2\n\nother 3",
755 "bookmarks": [],
755 "bookmarks": [],
756 "tags": [],
756 "tags": [],
757 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
757 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
758 },
758 },
759 {
759 {
760 "rev": 0,
760 "rev": 0,
761 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
761 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
762 "branch": "default",
762 "branch": "default",
763 "phase": "draft",
763 "phase": "draft",
764 "user": "User Name <user@hostname>",
764 "user": "User Name <user@hostname>",
765 "date": [1000000, 0],
765 "date": [1000000, 0],
766 "desc": "line 1\nline 2",
766 "desc": "line 1\nline 2",
767 "bookmarks": [],
767 "bookmarks": [],
768 "tags": [],
768 "tags": [],
769 "parents": ["0000000000000000000000000000000000000000"]
769 "parents": ["0000000000000000000000000000000000000000"]
770 }
770 }
771 ]
771 ]
772
772
773 $ hg heads -v -Tjson
773 $ hg heads -v -Tjson
774 [
774 [
775 {
775 {
776 "rev": 8,
776 "rev": 8,
777 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
777 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
778 "branch": "default",
778 "branch": "default",
779 "phase": "draft",
779 "phase": "draft",
780 "user": "test",
780 "user": "test",
781 "date": [1577872860, 0],
781 "date": [1577872860, 0],
782 "desc": "third",
782 "desc": "third",
783 "bookmarks": [],
783 "bookmarks": [],
784 "tags": ["tip"],
784 "tags": ["tip"],
785 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
785 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
786 "files": ["fourth", "second", "third"]
786 "files": ["fourth", "second", "third"]
787 },
787 },
788 {
788 {
789 "rev": 6,
789 "rev": 6,
790 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
790 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
791 "branch": "default",
791 "branch": "default",
792 "phase": "draft",
792 "phase": "draft",
793 "user": "person",
793 "user": "person",
794 "date": [1500001, 0],
794 "date": [1500001, 0],
795 "desc": "merge",
795 "desc": "merge",
796 "bookmarks": [],
796 "bookmarks": [],
797 "tags": [],
797 "tags": [],
798 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
798 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
799 "files": []
799 "files": []
800 },
800 },
801 {
801 {
802 "rev": 4,
802 "rev": 4,
803 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
803 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
804 "branch": "foo",
804 "branch": "foo",
805 "phase": "draft",
805 "phase": "draft",
806 "user": "person",
806 "user": "person",
807 "date": [1400000, 0],
807 "date": [1400000, 0],
808 "desc": "new branch",
808 "desc": "new branch",
809 "bookmarks": [],
809 "bookmarks": [],
810 "tags": [],
810 "tags": [],
811 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
811 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
812 "files": []
812 "files": []
813 }
813 }
814 ]
814 ]
815
815
816 $ hg log --debug -Tjson
816 $ hg log --debug -Tjson
817 [
817 [
818 {
818 {
819 "rev": 8,
819 "rev": 8,
820 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
820 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
821 "branch": "default",
821 "branch": "default",
822 "phase": "draft",
822 "phase": "draft",
823 "user": "test",
823 "user": "test",
824 "date": [1577872860, 0],
824 "date": [1577872860, 0],
825 "desc": "third",
825 "desc": "third",
826 "bookmarks": [],
826 "bookmarks": [],
827 "tags": ["tip"],
827 "tags": ["tip"],
828 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
828 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
829 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
829 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
830 "extra": {"branch": "default"},
830 "extra": {"branch": "default"},
831 "modified": [],
831 "modified": [],
832 "added": ["fourth", "third"],
832 "added": ["fourth", "third"],
833 "removed": ["second"]
833 "removed": ["second"]
834 },
834 },
835 {
835 {
836 "rev": 7,
836 "rev": 7,
837 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
837 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
838 "branch": "default",
838 "branch": "default",
839 "phase": "draft",
839 "phase": "draft",
840 "user": "User Name <user@hostname>",
840 "user": "User Name <user@hostname>",
841 "date": [1000000, 0],
841 "date": [1000000, 0],
842 "desc": "second",
842 "desc": "second",
843 "bookmarks": [],
843 "bookmarks": [],
844 "tags": [],
844 "tags": [],
845 "parents": ["0000000000000000000000000000000000000000"],
845 "parents": ["0000000000000000000000000000000000000000"],
846 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
846 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
847 "extra": {"branch": "default"},
847 "extra": {"branch": "default"},
848 "modified": [],
848 "modified": [],
849 "added": ["second"],
849 "added": ["second"],
850 "removed": []
850 "removed": []
851 },
851 },
852 {
852 {
853 "rev": 6,
853 "rev": 6,
854 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
854 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
855 "branch": "default",
855 "branch": "default",
856 "phase": "draft",
856 "phase": "draft",
857 "user": "person",
857 "user": "person",
858 "date": [1500001, 0],
858 "date": [1500001, 0],
859 "desc": "merge",
859 "desc": "merge",
860 "bookmarks": [],
860 "bookmarks": [],
861 "tags": [],
861 "tags": [],
862 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
862 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
863 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
863 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
864 "extra": {"branch": "default"},
864 "extra": {"branch": "default"},
865 "modified": [],
865 "modified": [],
866 "added": [],
866 "added": [],
867 "removed": []
867 "removed": []
868 },
868 },
869 {
869 {
870 "rev": 5,
870 "rev": 5,
871 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
871 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
872 "branch": "default",
872 "branch": "default",
873 "phase": "draft",
873 "phase": "draft",
874 "user": "person",
874 "user": "person",
875 "date": [1500000, 0],
875 "date": [1500000, 0],
876 "desc": "new head",
876 "desc": "new head",
877 "bookmarks": [],
877 "bookmarks": [],
878 "tags": [],
878 "tags": [],
879 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
879 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
880 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
880 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
881 "extra": {"branch": "default"},
881 "extra": {"branch": "default"},
882 "modified": [],
882 "modified": [],
883 "added": ["d"],
883 "added": ["d"],
884 "removed": []
884 "removed": []
885 },
885 },
886 {
886 {
887 "rev": 4,
887 "rev": 4,
888 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
888 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
889 "branch": "foo",
889 "branch": "foo",
890 "phase": "draft",
890 "phase": "draft",
891 "user": "person",
891 "user": "person",
892 "date": [1400000, 0],
892 "date": [1400000, 0],
893 "desc": "new branch",
893 "desc": "new branch",
894 "bookmarks": [],
894 "bookmarks": [],
895 "tags": [],
895 "tags": [],
896 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
896 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
897 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
897 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
898 "extra": {"branch": "foo"},
898 "extra": {"branch": "foo"},
899 "modified": [],
899 "modified": [],
900 "added": [],
900 "added": [],
901 "removed": []
901 "removed": []
902 },
902 },
903 {
903 {
904 "rev": 3,
904 "rev": 3,
905 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
905 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
906 "branch": "default",
906 "branch": "default",
907 "phase": "draft",
907 "phase": "draft",
908 "user": "person",
908 "user": "person",
909 "date": [1300000, 0],
909 "date": [1300000, 0],
910 "desc": "no user, no domain",
910 "desc": "no user, no domain",
911 "bookmarks": [],
911 "bookmarks": [],
912 "tags": [],
912 "tags": [],
913 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
913 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
914 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
914 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
915 "extra": {"branch": "default"},
915 "extra": {"branch": "default"},
916 "modified": ["c"],
916 "modified": ["c"],
917 "added": [],
917 "added": [],
918 "removed": []
918 "removed": []
919 },
919 },
920 {
920 {
921 "rev": 2,
921 "rev": 2,
922 "node": "97054abb4ab824450e9164180baf491ae0078465",
922 "node": "97054abb4ab824450e9164180baf491ae0078465",
923 "branch": "default",
923 "branch": "default",
924 "phase": "draft",
924 "phase": "draft",
925 "user": "other@place",
925 "user": "other@place",
926 "date": [1200000, 0],
926 "date": [1200000, 0],
927 "desc": "no person",
927 "desc": "no person",
928 "bookmarks": [],
928 "bookmarks": [],
929 "tags": [],
929 "tags": [],
930 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
930 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
931 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
931 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
932 "extra": {"branch": "default"},
932 "extra": {"branch": "default"},
933 "modified": [],
933 "modified": [],
934 "added": ["c"],
934 "added": ["c"],
935 "removed": []
935 "removed": []
936 },
936 },
937 {
937 {
938 "rev": 1,
938 "rev": 1,
939 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
939 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
940 "branch": "default",
940 "branch": "default",
941 "phase": "draft",
941 "phase": "draft",
942 "user": "A. N. Other <other@place>",
942 "user": "A. N. Other <other@place>",
943 "date": [1100000, 0],
943 "date": [1100000, 0],
944 "desc": "other 1\nother 2\n\nother 3",
944 "desc": "other 1\nother 2\n\nother 3",
945 "bookmarks": [],
945 "bookmarks": [],
946 "tags": [],
946 "tags": [],
947 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
947 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
948 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
948 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
949 "extra": {"branch": "default"},
949 "extra": {"branch": "default"},
950 "modified": [],
950 "modified": [],
951 "added": ["b"],
951 "added": ["b"],
952 "removed": []
952 "removed": []
953 },
953 },
954 {
954 {
955 "rev": 0,
955 "rev": 0,
956 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
956 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
957 "branch": "default",
957 "branch": "default",
958 "phase": "draft",
958 "phase": "draft",
959 "user": "User Name <user@hostname>",
959 "user": "User Name <user@hostname>",
960 "date": [1000000, 0],
960 "date": [1000000, 0],
961 "desc": "line 1\nline 2",
961 "desc": "line 1\nline 2",
962 "bookmarks": [],
962 "bookmarks": [],
963 "tags": [],
963 "tags": [],
964 "parents": ["0000000000000000000000000000000000000000"],
964 "parents": ["0000000000000000000000000000000000000000"],
965 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
965 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
966 "extra": {"branch": "default"},
966 "extra": {"branch": "default"},
967 "modified": [],
967 "modified": [],
968 "added": ["a"],
968 "added": ["a"],
969 "removed": []
969 "removed": []
970 }
970 }
971 ]
971 ]
972
972
973 Error if style not readable:
973 Error if style not readable:
974
974
975 #if unix-permissions no-root
975 #if unix-permissions no-root
976 $ touch q
976 $ touch q
977 $ chmod 0 q
977 $ chmod 0 q
978 $ hg log --style ./q
978 $ hg log --style ./q
979 abort: Permission denied: ./q
979 abort: Permission denied: ./q
980 [255]
980 [255]
981 #endif
981 #endif
982
982
983 Error if no style:
983 Error if no style:
984
984
985 $ hg log --style notexist
985 $ hg log --style notexist
986 abort: style 'notexist' not found
986 abort: style 'notexist' not found
987 (available styles: bisect, changelog, compact, default, phases, status, xml)
987 (available styles: bisect, changelog, compact, default, phases, status, xml)
988 [255]
988 [255]
989
989
990 $ hg log -T list
990 $ hg log -T list
991 available styles: bisect, changelog, compact, default, phases, status, xml
991 available styles: bisect, changelog, compact, default, phases, status, xml
992 abort: specify a template
992 abort: specify a template
993 [255]
993 [255]
994
994
995 Error if style missing key:
995 Error if style missing key:
996
996
997 $ echo 'q = q' > t
997 $ echo 'q = q' > t
998 $ hg log --style ./t
998 $ hg log --style ./t
999 abort: "changeset" not in template map
999 abort: "changeset" not in template map
1000 [255]
1000 [255]
1001
1001
1002 Error if style missing value:
1002 Error if style missing value:
1003
1003
1004 $ echo 'changeset =' > t
1004 $ echo 'changeset =' > t
1005 $ hg log --style t
1005 $ hg log --style t
1006 abort: t:1: missing value
1006 abort: t:1: missing value
1007 [255]
1007 [255]
1008
1008
1009 Error if include fails:
1009 Error if include fails:
1010
1010
1011 $ echo 'changeset = q' >> t
1011 $ echo 'changeset = q' >> t
1012 #if unix-permissions no-root
1012 #if unix-permissions no-root
1013 $ hg log --style ./t
1013 $ hg log --style ./t
1014 abort: template file ./q: Permission denied
1014 abort: template file ./q: Permission denied
1015 [255]
1015 [255]
1016 $ rm q
1016 $ rm q
1017 #endif
1017 #endif
1018
1018
1019 Include works:
1019 Include works:
1020
1020
1021 $ echo '{rev}' > q
1021 $ echo '{rev}' > q
1022 $ hg log --style ./t
1022 $ hg log --style ./t
1023 8
1023 8
1024 7
1024 7
1025 6
1025 6
1026 5
1026 5
1027 4
1027 4
1028 3
1028 3
1029 2
1029 2
1030 1
1030 1
1031 0
1031 0
1032
1032
1033 Check that {phase} works correctly on parents:
1033 Check that {phase} works correctly on parents:
1034
1034
1035 $ cat << EOF > parentphase
1035 $ cat << EOF > parentphase
1036 > changeset_debug = '{rev} ({phase}):{parents}\n'
1036 > changeset_debug = '{rev} ({phase}):{parents}\n'
1037 > parent = ' {rev} ({phase})'
1037 > parent = ' {rev} ({phase})'
1038 > EOF
1038 > EOF
1039 $ hg phase -r 5 --public
1039 $ hg phase -r 5 --public
1040 $ hg phase -r 7 --secret --force
1040 $ hg phase -r 7 --secret --force
1041 $ hg log --debug -G --style ./parentphase
1041 $ hg log --debug -G --style ./parentphase
1042 @ 8 (secret): 7 (secret) -1 (public)
1042 @ 8 (secret): 7 (secret) -1 (public)
1043 |
1043 |
1044 o 7 (secret): -1 (public) -1 (public)
1044 o 7 (secret): -1 (public) -1 (public)
1045
1045
1046 o 6 (draft): 5 (public) 4 (draft)
1046 o 6 (draft): 5 (public) 4 (draft)
1047 |\
1047 |\
1048 | o 5 (public): 3 (public) -1 (public)
1048 | o 5 (public): 3 (public) -1 (public)
1049 | |
1049 | |
1050 o | 4 (draft): 3 (public) -1 (public)
1050 o | 4 (draft): 3 (public) -1 (public)
1051 |/
1051 |/
1052 o 3 (public): 2 (public) -1 (public)
1052 o 3 (public): 2 (public) -1 (public)
1053 |
1053 |
1054 o 2 (public): 1 (public) -1 (public)
1054 o 2 (public): 1 (public) -1 (public)
1055 |
1055 |
1056 o 1 (public): 0 (public) -1 (public)
1056 o 1 (public): 0 (public) -1 (public)
1057 |
1057 |
1058 o 0 (public): -1 (public) -1 (public)
1058 o 0 (public): -1 (public) -1 (public)
1059
1059
1060
1060
1061 Missing non-standard names give no error (backward compatibility):
1061 Missing non-standard names give no error (backward compatibility):
1062
1062
1063 $ echo "changeset = '{c}'" > t
1063 $ echo "changeset = '{c}'" > t
1064 $ hg log --style ./t
1064 $ hg log --style ./t
1065
1065
1066 Defining non-standard name works:
1066 Defining non-standard name works:
1067
1067
1068 $ cat <<EOF > t
1068 $ cat <<EOF > t
1069 > changeset = '{c}'
1069 > changeset = '{c}'
1070 > c = q
1070 > c = q
1071 > EOF
1071 > EOF
1072 $ hg log --style ./t
1072 $ hg log --style ./t
1073 8
1073 8
1074 7
1074 7
1075 6
1075 6
1076 5
1076 5
1077 4
1077 4
1078 3
1078 3
1079 2
1079 2
1080 1
1080 1
1081 0
1081 0
1082
1082
1083 ui.style works:
1083 ui.style works:
1084
1084
1085 $ echo '[ui]' > .hg/hgrc
1085 $ echo '[ui]' > .hg/hgrc
1086 $ echo 'style = t' >> .hg/hgrc
1086 $ echo 'style = t' >> .hg/hgrc
1087 $ hg log
1087 $ hg log
1088 8
1088 8
1089 7
1089 7
1090 6
1090 6
1091 5
1091 5
1092 4
1092 4
1093 3
1093 3
1094 2
1094 2
1095 1
1095 1
1096 0
1096 0
1097
1097
1098
1098
1099 Issue338:
1099 Issue338:
1100
1100
1101 $ hg log --style=changelog > changelog
1101 $ hg log --style=changelog > changelog
1102
1102
1103 $ cat changelog
1103 $ cat changelog
1104 2020-01-01 test <test>
1104 2020-01-01 test <test>
1105
1105
1106 * fourth, second, third:
1106 * fourth, second, third:
1107 third
1107 third
1108 [95c24699272e] [tip]
1108 [95c24699272e] [tip]
1109
1109
1110 1970-01-12 User Name <user@hostname>
1110 1970-01-12 User Name <user@hostname>
1111
1111
1112 * second:
1112 * second:
1113 second
1113 second
1114 [29114dbae42b]
1114 [29114dbae42b]
1115
1115
1116 1970-01-18 person <person>
1116 1970-01-18 person <person>
1117
1117
1118 * merge
1118 * merge
1119 [d41e714fe50d]
1119 [d41e714fe50d]
1120
1120
1121 * d:
1121 * d:
1122 new head
1122 new head
1123 [13207e5a10d9]
1123 [13207e5a10d9]
1124
1124
1125 1970-01-17 person <person>
1125 1970-01-17 person <person>
1126
1126
1127 * new branch
1127 * new branch
1128 [bbe44766e73d] <foo>
1128 [bbe44766e73d] <foo>
1129
1129
1130 1970-01-16 person <person>
1130 1970-01-16 person <person>
1131
1131
1132 * c:
1132 * c:
1133 no user, no domain
1133 no user, no domain
1134 [10e46f2dcbf4]
1134 [10e46f2dcbf4]
1135
1135
1136 1970-01-14 other <other@place>
1136 1970-01-14 other <other@place>
1137
1137
1138 * c:
1138 * c:
1139 no person
1139 no person
1140 [97054abb4ab8]
1140 [97054abb4ab8]
1141
1141
1142 1970-01-13 A. N. Other <other@place>
1142 1970-01-13 A. N. Other <other@place>
1143
1143
1144 * b:
1144 * b:
1145 other 1 other 2
1145 other 1 other 2
1146
1146
1147 other 3
1147 other 3
1148 [b608e9d1a3f0]
1148 [b608e9d1a3f0]
1149
1149
1150 1970-01-12 User Name <user@hostname>
1150 1970-01-12 User Name <user@hostname>
1151
1151
1152 * a:
1152 * a:
1153 line 1 line 2
1153 line 1 line 2
1154 [1e4e1b8f71e0]
1154 [1e4e1b8f71e0]
1155
1155
1156
1156
1157 Issue2130: xml output for 'hg heads' is malformed
1157 Issue2130: xml output for 'hg heads' is malformed
1158
1158
1159 $ hg heads --style changelog
1159 $ hg heads --style changelog
1160 2020-01-01 test <test>
1160 2020-01-01 test <test>
1161
1161
1162 * fourth, second, third:
1162 * fourth, second, third:
1163 third
1163 third
1164 [95c24699272e] [tip]
1164 [95c24699272e] [tip]
1165
1165
1166 1970-01-18 person <person>
1166 1970-01-18 person <person>
1167
1167
1168 * merge
1168 * merge
1169 [d41e714fe50d]
1169 [d41e714fe50d]
1170
1170
1171 1970-01-17 person <person>
1171 1970-01-17 person <person>
1172
1172
1173 * new branch
1173 * new branch
1174 [bbe44766e73d] <foo>
1174 [bbe44766e73d] <foo>
1175
1175
1176
1176
1177 Keys work:
1177 Keys work:
1178
1178
1179 $ for key in author branch branches date desc file_adds file_dels file_mods \
1179 $ for key in author branch branches date desc file_adds file_dels file_mods \
1180 > file_copies file_copies_switch files \
1180 > file_copies file_copies_switch files \
1181 > manifest node parents rev tags diffstat extras \
1181 > manifest node parents rev tags diffstat extras \
1182 > p1rev p2rev p1node p2node; do
1182 > p1rev p2rev p1node p2node; do
1183 > for mode in '' --verbose --debug; do
1183 > for mode in '' --verbose --debug; do
1184 > hg log $mode --template "$key$mode: {$key}\n"
1184 > hg log $mode --template "$key$mode: {$key}\n"
1185 > done
1185 > done
1186 > done
1186 > done
1187 author: test
1187 author: test
1188 author: User Name <user@hostname>
1188 author: User Name <user@hostname>
1189 author: person
1189 author: person
1190 author: person
1190 author: person
1191 author: person
1191 author: person
1192 author: person
1192 author: person
1193 author: other@place
1193 author: other@place
1194 author: A. N. Other <other@place>
1194 author: A. N. Other <other@place>
1195 author: User Name <user@hostname>
1195 author: User Name <user@hostname>
1196 author--verbose: test
1196 author--verbose: test
1197 author--verbose: User Name <user@hostname>
1197 author--verbose: User Name <user@hostname>
1198 author--verbose: person
1198 author--verbose: person
1199 author--verbose: person
1199 author--verbose: person
1200 author--verbose: person
1200 author--verbose: person
1201 author--verbose: person
1201 author--verbose: person
1202 author--verbose: other@place
1202 author--verbose: other@place
1203 author--verbose: A. N. Other <other@place>
1203 author--verbose: A. N. Other <other@place>
1204 author--verbose: User Name <user@hostname>
1204 author--verbose: User Name <user@hostname>
1205 author--debug: test
1205 author--debug: test
1206 author--debug: User Name <user@hostname>
1206 author--debug: User Name <user@hostname>
1207 author--debug: person
1207 author--debug: person
1208 author--debug: person
1208 author--debug: person
1209 author--debug: person
1209 author--debug: person
1210 author--debug: person
1210 author--debug: person
1211 author--debug: other@place
1211 author--debug: other@place
1212 author--debug: A. N. Other <other@place>
1212 author--debug: A. N. Other <other@place>
1213 author--debug: User Name <user@hostname>
1213 author--debug: User Name <user@hostname>
1214 branch: default
1214 branch: default
1215 branch: default
1215 branch: default
1216 branch: default
1216 branch: default
1217 branch: default
1217 branch: default
1218 branch: foo
1218 branch: foo
1219 branch: default
1219 branch: default
1220 branch: default
1220 branch: default
1221 branch: default
1221 branch: default
1222 branch: default
1222 branch: default
1223 branch--verbose: default
1223 branch--verbose: default
1224 branch--verbose: default
1224 branch--verbose: default
1225 branch--verbose: default
1225 branch--verbose: default
1226 branch--verbose: default
1226 branch--verbose: default
1227 branch--verbose: foo
1227 branch--verbose: foo
1228 branch--verbose: default
1228 branch--verbose: default
1229 branch--verbose: default
1229 branch--verbose: default
1230 branch--verbose: default
1230 branch--verbose: default
1231 branch--verbose: default
1231 branch--verbose: default
1232 branch--debug: default
1232 branch--debug: default
1233 branch--debug: default
1233 branch--debug: default
1234 branch--debug: default
1234 branch--debug: default
1235 branch--debug: default
1235 branch--debug: default
1236 branch--debug: foo
1236 branch--debug: foo
1237 branch--debug: default
1237 branch--debug: default
1238 branch--debug: default
1238 branch--debug: default
1239 branch--debug: default
1239 branch--debug: default
1240 branch--debug: default
1240 branch--debug: default
1241 branches:
1241 branches:
1242 branches:
1242 branches:
1243 branches:
1243 branches:
1244 branches:
1244 branches:
1245 branches: foo
1245 branches: foo
1246 branches:
1246 branches:
1247 branches:
1247 branches:
1248 branches:
1248 branches:
1249 branches:
1249 branches:
1250 branches--verbose:
1250 branches--verbose:
1251 branches--verbose:
1251 branches--verbose:
1252 branches--verbose:
1252 branches--verbose:
1253 branches--verbose:
1253 branches--verbose:
1254 branches--verbose: foo
1254 branches--verbose: foo
1255 branches--verbose:
1255 branches--verbose:
1256 branches--verbose:
1256 branches--verbose:
1257 branches--verbose:
1257 branches--verbose:
1258 branches--verbose:
1258 branches--verbose:
1259 branches--debug:
1259 branches--debug:
1260 branches--debug:
1260 branches--debug:
1261 branches--debug:
1261 branches--debug:
1262 branches--debug:
1262 branches--debug:
1263 branches--debug: foo
1263 branches--debug: foo
1264 branches--debug:
1264 branches--debug:
1265 branches--debug:
1265 branches--debug:
1266 branches--debug:
1266 branches--debug:
1267 branches--debug:
1267 branches--debug:
1268 date: 1577872860.00
1268 date: 1577872860.00
1269 date: 1000000.00
1269 date: 1000000.00
1270 date: 1500001.00
1270 date: 1500001.00
1271 date: 1500000.00
1271 date: 1500000.00
1272 date: 1400000.00
1272 date: 1400000.00
1273 date: 1300000.00
1273 date: 1300000.00
1274 date: 1200000.00
1274 date: 1200000.00
1275 date: 1100000.00
1275 date: 1100000.00
1276 date: 1000000.00
1276 date: 1000000.00
1277 date--verbose: 1577872860.00
1277 date--verbose: 1577872860.00
1278 date--verbose: 1000000.00
1278 date--verbose: 1000000.00
1279 date--verbose: 1500001.00
1279 date--verbose: 1500001.00
1280 date--verbose: 1500000.00
1280 date--verbose: 1500000.00
1281 date--verbose: 1400000.00
1281 date--verbose: 1400000.00
1282 date--verbose: 1300000.00
1282 date--verbose: 1300000.00
1283 date--verbose: 1200000.00
1283 date--verbose: 1200000.00
1284 date--verbose: 1100000.00
1284 date--verbose: 1100000.00
1285 date--verbose: 1000000.00
1285 date--verbose: 1000000.00
1286 date--debug: 1577872860.00
1286 date--debug: 1577872860.00
1287 date--debug: 1000000.00
1287 date--debug: 1000000.00
1288 date--debug: 1500001.00
1288 date--debug: 1500001.00
1289 date--debug: 1500000.00
1289 date--debug: 1500000.00
1290 date--debug: 1400000.00
1290 date--debug: 1400000.00
1291 date--debug: 1300000.00
1291 date--debug: 1300000.00
1292 date--debug: 1200000.00
1292 date--debug: 1200000.00
1293 date--debug: 1100000.00
1293 date--debug: 1100000.00
1294 date--debug: 1000000.00
1294 date--debug: 1000000.00
1295 desc: third
1295 desc: third
1296 desc: second
1296 desc: second
1297 desc: merge
1297 desc: merge
1298 desc: new head
1298 desc: new head
1299 desc: new branch
1299 desc: new branch
1300 desc: no user, no domain
1300 desc: no user, no domain
1301 desc: no person
1301 desc: no person
1302 desc: other 1
1302 desc: other 1
1303 other 2
1303 other 2
1304
1304
1305 other 3
1305 other 3
1306 desc: line 1
1306 desc: line 1
1307 line 2
1307 line 2
1308 desc--verbose: third
1308 desc--verbose: third
1309 desc--verbose: second
1309 desc--verbose: second
1310 desc--verbose: merge
1310 desc--verbose: merge
1311 desc--verbose: new head
1311 desc--verbose: new head
1312 desc--verbose: new branch
1312 desc--verbose: new branch
1313 desc--verbose: no user, no domain
1313 desc--verbose: no user, no domain
1314 desc--verbose: no person
1314 desc--verbose: no person
1315 desc--verbose: other 1
1315 desc--verbose: other 1
1316 other 2
1316 other 2
1317
1317
1318 other 3
1318 other 3
1319 desc--verbose: line 1
1319 desc--verbose: line 1
1320 line 2
1320 line 2
1321 desc--debug: third
1321 desc--debug: third
1322 desc--debug: second
1322 desc--debug: second
1323 desc--debug: merge
1323 desc--debug: merge
1324 desc--debug: new head
1324 desc--debug: new head
1325 desc--debug: new branch
1325 desc--debug: new branch
1326 desc--debug: no user, no domain
1326 desc--debug: no user, no domain
1327 desc--debug: no person
1327 desc--debug: no person
1328 desc--debug: other 1
1328 desc--debug: other 1
1329 other 2
1329 other 2
1330
1330
1331 other 3
1331 other 3
1332 desc--debug: line 1
1332 desc--debug: line 1
1333 line 2
1333 line 2
1334 file_adds: fourth third
1334 file_adds: fourth third
1335 file_adds: second
1335 file_adds: second
1336 file_adds:
1336 file_adds:
1337 file_adds: d
1337 file_adds: d
1338 file_adds:
1338 file_adds:
1339 file_adds:
1339 file_adds:
1340 file_adds: c
1340 file_adds: c
1341 file_adds: b
1341 file_adds: b
1342 file_adds: a
1342 file_adds: a
1343 file_adds--verbose: fourth third
1343 file_adds--verbose: fourth third
1344 file_adds--verbose: second
1344 file_adds--verbose: second
1345 file_adds--verbose:
1345 file_adds--verbose:
1346 file_adds--verbose: d
1346 file_adds--verbose: d
1347 file_adds--verbose:
1347 file_adds--verbose:
1348 file_adds--verbose:
1348 file_adds--verbose:
1349 file_adds--verbose: c
1349 file_adds--verbose: c
1350 file_adds--verbose: b
1350 file_adds--verbose: b
1351 file_adds--verbose: a
1351 file_adds--verbose: a
1352 file_adds--debug: fourth third
1352 file_adds--debug: fourth third
1353 file_adds--debug: second
1353 file_adds--debug: second
1354 file_adds--debug:
1354 file_adds--debug:
1355 file_adds--debug: d
1355 file_adds--debug: d
1356 file_adds--debug:
1356 file_adds--debug:
1357 file_adds--debug:
1357 file_adds--debug:
1358 file_adds--debug: c
1358 file_adds--debug: c
1359 file_adds--debug: b
1359 file_adds--debug: b
1360 file_adds--debug: a
1360 file_adds--debug: a
1361 file_dels: second
1361 file_dels: second
1362 file_dels:
1362 file_dels:
1363 file_dels:
1363 file_dels:
1364 file_dels:
1364 file_dels:
1365 file_dels:
1365 file_dels:
1366 file_dels:
1366 file_dels:
1367 file_dels:
1367 file_dels:
1368 file_dels:
1368 file_dels:
1369 file_dels:
1369 file_dels:
1370 file_dels--verbose: second
1370 file_dels--verbose: second
1371 file_dels--verbose:
1371 file_dels--verbose:
1372 file_dels--verbose:
1372 file_dels--verbose:
1373 file_dels--verbose:
1373 file_dels--verbose:
1374 file_dels--verbose:
1374 file_dels--verbose:
1375 file_dels--verbose:
1375 file_dels--verbose:
1376 file_dels--verbose:
1376 file_dels--verbose:
1377 file_dels--verbose:
1377 file_dels--verbose:
1378 file_dels--verbose:
1378 file_dels--verbose:
1379 file_dels--debug: second
1379 file_dels--debug: second
1380 file_dels--debug:
1380 file_dels--debug:
1381 file_dels--debug:
1381 file_dels--debug:
1382 file_dels--debug:
1382 file_dels--debug:
1383 file_dels--debug:
1383 file_dels--debug:
1384 file_dels--debug:
1384 file_dels--debug:
1385 file_dels--debug:
1385 file_dels--debug:
1386 file_dels--debug:
1386 file_dels--debug:
1387 file_dels--debug:
1387 file_dels--debug:
1388 file_mods:
1388 file_mods:
1389 file_mods:
1389 file_mods:
1390 file_mods:
1390 file_mods:
1391 file_mods:
1391 file_mods:
1392 file_mods:
1392 file_mods:
1393 file_mods: c
1393 file_mods: c
1394 file_mods:
1394 file_mods:
1395 file_mods:
1395 file_mods:
1396 file_mods:
1396 file_mods:
1397 file_mods--verbose:
1397 file_mods--verbose:
1398 file_mods--verbose:
1398 file_mods--verbose:
1399 file_mods--verbose:
1399 file_mods--verbose:
1400 file_mods--verbose:
1400 file_mods--verbose:
1401 file_mods--verbose:
1401 file_mods--verbose:
1402 file_mods--verbose: c
1402 file_mods--verbose: c
1403 file_mods--verbose:
1403 file_mods--verbose:
1404 file_mods--verbose:
1404 file_mods--verbose:
1405 file_mods--verbose:
1405 file_mods--verbose:
1406 file_mods--debug:
1406 file_mods--debug:
1407 file_mods--debug:
1407 file_mods--debug:
1408 file_mods--debug:
1408 file_mods--debug:
1409 file_mods--debug:
1409 file_mods--debug:
1410 file_mods--debug:
1410 file_mods--debug:
1411 file_mods--debug: c
1411 file_mods--debug: c
1412 file_mods--debug:
1412 file_mods--debug:
1413 file_mods--debug:
1413 file_mods--debug:
1414 file_mods--debug:
1414 file_mods--debug:
1415 file_copies: fourth (second)
1415 file_copies: fourth (second)
1416 file_copies:
1416 file_copies:
1417 file_copies:
1417 file_copies:
1418 file_copies:
1418 file_copies:
1419 file_copies:
1419 file_copies:
1420 file_copies:
1420 file_copies:
1421 file_copies:
1421 file_copies:
1422 file_copies:
1422 file_copies:
1423 file_copies:
1423 file_copies:
1424 file_copies--verbose: fourth (second)
1424 file_copies--verbose: fourth (second)
1425 file_copies--verbose:
1425 file_copies--verbose:
1426 file_copies--verbose:
1426 file_copies--verbose:
1427 file_copies--verbose:
1427 file_copies--verbose:
1428 file_copies--verbose:
1428 file_copies--verbose:
1429 file_copies--verbose:
1429 file_copies--verbose:
1430 file_copies--verbose:
1430 file_copies--verbose:
1431 file_copies--verbose:
1431 file_copies--verbose:
1432 file_copies--verbose:
1432 file_copies--verbose:
1433 file_copies--debug: fourth (second)
1433 file_copies--debug: fourth (second)
1434 file_copies--debug:
1434 file_copies--debug:
1435 file_copies--debug:
1435 file_copies--debug:
1436 file_copies--debug:
1436 file_copies--debug:
1437 file_copies--debug:
1437 file_copies--debug:
1438 file_copies--debug:
1438 file_copies--debug:
1439 file_copies--debug:
1439 file_copies--debug:
1440 file_copies--debug:
1440 file_copies--debug:
1441 file_copies--debug:
1441 file_copies--debug:
1442 file_copies_switch:
1442 file_copies_switch:
1443 file_copies_switch:
1443 file_copies_switch:
1444 file_copies_switch:
1444 file_copies_switch:
1445 file_copies_switch:
1445 file_copies_switch:
1446 file_copies_switch:
1446 file_copies_switch:
1447 file_copies_switch:
1447 file_copies_switch:
1448 file_copies_switch:
1448 file_copies_switch:
1449 file_copies_switch:
1449 file_copies_switch:
1450 file_copies_switch:
1450 file_copies_switch:
1451 file_copies_switch--verbose:
1451 file_copies_switch--verbose:
1452 file_copies_switch--verbose:
1452 file_copies_switch--verbose:
1453 file_copies_switch--verbose:
1453 file_copies_switch--verbose:
1454 file_copies_switch--verbose:
1454 file_copies_switch--verbose:
1455 file_copies_switch--verbose:
1455 file_copies_switch--verbose:
1456 file_copies_switch--verbose:
1456 file_copies_switch--verbose:
1457 file_copies_switch--verbose:
1457 file_copies_switch--verbose:
1458 file_copies_switch--verbose:
1458 file_copies_switch--verbose:
1459 file_copies_switch--verbose:
1459 file_copies_switch--verbose:
1460 file_copies_switch--debug:
1460 file_copies_switch--debug:
1461 file_copies_switch--debug:
1461 file_copies_switch--debug:
1462 file_copies_switch--debug:
1462 file_copies_switch--debug:
1463 file_copies_switch--debug:
1463 file_copies_switch--debug:
1464 file_copies_switch--debug:
1464 file_copies_switch--debug:
1465 file_copies_switch--debug:
1465 file_copies_switch--debug:
1466 file_copies_switch--debug:
1466 file_copies_switch--debug:
1467 file_copies_switch--debug:
1467 file_copies_switch--debug:
1468 file_copies_switch--debug:
1468 file_copies_switch--debug:
1469 files: fourth second third
1469 files: fourth second third
1470 files: second
1470 files: second
1471 files:
1471 files:
1472 files: d
1472 files: d
1473 files:
1473 files:
1474 files: c
1474 files: c
1475 files: c
1475 files: c
1476 files: b
1476 files: b
1477 files: a
1477 files: a
1478 files--verbose: fourth second third
1478 files--verbose: fourth second third
1479 files--verbose: second
1479 files--verbose: second
1480 files--verbose:
1480 files--verbose:
1481 files--verbose: d
1481 files--verbose: d
1482 files--verbose:
1482 files--verbose:
1483 files--verbose: c
1483 files--verbose: c
1484 files--verbose: c
1484 files--verbose: c
1485 files--verbose: b
1485 files--verbose: b
1486 files--verbose: a
1486 files--verbose: a
1487 files--debug: fourth second third
1487 files--debug: fourth second third
1488 files--debug: second
1488 files--debug: second
1489 files--debug:
1489 files--debug:
1490 files--debug: d
1490 files--debug: d
1491 files--debug:
1491 files--debug:
1492 files--debug: c
1492 files--debug: c
1493 files--debug: c
1493 files--debug: c
1494 files--debug: b
1494 files--debug: b
1495 files--debug: a
1495 files--debug: a
1496 manifest: 6:94961b75a2da
1496 manifest: 6:94961b75a2da
1497 manifest: 5:f2dbc354b94e
1497 manifest: 5:f2dbc354b94e
1498 manifest: 4:4dc3def4f9b4
1498 manifest: 4:4dc3def4f9b4
1499 manifest: 4:4dc3def4f9b4
1499 manifest: 4:4dc3def4f9b4
1500 manifest: 3:cb5a1327723b
1500 manifest: 3:cb5a1327723b
1501 manifest: 3:cb5a1327723b
1501 manifest: 3:cb5a1327723b
1502 manifest: 2:6e0e82995c35
1502 manifest: 2:6e0e82995c35
1503 manifest: 1:4e8d705b1e53
1503 manifest: 1:4e8d705b1e53
1504 manifest: 0:a0c8bcbbb45c
1504 manifest: 0:a0c8bcbbb45c
1505 manifest--verbose: 6:94961b75a2da
1505 manifest--verbose: 6:94961b75a2da
1506 manifest--verbose: 5:f2dbc354b94e
1506 manifest--verbose: 5:f2dbc354b94e
1507 manifest--verbose: 4:4dc3def4f9b4
1507 manifest--verbose: 4:4dc3def4f9b4
1508 manifest--verbose: 4:4dc3def4f9b4
1508 manifest--verbose: 4:4dc3def4f9b4
1509 manifest--verbose: 3:cb5a1327723b
1509 manifest--verbose: 3:cb5a1327723b
1510 manifest--verbose: 3:cb5a1327723b
1510 manifest--verbose: 3:cb5a1327723b
1511 manifest--verbose: 2:6e0e82995c35
1511 manifest--verbose: 2:6e0e82995c35
1512 manifest--verbose: 1:4e8d705b1e53
1512 manifest--verbose: 1:4e8d705b1e53
1513 manifest--verbose: 0:a0c8bcbbb45c
1513 manifest--verbose: 0:a0c8bcbbb45c
1514 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1514 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1515 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1515 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1516 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1516 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1517 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1517 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1518 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1518 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1519 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1519 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1520 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1520 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1521 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1521 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1522 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1522 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1523 node: 95c24699272ef57d062b8bccc32c878bf841784a
1523 node: 95c24699272ef57d062b8bccc32c878bf841784a
1524 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1524 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1525 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1525 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1526 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1526 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1527 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1527 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1528 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1528 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1529 node: 97054abb4ab824450e9164180baf491ae0078465
1529 node: 97054abb4ab824450e9164180baf491ae0078465
1530 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1530 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1531 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1531 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1532 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1532 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1533 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1533 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1534 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1534 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1535 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1535 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1536 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1536 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1537 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1537 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1538 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1538 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1539 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1539 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1540 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1540 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1541 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1541 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1542 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1542 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1543 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1543 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1544 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1544 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1545 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1545 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1546 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1546 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1547 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1547 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1548 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1548 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1549 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1549 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1550 parents:
1550 parents:
1551 parents: -1:000000000000
1551 parents: -1:000000000000
1552 parents: 5:13207e5a10d9 4:bbe44766e73d
1552 parents: 5:13207e5a10d9 4:bbe44766e73d
1553 parents: 3:10e46f2dcbf4
1553 parents: 3:10e46f2dcbf4
1554 parents:
1554 parents:
1555 parents:
1555 parents:
1556 parents:
1556 parents:
1557 parents:
1557 parents:
1558 parents:
1558 parents:
1559 parents--verbose:
1559 parents--verbose:
1560 parents--verbose: -1:000000000000
1560 parents--verbose: -1:000000000000
1561 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1561 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1562 parents--verbose: 3:10e46f2dcbf4
1562 parents--verbose: 3:10e46f2dcbf4
1563 parents--verbose:
1563 parents--verbose:
1564 parents--verbose:
1564 parents--verbose:
1565 parents--verbose:
1565 parents--verbose:
1566 parents--verbose:
1566 parents--verbose:
1567 parents--verbose:
1567 parents--verbose:
1568 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1568 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1569 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1569 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1570 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1570 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1571 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1571 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1572 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1572 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1573 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1573 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1574 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1574 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1575 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1575 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1576 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1576 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1577 rev: 8
1577 rev: 8
1578 rev: 7
1578 rev: 7
1579 rev: 6
1579 rev: 6
1580 rev: 5
1580 rev: 5
1581 rev: 4
1581 rev: 4
1582 rev: 3
1582 rev: 3
1583 rev: 2
1583 rev: 2
1584 rev: 1
1584 rev: 1
1585 rev: 0
1585 rev: 0
1586 rev--verbose: 8
1586 rev--verbose: 8
1587 rev--verbose: 7
1587 rev--verbose: 7
1588 rev--verbose: 6
1588 rev--verbose: 6
1589 rev--verbose: 5
1589 rev--verbose: 5
1590 rev--verbose: 4
1590 rev--verbose: 4
1591 rev--verbose: 3
1591 rev--verbose: 3
1592 rev--verbose: 2
1592 rev--verbose: 2
1593 rev--verbose: 1
1593 rev--verbose: 1
1594 rev--verbose: 0
1594 rev--verbose: 0
1595 rev--debug: 8
1595 rev--debug: 8
1596 rev--debug: 7
1596 rev--debug: 7
1597 rev--debug: 6
1597 rev--debug: 6
1598 rev--debug: 5
1598 rev--debug: 5
1599 rev--debug: 4
1599 rev--debug: 4
1600 rev--debug: 3
1600 rev--debug: 3
1601 rev--debug: 2
1601 rev--debug: 2
1602 rev--debug: 1
1602 rev--debug: 1
1603 rev--debug: 0
1603 rev--debug: 0
1604 tags: tip
1604 tags: tip
1605 tags:
1605 tags:
1606 tags:
1606 tags:
1607 tags:
1607 tags:
1608 tags:
1608 tags:
1609 tags:
1609 tags:
1610 tags:
1610 tags:
1611 tags:
1611 tags:
1612 tags:
1612 tags:
1613 tags--verbose: tip
1613 tags--verbose: tip
1614 tags--verbose:
1614 tags--verbose:
1615 tags--verbose:
1615 tags--verbose:
1616 tags--verbose:
1616 tags--verbose:
1617 tags--verbose:
1617 tags--verbose:
1618 tags--verbose:
1618 tags--verbose:
1619 tags--verbose:
1619 tags--verbose:
1620 tags--verbose:
1620 tags--verbose:
1621 tags--verbose:
1621 tags--verbose:
1622 tags--debug: tip
1622 tags--debug: tip
1623 tags--debug:
1623 tags--debug:
1624 tags--debug:
1624 tags--debug:
1625 tags--debug:
1625 tags--debug:
1626 tags--debug:
1626 tags--debug:
1627 tags--debug:
1627 tags--debug:
1628 tags--debug:
1628 tags--debug:
1629 tags--debug:
1629 tags--debug:
1630 tags--debug:
1630 tags--debug:
1631 diffstat: 3: +2/-1
1631 diffstat: 3: +2/-1
1632 diffstat: 1: +1/-0
1632 diffstat: 1: +1/-0
1633 diffstat: 0: +0/-0
1633 diffstat: 0: +0/-0
1634 diffstat: 1: +1/-0
1634 diffstat: 1: +1/-0
1635 diffstat: 0: +0/-0
1635 diffstat: 0: +0/-0
1636 diffstat: 1: +1/-0
1636 diffstat: 1: +1/-0
1637 diffstat: 1: +4/-0
1637 diffstat: 1: +4/-0
1638 diffstat: 1: +2/-0
1638 diffstat: 1: +2/-0
1639 diffstat: 1: +1/-0
1639 diffstat: 1: +1/-0
1640 diffstat--verbose: 3: +2/-1
1640 diffstat--verbose: 3: +2/-1
1641 diffstat--verbose: 1: +1/-0
1641 diffstat--verbose: 1: +1/-0
1642 diffstat--verbose: 0: +0/-0
1642 diffstat--verbose: 0: +0/-0
1643 diffstat--verbose: 1: +1/-0
1643 diffstat--verbose: 1: +1/-0
1644 diffstat--verbose: 0: +0/-0
1644 diffstat--verbose: 0: +0/-0
1645 diffstat--verbose: 1: +1/-0
1645 diffstat--verbose: 1: +1/-0
1646 diffstat--verbose: 1: +4/-0
1646 diffstat--verbose: 1: +4/-0
1647 diffstat--verbose: 1: +2/-0
1647 diffstat--verbose: 1: +2/-0
1648 diffstat--verbose: 1: +1/-0
1648 diffstat--verbose: 1: +1/-0
1649 diffstat--debug: 3: +2/-1
1649 diffstat--debug: 3: +2/-1
1650 diffstat--debug: 1: +1/-0
1650 diffstat--debug: 1: +1/-0
1651 diffstat--debug: 0: +0/-0
1651 diffstat--debug: 0: +0/-0
1652 diffstat--debug: 1: +1/-0
1652 diffstat--debug: 1: +1/-0
1653 diffstat--debug: 0: +0/-0
1653 diffstat--debug: 0: +0/-0
1654 diffstat--debug: 1: +1/-0
1654 diffstat--debug: 1: +1/-0
1655 diffstat--debug: 1: +4/-0
1655 diffstat--debug: 1: +4/-0
1656 diffstat--debug: 1: +2/-0
1656 diffstat--debug: 1: +2/-0
1657 diffstat--debug: 1: +1/-0
1657 diffstat--debug: 1: +1/-0
1658 extras: branch=default
1658 extras: branch=default
1659 extras: branch=default
1659 extras: branch=default
1660 extras: branch=default
1660 extras: branch=default
1661 extras: branch=default
1661 extras: branch=default
1662 extras: branch=foo
1662 extras: branch=foo
1663 extras: branch=default
1663 extras: branch=default
1664 extras: branch=default
1664 extras: branch=default
1665 extras: branch=default
1665 extras: branch=default
1666 extras: branch=default
1666 extras: branch=default
1667 extras--verbose: branch=default
1667 extras--verbose: branch=default
1668 extras--verbose: branch=default
1668 extras--verbose: branch=default
1669 extras--verbose: branch=default
1669 extras--verbose: branch=default
1670 extras--verbose: branch=default
1670 extras--verbose: branch=default
1671 extras--verbose: branch=foo
1671 extras--verbose: branch=foo
1672 extras--verbose: branch=default
1672 extras--verbose: branch=default
1673 extras--verbose: branch=default
1673 extras--verbose: branch=default
1674 extras--verbose: branch=default
1674 extras--verbose: branch=default
1675 extras--verbose: branch=default
1675 extras--verbose: branch=default
1676 extras--debug: branch=default
1676 extras--debug: branch=default
1677 extras--debug: branch=default
1677 extras--debug: branch=default
1678 extras--debug: branch=default
1678 extras--debug: branch=default
1679 extras--debug: branch=default
1679 extras--debug: branch=default
1680 extras--debug: branch=foo
1680 extras--debug: branch=foo
1681 extras--debug: branch=default
1681 extras--debug: branch=default
1682 extras--debug: branch=default
1682 extras--debug: branch=default
1683 extras--debug: branch=default
1683 extras--debug: branch=default
1684 extras--debug: branch=default
1684 extras--debug: branch=default
1685 p1rev: 7
1685 p1rev: 7
1686 p1rev: -1
1686 p1rev: -1
1687 p1rev: 5
1687 p1rev: 5
1688 p1rev: 3
1688 p1rev: 3
1689 p1rev: 3
1689 p1rev: 3
1690 p1rev: 2
1690 p1rev: 2
1691 p1rev: 1
1691 p1rev: 1
1692 p1rev: 0
1692 p1rev: 0
1693 p1rev: -1
1693 p1rev: -1
1694 p1rev--verbose: 7
1694 p1rev--verbose: 7
1695 p1rev--verbose: -1
1695 p1rev--verbose: -1
1696 p1rev--verbose: 5
1696 p1rev--verbose: 5
1697 p1rev--verbose: 3
1697 p1rev--verbose: 3
1698 p1rev--verbose: 3
1698 p1rev--verbose: 3
1699 p1rev--verbose: 2
1699 p1rev--verbose: 2
1700 p1rev--verbose: 1
1700 p1rev--verbose: 1
1701 p1rev--verbose: 0
1701 p1rev--verbose: 0
1702 p1rev--verbose: -1
1702 p1rev--verbose: -1
1703 p1rev--debug: 7
1703 p1rev--debug: 7
1704 p1rev--debug: -1
1704 p1rev--debug: -1
1705 p1rev--debug: 5
1705 p1rev--debug: 5
1706 p1rev--debug: 3
1706 p1rev--debug: 3
1707 p1rev--debug: 3
1707 p1rev--debug: 3
1708 p1rev--debug: 2
1708 p1rev--debug: 2
1709 p1rev--debug: 1
1709 p1rev--debug: 1
1710 p1rev--debug: 0
1710 p1rev--debug: 0
1711 p1rev--debug: -1
1711 p1rev--debug: -1
1712 p2rev: -1
1712 p2rev: -1
1713 p2rev: -1
1713 p2rev: -1
1714 p2rev: 4
1714 p2rev: 4
1715 p2rev: -1
1715 p2rev: -1
1716 p2rev: -1
1716 p2rev: -1
1717 p2rev: -1
1717 p2rev: -1
1718 p2rev: -1
1718 p2rev: -1
1719 p2rev: -1
1719 p2rev: -1
1720 p2rev: -1
1720 p2rev: -1
1721 p2rev--verbose: -1
1721 p2rev--verbose: -1
1722 p2rev--verbose: -1
1722 p2rev--verbose: -1
1723 p2rev--verbose: 4
1723 p2rev--verbose: 4
1724 p2rev--verbose: -1
1724 p2rev--verbose: -1
1725 p2rev--verbose: -1
1725 p2rev--verbose: -1
1726 p2rev--verbose: -1
1726 p2rev--verbose: -1
1727 p2rev--verbose: -1
1727 p2rev--verbose: -1
1728 p2rev--verbose: -1
1728 p2rev--verbose: -1
1729 p2rev--verbose: -1
1729 p2rev--verbose: -1
1730 p2rev--debug: -1
1730 p2rev--debug: -1
1731 p2rev--debug: -1
1731 p2rev--debug: -1
1732 p2rev--debug: 4
1732 p2rev--debug: 4
1733 p2rev--debug: -1
1733 p2rev--debug: -1
1734 p2rev--debug: -1
1734 p2rev--debug: -1
1735 p2rev--debug: -1
1735 p2rev--debug: -1
1736 p2rev--debug: -1
1736 p2rev--debug: -1
1737 p2rev--debug: -1
1737 p2rev--debug: -1
1738 p2rev--debug: -1
1738 p2rev--debug: -1
1739 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1739 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1740 p1node: 0000000000000000000000000000000000000000
1740 p1node: 0000000000000000000000000000000000000000
1741 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1741 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1742 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1742 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1743 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1743 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1744 p1node: 97054abb4ab824450e9164180baf491ae0078465
1744 p1node: 97054abb4ab824450e9164180baf491ae0078465
1745 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1745 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1746 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1746 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1747 p1node: 0000000000000000000000000000000000000000
1747 p1node: 0000000000000000000000000000000000000000
1748 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1748 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1749 p1node--verbose: 0000000000000000000000000000000000000000
1749 p1node--verbose: 0000000000000000000000000000000000000000
1750 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1750 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1751 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1751 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1752 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1752 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1753 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1753 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1754 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1754 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1755 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1755 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1756 p1node--verbose: 0000000000000000000000000000000000000000
1756 p1node--verbose: 0000000000000000000000000000000000000000
1757 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1757 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1758 p1node--debug: 0000000000000000000000000000000000000000
1758 p1node--debug: 0000000000000000000000000000000000000000
1759 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1759 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1760 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1760 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1761 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1761 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1762 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1762 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1763 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1763 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1764 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1764 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1765 p1node--debug: 0000000000000000000000000000000000000000
1765 p1node--debug: 0000000000000000000000000000000000000000
1766 p2node: 0000000000000000000000000000000000000000
1766 p2node: 0000000000000000000000000000000000000000
1767 p2node: 0000000000000000000000000000000000000000
1767 p2node: 0000000000000000000000000000000000000000
1768 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1768 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1769 p2node: 0000000000000000000000000000000000000000
1769 p2node: 0000000000000000000000000000000000000000
1770 p2node: 0000000000000000000000000000000000000000
1770 p2node: 0000000000000000000000000000000000000000
1771 p2node: 0000000000000000000000000000000000000000
1771 p2node: 0000000000000000000000000000000000000000
1772 p2node: 0000000000000000000000000000000000000000
1772 p2node: 0000000000000000000000000000000000000000
1773 p2node: 0000000000000000000000000000000000000000
1773 p2node: 0000000000000000000000000000000000000000
1774 p2node: 0000000000000000000000000000000000000000
1774 p2node: 0000000000000000000000000000000000000000
1775 p2node--verbose: 0000000000000000000000000000000000000000
1775 p2node--verbose: 0000000000000000000000000000000000000000
1776 p2node--verbose: 0000000000000000000000000000000000000000
1776 p2node--verbose: 0000000000000000000000000000000000000000
1777 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1777 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1778 p2node--verbose: 0000000000000000000000000000000000000000
1778 p2node--verbose: 0000000000000000000000000000000000000000
1779 p2node--verbose: 0000000000000000000000000000000000000000
1779 p2node--verbose: 0000000000000000000000000000000000000000
1780 p2node--verbose: 0000000000000000000000000000000000000000
1780 p2node--verbose: 0000000000000000000000000000000000000000
1781 p2node--verbose: 0000000000000000000000000000000000000000
1781 p2node--verbose: 0000000000000000000000000000000000000000
1782 p2node--verbose: 0000000000000000000000000000000000000000
1782 p2node--verbose: 0000000000000000000000000000000000000000
1783 p2node--verbose: 0000000000000000000000000000000000000000
1783 p2node--verbose: 0000000000000000000000000000000000000000
1784 p2node--debug: 0000000000000000000000000000000000000000
1784 p2node--debug: 0000000000000000000000000000000000000000
1785 p2node--debug: 0000000000000000000000000000000000000000
1785 p2node--debug: 0000000000000000000000000000000000000000
1786 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1786 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1787 p2node--debug: 0000000000000000000000000000000000000000
1787 p2node--debug: 0000000000000000000000000000000000000000
1788 p2node--debug: 0000000000000000000000000000000000000000
1788 p2node--debug: 0000000000000000000000000000000000000000
1789 p2node--debug: 0000000000000000000000000000000000000000
1789 p2node--debug: 0000000000000000000000000000000000000000
1790 p2node--debug: 0000000000000000000000000000000000000000
1790 p2node--debug: 0000000000000000000000000000000000000000
1791 p2node--debug: 0000000000000000000000000000000000000000
1791 p2node--debug: 0000000000000000000000000000000000000000
1792 p2node--debug: 0000000000000000000000000000000000000000
1792 p2node--debug: 0000000000000000000000000000000000000000
1793
1793
1794 Filters work:
1794 Filters work:
1795
1795
1796 $ hg log --template '{author|domain}\n'
1796 $ hg log --template '{author|domain}\n'
1797
1797
1798 hostname
1798 hostname
1799
1799
1800
1800
1801
1801
1802
1802
1803 place
1803 place
1804 place
1804 place
1805 hostname
1805 hostname
1806
1806
1807 $ hg log --template '{author|person}\n'
1807 $ hg log --template '{author|person}\n'
1808 test
1808 test
1809 User Name
1809 User Name
1810 person
1810 person
1811 person
1811 person
1812 person
1812 person
1813 person
1813 person
1814 other
1814 other
1815 A. N. Other
1815 A. N. Other
1816 User Name
1816 User Name
1817
1817
1818 $ hg log --template '{author|user}\n'
1818 $ hg log --template '{author|user}\n'
1819 test
1819 test
1820 user
1820 user
1821 person
1821 person
1822 person
1822 person
1823 person
1823 person
1824 person
1824 person
1825 other
1825 other
1826 other
1826 other
1827 user
1827 user
1828
1828
1829 $ hg log --template '{date|date}\n'
1829 $ hg log --template '{date|date}\n'
1830 Wed Jan 01 10:01:00 2020 +0000
1830 Wed Jan 01 10:01:00 2020 +0000
1831 Mon Jan 12 13:46:40 1970 +0000
1831 Mon Jan 12 13:46:40 1970 +0000
1832 Sun Jan 18 08:40:01 1970 +0000
1832 Sun Jan 18 08:40:01 1970 +0000
1833 Sun Jan 18 08:40:00 1970 +0000
1833 Sun Jan 18 08:40:00 1970 +0000
1834 Sat Jan 17 04:53:20 1970 +0000
1834 Sat Jan 17 04:53:20 1970 +0000
1835 Fri Jan 16 01:06:40 1970 +0000
1835 Fri Jan 16 01:06:40 1970 +0000
1836 Wed Jan 14 21:20:00 1970 +0000
1836 Wed Jan 14 21:20:00 1970 +0000
1837 Tue Jan 13 17:33:20 1970 +0000
1837 Tue Jan 13 17:33:20 1970 +0000
1838 Mon Jan 12 13:46:40 1970 +0000
1838 Mon Jan 12 13:46:40 1970 +0000
1839
1839
1840 $ hg log --template '{date|isodate}\n'
1840 $ hg log --template '{date|isodate}\n'
1841 2020-01-01 10:01 +0000
1841 2020-01-01 10:01 +0000
1842 1970-01-12 13:46 +0000
1842 1970-01-12 13:46 +0000
1843 1970-01-18 08:40 +0000
1843 1970-01-18 08:40 +0000
1844 1970-01-18 08:40 +0000
1844 1970-01-18 08:40 +0000
1845 1970-01-17 04:53 +0000
1845 1970-01-17 04:53 +0000
1846 1970-01-16 01:06 +0000
1846 1970-01-16 01:06 +0000
1847 1970-01-14 21:20 +0000
1847 1970-01-14 21:20 +0000
1848 1970-01-13 17:33 +0000
1848 1970-01-13 17:33 +0000
1849 1970-01-12 13:46 +0000
1849 1970-01-12 13:46 +0000
1850
1850
1851 $ hg log --template '{date|isodatesec}\n'
1851 $ hg log --template '{date|isodatesec}\n'
1852 2020-01-01 10:01:00 +0000
1852 2020-01-01 10:01:00 +0000
1853 1970-01-12 13:46:40 +0000
1853 1970-01-12 13:46:40 +0000
1854 1970-01-18 08:40:01 +0000
1854 1970-01-18 08:40:01 +0000
1855 1970-01-18 08:40:00 +0000
1855 1970-01-18 08:40:00 +0000
1856 1970-01-17 04:53:20 +0000
1856 1970-01-17 04:53:20 +0000
1857 1970-01-16 01:06:40 +0000
1857 1970-01-16 01:06:40 +0000
1858 1970-01-14 21:20:00 +0000
1858 1970-01-14 21:20:00 +0000
1859 1970-01-13 17:33:20 +0000
1859 1970-01-13 17:33:20 +0000
1860 1970-01-12 13:46:40 +0000
1860 1970-01-12 13:46:40 +0000
1861
1861
1862 $ hg log --template '{date|rfc822date}\n'
1862 $ hg log --template '{date|rfc822date}\n'
1863 Wed, 01 Jan 2020 10:01:00 +0000
1863 Wed, 01 Jan 2020 10:01:00 +0000
1864 Mon, 12 Jan 1970 13:46:40 +0000
1864 Mon, 12 Jan 1970 13:46:40 +0000
1865 Sun, 18 Jan 1970 08:40:01 +0000
1865 Sun, 18 Jan 1970 08:40:01 +0000
1866 Sun, 18 Jan 1970 08:40:00 +0000
1866 Sun, 18 Jan 1970 08:40:00 +0000
1867 Sat, 17 Jan 1970 04:53:20 +0000
1867 Sat, 17 Jan 1970 04:53:20 +0000
1868 Fri, 16 Jan 1970 01:06:40 +0000
1868 Fri, 16 Jan 1970 01:06:40 +0000
1869 Wed, 14 Jan 1970 21:20:00 +0000
1869 Wed, 14 Jan 1970 21:20:00 +0000
1870 Tue, 13 Jan 1970 17:33:20 +0000
1870 Tue, 13 Jan 1970 17:33:20 +0000
1871 Mon, 12 Jan 1970 13:46:40 +0000
1871 Mon, 12 Jan 1970 13:46:40 +0000
1872
1872
1873 $ hg log --template '{desc|firstline}\n'
1873 $ hg log --template '{desc|firstline}\n'
1874 third
1874 third
1875 second
1875 second
1876 merge
1876 merge
1877 new head
1877 new head
1878 new branch
1878 new branch
1879 no user, no domain
1879 no user, no domain
1880 no person
1880 no person
1881 other 1
1881 other 1
1882 line 1
1882 line 1
1883
1883
1884 $ hg log --template '{node|short}\n'
1884 $ hg log --template '{node|short}\n'
1885 95c24699272e
1885 95c24699272e
1886 29114dbae42b
1886 29114dbae42b
1887 d41e714fe50d
1887 d41e714fe50d
1888 13207e5a10d9
1888 13207e5a10d9
1889 bbe44766e73d
1889 bbe44766e73d
1890 10e46f2dcbf4
1890 10e46f2dcbf4
1891 97054abb4ab8
1891 97054abb4ab8
1892 b608e9d1a3f0
1892 b608e9d1a3f0
1893 1e4e1b8f71e0
1893 1e4e1b8f71e0
1894
1894
1895 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1895 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1896 <changeset author="test"/>
1896 <changeset author="test"/>
1897 <changeset author="User Name &lt;user@hostname&gt;"/>
1897 <changeset author="User Name &lt;user@hostname&gt;"/>
1898 <changeset author="person"/>
1898 <changeset author="person"/>
1899 <changeset author="person"/>
1899 <changeset author="person"/>
1900 <changeset author="person"/>
1900 <changeset author="person"/>
1901 <changeset author="person"/>
1901 <changeset author="person"/>
1902 <changeset author="other@place"/>
1902 <changeset author="other@place"/>
1903 <changeset author="A. N. Other &lt;other@place&gt;"/>
1903 <changeset author="A. N. Other &lt;other@place&gt;"/>
1904 <changeset author="User Name &lt;user@hostname&gt;"/>
1904 <changeset author="User Name &lt;user@hostname&gt;"/>
1905
1905
1906 $ hg log --template '{rev}: {children}\n'
1906 $ hg log --template '{rev}: {children}\n'
1907 8:
1907 8:
1908 7: 8:95c24699272e
1908 7: 8:95c24699272e
1909 6:
1909 6:
1910 5: 6:d41e714fe50d
1910 5: 6:d41e714fe50d
1911 4: 6:d41e714fe50d
1911 4: 6:d41e714fe50d
1912 3: 4:bbe44766e73d 5:13207e5a10d9
1912 3: 4:bbe44766e73d 5:13207e5a10d9
1913 2: 3:10e46f2dcbf4
1913 2: 3:10e46f2dcbf4
1914 1: 2:97054abb4ab8
1914 1: 2:97054abb4ab8
1915 0: 1:b608e9d1a3f0
1915 0: 1:b608e9d1a3f0
1916
1916
1917 Formatnode filter works:
1917 Formatnode filter works:
1918
1918
1919 $ hg -q log -r 0 --template '{node|formatnode}\n'
1919 $ hg -q log -r 0 --template '{node|formatnode}\n'
1920 1e4e1b8f71e0
1920 1e4e1b8f71e0
1921
1921
1922 $ hg log -r 0 --template '{node|formatnode}\n'
1922 $ hg log -r 0 --template '{node|formatnode}\n'
1923 1e4e1b8f71e0
1923 1e4e1b8f71e0
1924
1924
1925 $ hg -v log -r 0 --template '{node|formatnode}\n'
1925 $ hg -v log -r 0 --template '{node|formatnode}\n'
1926 1e4e1b8f71e0
1926 1e4e1b8f71e0
1927
1927
1928 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1928 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1929 1e4e1b8f71e05681d422154f5421e385fec3454f
1929 1e4e1b8f71e05681d422154f5421e385fec3454f
1930
1930
1931 Age filter:
1931 Age filter:
1932
1932
1933 $ hg init unstable-hash
1933 $ hg init unstable-hash
1934 $ cd unstable-hash
1934 $ cd unstable-hash
1935 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1935 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1936
1936
1937 >>> from datetime import datetime, timedelta
1937 >>> from datetime import datetime, timedelta
1938 >>> fp = open('a', 'w')
1938 >>> fp = open('a', 'w')
1939 >>> n = datetime.now() + timedelta(366 * 7)
1939 >>> n = datetime.now() + timedelta(366 * 7)
1940 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1940 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1941 >>> fp.close()
1941 >>> fp.close()
1942 $ hg add a
1942 $ hg add a
1943 $ hg commit -m future -d "`cat a`"
1943 $ hg commit -m future -d "`cat a`"
1944
1944
1945 $ hg log -l1 --template '{date|age}\n'
1945 $ hg log -l1 --template '{date|age}\n'
1946 7 years from now
1946 7 years from now
1947
1947
1948 $ cd ..
1948 $ cd ..
1949 $ rm -rf unstable-hash
1949 $ rm -rf unstable-hash
1950
1950
1951 Add a dummy commit to make up for the instability of the above:
1951 Add a dummy commit to make up for the instability of the above:
1952
1952
1953 $ echo a > a
1953 $ echo a > a
1954 $ hg add a
1954 $ hg add a
1955 $ hg ci -m future
1955 $ hg ci -m future
1956
1956
1957 Count filter:
1957 Count filter:
1958
1958
1959 $ hg log -l1 --template '{node|count} {node|short|count}\n'
1959 $ hg log -l1 --template '{node|count} {node|short|count}\n'
1960 40 12
1960 40 12
1961
1961
1962 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
1962 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
1963 0 1 4
1963 0 1 4
1964
1964
1965 $ hg log -G --template '{rev}: children: {children|count}, \
1965 $ hg log -G --template '{rev}: children: {children|count}, \
1966 > tags: {tags|count}, file_adds: {file_adds|count}, \
1966 > tags: {tags|count}, file_adds: {file_adds|count}, \
1967 > ancestors: {revset("ancestors(%s)", rev)|count}'
1967 > ancestors: {revset("ancestors(%s)", rev)|count}'
1968 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
1968 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
1969 |
1969 |
1970 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
1970 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
1971 |
1971 |
1972 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
1972 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
1973
1973
1974 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
1974 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
1975 |\
1975 |\
1976 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
1976 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
1977 | |
1977 | |
1978 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
1978 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
1979 |/
1979 |/
1980 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
1980 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
1981 |
1981 |
1982 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
1982 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
1983 |
1983 |
1984 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
1984 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
1985 |
1985 |
1986 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
1986 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
1987
1987
1988
1988
1989 Upper/lower filters:
1989 Upper/lower filters:
1990
1990
1991 $ hg log -r0 --template '{branch|upper}\n'
1991 $ hg log -r0 --template '{branch|upper}\n'
1992 DEFAULT
1992 DEFAULT
1993 $ hg log -r0 --template '{author|lower}\n'
1993 $ hg log -r0 --template '{author|lower}\n'
1994 user name <user@hostname>
1994 user name <user@hostname>
1995 $ hg log -r0 --template '{date|upper}\n'
1995 $ hg log -r0 --template '{date|upper}\n'
1996 abort: template filter 'upper' is not compatible with keyword 'date'
1996 abort: template filter 'upper' is not compatible with keyword 'date'
1997 [255]
1997 [255]
1998
1998
1999 Add a commit that does all possible modifications at once
1999 Add a commit that does all possible modifications at once
2000
2000
2001 $ echo modify >> third
2001 $ echo modify >> third
2002 $ touch b
2002 $ touch b
2003 $ hg add b
2003 $ hg add b
2004 $ hg mv fourth fifth
2004 $ hg mv fourth fifth
2005 $ hg rm a
2005 $ hg rm a
2006 $ hg ci -m "Modify, add, remove, rename"
2006 $ hg ci -m "Modify, add, remove, rename"
2007
2007
2008 Check the status template
2008 Check the status template
2009
2009
2010 $ cat <<EOF >> $HGRCPATH
2010 $ cat <<EOF >> $HGRCPATH
2011 > [extensions]
2011 > [extensions]
2012 > color=
2012 > color=
2013 > EOF
2013 > EOF
2014
2014
2015 $ hg log -T status -r 10
2015 $ hg log -T status -r 10
2016 changeset: 10:0f9759ec227a
2016 changeset: 10:0f9759ec227a
2017 tag: tip
2017 tag: tip
2018 user: test
2018 user: test
2019 date: Thu Jan 01 00:00:00 1970 +0000
2019 date: Thu Jan 01 00:00:00 1970 +0000
2020 summary: Modify, add, remove, rename
2020 summary: Modify, add, remove, rename
2021 files:
2021 files:
2022 M third
2022 M third
2023 A b
2023 A b
2024 A fifth
2024 A fifth
2025 R a
2025 R a
2026 R fourth
2026 R fourth
2027
2027
2028 $ hg log -T status -C -r 10
2028 $ hg log -T status -C -r 10
2029 changeset: 10:0f9759ec227a
2029 changeset: 10:0f9759ec227a
2030 tag: tip
2030 tag: tip
2031 user: test
2031 user: test
2032 date: Thu Jan 01 00:00:00 1970 +0000
2032 date: Thu Jan 01 00:00:00 1970 +0000
2033 summary: Modify, add, remove, rename
2033 summary: Modify, add, remove, rename
2034 files:
2034 files:
2035 M third
2035 M third
2036 A b
2036 A b
2037 A fifth
2037 A fifth
2038 fourth
2038 fourth
2039 R a
2039 R a
2040 R fourth
2040 R fourth
2041
2041
2042 $ hg log -T status -C -r 10 -v
2042 $ hg log -T status -C -r 10 -v
2043 changeset: 10:0f9759ec227a
2043 changeset: 10:0f9759ec227a
2044 tag: tip
2044 tag: tip
2045 user: test
2045 user: test
2046 date: Thu Jan 01 00:00:00 1970 +0000
2046 date: Thu Jan 01 00:00:00 1970 +0000
2047 description:
2047 description:
2048 Modify, add, remove, rename
2048 Modify, add, remove, rename
2049
2049
2050 files:
2050 files:
2051 M third
2051 M third
2052 A b
2052 A b
2053 A fifth
2053 A fifth
2054 fourth
2054 fourth
2055 R a
2055 R a
2056 R fourth
2056 R fourth
2057
2057
2058 $ hg log -T status -C -r 10 --debug
2058 $ hg log -T status -C -r 10 --debug
2059 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2059 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2060 tag: tip
2060 tag: tip
2061 phase: secret
2061 phase: secret
2062 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2062 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2063 parent: -1:0000000000000000000000000000000000000000
2063 parent: -1:0000000000000000000000000000000000000000
2064 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2064 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2065 user: test
2065 user: test
2066 date: Thu Jan 01 00:00:00 1970 +0000
2066 date: Thu Jan 01 00:00:00 1970 +0000
2067 extra: branch=default
2067 extra: branch=default
2068 description:
2068 description:
2069 Modify, add, remove, rename
2069 Modify, add, remove, rename
2070
2070
2071 files:
2071 files:
2072 M third
2072 M third
2073 A b
2073 A b
2074 A fifth
2074 A fifth
2075 fourth
2075 fourth
2076 R a
2076 R a
2077 R fourth
2077 R fourth
2078
2078
2079 $ hg log -T status -C -r 10 --quiet
2079 $ hg log -T status -C -r 10 --quiet
2080 10:0f9759ec227a
2080 10:0f9759ec227a
2081 $ hg --color=debug log -T status -r 10
2081 $ hg --color=debug log -T status -r 10
2082 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2082 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2083 [log.tag|tag: tip]
2083 [log.tag|tag: tip]
2084 [log.user|user: test]
2084 [log.user|user: test]
2085 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2085 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2086 [log.summary|summary: Modify, add, remove, rename]
2086 [log.summary|summary: Modify, add, remove, rename]
2087 [ui.note log.files|files:]
2087 [ui.note log.files|files:]
2088 [status.modified|M third]
2088 [status.modified|M third]
2089 [status.added|A b]
2089 [status.added|A b]
2090 [status.added|A fifth]
2090 [status.added|A fifth]
2091 [status.removed|R a]
2091 [status.removed|R a]
2092 [status.removed|R fourth]
2092 [status.removed|R fourth]
2093
2093
2094 $ hg --color=debug log -T status -C -r 10
2094 $ hg --color=debug log -T status -C -r 10
2095 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2095 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2096 [log.tag|tag: tip]
2096 [log.tag|tag: tip]
2097 [log.user|user: test]
2097 [log.user|user: test]
2098 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2098 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2099 [log.summary|summary: Modify, add, remove, rename]
2099 [log.summary|summary: Modify, add, remove, rename]
2100 [ui.note log.files|files:]
2100 [ui.note log.files|files:]
2101 [status.modified|M third]
2101 [status.modified|M third]
2102 [status.added|A b]
2102 [status.added|A b]
2103 [status.added|A fifth]
2103 [status.added|A fifth]
2104 [status.copied| fourth]
2104 [status.copied| fourth]
2105 [status.removed|R a]
2105 [status.removed|R a]
2106 [status.removed|R fourth]
2106 [status.removed|R fourth]
2107
2107
2108 $ hg --color=debug log -T status -C -r 10 -v
2108 $ hg --color=debug log -T status -C -r 10 -v
2109 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2109 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2110 [log.tag|tag: tip]
2110 [log.tag|tag: tip]
2111 [log.user|user: test]
2111 [log.user|user: test]
2112 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2112 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2113 [ui.note log.description|description:]
2113 [ui.note log.description|description:]
2114 [ui.note log.description|Modify, add, remove, rename]
2114 [ui.note log.description|Modify, add, remove, rename]
2115
2115
2116 [ui.note log.files|files:]
2116 [ui.note log.files|files:]
2117 [status.modified|M third]
2117 [status.modified|M third]
2118 [status.added|A b]
2118 [status.added|A b]
2119 [status.added|A fifth]
2119 [status.added|A fifth]
2120 [status.copied| fourth]
2120 [status.copied| fourth]
2121 [status.removed|R a]
2121 [status.removed|R a]
2122 [status.removed|R fourth]
2122 [status.removed|R fourth]
2123
2123
2124 $ hg --color=debug log -T status -C -r 10 --debug
2124 $ hg --color=debug log -T status -C -r 10 --debug
2125 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2125 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2126 [log.tag|tag: tip]
2126 [log.tag|tag: tip]
2127 [log.phase|phase: secret]
2127 [log.phase|phase: secret]
2128 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2128 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2129 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2129 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2130 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2130 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2131 [log.user|user: test]
2131 [log.user|user: test]
2132 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2132 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2133 [ui.debug log.extra|extra: branch=default]
2133 [ui.debug log.extra|extra: branch=default]
2134 [ui.note log.description|description:]
2134 [ui.note log.description|description:]
2135 [ui.note log.description|Modify, add, remove, rename]
2135 [ui.note log.description|Modify, add, remove, rename]
2136
2136
2137 [ui.note log.files|files:]
2137 [ui.note log.files|files:]
2138 [status.modified|M third]
2138 [status.modified|M third]
2139 [status.added|A b]
2139 [status.added|A b]
2140 [status.added|A fifth]
2140 [status.added|A fifth]
2141 [status.copied| fourth]
2141 [status.copied| fourth]
2142 [status.removed|R a]
2142 [status.removed|R a]
2143 [status.removed|R fourth]
2143 [status.removed|R fourth]
2144
2144
2145 $ hg --color=debug log -T status -C -r 10 --quiet
2145 $ hg --color=debug log -T status -C -r 10 --quiet
2146 [log.node|10:0f9759ec227a]
2146 [log.node|10:0f9759ec227a]
2147
2147
2148 Check the bisect template
2148 Check the bisect template
2149
2149
2150 $ hg bisect -g 1
2150 $ hg bisect -g 1
2151 $ hg bisect -b 3 --noupdate
2151 $ hg bisect -b 3 --noupdate
2152 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2152 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2153 $ hg log -T bisect -r 0:4
2153 $ hg log -T bisect -r 0:4
2154 changeset: 0:1e4e1b8f71e0
2154 changeset: 0:1e4e1b8f71e0
2155 bisect: good (implicit)
2155 bisect: good (implicit)
2156 user: User Name <user@hostname>
2156 user: User Name <user@hostname>
2157 date: Mon Jan 12 13:46:40 1970 +0000
2157 date: Mon Jan 12 13:46:40 1970 +0000
2158 summary: line 1
2158 summary: line 1
2159
2159
2160 changeset: 1:b608e9d1a3f0
2160 changeset: 1:b608e9d1a3f0
2161 bisect: good
2161 bisect: good
2162 user: A. N. Other <other@place>
2162 user: A. N. Other <other@place>
2163 date: Tue Jan 13 17:33:20 1970 +0000
2163 date: Tue Jan 13 17:33:20 1970 +0000
2164 summary: other 1
2164 summary: other 1
2165
2165
2166 changeset: 2:97054abb4ab8
2166 changeset: 2:97054abb4ab8
2167 bisect: untested
2167 bisect: untested
2168 user: other@place
2168 user: other@place
2169 date: Wed Jan 14 21:20:00 1970 +0000
2169 date: Wed Jan 14 21:20:00 1970 +0000
2170 summary: no person
2170 summary: no person
2171
2171
2172 changeset: 3:10e46f2dcbf4
2172 changeset: 3:10e46f2dcbf4
2173 bisect: bad
2173 bisect: bad
2174 user: person
2174 user: person
2175 date: Fri Jan 16 01:06:40 1970 +0000
2175 date: Fri Jan 16 01:06:40 1970 +0000
2176 summary: no user, no domain
2176 summary: no user, no domain
2177
2177
2178 changeset: 4:bbe44766e73d
2178 changeset: 4:bbe44766e73d
2179 bisect: bad (implicit)
2179 bisect: bad (implicit)
2180 branch: foo
2180 branch: foo
2181 user: person
2181 user: person
2182 date: Sat Jan 17 04:53:20 1970 +0000
2182 date: Sat Jan 17 04:53:20 1970 +0000
2183 summary: new branch
2183 summary: new branch
2184
2184
2185 $ hg log --debug -T bisect -r 0:4
2185 $ hg log --debug -T bisect -r 0:4
2186 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2186 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2187 bisect: good (implicit)
2187 bisect: good (implicit)
2188 phase: public
2188 phase: public
2189 parent: -1:0000000000000000000000000000000000000000
2189 parent: -1:0000000000000000000000000000000000000000
2190 parent: -1:0000000000000000000000000000000000000000
2190 parent: -1:0000000000000000000000000000000000000000
2191 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2191 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2192 user: User Name <user@hostname>
2192 user: User Name <user@hostname>
2193 date: Mon Jan 12 13:46:40 1970 +0000
2193 date: Mon Jan 12 13:46:40 1970 +0000
2194 files+: a
2194 files+: a
2195 extra: branch=default
2195 extra: branch=default
2196 description:
2196 description:
2197 line 1
2197 line 1
2198 line 2
2198 line 2
2199
2199
2200
2200
2201 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2201 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2202 bisect: good
2202 bisect: good
2203 phase: public
2203 phase: public
2204 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2204 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2205 parent: -1:0000000000000000000000000000000000000000
2205 parent: -1:0000000000000000000000000000000000000000
2206 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2206 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2207 user: A. N. Other <other@place>
2207 user: A. N. Other <other@place>
2208 date: Tue Jan 13 17:33:20 1970 +0000
2208 date: Tue Jan 13 17:33:20 1970 +0000
2209 files+: b
2209 files+: b
2210 extra: branch=default
2210 extra: branch=default
2211 description:
2211 description:
2212 other 1
2212 other 1
2213 other 2
2213 other 2
2214
2214
2215 other 3
2215 other 3
2216
2216
2217
2217
2218 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2218 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2219 bisect: untested
2219 bisect: untested
2220 phase: public
2220 phase: public
2221 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2221 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2222 parent: -1:0000000000000000000000000000000000000000
2222 parent: -1:0000000000000000000000000000000000000000
2223 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2223 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2224 user: other@place
2224 user: other@place
2225 date: Wed Jan 14 21:20:00 1970 +0000
2225 date: Wed Jan 14 21:20:00 1970 +0000
2226 files+: c
2226 files+: c
2227 extra: branch=default
2227 extra: branch=default
2228 description:
2228 description:
2229 no person
2229 no person
2230
2230
2231
2231
2232 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2232 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2233 bisect: bad
2233 bisect: bad
2234 phase: public
2234 phase: public
2235 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2235 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2236 parent: -1:0000000000000000000000000000000000000000
2236 parent: -1:0000000000000000000000000000000000000000
2237 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2237 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2238 user: person
2238 user: person
2239 date: Fri Jan 16 01:06:40 1970 +0000
2239 date: Fri Jan 16 01:06:40 1970 +0000
2240 files: c
2240 files: c
2241 extra: branch=default
2241 extra: branch=default
2242 description:
2242 description:
2243 no user, no domain
2243 no user, no domain
2244
2244
2245
2245
2246 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2246 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2247 bisect: bad (implicit)
2247 bisect: bad (implicit)
2248 branch: foo
2248 branch: foo
2249 phase: draft
2249 phase: draft
2250 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2250 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2251 parent: -1:0000000000000000000000000000000000000000
2251 parent: -1:0000000000000000000000000000000000000000
2252 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2252 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2253 user: person
2253 user: person
2254 date: Sat Jan 17 04:53:20 1970 +0000
2254 date: Sat Jan 17 04:53:20 1970 +0000
2255 extra: branch=foo
2255 extra: branch=foo
2256 description:
2256 description:
2257 new branch
2257 new branch
2258
2258
2259
2259
2260 $ hg log -v -T bisect -r 0:4
2260 $ hg log -v -T bisect -r 0:4
2261 changeset: 0:1e4e1b8f71e0
2261 changeset: 0:1e4e1b8f71e0
2262 bisect: good (implicit)
2262 bisect: good (implicit)
2263 user: User Name <user@hostname>
2263 user: User Name <user@hostname>
2264 date: Mon Jan 12 13:46:40 1970 +0000
2264 date: Mon Jan 12 13:46:40 1970 +0000
2265 files: a
2265 files: a
2266 description:
2266 description:
2267 line 1
2267 line 1
2268 line 2
2268 line 2
2269
2269
2270
2270
2271 changeset: 1:b608e9d1a3f0
2271 changeset: 1:b608e9d1a3f0
2272 bisect: good
2272 bisect: good
2273 user: A. N. Other <other@place>
2273 user: A. N. Other <other@place>
2274 date: Tue Jan 13 17:33:20 1970 +0000
2274 date: Tue Jan 13 17:33:20 1970 +0000
2275 files: b
2275 files: b
2276 description:
2276 description:
2277 other 1
2277 other 1
2278 other 2
2278 other 2
2279
2279
2280 other 3
2280 other 3
2281
2281
2282
2282
2283 changeset: 2:97054abb4ab8
2283 changeset: 2:97054abb4ab8
2284 bisect: untested
2284 bisect: untested
2285 user: other@place
2285 user: other@place
2286 date: Wed Jan 14 21:20:00 1970 +0000
2286 date: Wed Jan 14 21:20:00 1970 +0000
2287 files: c
2287 files: c
2288 description:
2288 description:
2289 no person
2289 no person
2290
2290
2291
2291
2292 changeset: 3:10e46f2dcbf4
2292 changeset: 3:10e46f2dcbf4
2293 bisect: bad
2293 bisect: bad
2294 user: person
2294 user: person
2295 date: Fri Jan 16 01:06:40 1970 +0000
2295 date: Fri Jan 16 01:06:40 1970 +0000
2296 files: c
2296 files: c
2297 description:
2297 description:
2298 no user, no domain
2298 no user, no domain
2299
2299
2300
2300
2301 changeset: 4:bbe44766e73d
2301 changeset: 4:bbe44766e73d
2302 bisect: bad (implicit)
2302 bisect: bad (implicit)
2303 branch: foo
2303 branch: foo
2304 user: person
2304 user: person
2305 date: Sat Jan 17 04:53:20 1970 +0000
2305 date: Sat Jan 17 04:53:20 1970 +0000
2306 description:
2306 description:
2307 new branch
2307 new branch
2308
2308
2309
2309
2310 $ hg --color=debug log -T bisect -r 0:4
2310 $ hg --color=debug log -T bisect -r 0:4
2311 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2311 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2312 [log.bisect bisect.good|bisect: good (implicit)]
2312 [log.bisect bisect.good|bisect: good (implicit)]
2313 [log.user|user: User Name <user@hostname>]
2313 [log.user|user: User Name <user@hostname>]
2314 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2314 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2315 [log.summary|summary: line 1]
2315 [log.summary|summary: line 1]
2316
2316
2317 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2317 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2318 [log.bisect bisect.good|bisect: good]
2318 [log.bisect bisect.good|bisect: good]
2319 [log.user|user: A. N. Other <other@place>]
2319 [log.user|user: A. N. Other <other@place>]
2320 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2320 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2321 [log.summary|summary: other 1]
2321 [log.summary|summary: other 1]
2322
2322
2323 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2323 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2324 [log.bisect bisect.untested|bisect: untested]
2324 [log.bisect bisect.untested|bisect: untested]
2325 [log.user|user: other@place]
2325 [log.user|user: other@place]
2326 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2326 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2327 [log.summary|summary: no person]
2327 [log.summary|summary: no person]
2328
2328
2329 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2329 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2330 [log.bisect bisect.bad|bisect: bad]
2330 [log.bisect bisect.bad|bisect: bad]
2331 [log.user|user: person]
2331 [log.user|user: person]
2332 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2332 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2333 [log.summary|summary: no user, no domain]
2333 [log.summary|summary: no user, no domain]
2334
2334
2335 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2335 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2336 [log.bisect bisect.bad|bisect: bad (implicit)]
2336 [log.bisect bisect.bad|bisect: bad (implicit)]
2337 [log.branch|branch: foo]
2337 [log.branch|branch: foo]
2338 [log.user|user: person]
2338 [log.user|user: person]
2339 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2339 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2340 [log.summary|summary: new branch]
2340 [log.summary|summary: new branch]
2341
2341
2342 $ hg --color=debug log --debug -T bisect -r 0:4
2342 $ hg --color=debug log --debug -T bisect -r 0:4
2343 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2343 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2344 [log.bisect bisect.good|bisect: good (implicit)]
2344 [log.bisect bisect.good|bisect: good (implicit)]
2345 [log.phase|phase: public]
2345 [log.phase|phase: public]
2346 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2346 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2347 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2347 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2348 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2348 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2349 [log.user|user: User Name <user@hostname>]
2349 [log.user|user: User Name <user@hostname>]
2350 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2350 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2351 [ui.debug log.files|files+: a]
2351 [ui.debug log.files|files+: a]
2352 [ui.debug log.extra|extra: branch=default]
2352 [ui.debug log.extra|extra: branch=default]
2353 [ui.note log.description|description:]
2353 [ui.note log.description|description:]
2354 [ui.note log.description|line 1
2354 [ui.note log.description|line 1
2355 line 2]
2355 line 2]
2356
2356
2357
2357
2358 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2358 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2359 [log.bisect bisect.good|bisect: good]
2359 [log.bisect bisect.good|bisect: good]
2360 [log.phase|phase: public]
2360 [log.phase|phase: public]
2361 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2361 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2362 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2362 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2363 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2363 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2364 [log.user|user: A. N. Other <other@place>]
2364 [log.user|user: A. N. Other <other@place>]
2365 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2365 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2366 [ui.debug log.files|files+: b]
2366 [ui.debug log.files|files+: b]
2367 [ui.debug log.extra|extra: branch=default]
2367 [ui.debug log.extra|extra: branch=default]
2368 [ui.note log.description|description:]
2368 [ui.note log.description|description:]
2369 [ui.note log.description|other 1
2369 [ui.note log.description|other 1
2370 other 2
2370 other 2
2371
2371
2372 other 3]
2372 other 3]
2373
2373
2374
2374
2375 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2375 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2376 [log.bisect bisect.untested|bisect: untested]
2376 [log.bisect bisect.untested|bisect: untested]
2377 [log.phase|phase: public]
2377 [log.phase|phase: public]
2378 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2378 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2379 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2379 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2380 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2380 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2381 [log.user|user: other@place]
2381 [log.user|user: other@place]
2382 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2382 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2383 [ui.debug log.files|files+: c]
2383 [ui.debug log.files|files+: c]
2384 [ui.debug log.extra|extra: branch=default]
2384 [ui.debug log.extra|extra: branch=default]
2385 [ui.note log.description|description:]
2385 [ui.note log.description|description:]
2386 [ui.note log.description|no person]
2386 [ui.note log.description|no person]
2387
2387
2388
2388
2389 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2389 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2390 [log.bisect bisect.bad|bisect: bad]
2390 [log.bisect bisect.bad|bisect: bad]
2391 [log.phase|phase: public]
2391 [log.phase|phase: public]
2392 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2392 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2393 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2393 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2394 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2394 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2395 [log.user|user: person]
2395 [log.user|user: person]
2396 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2396 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2397 [ui.debug log.files|files: c]
2397 [ui.debug log.files|files: c]
2398 [ui.debug log.extra|extra: branch=default]
2398 [ui.debug log.extra|extra: branch=default]
2399 [ui.note log.description|description:]
2399 [ui.note log.description|description:]
2400 [ui.note log.description|no user, no domain]
2400 [ui.note log.description|no user, no domain]
2401
2401
2402
2402
2403 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2403 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2404 [log.bisect bisect.bad|bisect: bad (implicit)]
2404 [log.bisect bisect.bad|bisect: bad (implicit)]
2405 [log.branch|branch: foo]
2405 [log.branch|branch: foo]
2406 [log.phase|phase: draft]
2406 [log.phase|phase: draft]
2407 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2407 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2408 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2408 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2409 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2409 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2410 [log.user|user: person]
2410 [log.user|user: person]
2411 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2411 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2412 [ui.debug log.extra|extra: branch=foo]
2412 [ui.debug log.extra|extra: branch=foo]
2413 [ui.note log.description|description:]
2413 [ui.note log.description|description:]
2414 [ui.note log.description|new branch]
2414 [ui.note log.description|new branch]
2415
2415
2416
2416
2417 $ hg --color=debug log -v -T bisect -r 0:4
2417 $ hg --color=debug log -v -T bisect -r 0:4
2418 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2418 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2419 [log.bisect bisect.good|bisect: good (implicit)]
2419 [log.bisect bisect.good|bisect: good (implicit)]
2420 [log.user|user: User Name <user@hostname>]
2420 [log.user|user: User Name <user@hostname>]
2421 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2421 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2422 [ui.note log.files|files: a]
2422 [ui.note log.files|files: a]
2423 [ui.note log.description|description:]
2423 [ui.note log.description|description:]
2424 [ui.note log.description|line 1
2424 [ui.note log.description|line 1
2425 line 2]
2425 line 2]
2426
2426
2427
2427
2428 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2428 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2429 [log.bisect bisect.good|bisect: good]
2429 [log.bisect bisect.good|bisect: good]
2430 [log.user|user: A. N. Other <other@place>]
2430 [log.user|user: A. N. Other <other@place>]
2431 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2431 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2432 [ui.note log.files|files: b]
2432 [ui.note log.files|files: b]
2433 [ui.note log.description|description:]
2433 [ui.note log.description|description:]
2434 [ui.note log.description|other 1
2434 [ui.note log.description|other 1
2435 other 2
2435 other 2
2436
2436
2437 other 3]
2437 other 3]
2438
2438
2439
2439
2440 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2440 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2441 [log.bisect bisect.untested|bisect: untested]
2441 [log.bisect bisect.untested|bisect: untested]
2442 [log.user|user: other@place]
2442 [log.user|user: other@place]
2443 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2443 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2444 [ui.note log.files|files: c]
2444 [ui.note log.files|files: c]
2445 [ui.note log.description|description:]
2445 [ui.note log.description|description:]
2446 [ui.note log.description|no person]
2446 [ui.note log.description|no person]
2447
2447
2448
2448
2449 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2449 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2450 [log.bisect bisect.bad|bisect: bad]
2450 [log.bisect bisect.bad|bisect: bad]
2451 [log.user|user: person]
2451 [log.user|user: person]
2452 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2452 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2453 [ui.note log.files|files: c]
2453 [ui.note log.files|files: c]
2454 [ui.note log.description|description:]
2454 [ui.note log.description|description:]
2455 [ui.note log.description|no user, no domain]
2455 [ui.note log.description|no user, no domain]
2456
2456
2457
2457
2458 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2458 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2459 [log.bisect bisect.bad|bisect: bad (implicit)]
2459 [log.bisect bisect.bad|bisect: bad (implicit)]
2460 [log.branch|branch: foo]
2460 [log.branch|branch: foo]
2461 [log.user|user: person]
2461 [log.user|user: person]
2462 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2462 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2463 [ui.note log.description|description:]
2463 [ui.note log.description|description:]
2464 [ui.note log.description|new branch]
2464 [ui.note log.description|new branch]
2465
2465
2466
2466
2467 $ hg bisect --reset
2467 $ hg bisect --reset
2468
2468
2469 Error on syntax:
2469 Error on syntax:
2470
2470
2471 $ echo 'x = "f' >> t
2471 $ echo 'x = "f' >> t
2472 $ hg log
2472 $ hg log
2473 abort: t:3: unmatched quotes
2473 abort: t:3: unmatched quotes
2474 [255]
2474 [255]
2475
2475
2476 $ hg log -T '{date'
2476 $ hg log -T '{date'
2477 hg: parse error at 1: unterminated template expansion
2477 hg: parse error at 1: unterminated template expansion
2478 [255]
2478 [255]
2479
2479
2480 Behind the scenes, this will throw TypeError
2480 Behind the scenes, this will throw TypeError
2481
2481
2482 $ hg log -l 3 --template '{date|obfuscate}\n'
2482 $ hg log -l 3 --template '{date|obfuscate}\n'
2483 abort: template filter 'obfuscate' is not compatible with keyword 'date'
2483 abort: template filter 'obfuscate' is not compatible with keyword 'date'
2484 [255]
2484 [255]
2485
2485
2486 Behind the scenes, this will throw a ValueError
2486 Behind the scenes, this will throw a ValueError
2487
2487
2488 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2488 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2489 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2489 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2490 [255]
2490 [255]
2491
2491
2492 Behind the scenes, this will throw AttributeError
2492 Behind the scenes, this will throw AttributeError
2493
2493
2494 $ hg log -l 3 --template 'line: {date|escape}\n'
2494 $ hg log -l 3 --template 'line: {date|escape}\n'
2495 abort: template filter 'escape' is not compatible with keyword 'date'
2495 abort: template filter 'escape' is not compatible with keyword 'date'
2496 [255]
2496 [255]
2497
2497
2498 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2498 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2499 hg: parse error: localdate expects a date information
2499 hg: parse error: localdate expects a date information
2500 [255]
2500 [255]
2501
2501
2502 Behind the scenes, this will throw ValueError
2502 Behind the scenes, this will throw ValueError
2503
2503
2504 $ hg tip --template '{author|email|date}\n'
2504 $ hg tip --template '{author|email|date}\n'
2505 hg: parse error: date expects a date information
2505 hg: parse error: date expects a date information
2506 [255]
2506 [255]
2507
2507
2508 Error in nested template:
2508 Error in nested template:
2509
2509
2510 $ hg log -T '{"date'
2510 $ hg log -T '{"date'
2511 hg: parse error at 2: unterminated string
2511 hg: parse error at 2: unterminated string
2512 [255]
2512 [255]
2513
2513
2514 $ hg log -T '{"foo{date|=}"}'
2514 $ hg log -T '{"foo{date|=}"}'
2515 hg: parse error at 11: syntax error
2515 hg: parse error at 11: syntax error
2516 [255]
2516 [255]
2517
2517
2518 Thrown an error if a template function doesn't exist
2518 Thrown an error if a template function doesn't exist
2519
2519
2520 $ hg tip --template '{foo()}\n'
2520 $ hg tip --template '{foo()}\n'
2521 hg: parse error: unknown function 'foo'
2521 hg: parse error: unknown function 'foo'
2522 [255]
2522 [255]
2523
2523
2524 Pass generator object created by template function to filter
2524 Pass generator object created by template function to filter
2525
2525
2526 $ hg log -l 1 --template '{if(author, author)|user}\n'
2526 $ hg log -l 1 --template '{if(author, author)|user}\n'
2527 test
2527 test
2528
2528
2529 Test diff function:
2529 Test diff function:
2530
2530
2531 $ hg diff -c 8
2531 $ hg diff -c 8
2532 diff -r 29114dbae42b -r 95c24699272e fourth
2532 diff -r 29114dbae42b -r 95c24699272e fourth
2533 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2533 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2534 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2534 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2535 @@ -0,0 +1,1 @@
2535 @@ -0,0 +1,1 @@
2536 +second
2536 +second
2537 diff -r 29114dbae42b -r 95c24699272e second
2537 diff -r 29114dbae42b -r 95c24699272e second
2538 --- a/second Mon Jan 12 13:46:40 1970 +0000
2538 --- a/second Mon Jan 12 13:46:40 1970 +0000
2539 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2539 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2540 @@ -1,1 +0,0 @@
2540 @@ -1,1 +0,0 @@
2541 -second
2541 -second
2542 diff -r 29114dbae42b -r 95c24699272e third
2542 diff -r 29114dbae42b -r 95c24699272e third
2543 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2543 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2544 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2544 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2545 @@ -0,0 +1,1 @@
2545 @@ -0,0 +1,1 @@
2546 +third
2546 +third
2547
2547
2548 $ hg log -r 8 -T "{diff()}"
2548 $ hg log -r 8 -T "{diff()}"
2549 diff -r 29114dbae42b -r 95c24699272e fourth
2549 diff -r 29114dbae42b -r 95c24699272e fourth
2550 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2550 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2551 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2551 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2552 @@ -0,0 +1,1 @@
2552 @@ -0,0 +1,1 @@
2553 +second
2553 +second
2554 diff -r 29114dbae42b -r 95c24699272e second
2554 diff -r 29114dbae42b -r 95c24699272e second
2555 --- a/second Mon Jan 12 13:46:40 1970 +0000
2555 --- a/second Mon Jan 12 13:46:40 1970 +0000
2556 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2556 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2557 @@ -1,1 +0,0 @@
2557 @@ -1,1 +0,0 @@
2558 -second
2558 -second
2559 diff -r 29114dbae42b -r 95c24699272e third
2559 diff -r 29114dbae42b -r 95c24699272e third
2560 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2560 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2561 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2561 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2562 @@ -0,0 +1,1 @@
2562 @@ -0,0 +1,1 @@
2563 +third
2563 +third
2564
2564
2565 $ hg log -r 8 -T "{diff('glob:f*')}"
2565 $ hg log -r 8 -T "{diff('glob:f*')}"
2566 diff -r 29114dbae42b -r 95c24699272e fourth
2566 diff -r 29114dbae42b -r 95c24699272e fourth
2567 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2567 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2568 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2568 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2569 @@ -0,0 +1,1 @@
2569 @@ -0,0 +1,1 @@
2570 +second
2570 +second
2571
2571
2572 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2572 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2573 diff -r 29114dbae42b -r 95c24699272e second
2573 diff -r 29114dbae42b -r 95c24699272e second
2574 --- a/second Mon Jan 12 13:46:40 1970 +0000
2574 --- a/second Mon Jan 12 13:46:40 1970 +0000
2575 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2575 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2576 @@ -1,1 +0,0 @@
2576 @@ -1,1 +0,0 @@
2577 -second
2577 -second
2578 diff -r 29114dbae42b -r 95c24699272e third
2578 diff -r 29114dbae42b -r 95c24699272e third
2579 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2579 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2580 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2580 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2581 @@ -0,0 +1,1 @@
2581 @@ -0,0 +1,1 @@
2582 +third
2582 +third
2583
2583
2584 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2584 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2585 diff -r 29114dbae42b -r 95c24699272e fourth
2585 diff -r 29114dbae42b -r 95c24699272e fourth
2586 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2586 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2587 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2587 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2588 @@ -0,0 +1,1 @@
2588 @@ -0,0 +1,1 @@
2589 +second
2589 +second
2590
2590
2591 $ cd ..
2591 $ cd ..
2592
2592
2593
2593
2594 latesttag:
2594 latesttag:
2595
2595
2596 $ hg init latesttag
2596 $ hg init latesttag
2597 $ cd latesttag
2597 $ cd latesttag
2598
2598
2599 $ echo a > file
2599 $ echo a > file
2600 $ hg ci -Am a -d '0 0'
2600 $ hg ci -Am a -d '0 0'
2601 adding file
2601 adding file
2602
2602
2603 $ echo b >> file
2603 $ echo b >> file
2604 $ hg ci -m b -d '1 0'
2604 $ hg ci -m b -d '1 0'
2605
2605
2606 $ echo c >> head1
2606 $ echo c >> head1
2607 $ hg ci -Am h1c -d '2 0'
2607 $ hg ci -Am h1c -d '2 0'
2608 adding head1
2608 adding head1
2609
2609
2610 $ hg update -q 1
2610 $ hg update -q 1
2611 $ echo d >> head2
2611 $ echo d >> head2
2612 $ hg ci -Am h2d -d '3 0'
2612 $ hg ci -Am h2d -d '3 0'
2613 adding head2
2613 adding head2
2614 created new head
2614 created new head
2615
2615
2616 $ echo e >> head2
2616 $ echo e >> head2
2617 $ hg ci -m h2e -d '4 0'
2617 $ hg ci -m h2e -d '4 0'
2618
2618
2619 $ hg merge -q
2619 $ hg merge -q
2620 $ hg ci -m merge -d '5 -3600'
2620 $ hg ci -m merge -d '5 -3600'
2621
2621
2622 No tag set:
2622 No tag set:
2623
2623
2624 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2624 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2625 5: null+5
2625 5: null+5
2626 4: null+4
2626 4: null+4
2627 3: null+3
2627 3: null+3
2628 2: null+3
2628 2: null+3
2629 1: null+2
2629 1: null+2
2630 0: null+1
2630 0: null+1
2631
2631
2632 One common tag: longest path wins:
2632 One common tag: longest path wins:
2633
2633
2634 $ hg tag -r 1 -m t1 -d '6 0' t1
2634 $ hg tag -r 1 -m t1 -d '6 0' t1
2635 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2635 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2636 6: t1+4
2636 6: t1+4
2637 5: t1+3
2637 5: t1+3
2638 4: t1+2
2638 4: t1+2
2639 3: t1+1
2639 3: t1+1
2640 2: t1+1
2640 2: t1+1
2641 1: t1+0
2641 1: t1+0
2642 0: null+1
2642 0: null+1
2643
2643
2644 One ancestor tag: more recent wins:
2644 One ancestor tag: more recent wins:
2645
2645
2646 $ hg tag -r 2 -m t2 -d '7 0' t2
2646 $ hg tag -r 2 -m t2 -d '7 0' t2
2647 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2647 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2648 7: t2+3
2648 7: t2+3
2649 6: t2+2
2649 6: t2+2
2650 5: t2+1
2650 5: t2+1
2651 4: t1+2
2651 4: t1+2
2652 3: t1+1
2652 3: t1+1
2653 2: t2+0
2653 2: t2+0
2654 1: t1+0
2654 1: t1+0
2655 0: null+1
2655 0: null+1
2656
2656
2657 Two branch tags: more recent wins:
2657 Two branch tags: more recent wins:
2658
2658
2659 $ hg tag -r 3 -m t3 -d '8 0' t3
2659 $ hg tag -r 3 -m t3 -d '8 0' t3
2660 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2660 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2661 8: t3+5
2661 8: t3+5
2662 7: t3+4
2662 7: t3+4
2663 6: t3+3
2663 6: t3+3
2664 5: t3+2
2664 5: t3+2
2665 4: t3+1
2665 4: t3+1
2666 3: t3+0
2666 3: t3+0
2667 2: t2+0
2667 2: t2+0
2668 1: t1+0
2668 1: t1+0
2669 0: null+1
2669 0: null+1
2670
2670
2671 Merged tag overrides:
2671 Merged tag overrides:
2672
2672
2673 $ hg tag -r 5 -m t5 -d '9 0' t5
2673 $ hg tag -r 5 -m t5 -d '9 0' t5
2674 $ hg tag -r 3 -m at3 -d '10 0' at3
2674 $ hg tag -r 3 -m at3 -d '10 0' at3
2675 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2675 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2676 10: t5+5
2676 10: t5+5
2677 9: t5+4
2677 9: t5+4
2678 8: t5+3
2678 8: t5+3
2679 7: t5+2
2679 7: t5+2
2680 6: t5+1
2680 6: t5+1
2681 5: t5+0
2681 5: t5+0
2682 4: at3:t3+1
2682 4: at3:t3+1
2683 3: at3:t3+0
2683 3: at3:t3+0
2684 2: t2+0
2684 2: t2+0
2685 1: t1+0
2685 1: t1+0
2686 0: null+1
2686 0: null+1
2687
2687
2688 $ cd ..
2688 $ cd ..
2689
2689
2690
2690
2691 Style path expansion: issue1948 - ui.style option doesn't work on OSX
2691 Style path expansion: issue1948 - ui.style option doesn't work on OSX
2692 if it is a relative path
2692 if it is a relative path
2693
2693
2694 $ mkdir -p home/styles
2694 $ mkdir -p home/styles
2695
2695
2696 $ cat > home/styles/teststyle <<EOF
2696 $ cat > home/styles/teststyle <<EOF
2697 > changeset = 'test {rev}:{node|short}\n'
2697 > changeset = 'test {rev}:{node|short}\n'
2698 > EOF
2698 > EOF
2699
2699
2700 $ HOME=`pwd`/home; export HOME
2700 $ HOME=`pwd`/home; export HOME
2701
2701
2702 $ cat > latesttag/.hg/hgrc <<EOF
2702 $ cat > latesttag/.hg/hgrc <<EOF
2703 > [ui]
2703 > [ui]
2704 > style = ~/styles/teststyle
2704 > style = ~/styles/teststyle
2705 > EOF
2705 > EOF
2706
2706
2707 $ hg -R latesttag tip
2707 $ hg -R latesttag tip
2708 test 10:9b4a630e5f5f
2708 test 10:9b4a630e5f5f
2709
2709
2710 Test recursive showlist template (issue1989):
2710 Test recursive showlist template (issue1989):
2711
2711
2712 $ cat > style1989 <<EOF
2712 $ cat > style1989 <<EOF
2713 > changeset = '{file_mods}{manifest}{extras}'
2713 > changeset = '{file_mods}{manifest}{extras}'
2714 > file_mod = 'M|{author|person}\n'
2714 > file_mod = 'M|{author|person}\n'
2715 > manifest = '{rev},{author}\n'
2715 > manifest = '{rev},{author}\n'
2716 > extra = '{key}: {author}\n'
2716 > extra = '{key}: {author}\n'
2717 > EOF
2717 > EOF
2718
2718
2719 $ hg -R latesttag log -r tip --style=style1989
2719 $ hg -R latesttag log -r tip --style=style1989
2720 M|test
2720 M|test
2721 10,test
2721 10,test
2722 branch: test
2722 branch: test
2723
2723
2724 Test new-style inline templating:
2724 Test new-style inline templating:
2725
2725
2726 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
2726 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
2727 modified files: .hgtags
2727 modified files: .hgtags
2728
2728
2729 Test the sub function of templating for expansion:
2729 Test the sub function of templating for expansion:
2730
2730
2731 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
2731 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
2732 xx
2732 xx
2733
2733
2734 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
2734 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
2735 hg: parse error: sub got an invalid pattern: [
2735 hg: parse error: sub got an invalid pattern: [
2736 [255]
2736 [255]
2737 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
2737 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
2738 hg: parse error: sub got an invalid replacement: \1
2738 hg: parse error: sub got an invalid replacement: \1
2739 [255]
2739 [255]
2740
2740
2741 Test the strip function with chars specified:
2741 Test the strip function with chars specified:
2742
2742
2743 $ hg log -R latesttag --template '{desc}\n'
2743 $ hg log -R latesttag --template '{desc}\n'
2744 at3
2744 at3
2745 t5
2745 t5
2746 t3
2746 t3
2747 t2
2747 t2
2748 t1
2748 t1
2749 merge
2749 merge
2750 h2e
2750 h2e
2751 h2d
2751 h2d
2752 h1c
2752 h1c
2753 b
2753 b
2754 a
2754 a
2755
2755
2756 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2756 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2757 at3
2757 at3
2758 5
2758 5
2759 3
2759 3
2760 2
2760 2
2761 1
2761 1
2762 merg
2762 merg
2763 h2
2763 h2
2764 h2d
2764 h2d
2765 h1c
2765 h1c
2766 b
2766 b
2767 a
2767 a
2768
2768
2769 Test date format:
2769 Test date format:
2770
2770
2771 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2771 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2772 date: 70 01 01 10 +0000
2772 date: 70 01 01 10 +0000
2773 date: 70 01 01 09 +0000
2773 date: 70 01 01 09 +0000
2774 date: 70 01 01 08 +0000
2774 date: 70 01 01 08 +0000
2775 date: 70 01 01 07 +0000
2775 date: 70 01 01 07 +0000
2776 date: 70 01 01 06 +0000
2776 date: 70 01 01 06 +0000
2777 date: 70 01 01 05 +0100
2777 date: 70 01 01 05 +0100
2778 date: 70 01 01 04 +0000
2778 date: 70 01 01 04 +0000
2779 date: 70 01 01 03 +0000
2779 date: 70 01 01 03 +0000
2780 date: 70 01 01 02 +0000
2780 date: 70 01 01 02 +0000
2781 date: 70 01 01 01 +0000
2781 date: 70 01 01 01 +0000
2782 date: 70 01 01 00 +0000
2782 date: 70 01 01 00 +0000
2783
2783
2784 Test invalid date:
2784 Test invalid date:
2785
2785
2786 $ hg log -R latesttag -T '{date(rev)}\n'
2786 $ hg log -R latesttag -T '{date(rev)}\n'
2787 hg: parse error: date expects a date information
2787 hg: parse error: date expects a date information
2788 [255]
2788 [255]
2789
2789
2790 Test integer literal:
2790 Test integer literal:
2791
2791
2792 $ hg log -Ra -r0 -T '{(0)}\n'
2792 $ hg log -Ra -r0 -T '{(0)}\n'
2793 0
2793 0
2794 $ hg log -Ra -r0 -T '{(123)}\n'
2794 $ hg log -Ra -r0 -T '{(123)}\n'
2795 123
2795 123
2796 $ hg log -Ra -r0 -T '{(-4)}\n'
2796 $ hg log -Ra -r0 -T '{(-4)}\n'
2797 -4
2797 -4
2798 $ hg log -Ra -r0 -T '{(-)}\n'
2798 $ hg log -Ra -r0 -T '{(-)}\n'
2799 hg: parse error at 2: integer literal without digits
2799 hg: parse error at 2: integer literal without digits
2800 [255]
2800 [255]
2801 $ hg log -Ra -r0 -T '{(-a)}\n'
2801 $ hg log -Ra -r0 -T '{(-a)}\n'
2802 hg: parse error at 2: integer literal without digits
2802 hg: parse error at 2: integer literal without digits
2803 [255]
2803 [255]
2804
2804
2805 top-level integer literal is interpreted as symbol (i.e. variable name):
2805 top-level integer literal is interpreted as symbol (i.e. variable name):
2806
2806
2807 $ hg log -Ra -r0 -T '{1}\n'
2807 $ hg log -Ra -r0 -T '{1}\n'
2808
2808
2809 $ hg log -Ra -r0 -T '{if("t", "{1}")}\n'
2809 $ hg log -Ra -r0 -T '{if("t", "{1}")}\n'
2810
2810
2811 $ hg log -Ra -r0 -T '{1|stringify}\n'
2811 $ hg log -Ra -r0 -T '{1|stringify}\n'
2812
2812
2813
2813
2814 unless explicit symbol is expected:
2814 unless explicit symbol is expected:
2815
2815
2816 $ hg log -Ra -r0 -T '{desc|1}\n'
2816 $ hg log -Ra -r0 -T '{desc|1}\n'
2817 hg: parse error: expected a symbol, got 'integer'
2817 hg: parse error: expected a symbol, got 'integer'
2818 [255]
2818 [255]
2819 $ hg log -Ra -r0 -T '{1()}\n'
2819 $ hg log -Ra -r0 -T '{1()}\n'
2820 hg: parse error: expected a symbol, got 'integer'
2820 hg: parse error: expected a symbol, got 'integer'
2821 [255]
2821 [255]
2822
2822
2823 Test string literal:
2823 Test string literal:
2824
2824
2825 $ hg log -Ra -r0 -T '{"string with no template fragment"}\n'
2825 $ hg log -Ra -r0 -T '{"string with no template fragment"}\n'
2826 string with no template fragment
2826 string with no template fragment
2827 $ hg log -Ra -r0 -T '{"template: {rev}"}\n'
2827 $ hg log -Ra -r0 -T '{"template: {rev}"}\n'
2828 template: 0
2828 template: 0
2829 $ hg log -Ra -r0 -T '{r"rawstring: {rev}"}\n'
2829 $ hg log -Ra -r0 -T '{r"rawstring: {rev}"}\n'
2830 rawstring: {rev}
2830 rawstring: {rev}
2831
2831
2832 because map operation requires template, raw string can't be used
2832 because map operation requires template, raw string can't be used
2833
2833
2834 $ hg log -Ra -r0 -T '{files % r"rawstring"}\n'
2834 $ hg log -Ra -r0 -T '{files % r"rawstring"}\n'
2835 hg: parse error: expected template specifier
2835 hg: parse error: expected template specifier
2836 [255]
2836 [255]
2837
2837
2838 Test string escaping:
2838 Test string escaping:
2839
2839
2840 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2840 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2841 >
2841 >
2842 <>\n<[>
2842 <>\n<[>
2843 <>\n<]>
2843 <>\n<]>
2844 <>\n<
2844 <>\n<
2845
2845
2846 $ hg log -R latesttag -r 0 \
2846 $ hg log -R latesttag -r 0 \
2847 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2847 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2848 >
2848 >
2849 <>\n<[>
2849 <>\n<[>
2850 <>\n<]>
2850 <>\n<]>
2851 <>\n<
2851 <>\n<
2852
2852
2853 $ hg log -R latesttag -r 0 -T esc \
2853 $ hg log -R latesttag -r 0 -T esc \
2854 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2854 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2855 >
2855 >
2856 <>\n<[>
2856 <>\n<[>
2857 <>\n<]>
2857 <>\n<]>
2858 <>\n<
2858 <>\n<
2859
2859
2860 $ cat <<'EOF' > esctmpl
2860 $ cat <<'EOF' > esctmpl
2861 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2861 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2862 > EOF
2862 > EOF
2863 $ hg log -R latesttag -r 0 --style ./esctmpl
2863 $ hg log -R latesttag -r 0 --style ./esctmpl
2864 >
2864 >
2865 <>\n<[>
2865 <>\n<[>
2866 <>\n<]>
2866 <>\n<]>
2867 <>\n<
2867 <>\n<
2868
2868
2869 Test string escaping of quotes:
2869 Test string escaping of quotes:
2870
2870
2871 $ hg log -Ra -r0 -T '{"\""}\n'
2871 $ hg log -Ra -r0 -T '{"\""}\n'
2872 "
2872 "
2873 $ hg log -Ra -r0 -T '{"\\\""}\n'
2873 $ hg log -Ra -r0 -T '{"\\\""}\n'
2874 \"
2874 \"
2875 $ hg log -Ra -r0 -T '{r"\""}\n'
2875 $ hg log -Ra -r0 -T '{r"\""}\n'
2876 \"
2876 \"
2877 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2877 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2878 \\\"
2878 \\\"
2879
2879
2880
2880
2881 $ hg log -Ra -r0 -T '{"\""}\n'
2881 $ hg log -Ra -r0 -T '{"\""}\n'
2882 "
2882 "
2883 $ hg log -Ra -r0 -T '{"\\\""}\n'
2883 $ hg log -Ra -r0 -T '{"\\\""}\n'
2884 \"
2884 \"
2885 $ hg log -Ra -r0 -T '{r"\""}\n'
2885 $ hg log -Ra -r0 -T '{r"\""}\n'
2886 \"
2886 \"
2887 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2887 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2888 \\\"
2888 \\\"
2889
2889
2890 Test exception in quoted template. single backslash before quotation mark is
2890 Test exception in quoted template. single backslash before quotation mark is
2891 stripped before parsing:
2891 stripped before parsing:
2892
2892
2893 $ cat <<'EOF' > escquotetmpl
2893 $ cat <<'EOF' > escquotetmpl
2894 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
2894 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
2895 > EOF
2895 > EOF
2896 $ cd latesttag
2896 $ cd latesttag
2897 $ hg log -r 2 --style ../escquotetmpl
2897 $ hg log -r 2 --style ../escquotetmpl
2898 " \" \" \\" head1
2898 " \" \" \\" head1
2899
2899
2900 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
2900 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
2901 valid
2901 valid
2902 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
2902 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
2903 valid
2903 valid
2904
2904
2905 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
2905 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
2906 _evalifliteral() templates (issue4733):
2906 _evalifliteral() templates (issue4733):
2907
2907
2908 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
2908 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
2909 "2
2909 "2
2910 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
2910 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
2911 "2
2911 "2
2912 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
2912 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
2913 "2
2913 "2
2914
2914
2915 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
2915 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
2916 \"
2916 \"
2917 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
2917 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
2918 \"
2918 \"
2919 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2919 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2920 \"
2920 \"
2921
2921
2922 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
2922 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
2923 \\\"
2923 \\\"
2924 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
2924 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
2925 \\\"
2925 \\\"
2926 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2926 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2927 \\\"
2927 \\\"
2928
2928
2929 escaped single quotes and errors:
2929 escaped single quotes and errors:
2930
2930
2931 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
2931 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
2932 foo
2932 foo
2933 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
2933 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
2934 foo
2934 foo
2935 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
2935 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
2936 hg: parse error at 21: unterminated string
2936 hg: parse error at 21: unterminated string
2937 [255]
2937 [255]
2938 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
2938 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
2939 hg: parse error at 11: syntax error
2939 hg: parse error: trailing \ in string
2940 [255]
2940 [255]
2941 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
2941 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
2942 hg: parse error at 12: syntax error
2942 hg: parse error: trailing \ in string
2943 [255]
2943 [255]
2944
2944
2945 $ cd ..
2945 $ cd ..
2946
2946
2947 Test leading backslashes:
2947 Test leading backslashes:
2948
2948
2949 $ cd latesttag
2949 $ cd latesttag
2950 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
2950 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
2951 {rev} {file}
2951 {rev} {file}
2952 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
2952 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
2953 \2 \head1
2953 \2 \head1
2954 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
2954 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
2955 \{rev} \{file}
2955 \{rev} \{file}
2956 $ cd ..
2956 $ cd ..
2957
2957
2958 Test leading backslashes in "if" expression (issue4714):
2958 Test leading backslashes in "if" expression (issue4714):
2959
2959
2960 $ cd latesttag
2960 $ cd latesttag
2961 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
2961 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
2962 {rev} \{rev}
2962 {rev} \{rev}
2963 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
2963 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
2964 \2 \\{rev}
2964 \2 \\{rev}
2965 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
2965 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
2966 \{rev} \\\{rev}
2966 \{rev} \\\{rev}
2967 $ cd ..
2967 $ cd ..
2968
2968
2969 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
2969 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
2970
2970
2971 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
2971 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
2972 \x6e
2972 \x6e
2973 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
2973 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
2974 \x5c\x786e
2974 \x5c\x786e
2975 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
2975 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
2976 \x6e
2976 \x6e
2977 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
2977 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
2978 \x5c\x786e
2978 \x5c\x786e
2979
2979
2980 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
2980 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
2981 \x6e
2981 \x6e
2982 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
2982 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
2983 \x5c\x786e
2983 \x5c\x786e
2984 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
2984 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
2985 \x6e
2985 \x6e
2986 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
2986 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
2987 \x5c\x786e
2987 \x5c\x786e
2988
2988
2989 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
2989 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
2990 fourth
2990 fourth
2991 second
2991 second
2992 third
2992 third
2993 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
2993 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
2994 fourth\nsecond\nthird
2994 fourth\nsecond\nthird
2995
2995
2996 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
2996 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
2997 <p>
2997 <p>
2998 1st
2998 1st
2999 </p>
2999 </p>
3000 <p>
3000 <p>
3001 2nd
3001 2nd
3002 </p>
3002 </p>
3003 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3003 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3004 <p>
3004 <p>
3005 1st\n\n2nd
3005 1st\n\n2nd
3006 </p>
3006 </p>
3007 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3007 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3008 1st
3008 1st
3009
3009
3010 2nd
3010 2nd
3011
3011
3012 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3012 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3013 o perso
3013 o perso
3014 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3014 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3015 no person
3015 no person
3016 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3016 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3017 o perso
3017 o perso
3018 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3018 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3019 no perso
3019 no perso
3020
3020
3021 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3021 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3022 -o perso-
3022 -o perso-
3023 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3023 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3024 no person
3024 no person
3025 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3025 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3026 \x2do perso\x2d
3026 \x2do perso\x2d
3027 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3027 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3028 -o perso-
3028 -o perso-
3029 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3029 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3030 \x2do perso\x6e
3030 \x2do perso\x6e
3031
3031
3032 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3032 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3033 fourth
3033 fourth
3034 second
3034 second
3035 third
3035 third
3036
3036
3037 Test string escaping in nested expression:
3037 Test string escaping in nested expression:
3038
3038
3039 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3039 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3040 fourth\x6esecond\x6ethird
3040 fourth\x6esecond\x6ethird
3041 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3041 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3042 fourth\x6esecond\x6ethird
3042 fourth\x6esecond\x6ethird
3043
3043
3044 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3044 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3045 fourth\x6esecond\x6ethird
3045 fourth\x6esecond\x6ethird
3046 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3046 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3047 fourth\x5c\x786esecond\x5c\x786ethird
3047 fourth\x5c\x786esecond\x5c\x786ethird
3048
3048
3049 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3049 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3050 3:\x6eo user, \x6eo domai\x6e
3050 3:\x6eo user, \x6eo domai\x6e
3051 4:\x5c\x786eew bra\x5c\x786ech
3051 4:\x5c\x786eew bra\x5c\x786ech
3052
3052
3053 Test quotes in nested expression are evaluated just like a $(command)
3053 Test quotes in nested expression are evaluated just like a $(command)
3054 substitution in POSIX shells:
3054 substitution in POSIX shells:
3055
3055
3056 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3056 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3057 8:95c24699272e
3057 8:95c24699272e
3058 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3058 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3059 {8} "95c24699272e"
3059 {8} "95c24699272e"
3060
3060
3061 Test recursive evaluation:
3061 Test recursive evaluation:
3062
3062
3063 $ hg init r
3063 $ hg init r
3064 $ cd r
3064 $ cd r
3065 $ echo a > a
3065 $ echo a > a
3066 $ hg ci -Am '{rev}'
3066 $ hg ci -Am '{rev}'
3067 adding a
3067 adding a
3068 $ hg log -r 0 --template '{if(rev, desc)}\n'
3068 $ hg log -r 0 --template '{if(rev, desc)}\n'
3069 {rev}
3069 {rev}
3070 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3070 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3071 test 0
3071 test 0
3072
3072
3073 $ hg branch -q 'text.{rev}'
3073 $ hg branch -q 'text.{rev}'
3074 $ echo aa >> aa
3074 $ echo aa >> aa
3075 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3075 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3076
3076
3077 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3077 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3078 {node|short}desc to
3078 {node|short}desc to
3079 text.{rev}be wrapped
3079 text.{rev}be wrapped
3080 text.{rev}desc to be
3080 text.{rev}desc to be
3081 text.{rev}wrapped (no-eol)
3081 text.{rev}wrapped (no-eol)
3082 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3082 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3083 bcc7ff960b8e:desc to
3083 bcc7ff960b8e:desc to
3084 text.1:be wrapped
3084 text.1:be wrapped
3085 text.1:desc to be
3085 text.1:desc to be
3086 text.1:wrapped (no-eol)
3086 text.1:wrapped (no-eol)
3087
3087
3088 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3088 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3089 {node|short} (no-eol)
3089 {node|short} (no-eol)
3090 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3090 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3091 bcc-ff---b-e (no-eol)
3091 bcc-ff---b-e (no-eol)
3092
3092
3093 $ cat >> .hg/hgrc <<EOF
3093 $ cat >> .hg/hgrc <<EOF
3094 > [extensions]
3094 > [extensions]
3095 > color=
3095 > color=
3096 > [color]
3096 > [color]
3097 > mode=ansi
3097 > mode=ansi
3098 > text.{rev} = red
3098 > text.{rev} = red
3099 > text.1 = green
3099 > text.1 = green
3100 > EOF
3100 > EOF
3101 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3101 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3102 \x1b[0;31mtext\x1b[0m (esc)
3102 \x1b[0;31mtext\x1b[0m (esc)
3103 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3103 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3104 \x1b[0;32mtext\x1b[0m (esc)
3104 \x1b[0;32mtext\x1b[0m (esc)
3105
3105
3106 Test branches inside if statement:
3106 Test branches inside if statement:
3107
3107
3108 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3108 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3109 no
3109 no
3110
3110
3111 Test get function:
3111 Test get function:
3112
3112
3113 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3113 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3114 default
3114 default
3115 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3115 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3116 hg: parse error: get() expects a dict as first argument
3116 hg: parse error: get() expects a dict as first argument
3117 [255]
3117 [255]
3118
3118
3119 Test localdate(date, tz) function:
3119 Test localdate(date, tz) function:
3120
3120
3121 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3121 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3122 1970-01-01 09:00 +0900
3122 1970-01-01 09:00 +0900
3123 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3123 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3124 1970-01-01 00:00 +0000
3124 1970-01-01 00:00 +0000
3125 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3125 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3126 1970-01-01 02:00 +0200
3126 1970-01-01 02:00 +0200
3127 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3127 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3128 1970-01-01 00:00 +0000
3128 1970-01-01 00:00 +0000
3129 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3129 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3130 1970-01-01 00:00 +0000
3130 1970-01-01 00:00 +0000
3131 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3131 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3132 hg: parse error: localdate expects a timezone
3132 hg: parse error: localdate expects a timezone
3133 [255]
3133 [255]
3134 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3134 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3135 hg: parse error: localdate expects a timezone
3135 hg: parse error: localdate expects a timezone
3136 [255]
3136 [255]
3137
3137
3138 Test shortest(node) function:
3138 Test shortest(node) function:
3139
3139
3140 $ echo b > b
3140 $ echo b > b
3141 $ hg ci -qAm b
3141 $ hg ci -qAm b
3142 $ hg log --template '{shortest(node)}\n'
3142 $ hg log --template '{shortest(node)}\n'
3143 e777
3143 e777
3144 bcc7
3144 bcc7
3145 f776
3145 f776
3146 $ hg log --template '{shortest(node, 10)}\n'
3146 $ hg log --template '{shortest(node, 10)}\n'
3147 e777603221
3147 e777603221
3148 bcc7ff960b
3148 bcc7ff960b
3149 f7769ec2ab
3149 f7769ec2ab
3150 $ hg log --template '{node|shortest}\n' -l1
3150 $ hg log --template '{node|shortest}\n' -l1
3151 e777
3151 e777
3152
3152
3153 Test pad function
3153 Test pad function
3154
3154
3155 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3155 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3156 2 test
3156 2 test
3157 1 {node|short}
3157 1 {node|short}
3158 0 test
3158 0 test
3159
3159
3160 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3160 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3161 2 test
3161 2 test
3162 1 {node|short}
3162 1 {node|short}
3163 0 test
3163 0 test
3164
3164
3165 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3165 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3166 2------------------- test
3166 2------------------- test
3167 1------------------- {node|short}
3167 1------------------- {node|short}
3168 0------------------- test
3168 0------------------- test
3169
3169
3170 Test template string in pad function
3170 Test template string in pad function
3171
3171
3172 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3172 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3173 {0} test
3173 {0} test
3174
3174
3175 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3175 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3176 \{rev} test
3176 \{rev} test
3177
3177
3178 Test ifcontains function
3178 Test ifcontains function
3179
3179
3180 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
3180 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
3181 2 is in the string
3181 2 is in the string
3182 1 is not
3182 1 is not
3183 0 is in the string
3183 0 is in the string
3184
3184
3185 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
3185 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
3186 2 did not add a
3186 2 did not add a
3187 1 did not add a
3187 1 did not add a
3188 0 added a
3188 0 added a
3189
3189
3190 Test revset function
3190 Test revset function
3191
3191
3192 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
3192 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
3193 2 current rev
3193 2 current rev
3194 1 not current rev
3194 1 not current rev
3195 0 not current rev
3195 0 not current rev
3196
3196
3197 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
3197 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
3198 2 match rev
3198 2 match rev
3199 1 match rev
3199 1 match rev
3200 0 not match rev
3200 0 not match rev
3201
3201
3202 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
3202 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
3203 2 Parents: 1
3203 2 Parents: 1
3204 1 Parents: 0
3204 1 Parents: 0
3205 0 Parents:
3205 0 Parents:
3206
3206
3207 $ cat >> .hg/hgrc <<EOF
3207 $ cat >> .hg/hgrc <<EOF
3208 > [revsetalias]
3208 > [revsetalias]
3209 > myparents(\$1) = parents(\$1)
3209 > myparents(\$1) = parents(\$1)
3210 > EOF
3210 > EOF
3211 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
3211 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
3212 2 Parents: 1
3212 2 Parents: 1
3213 1 Parents: 0
3213 1 Parents: 0
3214 0 Parents:
3214 0 Parents:
3215
3215
3216 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
3216 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
3217 Rev: 2
3217 Rev: 2
3218 Ancestor: 0
3218 Ancestor: 0
3219 Ancestor: 1
3219 Ancestor: 1
3220 Ancestor: 2
3220 Ancestor: 2
3221
3221
3222 Rev: 1
3222 Rev: 1
3223 Ancestor: 0
3223 Ancestor: 0
3224 Ancestor: 1
3224 Ancestor: 1
3225
3225
3226 Rev: 0
3226 Rev: 0
3227 Ancestor: 0
3227 Ancestor: 0
3228
3228
3229 $ hg log --template '{revset("TIP"|lower)}\n' -l1
3229 $ hg log --template '{revset("TIP"|lower)}\n' -l1
3230 2
3230 2
3231
3231
3232 Test active bookmark templating
3232 Test active bookmark templating
3233
3233
3234 $ hg book foo
3234 $ hg book foo
3235 $ hg book bar
3235 $ hg book bar
3236 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
3236 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
3237 2 bar* foo
3237 2 bar* foo
3238 1
3238 1
3239 0
3239 0
3240 $ hg log --template "{rev} {activebookmark}\n"
3240 $ hg log --template "{rev} {activebookmark}\n"
3241 2 bar
3241 2 bar
3242 1
3242 1
3243 0
3243 0
3244 $ hg bookmarks --inactive bar
3244 $ hg bookmarks --inactive bar
3245 $ hg log --template "{rev} {activebookmark}\n"
3245 $ hg log --template "{rev} {activebookmark}\n"
3246 2
3246 2
3247 1
3247 1
3248 0
3248 0
3249 $ hg book -r1 baz
3249 $ hg book -r1 baz
3250 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
3250 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
3251 2 bar foo
3251 2 bar foo
3252 1 baz
3252 1 baz
3253 0
3253 0
3254 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
3254 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
3255 2 t
3255 2 t
3256 1 f
3256 1 f
3257 0 f
3257 0 f
3258
3258
3259 Test stringify on sub expressions
3259 Test stringify on sub expressions
3260
3260
3261 $ cd ..
3261 $ cd ..
3262 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
3262 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
3263 fourth, second, third
3263 fourth, second, third
3264 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
3264 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
3265 abc
3265 abc
3266
3266
3267 Test splitlines
3267 Test splitlines
3268
3268
3269 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
3269 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
3270 @ foo Modify, add, remove, rename
3270 @ foo Modify, add, remove, rename
3271 |
3271 |
3272 o foo future
3272 o foo future
3273 |
3273 |
3274 o foo third
3274 o foo third
3275 |
3275 |
3276 o foo second
3276 o foo second
3277
3277
3278 o foo merge
3278 o foo merge
3279 |\
3279 |\
3280 | o foo new head
3280 | o foo new head
3281 | |
3281 | |
3282 o | foo new branch
3282 o | foo new branch
3283 |/
3283 |/
3284 o foo no user, no domain
3284 o foo no user, no domain
3285 |
3285 |
3286 o foo no person
3286 o foo no person
3287 |
3287 |
3288 o foo other 1
3288 o foo other 1
3289 | foo other 2
3289 | foo other 2
3290 | foo
3290 | foo
3291 | foo other 3
3291 | foo other 3
3292 o foo line 1
3292 o foo line 1
3293 foo line 2
3293 foo line 2
3294
3294
3295 Test startswith
3295 Test startswith
3296 $ hg log -Gv -R a --template "{startswith(desc)}"
3296 $ hg log -Gv -R a --template "{startswith(desc)}"
3297 hg: parse error: startswith expects two arguments
3297 hg: parse error: startswith expects two arguments
3298 [255]
3298 [255]
3299
3299
3300 $ hg log -Gv -R a --template "{startswith('line', desc)}"
3300 $ hg log -Gv -R a --template "{startswith('line', desc)}"
3301 @
3301 @
3302 |
3302 |
3303 o
3303 o
3304 |
3304 |
3305 o
3305 o
3306 |
3306 |
3307 o
3307 o
3308
3308
3309 o
3309 o
3310 |\
3310 |\
3311 | o
3311 | o
3312 | |
3312 | |
3313 o |
3313 o |
3314 |/
3314 |/
3315 o
3315 o
3316 |
3316 |
3317 o
3317 o
3318 |
3318 |
3319 o
3319 o
3320 |
3320 |
3321 o line 1
3321 o line 1
3322 line 2
3322 line 2
3323
3323
3324 Test bad template with better error message
3324 Test bad template with better error message
3325
3325
3326 $ hg log -Gv -R a --template '{desc|user()}'
3326 $ hg log -Gv -R a --template '{desc|user()}'
3327 hg: parse error: expected a symbol, got 'func'
3327 hg: parse error: expected a symbol, got 'func'
3328 [255]
3328 [255]
3329
3329
3330 Test word function (including index out of bounds graceful failure)
3330 Test word function (including index out of bounds graceful failure)
3331
3331
3332 $ hg log -Gv -R a --template "{word('1', desc)}"
3332 $ hg log -Gv -R a --template "{word('1', desc)}"
3333 @ add,
3333 @ add,
3334 |
3334 |
3335 o
3335 o
3336 |
3336 |
3337 o
3337 o
3338 |
3338 |
3339 o
3339 o
3340
3340
3341 o
3341 o
3342 |\
3342 |\
3343 | o head
3343 | o head
3344 | |
3344 | |
3345 o | branch
3345 o | branch
3346 |/
3346 |/
3347 o user,
3347 o user,
3348 |
3348 |
3349 o person
3349 o person
3350 |
3350 |
3351 o 1
3351 o 1
3352 |
3352 |
3353 o 1
3353 o 1
3354
3354
3355
3355
3356 Test word third parameter used as splitter
3356 Test word third parameter used as splitter
3357
3357
3358 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
3358 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
3359 @ M
3359 @ M
3360 |
3360 |
3361 o future
3361 o future
3362 |
3362 |
3363 o third
3363 o third
3364 |
3364 |
3365 o sec
3365 o sec
3366
3366
3367 o merge
3367 o merge
3368 |\
3368 |\
3369 | o new head
3369 | o new head
3370 | |
3370 | |
3371 o | new branch
3371 o | new branch
3372 |/
3372 |/
3373 o n
3373 o n
3374 |
3374 |
3375 o n
3375 o n
3376 |
3376 |
3377 o
3377 o
3378 |
3378 |
3379 o line 1
3379 o line 1
3380 line 2
3380 line 2
3381
3381
3382 Test word error messages for not enough and too many arguments
3382 Test word error messages for not enough and too many arguments
3383
3383
3384 $ hg log -Gv -R a --template "{word('0')}"
3384 $ hg log -Gv -R a --template "{word('0')}"
3385 hg: parse error: word expects two or three arguments, got 1
3385 hg: parse error: word expects two or three arguments, got 1
3386 [255]
3386 [255]
3387
3387
3388 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
3388 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
3389 hg: parse error: word expects two or three arguments, got 7
3389 hg: parse error: word expects two or three arguments, got 7
3390 [255]
3390 [255]
3391
3391
3392 Test word for integer literal
3392 Test word for integer literal
3393
3393
3394 $ hg log -R a --template "{word(2, desc)}\n" -r0
3394 $ hg log -R a --template "{word(2, desc)}\n" -r0
3395 line
3395 line
3396
3396
3397 Test word for invalid numbers
3397 Test word for invalid numbers
3398
3398
3399 $ hg log -Gv -R a --template "{word('a', desc)}"
3399 $ hg log -Gv -R a --template "{word('a', desc)}"
3400 hg: parse error: word expects an integer index
3400 hg: parse error: word expects an integer index
3401 [255]
3401 [255]
3402
3402
3403 Test indent and not adding to empty lines
3403 Test indent and not adding to empty lines
3404
3404
3405 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
3405 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
3406 -----
3406 -----
3407 > line 1
3407 > line 1
3408 >> line 2
3408 >> line 2
3409 -----
3409 -----
3410 > other 1
3410 > other 1
3411 >> other 2
3411 >> other 2
3412
3412
3413 >> other 3
3413 >> other 3
3414
3414
3415 Test with non-strings like dates
3415 Test with non-strings like dates
3416
3416
3417 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3417 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3418 1200000.00
3418 1200000.00
3419 1300000.00
3419 1300000.00
3420
3421 Test broken string escapes:
3422
3423 $ hg log -T "bogus\\" -R a
3424 hg: parse error: trailing \ in string
3425 [255]
3426 $ hg log -T "\\xy" -R a
3427 hg: parse error: invalid \x escape
3428 [255]
General Comments 0
You need to be logged in to leave comments. Login now