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