##// END OF EJS Templates
templater: protect word() from crashing on out of range negative value...
Matt Harbison -
r26502:4ca98a38 stable
parent child Browse files
Show More
@@ -1,903 +1,903 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 i18n import _
8 from i18n import _
9 import os, re
9 import os, re
10 import util, config, templatefilters, templatekw, parser, error
10 import util, config, templatefilters, templatekw, parser, error
11 import revset as revsetmod
11 import revset as revsetmod
12 import types
12 import types
13 import minirst
13 import minirst
14
14
15 # template parsing
15 # template parsing
16
16
17 elements = {
17 elements = {
18 # token-type: binding-strength, primary, prefix, infix, suffix
18 # token-type: binding-strength, primary, prefix, infix, suffix
19 "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None),
19 "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None),
20 ",": (2, None, None, ("list", 2), None),
20 ",": (2, None, None, ("list", 2), None),
21 "|": (5, None, None, ("|", 5), None),
21 "|": (5, None, None, ("|", 5), None),
22 "%": (6, None, None, ("%", 6), None),
22 "%": (6, None, None, ("%", 6), None),
23 ")": (0, None, None, None, None),
23 ")": (0, None, None, None, None),
24 "integer": (0, "integer", None, None, None),
24 "integer": (0, "integer", None, None, None),
25 "symbol": (0, "symbol", None, None, None),
25 "symbol": (0, "symbol", None, None, None),
26 "string": (0, "string", None, None, None),
26 "string": (0, "string", None, None, None),
27 "template": (0, "template", None, None, None),
27 "template": (0, "template", None, None, None),
28 "end": (0, None, None, None, None),
28 "end": (0, None, None, None, None),
29 }
29 }
30
30
31 def tokenize(program, start, end):
31 def tokenize(program, start, end):
32 pos = start
32 pos = start
33 while pos < end:
33 while pos < end:
34 c = program[pos]
34 c = program[pos]
35 if c.isspace(): # skip inter-token whitespace
35 if c.isspace(): # skip inter-token whitespace
36 pass
36 pass
37 elif c in "(,)%|": # handle simple operators
37 elif c in "(,)%|": # handle simple operators
38 yield (c, None, pos)
38 yield (c, None, pos)
39 elif c in '"\'': # handle quoted templates
39 elif c in '"\'': # handle quoted templates
40 s = pos + 1
40 s = pos + 1
41 data, pos = _parsetemplate(program, s, end, c)
41 data, pos = _parsetemplate(program, s, end, c)
42 yield ('template', data, s)
42 yield ('template', data, s)
43 pos -= 1
43 pos -= 1
44 elif c == 'r' and program[pos:pos + 2] in ("r'", 'r"'):
44 elif c == 'r' and program[pos:pos + 2] in ("r'", 'r"'):
45 # handle quoted strings
45 # handle quoted strings
46 c = program[pos + 1]
46 c = program[pos + 1]
47 s = pos = pos + 2
47 s = pos = pos + 2
48 while pos < end: # find closing quote
48 while pos < end: # find closing quote
49 d = program[pos]
49 d = program[pos]
50 if d == '\\': # skip over escaped characters
50 if d == '\\': # skip over escaped characters
51 pos += 2
51 pos += 2
52 continue
52 continue
53 if d == c:
53 if d == c:
54 yield ('string', program[s:pos], s)
54 yield ('string', program[s:pos], s)
55 break
55 break
56 pos += 1
56 pos += 1
57 else:
57 else:
58 raise error.ParseError(_("unterminated string"), s)
58 raise error.ParseError(_("unterminated string"), s)
59 elif c.isdigit() or c == '-':
59 elif c.isdigit() or c == '-':
60 s = pos
60 s = pos
61 if c == '-': # simply take negate operator as part of integer
61 if c == '-': # simply take negate operator as part of integer
62 pos += 1
62 pos += 1
63 if pos >= end or not program[pos].isdigit():
63 if pos >= end or not program[pos].isdigit():
64 raise error.ParseError(_("integer literal without digits"), s)
64 raise error.ParseError(_("integer literal without digits"), s)
65 pos += 1
65 pos += 1
66 while pos < end:
66 while pos < end:
67 d = program[pos]
67 d = program[pos]
68 if not d.isdigit():
68 if not d.isdigit():
69 break
69 break
70 pos += 1
70 pos += 1
71 yield ('integer', program[s:pos], s)
71 yield ('integer', program[s:pos], s)
72 pos -= 1
72 pos -= 1
73 elif (c == '\\' and program[pos:pos + 2] in (r"\'", r'\"')
73 elif (c == '\\' and program[pos:pos + 2] in (r"\'", r'\"')
74 or c == 'r' and program[pos:pos + 3] in (r"r\'", r'r\"')):
74 or c == 'r' and program[pos:pos + 3] in (r"r\'", r'r\"')):
75 # handle escaped quoted strings for compatibility with 2.9.2-3.4,
75 # handle escaped quoted strings for compatibility with 2.9.2-3.4,
76 # where some of nested templates were preprocessed as strings and
76 # where some of nested templates were preprocessed as strings and
77 # then compiled. therefore, \"...\" was allowed. (issue4733)
77 # then compiled. therefore, \"...\" was allowed. (issue4733)
78 #
78 #
79 # processing flow of _evalifliteral() at 5ab28a2e9962:
79 # processing flow of _evalifliteral() at 5ab28a2e9962:
80 # outer template string -> stringify() -> compiletemplate()
80 # outer template string -> stringify() -> compiletemplate()
81 # ------------------------ ------------ ------------------
81 # ------------------------ ------------ ------------------
82 # {f("\\\\ {g(\"\\\"\")}"} \\ {g("\"")} [r'\\', {g("\"")}]
82 # {f("\\\\ {g(\"\\\"\")}"} \\ {g("\"")} [r'\\', {g("\"")}]
83 # ~~~~~~~~
83 # ~~~~~~~~
84 # escaped quoted string
84 # escaped quoted string
85 if c == 'r':
85 if c == 'r':
86 pos += 1
86 pos += 1
87 token = 'string'
87 token = 'string'
88 else:
88 else:
89 token = 'template'
89 token = 'template'
90 quote = program[pos:pos + 2]
90 quote = program[pos:pos + 2]
91 s = pos = pos + 2
91 s = pos = pos + 2
92 while pos < end: # find closing escaped quote
92 while pos < end: # find closing escaped quote
93 if program.startswith('\\\\\\', pos, end):
93 if program.startswith('\\\\\\', pos, end):
94 pos += 4 # skip over double escaped characters
94 pos += 4 # skip over double escaped characters
95 continue
95 continue
96 if program.startswith(quote, pos, end):
96 if program.startswith(quote, pos, end):
97 try:
97 try:
98 # interpret as if it were a part of an outer string
98 # interpret as if it were a part of an outer string
99 data = program[s:pos].decode('string-escape')
99 data = program[s:pos].decode('string-escape')
100 except ValueError: # unbalanced escapes
100 except ValueError: # unbalanced escapes
101 raise error.ParseError(_("syntax error"), s)
101 raise error.ParseError(_("syntax error"), s)
102 if token == 'template':
102 if token == 'template':
103 data = _parsetemplate(data, 0, len(data))[0]
103 data = _parsetemplate(data, 0, len(data))[0]
104 yield (token, data, s)
104 yield (token, data, s)
105 pos += 1
105 pos += 1
106 break
106 break
107 pos += 1
107 pos += 1
108 else:
108 else:
109 raise error.ParseError(_("unterminated string"), s)
109 raise error.ParseError(_("unterminated string"), s)
110 elif c.isalnum() or c in '_':
110 elif c.isalnum() or c in '_':
111 s = pos
111 s = pos
112 pos += 1
112 pos += 1
113 while pos < end: # find end of symbol
113 while pos < end: # find end of symbol
114 d = program[pos]
114 d = program[pos]
115 if not (d.isalnum() or d == "_"):
115 if not (d.isalnum() or d == "_"):
116 break
116 break
117 pos += 1
117 pos += 1
118 sym = program[s:pos]
118 sym = program[s:pos]
119 yield ('symbol', sym, s)
119 yield ('symbol', sym, s)
120 pos -= 1
120 pos -= 1
121 elif c == '}':
121 elif c == '}':
122 yield ('end', None, pos + 1)
122 yield ('end', None, pos + 1)
123 return
123 return
124 else:
124 else:
125 raise error.ParseError(_("syntax error"), pos)
125 raise error.ParseError(_("syntax error"), pos)
126 pos += 1
126 pos += 1
127 raise error.ParseError(_("unterminated template expansion"), start)
127 raise error.ParseError(_("unterminated template expansion"), start)
128
128
129 def _parsetemplate(tmpl, start, stop, quote=''):
129 def _parsetemplate(tmpl, start, stop, quote=''):
130 r"""
130 r"""
131 >>> _parsetemplate('foo{bar}"baz', 0, 12)
131 >>> _parsetemplate('foo{bar}"baz', 0, 12)
132 ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12)
132 ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12)
133 >>> _parsetemplate('foo{bar}"baz', 0, 12, quote='"')
133 >>> _parsetemplate('foo{bar}"baz', 0, 12, quote='"')
134 ([('string', 'foo'), ('symbol', 'bar')], 9)
134 ([('string', 'foo'), ('symbol', 'bar')], 9)
135 >>> _parsetemplate('foo"{bar}', 0, 9, quote='"')
135 >>> _parsetemplate('foo"{bar}', 0, 9, quote='"')
136 ([('string', 'foo')], 4)
136 ([('string', 'foo')], 4)
137 >>> _parsetemplate(r'foo\"bar"baz', 0, 12, quote='"')
137 >>> _parsetemplate(r'foo\"bar"baz', 0, 12, quote='"')
138 ([('string', 'foo"'), ('string', 'bar')], 9)
138 ([('string', 'foo"'), ('string', 'bar')], 9)
139 >>> _parsetemplate(r'foo\\"bar', 0, 10, quote='"')
139 >>> _parsetemplate(r'foo\\"bar', 0, 10, quote='"')
140 ([('string', 'foo\\')], 6)
140 ([('string', 'foo\\')], 6)
141 """
141 """
142 parsed = []
142 parsed = []
143 sepchars = '{' + quote
143 sepchars = '{' + quote
144 pos = start
144 pos = start
145 p = parser.parser(elements)
145 p = parser.parser(elements)
146 while pos < stop:
146 while pos < stop:
147 n = min((tmpl.find(c, pos, stop) for c in sepchars),
147 n = min((tmpl.find(c, pos, stop) for c in sepchars),
148 key=lambda n: (n < 0, n))
148 key=lambda n: (n < 0, n))
149 if n < 0:
149 if n < 0:
150 parsed.append(('string', tmpl[pos:stop].decode('string-escape')))
150 parsed.append(('string', tmpl[pos:stop].decode('string-escape')))
151 pos = stop
151 pos = stop
152 break
152 break
153 c = tmpl[n]
153 c = tmpl[n]
154 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
154 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
155 if bs % 2 == 1:
155 if bs % 2 == 1:
156 # escaped (e.g. '\{', '\\\{', but not '\\{')
156 # escaped (e.g. '\{', '\\\{', but not '\\{')
157 parsed.append(('string',
157 parsed.append(('string',
158 tmpl[pos:n - 1].decode('string-escape') + c))
158 tmpl[pos:n - 1].decode('string-escape') + c))
159 pos = n + 1
159 pos = n + 1
160 continue
160 continue
161 if n > pos:
161 if n > pos:
162 parsed.append(('string', tmpl[pos:n].decode('string-escape')))
162 parsed.append(('string', tmpl[pos:n].decode('string-escape')))
163 if c == quote:
163 if c == quote:
164 return parsed, n + 1
164 return parsed, n + 1
165
165
166 parseres, pos = p.parse(tokenize(tmpl, n + 1, stop))
166 parseres, pos = p.parse(tokenize(tmpl, n + 1, stop))
167 parsed.append(parseres)
167 parsed.append(parseres)
168
168
169 if quote:
169 if quote:
170 raise error.ParseError(_("unterminated string"), start)
170 raise error.ParseError(_("unterminated string"), start)
171 return parsed, pos
171 return parsed, pos
172
172
173 def compiletemplate(tmpl, context):
173 def compiletemplate(tmpl, context):
174 parsed, pos = _parsetemplate(tmpl, 0, len(tmpl))
174 parsed, pos = _parsetemplate(tmpl, 0, len(tmpl))
175 return [compileexp(e, context, methods) for e in parsed]
175 return [compileexp(e, context, methods) for e in parsed]
176
176
177 def compileexp(exp, context, curmethods):
177 def compileexp(exp, context, curmethods):
178 t = exp[0]
178 t = exp[0]
179 if t in curmethods:
179 if t in curmethods:
180 return curmethods[t](exp, context)
180 return curmethods[t](exp, context)
181 raise error.ParseError(_("unknown method '%s'") % t)
181 raise error.ParseError(_("unknown method '%s'") % t)
182
182
183 # template evaluation
183 # template evaluation
184
184
185 def getsymbol(exp):
185 def getsymbol(exp):
186 if exp[0] == 'symbol':
186 if exp[0] == 'symbol':
187 return exp[1]
187 return exp[1]
188 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
188 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
189
189
190 def getlist(x):
190 def getlist(x):
191 if not x:
191 if not x:
192 return []
192 return []
193 if x[0] == 'list':
193 if x[0] == 'list':
194 return getlist(x[1]) + [x[2]]
194 return getlist(x[1]) + [x[2]]
195 return [x]
195 return [x]
196
196
197 def getfilter(exp, context):
197 def getfilter(exp, context):
198 f = getsymbol(exp)
198 f = getsymbol(exp)
199 if f not in context._filters:
199 if f not in context._filters:
200 raise error.ParseError(_("unknown function '%s'") % f)
200 raise error.ParseError(_("unknown function '%s'") % f)
201 return context._filters[f]
201 return context._filters[f]
202
202
203 def gettemplate(exp, context):
203 def gettemplate(exp, context):
204 if exp[0] == 'template':
204 if exp[0] == 'template':
205 return [compileexp(e, context, methods) for e in exp[1]]
205 return [compileexp(e, context, methods) for e in exp[1]]
206 if exp[0] == 'symbol':
206 if exp[0] == 'symbol':
207 # unlike runsymbol(), here 'symbol' is always taken as template name
207 # unlike runsymbol(), here 'symbol' is always taken as template name
208 # even if it exists in mapping. this allows us to override mapping
208 # even if it exists in mapping. this allows us to override mapping
209 # by web templates, e.g. 'changelogtag' is redefined in map file.
209 # by web templates, e.g. 'changelogtag' is redefined in map file.
210 return context._load(exp[1])
210 return context._load(exp[1])
211 raise error.ParseError(_("expected template specifier"))
211 raise error.ParseError(_("expected template specifier"))
212
212
213 def runinteger(context, mapping, data):
213 def runinteger(context, mapping, data):
214 return int(data)
214 return int(data)
215
215
216 def runstring(context, mapping, data):
216 def runstring(context, mapping, data):
217 return data
217 return data
218
218
219 def runsymbol(context, mapping, key):
219 def runsymbol(context, mapping, key):
220 v = mapping.get(key)
220 v = mapping.get(key)
221 if v is None:
221 if v is None:
222 v = context._defaults.get(key)
222 v = context._defaults.get(key)
223 if v is None:
223 if v is None:
224 try:
224 try:
225 v = context.process(key, mapping)
225 v = context.process(key, mapping)
226 except TemplateNotFound:
226 except TemplateNotFound:
227 v = ''
227 v = ''
228 if callable(v):
228 if callable(v):
229 return v(**mapping)
229 return v(**mapping)
230 if isinstance(v, types.GeneratorType):
230 if isinstance(v, types.GeneratorType):
231 v = list(v)
231 v = list(v)
232 return v
232 return v
233
233
234 def buildtemplate(exp, context):
234 def buildtemplate(exp, context):
235 ctmpl = [compileexp(e, context, methods) for e in exp[1]]
235 ctmpl = [compileexp(e, context, methods) for e in exp[1]]
236 if len(ctmpl) == 1:
236 if len(ctmpl) == 1:
237 return ctmpl[0] # fast path for string with no template fragment
237 return ctmpl[0] # fast path for string with no template fragment
238 return (runtemplate, ctmpl)
238 return (runtemplate, ctmpl)
239
239
240 def runtemplate(context, mapping, template):
240 def runtemplate(context, mapping, template):
241 for func, data in template:
241 for func, data in template:
242 yield func(context, mapping, data)
242 yield func(context, mapping, data)
243
243
244 def buildfilter(exp, context):
244 def buildfilter(exp, context):
245 func, data = compileexp(exp[1], context, methods)
245 func, data = compileexp(exp[1], context, methods)
246 filt = getfilter(exp[2], context)
246 filt = getfilter(exp[2], context)
247 return (runfilter, (func, data, filt))
247 return (runfilter, (func, data, filt))
248
248
249 def runfilter(context, mapping, data):
249 def runfilter(context, mapping, data):
250 func, data, filt = data
250 func, data, filt = data
251 # func() may return string, generator of strings or arbitrary object such
251 # func() may return string, generator of strings or arbitrary object such
252 # as date tuple, but filter does not want generator.
252 # as date tuple, but filter does not want generator.
253 thing = func(context, mapping, data)
253 thing = func(context, mapping, data)
254 if isinstance(thing, types.GeneratorType):
254 if isinstance(thing, types.GeneratorType):
255 thing = stringify(thing)
255 thing = stringify(thing)
256 try:
256 try:
257 return filt(thing)
257 return filt(thing)
258 except (ValueError, AttributeError, TypeError):
258 except (ValueError, AttributeError, TypeError):
259 if isinstance(data, tuple):
259 if isinstance(data, tuple):
260 dt = data[1]
260 dt = data[1]
261 else:
261 else:
262 dt = data
262 dt = data
263 raise util.Abort(_("template filter '%s' is not compatible with "
263 raise util.Abort(_("template filter '%s' is not compatible with "
264 "keyword '%s'") % (filt.func_name, dt))
264 "keyword '%s'") % (filt.func_name, dt))
265
265
266 def buildmap(exp, context):
266 def buildmap(exp, context):
267 func, data = compileexp(exp[1], context, methods)
267 func, data = compileexp(exp[1], context, methods)
268 ctmpl = gettemplate(exp[2], context)
268 ctmpl = gettemplate(exp[2], context)
269 return (runmap, (func, data, ctmpl))
269 return (runmap, (func, data, ctmpl))
270
270
271 def runmap(context, mapping, data):
271 def runmap(context, mapping, data):
272 func, data, ctmpl = data
272 func, data, ctmpl = data
273 d = func(context, mapping, data)
273 d = func(context, mapping, data)
274 if callable(d):
274 if callable(d):
275 d = d()
275 d = d()
276
276
277 lm = mapping.copy()
277 lm = mapping.copy()
278
278
279 for i in d:
279 for i in d:
280 if isinstance(i, dict):
280 if isinstance(i, dict):
281 lm.update(i)
281 lm.update(i)
282 lm['originalnode'] = mapping.get('node')
282 lm['originalnode'] = mapping.get('node')
283 yield runtemplate(context, lm, ctmpl)
283 yield runtemplate(context, lm, ctmpl)
284 else:
284 else:
285 # v is not an iterable of dicts, this happen when 'key'
285 # v is not an iterable of dicts, this happen when 'key'
286 # has been fully expanded already and format is useless.
286 # has been fully expanded already and format is useless.
287 # If so, return the expanded value.
287 # If so, return the expanded value.
288 yield i
288 yield i
289
289
290 def buildfunc(exp, context):
290 def buildfunc(exp, context):
291 n = getsymbol(exp[1])
291 n = getsymbol(exp[1])
292 args = [compileexp(x, context, exprmethods) for x in getlist(exp[2])]
292 args = [compileexp(x, context, exprmethods) for x in getlist(exp[2])]
293 if n in funcs:
293 if n in funcs:
294 f = funcs[n]
294 f = funcs[n]
295 return (f, args)
295 return (f, args)
296 if n in context._filters:
296 if n in context._filters:
297 if len(args) != 1:
297 if len(args) != 1:
298 raise error.ParseError(_("filter %s expects one argument") % n)
298 raise error.ParseError(_("filter %s expects one argument") % n)
299 f = context._filters[n]
299 f = context._filters[n]
300 return (runfilter, (args[0][0], args[0][1], f))
300 return (runfilter, (args[0][0], args[0][1], f))
301 raise error.ParseError(_("unknown function '%s'") % n)
301 raise error.ParseError(_("unknown function '%s'") % n)
302
302
303 def date(context, mapping, args):
303 def date(context, mapping, args):
304 """:date(date[, fmt]): Format a date. See :hg:`help dates` for formatting
304 """:date(date[, fmt]): Format a date. See :hg:`help dates` for formatting
305 strings."""
305 strings."""
306 if not (1 <= len(args) <= 2):
306 if not (1 <= len(args) <= 2):
307 # i18n: "date" is a keyword
307 # i18n: "date" is a keyword
308 raise error.ParseError(_("date expects one or two arguments"))
308 raise error.ParseError(_("date expects one or two arguments"))
309
309
310 date = args[0][0](context, mapping, args[0][1])
310 date = args[0][0](context, mapping, args[0][1])
311 fmt = None
311 fmt = None
312 if len(args) == 2:
312 if len(args) == 2:
313 fmt = stringify(args[1][0](context, mapping, args[1][1]))
313 fmt = stringify(args[1][0](context, mapping, args[1][1]))
314 try:
314 try:
315 if fmt is None:
315 if fmt is None:
316 return util.datestr(date)
316 return util.datestr(date)
317 else:
317 else:
318 return util.datestr(date, fmt)
318 return util.datestr(date, fmt)
319 except (TypeError, ValueError):
319 except (TypeError, ValueError):
320 # i18n: "date" is a keyword
320 # i18n: "date" is a keyword
321 raise error.ParseError(_("date expects a date information"))
321 raise error.ParseError(_("date expects a date information"))
322
322
323 def diff(context, mapping, args):
323 def diff(context, mapping, args):
324 """:diff([includepattern [, excludepattern]]): Show a diff, optionally
324 """:diff([includepattern [, excludepattern]]): Show a diff, optionally
325 specifying files to include or exclude."""
325 specifying files to include or exclude."""
326 if len(args) > 2:
326 if len(args) > 2:
327 # i18n: "diff" is a keyword
327 # i18n: "diff" is a keyword
328 raise error.ParseError(_("diff expects one, two or no arguments"))
328 raise error.ParseError(_("diff expects one, two or no arguments"))
329
329
330 def getpatterns(i):
330 def getpatterns(i):
331 if i < len(args):
331 if i < len(args):
332 s = stringify(args[i][0](context, mapping, args[i][1])).strip()
332 s = stringify(args[i][0](context, mapping, args[i][1])).strip()
333 if s:
333 if s:
334 return [s]
334 return [s]
335 return []
335 return []
336
336
337 ctx = mapping['ctx']
337 ctx = mapping['ctx']
338 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
338 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
339
339
340 return ''.join(chunks)
340 return ''.join(chunks)
341
341
342 def fill(context, mapping, args):
342 def fill(context, mapping, args):
343 """:fill(text[, width[, initialident[, hangindent]]]): Fill many
343 """:fill(text[, width[, initialident[, hangindent]]]): Fill many
344 paragraphs with optional indentation. See the "fill" filter."""
344 paragraphs with optional indentation. See the "fill" filter."""
345 if not (1 <= len(args) <= 4):
345 if not (1 <= len(args) <= 4):
346 # i18n: "fill" is a keyword
346 # i18n: "fill" is a keyword
347 raise error.ParseError(_("fill expects one to four arguments"))
347 raise error.ParseError(_("fill expects one to four arguments"))
348
348
349 text = stringify(args[0][0](context, mapping, args[0][1]))
349 text = stringify(args[0][0](context, mapping, args[0][1]))
350 width = 76
350 width = 76
351 initindent = ''
351 initindent = ''
352 hangindent = ''
352 hangindent = ''
353 if 2 <= len(args) <= 4:
353 if 2 <= len(args) <= 4:
354 try:
354 try:
355 width = int(stringify(args[1][0](context, mapping, args[1][1])))
355 width = int(stringify(args[1][0](context, mapping, args[1][1])))
356 except ValueError:
356 except ValueError:
357 # i18n: "fill" is a keyword
357 # i18n: "fill" is a keyword
358 raise error.ParseError(_("fill expects an integer width"))
358 raise error.ParseError(_("fill expects an integer width"))
359 try:
359 try:
360 initindent = stringify(args[2][0](context, mapping, args[2][1]))
360 initindent = stringify(args[2][0](context, mapping, args[2][1]))
361 hangindent = stringify(args[3][0](context, mapping, args[3][1]))
361 hangindent = stringify(args[3][0](context, mapping, args[3][1]))
362 except IndexError:
362 except IndexError:
363 pass
363 pass
364
364
365 return templatefilters.fill(text, width, initindent, hangindent)
365 return templatefilters.fill(text, width, initindent, hangindent)
366
366
367 def pad(context, mapping, args):
367 def pad(context, mapping, args):
368 """:pad(text, width[, fillchar=' '[, right=False]]): Pad text with a
368 """:pad(text, width[, fillchar=' '[, right=False]]): Pad text with a
369 fill character."""
369 fill character."""
370 if not (2 <= len(args) <= 4):
370 if not (2 <= len(args) <= 4):
371 # i18n: "pad" is a keyword
371 # i18n: "pad" is a keyword
372 raise error.ParseError(_("pad() expects two to four arguments"))
372 raise error.ParseError(_("pad() expects two to four arguments"))
373
373
374 width = int(args[1][1])
374 width = int(args[1][1])
375
375
376 text = stringify(args[0][0](context, mapping, args[0][1]))
376 text = stringify(args[0][0](context, mapping, args[0][1]))
377
377
378 right = False
378 right = False
379 fillchar = ' '
379 fillchar = ' '
380 if len(args) > 2:
380 if len(args) > 2:
381 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
381 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
382 if len(args) > 3:
382 if len(args) > 3:
383 right = util.parsebool(args[3][1])
383 right = util.parsebool(args[3][1])
384
384
385 if right:
385 if right:
386 return text.rjust(width, fillchar)
386 return text.rjust(width, fillchar)
387 else:
387 else:
388 return text.ljust(width, fillchar)
388 return text.ljust(width, fillchar)
389
389
390 def indent(context, mapping, args):
390 def indent(context, mapping, args):
391 """:indent(text, indentchars[, firstline]): Indents all non-empty lines
391 """:indent(text, indentchars[, firstline]): Indents all non-empty lines
392 with the characters given in the indentchars string. An optional
392 with the characters given in the indentchars string. An optional
393 third parameter will override the indent for the first line only
393 third parameter will override the indent for the first line only
394 if present."""
394 if present."""
395 if not (2 <= len(args) <= 3):
395 if not (2 <= len(args) <= 3):
396 # i18n: "indent" is a keyword
396 # i18n: "indent" is a keyword
397 raise error.ParseError(_("indent() expects two or three arguments"))
397 raise error.ParseError(_("indent() expects two or three arguments"))
398
398
399 text = stringify(args[0][0](context, mapping, args[0][1]))
399 text = stringify(args[0][0](context, mapping, args[0][1]))
400 indent = stringify(args[1][0](context, mapping, args[1][1]))
400 indent = stringify(args[1][0](context, mapping, args[1][1]))
401
401
402 if len(args) == 3:
402 if len(args) == 3:
403 firstline = stringify(args[2][0](context, mapping, args[2][1]))
403 firstline = stringify(args[2][0](context, mapping, args[2][1]))
404 else:
404 else:
405 firstline = indent
405 firstline = indent
406
406
407 # the indent function doesn't indent the first line, so we do it here
407 # the indent function doesn't indent the first line, so we do it here
408 return templatefilters.indent(firstline + text, indent)
408 return templatefilters.indent(firstline + text, indent)
409
409
410 def get(context, mapping, args):
410 def get(context, mapping, args):
411 """:get(dict, key): Get an attribute/key from an object. Some keywords
411 """:get(dict, key): Get an attribute/key from an object. Some keywords
412 are complex types. This function allows you to obtain the value of an
412 are complex types. This function allows you to obtain the value of an
413 attribute on these type."""
413 attribute on these type."""
414 if len(args) != 2:
414 if len(args) != 2:
415 # i18n: "get" is a keyword
415 # i18n: "get" is a keyword
416 raise error.ParseError(_("get() expects two arguments"))
416 raise error.ParseError(_("get() expects two arguments"))
417
417
418 dictarg = args[0][0](context, mapping, args[0][1])
418 dictarg = args[0][0](context, mapping, args[0][1])
419 if not util.safehasattr(dictarg, 'get'):
419 if not util.safehasattr(dictarg, 'get'):
420 # i18n: "get" is a keyword
420 # i18n: "get" is a keyword
421 raise error.ParseError(_("get() expects a dict as first argument"))
421 raise error.ParseError(_("get() expects a dict as first argument"))
422
422
423 key = args[1][0](context, mapping, args[1][1])
423 key = args[1][0](context, mapping, args[1][1])
424 yield dictarg.get(key)
424 yield dictarg.get(key)
425
425
426 def if_(context, mapping, args):
426 def if_(context, mapping, args):
427 """:if(expr, then[, else]): Conditionally execute based on the result of
427 """:if(expr, then[, else]): Conditionally execute based on the result of
428 an expression."""
428 an expression."""
429 if not (2 <= len(args) <= 3):
429 if not (2 <= len(args) <= 3):
430 # i18n: "if" is a keyword
430 # i18n: "if" is a keyword
431 raise error.ParseError(_("if expects two or three arguments"))
431 raise error.ParseError(_("if expects two or three arguments"))
432
432
433 test = stringify(args[0][0](context, mapping, args[0][1]))
433 test = stringify(args[0][0](context, mapping, args[0][1]))
434 if test:
434 if test:
435 yield args[1][0](context, mapping, args[1][1])
435 yield args[1][0](context, mapping, args[1][1])
436 elif len(args) == 3:
436 elif len(args) == 3:
437 yield args[2][0](context, mapping, args[2][1])
437 yield args[2][0](context, mapping, args[2][1])
438
438
439 def ifcontains(context, mapping, args):
439 def ifcontains(context, mapping, args):
440 """:ifcontains(search, thing, then[, else]): Conditionally execute based
440 """:ifcontains(search, thing, then[, else]): Conditionally execute based
441 on whether the item "search" is in "thing"."""
441 on whether the item "search" is in "thing"."""
442 if not (3 <= len(args) <= 4):
442 if not (3 <= len(args) <= 4):
443 # i18n: "ifcontains" is a keyword
443 # i18n: "ifcontains" is a keyword
444 raise error.ParseError(_("ifcontains expects three or four arguments"))
444 raise error.ParseError(_("ifcontains expects three or four arguments"))
445
445
446 item = stringify(args[0][0](context, mapping, args[0][1]))
446 item = stringify(args[0][0](context, mapping, args[0][1]))
447 items = args[1][0](context, mapping, args[1][1])
447 items = args[1][0](context, mapping, args[1][1])
448
448
449 if item in items:
449 if item in items:
450 yield args[2][0](context, mapping, args[2][1])
450 yield args[2][0](context, mapping, args[2][1])
451 elif len(args) == 4:
451 elif len(args) == 4:
452 yield args[3][0](context, mapping, args[3][1])
452 yield args[3][0](context, mapping, args[3][1])
453
453
454 def ifeq(context, mapping, args):
454 def ifeq(context, mapping, args):
455 """:ifeq(expr1, expr2, then[, else]): Conditionally execute based on
455 """:ifeq(expr1, expr2, then[, else]): Conditionally execute based on
456 whether 2 items are equivalent."""
456 whether 2 items are equivalent."""
457 if not (3 <= len(args) <= 4):
457 if not (3 <= len(args) <= 4):
458 # i18n: "ifeq" is a keyword
458 # i18n: "ifeq" is a keyword
459 raise error.ParseError(_("ifeq expects three or four arguments"))
459 raise error.ParseError(_("ifeq expects three or four arguments"))
460
460
461 test = stringify(args[0][0](context, mapping, args[0][1]))
461 test = stringify(args[0][0](context, mapping, args[0][1]))
462 match = stringify(args[1][0](context, mapping, args[1][1]))
462 match = stringify(args[1][0](context, mapping, args[1][1]))
463 if test == match:
463 if test == match:
464 yield args[2][0](context, mapping, args[2][1])
464 yield args[2][0](context, mapping, args[2][1])
465 elif len(args) == 4:
465 elif len(args) == 4:
466 yield args[3][0](context, mapping, args[3][1])
466 yield args[3][0](context, mapping, args[3][1])
467
467
468 def join(context, mapping, args):
468 def join(context, mapping, args):
469 """:join(list, sep): Join items in a list with a delimiter."""
469 """:join(list, sep): Join items in a list with a delimiter."""
470 if not (1 <= len(args) <= 2):
470 if not (1 <= len(args) <= 2):
471 # i18n: "join" is a keyword
471 # i18n: "join" is a keyword
472 raise error.ParseError(_("join expects one or two arguments"))
472 raise error.ParseError(_("join expects one or two arguments"))
473
473
474 joinset = args[0][0](context, mapping, args[0][1])
474 joinset = args[0][0](context, mapping, args[0][1])
475 if callable(joinset):
475 if callable(joinset):
476 jf = joinset.joinfmt
476 jf = joinset.joinfmt
477 joinset = [jf(x) for x in joinset()]
477 joinset = [jf(x) for x in joinset()]
478
478
479 joiner = " "
479 joiner = " "
480 if len(args) > 1:
480 if len(args) > 1:
481 joiner = stringify(args[1][0](context, mapping, args[1][1]))
481 joiner = stringify(args[1][0](context, mapping, args[1][1]))
482
482
483 first = True
483 first = True
484 for x in joinset:
484 for x in joinset:
485 if first:
485 if first:
486 first = False
486 first = False
487 else:
487 else:
488 yield joiner
488 yield joiner
489 yield x
489 yield x
490
490
491 def label(context, mapping, args):
491 def label(context, mapping, args):
492 """:label(label, expr): Apply a label to generated content. Content with
492 """:label(label, expr): Apply a label to generated content. Content with
493 a label applied can result in additional post-processing, such as
493 a label applied can result in additional post-processing, such as
494 automatic colorization."""
494 automatic colorization."""
495 if len(args) != 2:
495 if len(args) != 2:
496 # i18n: "label" is a keyword
496 # i18n: "label" is a keyword
497 raise error.ParseError(_("label expects two arguments"))
497 raise error.ParseError(_("label expects two arguments"))
498
498
499 # ignore args[0] (the label string) since this is supposed to be a a no-op
499 # ignore args[0] (the label string) since this is supposed to be a a no-op
500 yield args[1][0](context, mapping, args[1][1])
500 yield args[1][0](context, mapping, args[1][1])
501
501
502 def revset(context, mapping, args):
502 def revset(context, mapping, args):
503 """:revset(query[, formatargs...]): Execute a revision set query. See
503 """:revset(query[, formatargs...]): Execute a revision set query. See
504 :hg:`help revset`."""
504 :hg:`help revset`."""
505 if not len(args) > 0:
505 if not len(args) > 0:
506 # i18n: "revset" is a keyword
506 # i18n: "revset" is a keyword
507 raise error.ParseError(_("revset expects one or more arguments"))
507 raise error.ParseError(_("revset expects one or more arguments"))
508
508
509 raw = stringify(args[0][0](context, mapping, args[0][1]))
509 raw = stringify(args[0][0](context, mapping, args[0][1]))
510 ctx = mapping['ctx']
510 ctx = mapping['ctx']
511 repo = ctx.repo()
511 repo = ctx.repo()
512
512
513 def query(expr):
513 def query(expr):
514 m = revsetmod.match(repo.ui, expr)
514 m = revsetmod.match(repo.ui, expr)
515 return m(repo)
515 return m(repo)
516
516
517 if len(args) > 1:
517 if len(args) > 1:
518 formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
518 formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
519 revs = query(revsetmod.formatspec(raw, *formatargs))
519 revs = query(revsetmod.formatspec(raw, *formatargs))
520 revs = list([str(r) for r in revs])
520 revs = list([str(r) for r in revs])
521 else:
521 else:
522 revsetcache = mapping['cache'].setdefault("revsetcache", {})
522 revsetcache = mapping['cache'].setdefault("revsetcache", {})
523 if raw in revsetcache:
523 if raw in revsetcache:
524 revs = revsetcache[raw]
524 revs = revsetcache[raw]
525 else:
525 else:
526 revs = query(raw)
526 revs = query(raw)
527 revs = list([str(r) for r in revs])
527 revs = list([str(r) for r in revs])
528 revsetcache[raw] = revs
528 revsetcache[raw] = revs
529
529
530 return templatekw.showlist("revision", revs, **mapping)
530 return templatekw.showlist("revision", revs, **mapping)
531
531
532 def rstdoc(context, mapping, args):
532 def rstdoc(context, mapping, args):
533 """:rstdoc(text, style): Format ReStructuredText."""
533 """:rstdoc(text, style): Format ReStructuredText."""
534 if len(args) != 2:
534 if len(args) != 2:
535 # i18n: "rstdoc" is a keyword
535 # i18n: "rstdoc" is a keyword
536 raise error.ParseError(_("rstdoc expects two arguments"))
536 raise error.ParseError(_("rstdoc expects two arguments"))
537
537
538 text = stringify(args[0][0](context, mapping, args[0][1]))
538 text = stringify(args[0][0](context, mapping, args[0][1]))
539 style = stringify(args[1][0](context, mapping, args[1][1]))
539 style = stringify(args[1][0](context, mapping, args[1][1]))
540
540
541 return minirst.format(text, style=style, keep=['verbose'])
541 return minirst.format(text, style=style, keep=['verbose'])
542
542
543 def shortest(context, mapping, args):
543 def shortest(context, mapping, args):
544 """:shortest(node, minlength=4): Obtain the shortest representation of
544 """:shortest(node, minlength=4): Obtain the shortest representation of
545 a node."""
545 a node."""
546 if not (1 <= len(args) <= 2):
546 if not (1 <= len(args) <= 2):
547 # i18n: "shortest" is a keyword
547 # i18n: "shortest" is a keyword
548 raise error.ParseError(_("shortest() expects one or two arguments"))
548 raise error.ParseError(_("shortest() expects one or two arguments"))
549
549
550 node = stringify(args[0][0](context, mapping, args[0][1]))
550 node = stringify(args[0][0](context, mapping, args[0][1]))
551
551
552 minlength = 4
552 minlength = 4
553 if len(args) > 1:
553 if len(args) > 1:
554 minlength = int(args[1][1])
554 minlength = int(args[1][1])
555
555
556 cl = mapping['ctx']._repo.changelog
556 cl = mapping['ctx']._repo.changelog
557 def isvalid(test):
557 def isvalid(test):
558 try:
558 try:
559 try:
559 try:
560 cl.index.partialmatch(test)
560 cl.index.partialmatch(test)
561 except AttributeError:
561 except AttributeError:
562 # Pure mercurial doesn't support partialmatch on the index.
562 # Pure mercurial doesn't support partialmatch on the index.
563 # Fallback to the slow way.
563 # Fallback to the slow way.
564 if cl._partialmatch(test) is None:
564 if cl._partialmatch(test) is None:
565 return False
565 return False
566
566
567 try:
567 try:
568 i = int(test)
568 i = int(test)
569 # if we are a pure int, then starting with zero will not be
569 # if we are a pure int, then starting with zero will not be
570 # confused as a rev; or, obviously, if the int is larger than
570 # confused as a rev; or, obviously, if the int is larger than
571 # the value of the tip rev
571 # the value of the tip rev
572 if test[0] == '0' or i > len(cl):
572 if test[0] == '0' or i > len(cl):
573 return True
573 return True
574 return False
574 return False
575 except ValueError:
575 except ValueError:
576 return True
576 return True
577 except error.RevlogError:
577 except error.RevlogError:
578 return False
578 return False
579
579
580 shortest = node
580 shortest = node
581 startlength = max(6, minlength)
581 startlength = max(6, minlength)
582 length = startlength
582 length = startlength
583 while True:
583 while True:
584 test = node[:length]
584 test = node[:length]
585 if isvalid(test):
585 if isvalid(test):
586 shortest = test
586 shortest = test
587 if length == minlength or length > startlength:
587 if length == minlength or length > startlength:
588 return shortest
588 return shortest
589 length -= 1
589 length -= 1
590 else:
590 else:
591 length += 1
591 length += 1
592 if len(shortest) <= length:
592 if len(shortest) <= length:
593 return shortest
593 return shortest
594
594
595 def strip(context, mapping, args):
595 def strip(context, mapping, args):
596 """:strip(text[, chars]): Strip characters from a string."""
596 """:strip(text[, chars]): Strip characters from a string."""
597 if not (1 <= len(args) <= 2):
597 if not (1 <= len(args) <= 2):
598 # i18n: "strip" is a keyword
598 # i18n: "strip" is a keyword
599 raise error.ParseError(_("strip expects one or two arguments"))
599 raise error.ParseError(_("strip expects one or two arguments"))
600
600
601 text = stringify(args[0][0](context, mapping, args[0][1]))
601 text = stringify(args[0][0](context, mapping, args[0][1]))
602 if len(args) == 2:
602 if len(args) == 2:
603 chars = stringify(args[1][0](context, mapping, args[1][1]))
603 chars = stringify(args[1][0](context, mapping, args[1][1]))
604 return text.strip(chars)
604 return text.strip(chars)
605 return text.strip()
605 return text.strip()
606
606
607 def sub(context, mapping, args):
607 def sub(context, mapping, args):
608 """:sub(pattern, replacement, expression): Perform text substitution
608 """:sub(pattern, replacement, expression): Perform text substitution
609 using regular expressions."""
609 using regular expressions."""
610 if len(args) != 3:
610 if len(args) != 3:
611 # i18n: "sub" is a keyword
611 # i18n: "sub" is a keyword
612 raise error.ParseError(_("sub expects three arguments"))
612 raise error.ParseError(_("sub expects three arguments"))
613
613
614 pat = stringify(args[0][0](context, mapping, args[0][1]))
614 pat = stringify(args[0][0](context, mapping, args[0][1]))
615 rpl = stringify(args[1][0](context, mapping, args[1][1]))
615 rpl = stringify(args[1][0](context, mapping, args[1][1]))
616 src = stringify(args[2][0](context, mapping, args[2][1]))
616 src = stringify(args[2][0](context, mapping, args[2][1]))
617 yield re.sub(pat, rpl, src)
617 yield re.sub(pat, rpl, src)
618
618
619 def startswith(context, mapping, args):
619 def startswith(context, mapping, args):
620 """:startswith(pattern, text): Returns the value from the "text" argument
620 """:startswith(pattern, text): Returns the value from the "text" argument
621 if it begins with the content from the "pattern" argument."""
621 if it begins with the content from the "pattern" argument."""
622 if len(args) != 2:
622 if len(args) != 2:
623 # i18n: "startswith" is a keyword
623 # i18n: "startswith" is a keyword
624 raise error.ParseError(_("startswith expects two arguments"))
624 raise error.ParseError(_("startswith expects two arguments"))
625
625
626 patn = stringify(args[0][0](context, mapping, args[0][1]))
626 patn = stringify(args[0][0](context, mapping, args[0][1]))
627 text = stringify(args[1][0](context, mapping, args[1][1]))
627 text = stringify(args[1][0](context, mapping, args[1][1]))
628 if text.startswith(patn):
628 if text.startswith(patn):
629 return text
629 return text
630 return ''
630 return ''
631
631
632
632
633 def word(context, mapping, args):
633 def word(context, mapping, args):
634 """:word(number, text[, separator]): Return the nth word from a string."""
634 """:word(number, text[, separator]): Return the nth word from a string."""
635 if not (2 <= len(args) <= 3):
635 if not (2 <= len(args) <= 3):
636 # i18n: "word" is a keyword
636 # i18n: "word" is a keyword
637 raise error.ParseError(_("word expects two or three arguments, got %d")
637 raise error.ParseError(_("word expects two or three arguments, got %d")
638 % len(args))
638 % len(args))
639
639
640 try:
640 try:
641 num = int(stringify(args[0][0](context, mapping, args[0][1])))
641 num = int(stringify(args[0][0](context, mapping, args[0][1])))
642 except ValueError:
642 except ValueError:
643 # i18n: "word" is a keyword
643 # i18n: "word" is a keyword
644 raise error.ParseError(_("word expects an integer index"))
644 raise error.ParseError(_("word expects an integer index"))
645 text = stringify(args[1][0](context, mapping, args[1][1]))
645 text = stringify(args[1][0](context, mapping, args[1][1]))
646 if len(args) == 3:
646 if len(args) == 3:
647 splitter = stringify(args[2][0](context, mapping, args[2][1]))
647 splitter = stringify(args[2][0](context, mapping, args[2][1]))
648 else:
648 else:
649 splitter = None
649 splitter = None
650
650
651 tokens = text.split(splitter)
651 tokens = text.split(splitter)
652 if num >= len(tokens):
652 if num >= len(tokens) or num < -len(tokens):
653 return ''
653 return ''
654 else:
654 else:
655 return tokens[num]
655 return tokens[num]
656
656
657 # methods to interpret function arguments or inner expressions (e.g. {_(x)})
657 # methods to interpret function arguments or inner expressions (e.g. {_(x)})
658 exprmethods = {
658 exprmethods = {
659 "integer": lambda e, c: (runinteger, e[1]),
659 "integer": lambda e, c: (runinteger, e[1]),
660 "string": lambda e, c: (runstring, e[1]),
660 "string": lambda e, c: (runstring, e[1]),
661 "symbol": lambda e, c: (runsymbol, e[1]),
661 "symbol": lambda e, c: (runsymbol, e[1]),
662 "template": buildtemplate,
662 "template": buildtemplate,
663 "group": lambda e, c: compileexp(e[1], c, exprmethods),
663 "group": lambda e, c: compileexp(e[1], c, exprmethods),
664 # ".": buildmember,
664 # ".": buildmember,
665 "|": buildfilter,
665 "|": buildfilter,
666 "%": buildmap,
666 "%": buildmap,
667 "func": buildfunc,
667 "func": buildfunc,
668 }
668 }
669
669
670 # methods to interpret top-level template (e.g. {x}, {x|_}, {x % "y"})
670 # methods to interpret top-level template (e.g. {x}, {x|_}, {x % "y"})
671 methods = exprmethods.copy()
671 methods = exprmethods.copy()
672 methods["integer"] = exprmethods["symbol"] # '{1}' as variable
672 methods["integer"] = exprmethods["symbol"] # '{1}' as variable
673
673
674 funcs = {
674 funcs = {
675 "date": date,
675 "date": date,
676 "diff": diff,
676 "diff": diff,
677 "fill": fill,
677 "fill": fill,
678 "get": get,
678 "get": get,
679 "if": if_,
679 "if": if_,
680 "ifcontains": ifcontains,
680 "ifcontains": ifcontains,
681 "ifeq": ifeq,
681 "ifeq": ifeq,
682 "indent": indent,
682 "indent": indent,
683 "join": join,
683 "join": join,
684 "label": label,
684 "label": label,
685 "pad": pad,
685 "pad": pad,
686 "revset": revset,
686 "revset": revset,
687 "rstdoc": rstdoc,
687 "rstdoc": rstdoc,
688 "shortest": shortest,
688 "shortest": shortest,
689 "startswith": startswith,
689 "startswith": startswith,
690 "strip": strip,
690 "strip": strip,
691 "sub": sub,
691 "sub": sub,
692 "word": word,
692 "word": word,
693 }
693 }
694
694
695 # template engine
695 # template engine
696
696
697 stringify = templatefilters.stringify
697 stringify = templatefilters.stringify
698
698
699 def _flatten(thing):
699 def _flatten(thing):
700 '''yield a single stream from a possibly nested set of iterators'''
700 '''yield a single stream from a possibly nested set of iterators'''
701 if isinstance(thing, str):
701 if isinstance(thing, str):
702 yield thing
702 yield thing
703 elif not util.safehasattr(thing, '__iter__'):
703 elif not util.safehasattr(thing, '__iter__'):
704 if thing is not None:
704 if thing is not None:
705 yield str(thing)
705 yield str(thing)
706 else:
706 else:
707 for i in thing:
707 for i in thing:
708 if isinstance(i, str):
708 if isinstance(i, str):
709 yield i
709 yield i
710 elif not util.safehasattr(i, '__iter__'):
710 elif not util.safehasattr(i, '__iter__'):
711 if i is not None:
711 if i is not None:
712 yield str(i)
712 yield str(i)
713 elif i is not None:
713 elif i is not None:
714 for j in _flatten(i):
714 for j in _flatten(i):
715 yield j
715 yield j
716
716
717 def unquotestring(s):
717 def unquotestring(s):
718 '''unwrap quotes'''
718 '''unwrap quotes'''
719 if len(s) < 2 or s[0] != s[-1]:
719 if len(s) < 2 or s[0] != s[-1]:
720 raise SyntaxError(_('unmatched quotes'))
720 raise SyntaxError(_('unmatched quotes'))
721 return s[1:-1]
721 return s[1:-1]
722
722
723 class engine(object):
723 class engine(object):
724 '''template expansion engine.
724 '''template expansion engine.
725
725
726 template expansion works like this. a map file contains key=value
726 template expansion works like this. a map file contains key=value
727 pairs. if value is quoted, it is treated as string. otherwise, it
727 pairs. if value is quoted, it is treated as string. otherwise, it
728 is treated as name of template file.
728 is treated as name of template file.
729
729
730 templater is asked to expand a key in map. it looks up key, and
730 templater is asked to expand a key in map. it looks up key, and
731 looks for strings like this: {foo}. it expands {foo} by looking up
731 looks for strings like this: {foo}. it expands {foo} by looking up
732 foo in map, and substituting it. expansion is recursive: it stops
732 foo in map, and substituting it. expansion is recursive: it stops
733 when there is no more {foo} to replace.
733 when there is no more {foo} to replace.
734
734
735 expansion also allows formatting and filtering.
735 expansion also allows formatting and filtering.
736
736
737 format uses key to expand each item in list. syntax is
737 format uses key to expand each item in list. syntax is
738 {key%format}.
738 {key%format}.
739
739
740 filter uses function to transform value. syntax is
740 filter uses function to transform value. syntax is
741 {key|filter1|filter2|...}.'''
741 {key|filter1|filter2|...}.'''
742
742
743 def __init__(self, loader, filters={}, defaults={}):
743 def __init__(self, loader, filters={}, defaults={}):
744 self._loader = loader
744 self._loader = loader
745 self._filters = filters
745 self._filters = filters
746 self._defaults = defaults
746 self._defaults = defaults
747 self._cache = {}
747 self._cache = {}
748
748
749 def _load(self, t):
749 def _load(self, t):
750 '''load, parse, and cache a template'''
750 '''load, parse, and cache a template'''
751 if t not in self._cache:
751 if t not in self._cache:
752 self._cache[t] = compiletemplate(self._loader(t), self)
752 self._cache[t] = compiletemplate(self._loader(t), self)
753 return self._cache[t]
753 return self._cache[t]
754
754
755 def process(self, t, mapping):
755 def process(self, t, mapping):
756 '''Perform expansion. t is name of map element to expand.
756 '''Perform expansion. t is name of map element to expand.
757 mapping contains added elements for use during expansion. Is a
757 mapping contains added elements for use during expansion. Is a
758 generator.'''
758 generator.'''
759 return _flatten(runtemplate(self, mapping, self._load(t)))
759 return _flatten(runtemplate(self, mapping, self._load(t)))
760
760
761 engines = {'default': engine}
761 engines = {'default': engine}
762
762
763 def stylelist():
763 def stylelist():
764 paths = templatepaths()
764 paths = templatepaths()
765 if not paths:
765 if not paths:
766 return _('no templates found, try `hg debuginstall` for more info')
766 return _('no templates found, try `hg debuginstall` for more info')
767 dirlist = os.listdir(paths[0])
767 dirlist = os.listdir(paths[0])
768 stylelist = []
768 stylelist = []
769 for file in dirlist:
769 for file in dirlist:
770 split = file.split(".")
770 split = file.split(".")
771 if split[0] == "map-cmdline":
771 if split[0] == "map-cmdline":
772 stylelist.append(split[1])
772 stylelist.append(split[1])
773 return ", ".join(sorted(stylelist))
773 return ", ".join(sorted(stylelist))
774
774
775 class TemplateNotFound(util.Abort):
775 class TemplateNotFound(util.Abort):
776 pass
776 pass
777
777
778 class templater(object):
778 class templater(object):
779
779
780 def __init__(self, mapfile, filters={}, defaults={}, cache={},
780 def __init__(self, mapfile, filters={}, defaults={}, cache={},
781 minchunk=1024, maxchunk=65536):
781 minchunk=1024, maxchunk=65536):
782 '''set up template engine.
782 '''set up template engine.
783 mapfile is name of file to read map definitions from.
783 mapfile is name of file to read map definitions from.
784 filters is dict of functions. each transforms a value into another.
784 filters is dict of functions. each transforms a value into another.
785 defaults is dict of default map definitions.'''
785 defaults is dict of default map definitions.'''
786 self.mapfile = mapfile or 'template'
786 self.mapfile = mapfile or 'template'
787 self.cache = cache.copy()
787 self.cache = cache.copy()
788 self.map = {}
788 self.map = {}
789 if mapfile:
789 if mapfile:
790 self.base = os.path.dirname(mapfile)
790 self.base = os.path.dirname(mapfile)
791 else:
791 else:
792 self.base = ''
792 self.base = ''
793 self.filters = templatefilters.filters.copy()
793 self.filters = templatefilters.filters.copy()
794 self.filters.update(filters)
794 self.filters.update(filters)
795 self.defaults = defaults
795 self.defaults = defaults
796 self.minchunk, self.maxchunk = minchunk, maxchunk
796 self.minchunk, self.maxchunk = minchunk, maxchunk
797 self.ecache = {}
797 self.ecache = {}
798
798
799 if not mapfile:
799 if not mapfile:
800 return
800 return
801 if not os.path.exists(mapfile):
801 if not os.path.exists(mapfile):
802 raise util.Abort(_("style '%s' not found") % mapfile,
802 raise util.Abort(_("style '%s' not found") % mapfile,
803 hint=_("available styles: %s") % stylelist())
803 hint=_("available styles: %s") % stylelist())
804
804
805 conf = config.config(includepaths=templatepaths())
805 conf = config.config(includepaths=templatepaths())
806 conf.read(mapfile)
806 conf.read(mapfile)
807
807
808 for key, val in conf[''].items():
808 for key, val in conf[''].items():
809 if not val:
809 if not val:
810 raise SyntaxError(_('%s: missing value') % conf.source('', key))
810 raise SyntaxError(_('%s: missing value') % conf.source('', key))
811 if val[0] in "'\"":
811 if val[0] in "'\"":
812 try:
812 try:
813 self.cache[key] = unquotestring(val)
813 self.cache[key] = unquotestring(val)
814 except SyntaxError as inst:
814 except SyntaxError as inst:
815 raise SyntaxError('%s: %s' %
815 raise SyntaxError('%s: %s' %
816 (conf.source('', key), inst.args[0]))
816 (conf.source('', key), inst.args[0]))
817 else:
817 else:
818 val = 'default', val
818 val = 'default', val
819 if ':' in val[1]:
819 if ':' in val[1]:
820 val = val[1].split(':', 1)
820 val = val[1].split(':', 1)
821 self.map[key] = val[0], os.path.join(self.base, val[1])
821 self.map[key] = val[0], os.path.join(self.base, val[1])
822
822
823 def __contains__(self, key):
823 def __contains__(self, key):
824 return key in self.cache or key in self.map
824 return key in self.cache or key in self.map
825
825
826 def load(self, t):
826 def load(self, t):
827 '''Get the template for the given template name. Use a local cache.'''
827 '''Get the template for the given template name. Use a local cache.'''
828 if t not in self.cache:
828 if t not in self.cache:
829 try:
829 try:
830 self.cache[t] = util.readfile(self.map[t][1])
830 self.cache[t] = util.readfile(self.map[t][1])
831 except KeyError as inst:
831 except KeyError as inst:
832 raise TemplateNotFound(_('"%s" not in template map') %
832 raise TemplateNotFound(_('"%s" not in template map') %
833 inst.args[0])
833 inst.args[0])
834 except IOError as inst:
834 except IOError as inst:
835 raise IOError(inst.args[0], _('template file %s: %s') %
835 raise IOError(inst.args[0], _('template file %s: %s') %
836 (self.map[t][1], inst.args[1]))
836 (self.map[t][1], inst.args[1]))
837 return self.cache[t]
837 return self.cache[t]
838
838
839 def __call__(self, t, **mapping):
839 def __call__(self, t, **mapping):
840 ttype = t in self.map and self.map[t][0] or 'default'
840 ttype = t in self.map and self.map[t][0] or 'default'
841 if ttype not in self.ecache:
841 if ttype not in self.ecache:
842 self.ecache[ttype] = engines[ttype](self.load,
842 self.ecache[ttype] = engines[ttype](self.load,
843 self.filters, self.defaults)
843 self.filters, self.defaults)
844 proc = self.ecache[ttype]
844 proc = self.ecache[ttype]
845
845
846 stream = proc.process(t, mapping)
846 stream = proc.process(t, mapping)
847 if self.minchunk:
847 if self.minchunk:
848 stream = util.increasingchunks(stream, min=self.minchunk,
848 stream = util.increasingchunks(stream, min=self.minchunk,
849 max=self.maxchunk)
849 max=self.maxchunk)
850 return stream
850 return stream
851
851
852 def templatepaths():
852 def templatepaths():
853 '''return locations used for template files.'''
853 '''return locations used for template files.'''
854 pathsrel = ['templates']
854 pathsrel = ['templates']
855 paths = [os.path.normpath(os.path.join(util.datapath, f))
855 paths = [os.path.normpath(os.path.join(util.datapath, f))
856 for f in pathsrel]
856 for f in pathsrel]
857 return [p for p in paths if os.path.isdir(p)]
857 return [p for p in paths if os.path.isdir(p)]
858
858
859 def templatepath(name):
859 def templatepath(name):
860 '''return location of template file. returns None if not found.'''
860 '''return location of template file. returns None if not found.'''
861 for p in templatepaths():
861 for p in templatepaths():
862 f = os.path.join(p, name)
862 f = os.path.join(p, name)
863 if os.path.exists(f):
863 if os.path.exists(f):
864 return f
864 return f
865 return None
865 return None
866
866
867 def stylemap(styles, paths=None):
867 def stylemap(styles, paths=None):
868 """Return path to mapfile for a given style.
868 """Return path to mapfile for a given style.
869
869
870 Searches mapfile in the following locations:
870 Searches mapfile in the following locations:
871 1. templatepath/style/map
871 1. templatepath/style/map
872 2. templatepath/map-style
872 2. templatepath/map-style
873 3. templatepath/map
873 3. templatepath/map
874 """
874 """
875
875
876 if paths is None:
876 if paths is None:
877 paths = templatepaths()
877 paths = templatepaths()
878 elif isinstance(paths, str):
878 elif isinstance(paths, str):
879 paths = [paths]
879 paths = [paths]
880
880
881 if isinstance(styles, str):
881 if isinstance(styles, str):
882 styles = [styles]
882 styles = [styles]
883
883
884 for style in styles:
884 for style in styles:
885 # only plain name is allowed to honor template paths
885 # only plain name is allowed to honor template paths
886 if (not style
886 if (not style
887 or style in (os.curdir, os.pardir)
887 or style in (os.curdir, os.pardir)
888 or os.sep in style
888 or os.sep in style
889 or os.altsep and os.altsep in style):
889 or os.altsep and os.altsep in style):
890 continue
890 continue
891 locations = [os.path.join(style, 'map'), 'map-' + style]
891 locations = [os.path.join(style, 'map'), 'map-' + style]
892 locations.append('map')
892 locations.append('map')
893
893
894 for path in paths:
894 for path in paths:
895 for location in locations:
895 for location in locations:
896 mapfile = os.path.join(path, location)
896 mapfile = os.path.join(path, location)
897 if os.path.isfile(mapfile):
897 if os.path.isfile(mapfile):
898 return style, mapfile
898 return style, mapfile
899
899
900 raise RuntimeError("No hgweb templates found in %r" % paths)
900 raise RuntimeError("No hgweb templates found in %r" % paths)
901
901
902 # tell hggettext to extract docstrings from these functions:
902 # tell hggettext to extract docstrings from these functions:
903 i18nfunctions = funcs.values()
903 i18nfunctions = funcs.values()
@@ -1,3387 +1,3392 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 Behind the scenes, this will throw ValueError
2498 Behind the scenes, this will throw ValueError
2499
2499
2500 $ hg tip --template '{author|email|date}\n'
2500 $ hg tip --template '{author|email|date}\n'
2501 abort: template filter 'datefilter' is not compatible with keyword 'author'
2501 abort: template filter 'datefilter' is not compatible with keyword 'author'
2502 [255]
2502 [255]
2503
2503
2504 Error in nested template:
2504 Error in nested template:
2505
2505
2506 $ hg log -T '{"date'
2506 $ hg log -T '{"date'
2507 hg: parse error at 2: unterminated string
2507 hg: parse error at 2: unterminated string
2508 [255]
2508 [255]
2509
2509
2510 $ hg log -T '{"foo{date|=}"}'
2510 $ hg log -T '{"foo{date|=}"}'
2511 hg: parse error at 11: syntax error
2511 hg: parse error at 11: syntax error
2512 [255]
2512 [255]
2513
2513
2514 Thrown an error if a template function doesn't exist
2514 Thrown an error if a template function doesn't exist
2515
2515
2516 $ hg tip --template '{foo()}\n'
2516 $ hg tip --template '{foo()}\n'
2517 hg: parse error: unknown function 'foo'
2517 hg: parse error: unknown function 'foo'
2518 [255]
2518 [255]
2519
2519
2520 Pass generator object created by template function to filter
2520 Pass generator object created by template function to filter
2521
2521
2522 $ hg log -l 1 --template '{if(author, author)|user}\n'
2522 $ hg log -l 1 --template '{if(author, author)|user}\n'
2523 test
2523 test
2524
2524
2525 Test diff function:
2525 Test diff function:
2526
2526
2527 $ hg diff -c 8
2527 $ hg diff -c 8
2528 diff -r 29114dbae42b -r 95c24699272e fourth
2528 diff -r 29114dbae42b -r 95c24699272e fourth
2529 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2529 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2530 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2530 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2531 @@ -0,0 +1,1 @@
2531 @@ -0,0 +1,1 @@
2532 +second
2532 +second
2533 diff -r 29114dbae42b -r 95c24699272e second
2533 diff -r 29114dbae42b -r 95c24699272e second
2534 --- a/second Mon Jan 12 13:46:40 1970 +0000
2534 --- a/second Mon Jan 12 13:46:40 1970 +0000
2535 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2535 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2536 @@ -1,1 +0,0 @@
2536 @@ -1,1 +0,0 @@
2537 -second
2537 -second
2538 diff -r 29114dbae42b -r 95c24699272e third
2538 diff -r 29114dbae42b -r 95c24699272e third
2539 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2539 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2540 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2540 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2541 @@ -0,0 +1,1 @@
2541 @@ -0,0 +1,1 @@
2542 +third
2542 +third
2543
2543
2544 $ hg log -r 8 -T "{diff()}"
2544 $ hg log -r 8 -T "{diff()}"
2545 diff -r 29114dbae42b -r 95c24699272e fourth
2545 diff -r 29114dbae42b -r 95c24699272e fourth
2546 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2546 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2547 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2547 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2548 @@ -0,0 +1,1 @@
2548 @@ -0,0 +1,1 @@
2549 +second
2549 +second
2550 diff -r 29114dbae42b -r 95c24699272e second
2550 diff -r 29114dbae42b -r 95c24699272e second
2551 --- a/second Mon Jan 12 13:46:40 1970 +0000
2551 --- a/second Mon Jan 12 13:46:40 1970 +0000
2552 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2552 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2553 @@ -1,1 +0,0 @@
2553 @@ -1,1 +0,0 @@
2554 -second
2554 -second
2555 diff -r 29114dbae42b -r 95c24699272e third
2555 diff -r 29114dbae42b -r 95c24699272e third
2556 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2556 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2557 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2557 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2558 @@ -0,0 +1,1 @@
2558 @@ -0,0 +1,1 @@
2559 +third
2559 +third
2560
2560
2561 $ hg log -r 8 -T "{diff('glob:f*')}"
2561 $ hg log -r 8 -T "{diff('glob:f*')}"
2562 diff -r 29114dbae42b -r 95c24699272e fourth
2562 diff -r 29114dbae42b -r 95c24699272e fourth
2563 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2563 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2564 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2564 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2565 @@ -0,0 +1,1 @@
2565 @@ -0,0 +1,1 @@
2566 +second
2566 +second
2567
2567
2568 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2568 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2569 diff -r 29114dbae42b -r 95c24699272e second
2569 diff -r 29114dbae42b -r 95c24699272e second
2570 --- a/second Mon Jan 12 13:46:40 1970 +0000
2570 --- a/second Mon Jan 12 13:46:40 1970 +0000
2571 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2571 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2572 @@ -1,1 +0,0 @@
2572 @@ -1,1 +0,0 @@
2573 -second
2573 -second
2574 diff -r 29114dbae42b -r 95c24699272e third
2574 diff -r 29114dbae42b -r 95c24699272e third
2575 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2575 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2576 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2576 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2577 @@ -0,0 +1,1 @@
2577 @@ -0,0 +1,1 @@
2578 +third
2578 +third
2579
2579
2580 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2580 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2581 diff -r 29114dbae42b -r 95c24699272e fourth
2581 diff -r 29114dbae42b -r 95c24699272e fourth
2582 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2582 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2583 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2583 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2584 @@ -0,0 +1,1 @@
2584 @@ -0,0 +1,1 @@
2585 +second
2585 +second
2586
2586
2587 $ cd ..
2587 $ cd ..
2588
2588
2589
2589
2590 latesttag:
2590 latesttag:
2591
2591
2592 $ hg init latesttag
2592 $ hg init latesttag
2593 $ cd latesttag
2593 $ cd latesttag
2594
2594
2595 $ echo a > file
2595 $ echo a > file
2596 $ hg ci -Am a -d '0 0'
2596 $ hg ci -Am a -d '0 0'
2597 adding file
2597 adding file
2598
2598
2599 $ echo b >> file
2599 $ echo b >> file
2600 $ hg ci -m b -d '1 0'
2600 $ hg ci -m b -d '1 0'
2601
2601
2602 $ echo c >> head1
2602 $ echo c >> head1
2603 $ hg ci -Am h1c -d '2 0'
2603 $ hg ci -Am h1c -d '2 0'
2604 adding head1
2604 adding head1
2605
2605
2606 $ hg update -q 1
2606 $ hg update -q 1
2607 $ echo d >> head2
2607 $ echo d >> head2
2608 $ hg ci -Am h2d -d '3 0'
2608 $ hg ci -Am h2d -d '3 0'
2609 adding head2
2609 adding head2
2610 created new head
2610 created new head
2611
2611
2612 $ echo e >> head2
2612 $ echo e >> head2
2613 $ hg ci -m h2e -d '4 0'
2613 $ hg ci -m h2e -d '4 0'
2614
2614
2615 $ hg merge -q
2615 $ hg merge -q
2616 $ hg ci -m merge -d '5 -3600'
2616 $ hg ci -m merge -d '5 -3600'
2617
2617
2618 No tag set:
2618 No tag set:
2619
2619
2620 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2620 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2621 5: null+5
2621 5: null+5
2622 4: null+4
2622 4: null+4
2623 3: null+3
2623 3: null+3
2624 2: null+3
2624 2: null+3
2625 1: null+2
2625 1: null+2
2626 0: null+1
2626 0: null+1
2627
2627
2628 One common tag: longest path wins:
2628 One common tag: longest path wins:
2629
2629
2630 $ hg tag -r 1 -m t1 -d '6 0' t1
2630 $ hg tag -r 1 -m t1 -d '6 0' t1
2631 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2631 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2632 6: t1+4
2632 6: t1+4
2633 5: t1+3
2633 5: t1+3
2634 4: t1+2
2634 4: t1+2
2635 3: t1+1
2635 3: t1+1
2636 2: t1+1
2636 2: t1+1
2637 1: t1+0
2637 1: t1+0
2638 0: null+1
2638 0: null+1
2639
2639
2640 One ancestor tag: more recent wins:
2640 One ancestor tag: more recent wins:
2641
2641
2642 $ hg tag -r 2 -m t2 -d '7 0' t2
2642 $ hg tag -r 2 -m t2 -d '7 0' t2
2643 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2643 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2644 7: t2+3
2644 7: t2+3
2645 6: t2+2
2645 6: t2+2
2646 5: t2+1
2646 5: t2+1
2647 4: t1+2
2647 4: t1+2
2648 3: t1+1
2648 3: t1+1
2649 2: t2+0
2649 2: t2+0
2650 1: t1+0
2650 1: t1+0
2651 0: null+1
2651 0: null+1
2652
2652
2653 Two branch tags: more recent wins:
2653 Two branch tags: more recent wins:
2654
2654
2655 $ hg tag -r 3 -m t3 -d '8 0' t3
2655 $ hg tag -r 3 -m t3 -d '8 0' t3
2656 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2656 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2657 8: t3+5
2657 8: t3+5
2658 7: t3+4
2658 7: t3+4
2659 6: t3+3
2659 6: t3+3
2660 5: t3+2
2660 5: t3+2
2661 4: t3+1
2661 4: t3+1
2662 3: t3+0
2662 3: t3+0
2663 2: t2+0
2663 2: t2+0
2664 1: t1+0
2664 1: t1+0
2665 0: null+1
2665 0: null+1
2666
2666
2667 Merged tag overrides:
2667 Merged tag overrides:
2668
2668
2669 $ hg tag -r 5 -m t5 -d '9 0' t5
2669 $ hg tag -r 5 -m t5 -d '9 0' t5
2670 $ hg tag -r 3 -m at3 -d '10 0' at3
2670 $ hg tag -r 3 -m at3 -d '10 0' at3
2671 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2671 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2672 10: t5+5
2672 10: t5+5
2673 9: t5+4
2673 9: t5+4
2674 8: t5+3
2674 8: t5+3
2675 7: t5+2
2675 7: t5+2
2676 6: t5+1
2676 6: t5+1
2677 5: t5+0
2677 5: t5+0
2678 4: at3:t3+1
2678 4: at3:t3+1
2679 3: at3:t3+0
2679 3: at3:t3+0
2680 2: t2+0
2680 2: t2+0
2681 1: t1+0
2681 1: t1+0
2682 0: null+1
2682 0: null+1
2683
2683
2684 $ cd ..
2684 $ cd ..
2685
2685
2686
2686
2687 Style path expansion: issue1948 - ui.style option doesn't work on OSX
2687 Style path expansion: issue1948 - ui.style option doesn't work on OSX
2688 if it is a relative path
2688 if it is a relative path
2689
2689
2690 $ mkdir -p home/styles
2690 $ mkdir -p home/styles
2691
2691
2692 $ cat > home/styles/teststyle <<EOF
2692 $ cat > home/styles/teststyle <<EOF
2693 > changeset = 'test {rev}:{node|short}\n'
2693 > changeset = 'test {rev}:{node|short}\n'
2694 > EOF
2694 > EOF
2695
2695
2696 $ HOME=`pwd`/home; export HOME
2696 $ HOME=`pwd`/home; export HOME
2697
2697
2698 $ cat > latesttag/.hg/hgrc <<EOF
2698 $ cat > latesttag/.hg/hgrc <<EOF
2699 > [ui]
2699 > [ui]
2700 > style = ~/styles/teststyle
2700 > style = ~/styles/teststyle
2701 > EOF
2701 > EOF
2702
2702
2703 $ hg -R latesttag tip
2703 $ hg -R latesttag tip
2704 test 10:9b4a630e5f5f
2704 test 10:9b4a630e5f5f
2705
2705
2706 Test recursive showlist template (issue1989):
2706 Test recursive showlist template (issue1989):
2707
2707
2708 $ cat > style1989 <<EOF
2708 $ cat > style1989 <<EOF
2709 > changeset = '{file_mods}{manifest}{extras}'
2709 > changeset = '{file_mods}{manifest}{extras}'
2710 > file_mod = 'M|{author|person}\n'
2710 > file_mod = 'M|{author|person}\n'
2711 > manifest = '{rev},{author}\n'
2711 > manifest = '{rev},{author}\n'
2712 > extra = '{key}: {author}\n'
2712 > extra = '{key}: {author}\n'
2713 > EOF
2713 > EOF
2714
2714
2715 $ hg -R latesttag log -r tip --style=style1989
2715 $ hg -R latesttag log -r tip --style=style1989
2716 M|test
2716 M|test
2717 10,test
2717 10,test
2718 branch: test
2718 branch: test
2719
2719
2720 Test new-style inline templating:
2720 Test new-style inline templating:
2721
2721
2722 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
2722 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
2723 modified files: .hgtags
2723 modified files: .hgtags
2724
2724
2725 Test the sub function of templating for expansion:
2725 Test the sub function of templating for expansion:
2726
2726
2727 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
2727 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
2728 xx
2728 xx
2729
2729
2730 Test the strip function with chars specified:
2730 Test the strip function with chars specified:
2731
2731
2732 $ hg log -R latesttag --template '{desc}\n'
2732 $ hg log -R latesttag --template '{desc}\n'
2733 at3
2733 at3
2734 t5
2734 t5
2735 t3
2735 t3
2736 t2
2736 t2
2737 t1
2737 t1
2738 merge
2738 merge
2739 h2e
2739 h2e
2740 h2d
2740 h2d
2741 h1c
2741 h1c
2742 b
2742 b
2743 a
2743 a
2744
2744
2745 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2745 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2746 at3
2746 at3
2747 5
2747 5
2748 3
2748 3
2749 2
2749 2
2750 1
2750 1
2751 merg
2751 merg
2752 h2
2752 h2
2753 h2d
2753 h2d
2754 h1c
2754 h1c
2755 b
2755 b
2756 a
2756 a
2757
2757
2758 Test date format:
2758 Test date format:
2759
2759
2760 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2760 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2761 date: 70 01 01 10 +0000
2761 date: 70 01 01 10 +0000
2762 date: 70 01 01 09 +0000
2762 date: 70 01 01 09 +0000
2763 date: 70 01 01 08 +0000
2763 date: 70 01 01 08 +0000
2764 date: 70 01 01 07 +0000
2764 date: 70 01 01 07 +0000
2765 date: 70 01 01 06 +0000
2765 date: 70 01 01 06 +0000
2766 date: 70 01 01 05 +0100
2766 date: 70 01 01 05 +0100
2767 date: 70 01 01 04 +0000
2767 date: 70 01 01 04 +0000
2768 date: 70 01 01 03 +0000
2768 date: 70 01 01 03 +0000
2769 date: 70 01 01 02 +0000
2769 date: 70 01 01 02 +0000
2770 date: 70 01 01 01 +0000
2770 date: 70 01 01 01 +0000
2771 date: 70 01 01 00 +0000
2771 date: 70 01 01 00 +0000
2772
2772
2773 Test invalid date:
2773 Test invalid date:
2774
2774
2775 $ hg log -R latesttag -T '{date(rev)}\n'
2775 $ hg log -R latesttag -T '{date(rev)}\n'
2776 hg: parse error: date expects a date information
2776 hg: parse error: date expects a date information
2777 [255]
2777 [255]
2778
2778
2779 Test integer literal:
2779 Test integer literal:
2780
2780
2781 $ hg log -Ra -r0 -T '{(0)}\n'
2781 $ hg log -Ra -r0 -T '{(0)}\n'
2782 0
2782 0
2783 $ hg log -Ra -r0 -T '{(123)}\n'
2783 $ hg log -Ra -r0 -T '{(123)}\n'
2784 123
2784 123
2785 $ hg log -Ra -r0 -T '{(-4)}\n'
2785 $ hg log -Ra -r0 -T '{(-4)}\n'
2786 -4
2786 -4
2787 $ hg log -Ra -r0 -T '{(-)}\n'
2787 $ hg log -Ra -r0 -T '{(-)}\n'
2788 hg: parse error at 2: integer literal without digits
2788 hg: parse error at 2: integer literal without digits
2789 [255]
2789 [255]
2790 $ hg log -Ra -r0 -T '{(-a)}\n'
2790 $ hg log -Ra -r0 -T '{(-a)}\n'
2791 hg: parse error at 2: integer literal without digits
2791 hg: parse error at 2: integer literal without digits
2792 [255]
2792 [255]
2793
2793
2794 top-level integer literal is interpreted as symbol (i.e. variable name):
2794 top-level integer literal is interpreted as symbol (i.e. variable name):
2795
2795
2796 $ hg log -Ra -r0 -T '{1}\n'
2796 $ hg log -Ra -r0 -T '{1}\n'
2797
2797
2798 $ hg log -Ra -r0 -T '{if("t", "{1}")}\n'
2798 $ hg log -Ra -r0 -T '{if("t", "{1}")}\n'
2799
2799
2800 $ hg log -Ra -r0 -T '{1|stringify}\n'
2800 $ hg log -Ra -r0 -T '{1|stringify}\n'
2801
2801
2802
2802
2803 unless explicit symbol is expected:
2803 unless explicit symbol is expected:
2804
2804
2805 $ hg log -Ra -r0 -T '{desc|1}\n'
2805 $ hg log -Ra -r0 -T '{desc|1}\n'
2806 hg: parse error: expected a symbol, got 'integer'
2806 hg: parse error: expected a symbol, got 'integer'
2807 [255]
2807 [255]
2808 $ hg log -Ra -r0 -T '{1()}\n'
2808 $ hg log -Ra -r0 -T '{1()}\n'
2809 hg: parse error: expected a symbol, got 'integer'
2809 hg: parse error: expected a symbol, got 'integer'
2810 [255]
2810 [255]
2811
2811
2812 Test string literal:
2812 Test string literal:
2813
2813
2814 $ hg log -Ra -r0 -T '{"string with no template fragment"}\n'
2814 $ hg log -Ra -r0 -T '{"string with no template fragment"}\n'
2815 string with no template fragment
2815 string with no template fragment
2816 $ hg log -Ra -r0 -T '{"template: {rev}"}\n'
2816 $ hg log -Ra -r0 -T '{"template: {rev}"}\n'
2817 template: 0
2817 template: 0
2818 $ hg log -Ra -r0 -T '{r"rawstring: {rev}"}\n'
2818 $ hg log -Ra -r0 -T '{r"rawstring: {rev}"}\n'
2819 rawstring: {rev}
2819 rawstring: {rev}
2820
2820
2821 because map operation requires template, raw string can't be used
2821 because map operation requires template, raw string can't be used
2822
2822
2823 $ hg log -Ra -r0 -T '{files % r"rawstring"}\n'
2823 $ hg log -Ra -r0 -T '{files % r"rawstring"}\n'
2824 hg: parse error: expected template specifier
2824 hg: parse error: expected template specifier
2825 [255]
2825 [255]
2826
2826
2827 Test string escaping:
2827 Test string escaping:
2828
2828
2829 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2829 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2830 >
2830 >
2831 <>\n<[>
2831 <>\n<[>
2832 <>\n<]>
2832 <>\n<]>
2833 <>\n<
2833 <>\n<
2834
2834
2835 $ hg log -R latesttag -r 0 \
2835 $ hg log -R latesttag -r 0 \
2836 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2836 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2837 >
2837 >
2838 <>\n<[>
2838 <>\n<[>
2839 <>\n<]>
2839 <>\n<]>
2840 <>\n<
2840 <>\n<
2841
2841
2842 $ hg log -R latesttag -r 0 -T esc \
2842 $ hg log -R latesttag -r 0 -T esc \
2843 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2843 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2844 >
2844 >
2845 <>\n<[>
2845 <>\n<[>
2846 <>\n<]>
2846 <>\n<]>
2847 <>\n<
2847 <>\n<
2848
2848
2849 $ cat <<'EOF' > esctmpl
2849 $ cat <<'EOF' > esctmpl
2850 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2850 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2851 > EOF
2851 > EOF
2852 $ hg log -R latesttag -r 0 --style ./esctmpl
2852 $ hg log -R latesttag -r 0 --style ./esctmpl
2853 >
2853 >
2854 <>\n<[>
2854 <>\n<[>
2855 <>\n<]>
2855 <>\n<]>
2856 <>\n<
2856 <>\n<
2857
2857
2858 Test string escaping of quotes:
2858 Test string escaping of quotes:
2859
2859
2860 $ hg log -Ra -r0 -T '{"\""}\n'
2860 $ hg log -Ra -r0 -T '{"\""}\n'
2861 "
2861 "
2862 $ hg log -Ra -r0 -T '{"\\\""}\n'
2862 $ hg log -Ra -r0 -T '{"\\\""}\n'
2863 \"
2863 \"
2864 $ hg log -Ra -r0 -T '{r"\""}\n'
2864 $ hg log -Ra -r0 -T '{r"\""}\n'
2865 \"
2865 \"
2866 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2866 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2867 \\\"
2867 \\\"
2868
2868
2869
2869
2870 $ hg log -Ra -r0 -T '{"\""}\n'
2870 $ hg log -Ra -r0 -T '{"\""}\n'
2871 "
2871 "
2872 $ hg log -Ra -r0 -T '{"\\\""}\n'
2872 $ hg log -Ra -r0 -T '{"\\\""}\n'
2873 \"
2873 \"
2874 $ hg log -Ra -r0 -T '{r"\""}\n'
2874 $ hg log -Ra -r0 -T '{r"\""}\n'
2875 \"
2875 \"
2876 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2876 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2877 \\\"
2877 \\\"
2878
2878
2879 Test exception in quoted template. single backslash before quotation mark is
2879 Test exception in quoted template. single backslash before quotation mark is
2880 stripped before parsing:
2880 stripped before parsing:
2881
2881
2882 $ cat <<'EOF' > escquotetmpl
2882 $ cat <<'EOF' > escquotetmpl
2883 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
2883 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
2884 > EOF
2884 > EOF
2885 $ cd latesttag
2885 $ cd latesttag
2886 $ hg log -r 2 --style ../escquotetmpl
2886 $ hg log -r 2 --style ../escquotetmpl
2887 " \" \" \\" head1
2887 " \" \" \\" head1
2888
2888
2889 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
2889 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
2890 valid
2890 valid
2891 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
2891 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
2892 valid
2892 valid
2893
2893
2894 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
2894 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
2895 _evalifliteral() templates (issue4733):
2895 _evalifliteral() templates (issue4733):
2896
2896
2897 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
2897 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
2898 "2
2898 "2
2899 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
2899 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
2900 "2
2900 "2
2901 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
2901 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
2902 "2
2902 "2
2903
2903
2904 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
2904 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
2905 \"
2905 \"
2906 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
2906 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
2907 \"
2907 \"
2908 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2908 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2909 \"
2909 \"
2910
2910
2911 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
2911 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
2912 \\\"
2912 \\\"
2913 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
2913 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
2914 \\\"
2914 \\\"
2915 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2915 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2916 \\\"
2916 \\\"
2917
2917
2918 escaped single quotes and errors:
2918 escaped single quotes and errors:
2919
2919
2920 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
2920 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
2921 foo
2921 foo
2922 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
2922 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
2923 foo
2923 foo
2924 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
2924 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
2925 hg: parse error at 21: unterminated string
2925 hg: parse error at 21: unterminated string
2926 [255]
2926 [255]
2927 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
2927 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
2928 hg: parse error at 11: syntax error
2928 hg: parse error at 11: syntax error
2929 [255]
2929 [255]
2930 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
2930 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
2931 hg: parse error at 12: syntax error
2931 hg: parse error at 12: syntax error
2932 [255]
2932 [255]
2933
2933
2934 $ cd ..
2934 $ cd ..
2935
2935
2936 Test leading backslashes:
2936 Test leading backslashes:
2937
2937
2938 $ cd latesttag
2938 $ cd latesttag
2939 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
2939 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
2940 {rev} {file}
2940 {rev} {file}
2941 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
2941 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
2942 \2 \head1
2942 \2 \head1
2943 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
2943 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
2944 \{rev} \{file}
2944 \{rev} \{file}
2945 $ cd ..
2945 $ cd ..
2946
2946
2947 Test leading backslashes in "if" expression (issue4714):
2947 Test leading backslashes in "if" expression (issue4714):
2948
2948
2949 $ cd latesttag
2949 $ cd latesttag
2950 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
2950 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
2951 {rev} \{rev}
2951 {rev} \{rev}
2952 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
2952 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
2953 \2 \\{rev}
2953 \2 \\{rev}
2954 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
2954 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
2955 \{rev} \\\{rev}
2955 \{rev} \\\{rev}
2956 $ cd ..
2956 $ cd ..
2957
2957
2958 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
2958 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
2959
2959
2960 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
2960 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
2961 \x6e
2961 \x6e
2962 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
2962 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
2963 \x5c\x786e
2963 \x5c\x786e
2964 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
2964 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
2965 \x6e
2965 \x6e
2966 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
2966 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
2967 \x5c\x786e
2967 \x5c\x786e
2968
2968
2969 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
2969 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
2970 \x6e
2970 \x6e
2971 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
2971 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
2972 \x5c\x786e
2972 \x5c\x786e
2973 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
2973 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
2974 \x6e
2974 \x6e
2975 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
2975 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
2976 \x5c\x786e
2976 \x5c\x786e
2977
2977
2978 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
2978 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
2979 fourth
2979 fourth
2980 second
2980 second
2981 third
2981 third
2982 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
2982 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
2983 fourth\nsecond\nthird
2983 fourth\nsecond\nthird
2984
2984
2985 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
2985 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
2986 <p>
2986 <p>
2987 1st
2987 1st
2988 </p>
2988 </p>
2989 <p>
2989 <p>
2990 2nd
2990 2nd
2991 </p>
2991 </p>
2992 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
2992 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
2993 <p>
2993 <p>
2994 1st\n\n2nd
2994 1st\n\n2nd
2995 </p>
2995 </p>
2996 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
2996 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
2997 1st
2997 1st
2998
2998
2999 2nd
2999 2nd
3000
3000
3001 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3001 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3002 o perso
3002 o perso
3003 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3003 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3004 no person
3004 no person
3005 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3005 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3006 o perso
3006 o perso
3007 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3007 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3008 no perso
3008 no perso
3009
3009
3010 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3010 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3011 -o perso-
3011 -o perso-
3012 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3012 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3013 no person
3013 no person
3014 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3014 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3015 \x2do perso\x2d
3015 \x2do perso\x2d
3016 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3016 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3017 -o perso-
3017 -o perso-
3018 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3018 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3019 \x2do perso\x6e
3019 \x2do perso\x6e
3020
3020
3021 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3021 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3022 fourth
3022 fourth
3023 second
3023 second
3024 third
3024 third
3025
3025
3026 Test string escaping in nested expression:
3026 Test string escaping in nested expression:
3027
3027
3028 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3028 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3029 fourth\x6esecond\x6ethird
3029 fourth\x6esecond\x6ethird
3030 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3030 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3031 fourth\x6esecond\x6ethird
3031 fourth\x6esecond\x6ethird
3032
3032
3033 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3033 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3034 fourth\x6esecond\x6ethird
3034 fourth\x6esecond\x6ethird
3035 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3035 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3036 fourth\x5c\x786esecond\x5c\x786ethird
3036 fourth\x5c\x786esecond\x5c\x786ethird
3037
3037
3038 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3038 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3039 3:\x6eo user, \x6eo domai\x6e
3039 3:\x6eo user, \x6eo domai\x6e
3040 4:\x5c\x786eew bra\x5c\x786ech
3040 4:\x5c\x786eew bra\x5c\x786ech
3041
3041
3042 Test quotes in nested expression are evaluated just like a $(command)
3042 Test quotes in nested expression are evaluated just like a $(command)
3043 substitution in POSIX shells:
3043 substitution in POSIX shells:
3044
3044
3045 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3045 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3046 8:95c24699272e
3046 8:95c24699272e
3047 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3047 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3048 {8} "95c24699272e"
3048 {8} "95c24699272e"
3049
3049
3050 Test recursive evaluation:
3050 Test recursive evaluation:
3051
3051
3052 $ hg init r
3052 $ hg init r
3053 $ cd r
3053 $ cd r
3054 $ echo a > a
3054 $ echo a > a
3055 $ hg ci -Am '{rev}'
3055 $ hg ci -Am '{rev}'
3056 adding a
3056 adding a
3057 $ hg log -r 0 --template '{if(rev, desc)}\n'
3057 $ hg log -r 0 --template '{if(rev, desc)}\n'
3058 {rev}
3058 {rev}
3059 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3059 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3060 test 0
3060 test 0
3061
3061
3062 $ hg branch -q 'text.{rev}'
3062 $ hg branch -q 'text.{rev}'
3063 $ echo aa >> aa
3063 $ echo aa >> aa
3064 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3064 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3065
3065
3066 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3066 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3067 {node|short}desc to
3067 {node|short}desc to
3068 text.{rev}be wrapped
3068 text.{rev}be wrapped
3069 text.{rev}desc to be
3069 text.{rev}desc to be
3070 text.{rev}wrapped (no-eol)
3070 text.{rev}wrapped (no-eol)
3071 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3071 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3072 bcc7ff960b8e:desc to
3072 bcc7ff960b8e:desc to
3073 text.1:be wrapped
3073 text.1:be wrapped
3074 text.1:desc to be
3074 text.1:desc to be
3075 text.1:wrapped (no-eol)
3075 text.1:wrapped (no-eol)
3076
3076
3077 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3077 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3078 {node|short} (no-eol)
3078 {node|short} (no-eol)
3079 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3079 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3080 bcc-ff---b-e (no-eol)
3080 bcc-ff---b-e (no-eol)
3081
3081
3082 $ cat >> .hg/hgrc <<EOF
3082 $ cat >> .hg/hgrc <<EOF
3083 > [extensions]
3083 > [extensions]
3084 > color=
3084 > color=
3085 > [color]
3085 > [color]
3086 > mode=ansi
3086 > mode=ansi
3087 > text.{rev} = red
3087 > text.{rev} = red
3088 > text.1 = green
3088 > text.1 = green
3089 > EOF
3089 > EOF
3090 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3090 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3091 \x1b[0;31mtext\x1b[0m (esc)
3091 \x1b[0;31mtext\x1b[0m (esc)
3092 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3092 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3093 \x1b[0;32mtext\x1b[0m (esc)
3093 \x1b[0;32mtext\x1b[0m (esc)
3094
3094
3095 Test branches inside if statement:
3095 Test branches inside if statement:
3096
3096
3097 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3097 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3098 no
3098 no
3099
3099
3100 Test get function:
3100 Test get function:
3101
3101
3102 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3102 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3103 default
3103 default
3104 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3104 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3105 hg: parse error: get() expects a dict as first argument
3105 hg: parse error: get() expects a dict as first argument
3106 [255]
3106 [255]
3107
3107
3108 Test shortest(node) function:
3108 Test shortest(node) function:
3109
3109
3110 $ echo b > b
3110 $ echo b > b
3111 $ hg ci -qAm b
3111 $ hg ci -qAm b
3112 $ hg log --template '{shortest(node)}\n'
3112 $ hg log --template '{shortest(node)}\n'
3113 e777
3113 e777
3114 bcc7
3114 bcc7
3115 f776
3115 f776
3116 $ hg log --template '{shortest(node, 10)}\n'
3116 $ hg log --template '{shortest(node, 10)}\n'
3117 e777603221
3117 e777603221
3118 bcc7ff960b
3118 bcc7ff960b
3119 f7769ec2ab
3119 f7769ec2ab
3120
3120
3121 Test pad function
3121 Test pad function
3122
3122
3123 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3123 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3124 2 test
3124 2 test
3125 1 {node|short}
3125 1 {node|short}
3126 0 test
3126 0 test
3127
3127
3128 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3128 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3129 2 test
3129 2 test
3130 1 {node|short}
3130 1 {node|short}
3131 0 test
3131 0 test
3132
3132
3133 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3133 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3134 2------------------- test
3134 2------------------- test
3135 1------------------- {node|short}
3135 1------------------- {node|short}
3136 0------------------- test
3136 0------------------- test
3137
3137
3138 Test template string in pad function
3138 Test template string in pad function
3139
3139
3140 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3140 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3141 {0} test
3141 {0} test
3142
3142
3143 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3143 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3144 \{rev} test
3144 \{rev} test
3145
3145
3146 Test ifcontains function
3146 Test ifcontains function
3147
3147
3148 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
3148 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
3149 2 is in the string
3149 2 is in the string
3150 1 is not
3150 1 is not
3151 0 is in the string
3151 0 is in the string
3152
3152
3153 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
3153 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
3154 2 did not add a
3154 2 did not add a
3155 1 did not add a
3155 1 did not add a
3156 0 added a
3156 0 added a
3157
3157
3158 Test revset function
3158 Test revset function
3159
3159
3160 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
3160 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
3161 2 current rev
3161 2 current rev
3162 1 not current rev
3162 1 not current rev
3163 0 not current rev
3163 0 not current rev
3164
3164
3165 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
3165 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
3166 2 match rev
3166 2 match rev
3167 1 match rev
3167 1 match rev
3168 0 not match rev
3168 0 not match rev
3169
3169
3170 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
3170 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
3171 2 Parents: 1
3171 2 Parents: 1
3172 1 Parents: 0
3172 1 Parents: 0
3173 0 Parents:
3173 0 Parents:
3174
3174
3175 $ cat >> .hg/hgrc <<EOF
3175 $ cat >> .hg/hgrc <<EOF
3176 > [revsetalias]
3176 > [revsetalias]
3177 > myparents(\$1) = parents(\$1)
3177 > myparents(\$1) = parents(\$1)
3178 > EOF
3178 > EOF
3179 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
3179 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
3180 2 Parents: 1
3180 2 Parents: 1
3181 1 Parents: 0
3181 1 Parents: 0
3182 0 Parents:
3182 0 Parents:
3183
3183
3184 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
3184 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
3185 Rev: 2
3185 Rev: 2
3186 Ancestor: 0
3186 Ancestor: 0
3187 Ancestor: 1
3187 Ancestor: 1
3188 Ancestor: 2
3188 Ancestor: 2
3189
3189
3190 Rev: 1
3190 Rev: 1
3191 Ancestor: 0
3191 Ancestor: 0
3192 Ancestor: 1
3192 Ancestor: 1
3193
3193
3194 Rev: 0
3194 Rev: 0
3195 Ancestor: 0
3195 Ancestor: 0
3196
3196
3197 $ hg log --template '{revset("TIP"|lower)}\n' -l1
3197 $ hg log --template '{revset("TIP"|lower)}\n' -l1
3198 2
3198 2
3199
3199
3200 Test active bookmark templating
3200 Test active bookmark templating
3201
3201
3202 $ hg book foo
3202 $ hg book foo
3203 $ hg book bar
3203 $ hg book bar
3204 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
3204 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
3205 2 bar* foo
3205 2 bar* foo
3206 1
3206 1
3207 0
3207 0
3208 $ hg log --template "{rev} {activebookmark}\n"
3208 $ hg log --template "{rev} {activebookmark}\n"
3209 2 bar
3209 2 bar
3210 1
3210 1
3211 0
3211 0
3212 $ hg bookmarks --inactive bar
3212 $ hg bookmarks --inactive bar
3213 $ hg log --template "{rev} {activebookmark}\n"
3213 $ hg log --template "{rev} {activebookmark}\n"
3214 2
3214 2
3215 1
3215 1
3216 0
3216 0
3217 $ hg book -r1 baz
3217 $ hg book -r1 baz
3218 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
3218 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
3219 2 bar foo
3219 2 bar foo
3220 1 baz
3220 1 baz
3221 0
3221 0
3222 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
3222 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
3223 2 t
3223 2 t
3224 1 f
3224 1 f
3225 0 f
3225 0 f
3226
3226
3227 Test stringify on sub expressions
3227 Test stringify on sub expressions
3228
3228
3229 $ cd ..
3229 $ cd ..
3230 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
3230 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
3231 fourth, second, third
3231 fourth, second, third
3232 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
3232 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
3233 abc
3233 abc
3234
3234
3235 Test splitlines
3235 Test splitlines
3236
3236
3237 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
3237 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
3238 @ foo Modify, add, remove, rename
3238 @ foo Modify, add, remove, rename
3239 |
3239 |
3240 o foo future
3240 o foo future
3241 |
3241 |
3242 o foo third
3242 o foo third
3243 |
3243 |
3244 o foo second
3244 o foo second
3245
3245
3246 o foo merge
3246 o foo merge
3247 |\
3247 |\
3248 | o foo new head
3248 | o foo new head
3249 | |
3249 | |
3250 o | foo new branch
3250 o | foo new branch
3251 |/
3251 |/
3252 o foo no user, no domain
3252 o foo no user, no domain
3253 |
3253 |
3254 o foo no person
3254 o foo no person
3255 |
3255 |
3256 o foo other 1
3256 o foo other 1
3257 | foo other 2
3257 | foo other 2
3258 | foo
3258 | foo
3259 | foo other 3
3259 | foo other 3
3260 o foo line 1
3260 o foo line 1
3261 foo line 2
3261 foo line 2
3262
3262
3263 Test startswith
3263 Test startswith
3264 $ hg log -Gv -R a --template "{startswith(desc)}"
3264 $ hg log -Gv -R a --template "{startswith(desc)}"
3265 hg: parse error: startswith expects two arguments
3265 hg: parse error: startswith expects two arguments
3266 [255]
3266 [255]
3267
3267
3268 $ hg log -Gv -R a --template "{startswith('line', desc)}"
3268 $ hg log -Gv -R a --template "{startswith('line', desc)}"
3269 @
3269 @
3270 |
3270 |
3271 o
3271 o
3272 |
3272 |
3273 o
3273 o
3274 |
3274 |
3275 o
3275 o
3276
3276
3277 o
3277 o
3278 |\
3278 |\
3279 | o
3279 | o
3280 | |
3280 | |
3281 o |
3281 o |
3282 |/
3282 |/
3283 o
3283 o
3284 |
3284 |
3285 o
3285 o
3286 |
3286 |
3287 o
3287 o
3288 |
3288 |
3289 o line 1
3289 o line 1
3290 line 2
3290 line 2
3291
3291
3292 Test bad template with better error message
3292 Test bad template with better error message
3293
3293
3294 $ hg log -Gv -R a --template '{desc|user()}'
3294 $ hg log -Gv -R a --template '{desc|user()}'
3295 hg: parse error: expected a symbol, got 'func'
3295 hg: parse error: expected a symbol, got 'func'
3296 [255]
3296 [255]
3297
3297
3298 Test word function (including index out of bounds graceful failure)
3298 Test word function (including index out of bounds graceful failure)
3299
3299
3300 $ hg log -Gv -R a --template "{word('1', desc)}"
3300 $ hg log -Gv -R a --template "{word('1', desc)}"
3301 @ add,
3301 @ add,
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 head
3311 | o head
3312 | |
3312 | |
3313 o | branch
3313 o | branch
3314 |/
3314 |/
3315 o user,
3315 o user,
3316 |
3316 |
3317 o person
3317 o person
3318 |
3318 |
3319 o 1
3319 o 1
3320 |
3320 |
3321 o 1
3321 o 1
3322
3322
3323
3323
3324 Test word third parameter used as splitter
3324 Test word third parameter used as splitter
3325
3325
3326 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
3326 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
3327 @ M
3327 @ M
3328 |
3328 |
3329 o future
3329 o future
3330 |
3330 |
3331 o third
3331 o third
3332 |
3332 |
3333 o sec
3333 o sec
3334
3334
3335 o merge
3335 o merge
3336 |\
3336 |\
3337 | o new head
3337 | o new head
3338 | |
3338 | |
3339 o | new branch
3339 o | new branch
3340 |/
3340 |/
3341 o n
3341 o n
3342 |
3342 |
3343 o n
3343 o n
3344 |
3344 |
3345 o
3345 o
3346 |
3346 |
3347 o line 1
3347 o line 1
3348 line 2
3348 line 2
3349
3349
3350 Test word error messages for not enough and too many arguments
3350 Test word error messages for not enough and too many arguments
3351
3351
3352 $ hg log -Gv -R a --template "{word('0')}"
3352 $ hg log -Gv -R a --template "{word('0')}"
3353 hg: parse error: word expects two or three arguments, got 1
3353 hg: parse error: word expects two or three arguments, got 1
3354 [255]
3354 [255]
3355
3355
3356 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
3356 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
3357 hg: parse error: word expects two or three arguments, got 7
3357 hg: parse error: word expects two or three arguments, got 7
3358 [255]
3358 [255]
3359
3359
3360 Test word for integer literal
3360 Test word for integer literal
3361
3361
3362 $ hg log -R a --template "{word(2, desc)}\n" -r0
3362 $ hg log -R a --template "{word(2, desc)}\n" -r0
3363 line
3363 line
3364
3364
3365 Test word for invalid numbers
3365 Test word for invalid numbers
3366
3366
3367 $ hg log -Gv -R a --template "{word('a', desc)}"
3367 $ hg log -Gv -R a --template "{word('a', desc)}"
3368 hg: parse error: word expects an integer index
3368 hg: parse error: word expects an integer index
3369 [255]
3369 [255]
3370
3370
3371 Test word for out of range
3372
3373 $ hg log -R a --template "{word(10000, desc)}"
3374 $ hg log -R a --template "{word(-10000, desc)}"
3375
3371 Test indent and not adding to empty lines
3376 Test indent and not adding to empty lines
3372
3377
3373 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
3378 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
3374 -----
3379 -----
3375 > line 1
3380 > line 1
3376 >> line 2
3381 >> line 2
3377 -----
3382 -----
3378 > other 1
3383 > other 1
3379 >> other 2
3384 >> other 2
3380
3385
3381 >> other 3
3386 >> other 3
3382
3387
3383 Test with non-strings like dates
3388 Test with non-strings like dates
3384
3389
3385 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3390 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3386 1200000.00
3391 1200000.00
3387 1300000.00
3392 1300000.00
General Comments 0
You need to be logged in to leave comments. Login now