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