##// END OF EJS Templates
templater: do not process \-escapes at parsestring() (issue4290)...
Yuya Nishihara -
r24948:db7463aa stable
parent child Browse files
Show More
@@ -1,810 +1,809 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 "symbol": (0, ("symbol",), None),
23 "symbol": (0, ("symbol",), None),
24 "string": (0, ("string",), None),
24 "string": (0, ("string",), None),
25 "rawstring": (0, ("rawstring",), None),
25 "rawstring": (0, ("rawstring",), None),
26 "end": (0, None, None),
26 "end": (0, None, None),
27 }
27 }
28
28
29 def tokenizer(data):
29 def tokenizer(data):
30 program, start, end = data
30 program, start, end = data
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 decode and d == '\\': # skip over escaped characters
50 if decode and 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.isalnum() or c in '_':
62 elif c.isalnum() or c in '_':
63 s = pos
63 s = pos
64 pos += 1
64 pos += 1
65 while pos < end: # find end of symbol
65 while pos < end: # find end of symbol
66 d = program[pos]
66 d = program[pos]
67 if not (d.isalnum() or d == "_"):
67 if not (d.isalnum() or d == "_"):
68 break
68 break
69 pos += 1
69 pos += 1
70 sym = program[s:pos]
70 sym = program[s:pos]
71 yield ('symbol', sym, s)
71 yield ('symbol', sym, s)
72 pos -= 1
72 pos -= 1
73 elif c == '}':
73 elif c == '}':
74 pos += 1
74 pos += 1
75 break
75 break
76 else:
76 else:
77 raise error.ParseError(_("syntax error"), pos)
77 raise error.ParseError(_("syntax error"), pos)
78 pos += 1
78 pos += 1
79 yield ('end', None, pos)
79 yield ('end', None, pos)
80
80
81 def compiletemplate(tmpl, context, strtoken="string"):
81 def compiletemplate(tmpl, context, strtoken="string"):
82 parsed = []
82 parsed = []
83 pos, stop = 0, len(tmpl)
83 pos, stop = 0, len(tmpl)
84 p = parser.parser(tokenizer, elements)
84 p = parser.parser(tokenizer, elements)
85 while pos < stop:
85 while pos < stop:
86 n = tmpl.find('{', pos)
86 n = tmpl.find('{', pos)
87 if n < 0:
87 if n < 0:
88 parsed.append((strtoken, tmpl[pos:]))
88 parsed.append((strtoken, tmpl[pos:]))
89 break
89 break
90 if n > 0 and tmpl[n - 1] == '\\':
90 if n > 0 and tmpl[n - 1] == '\\':
91 # escaped
91 # escaped
92 parsed.append((strtoken, (tmpl[pos:n - 1] + "{")))
92 parsed.append((strtoken, (tmpl[pos:n - 1] + "{")))
93 pos = n + 1
93 pos = n + 1
94 continue
94 continue
95 if n > pos:
95 if n > pos:
96 parsed.append((strtoken, tmpl[pos:n]))
96 parsed.append((strtoken, tmpl[pos:n]))
97
97
98 pd = [tmpl, n + 1, stop]
98 pd = [tmpl, n + 1, stop]
99 parseres, pos = p.parse(pd)
99 parseres, pos = p.parse(pd)
100 parsed.append(parseres)
100 parsed.append(parseres)
101
101
102 return [compileexp(e, context) for e in parsed]
102 return [compileexp(e, context) for e in parsed]
103
103
104 def compileexp(exp, context):
104 def compileexp(exp, context):
105 t = exp[0]
105 t = exp[0]
106 if t in methods:
106 if t in methods:
107 return methods[t](exp, context)
107 return methods[t](exp, context)
108 raise error.ParseError(_("unknown method '%s'") % t)
108 raise error.ParseError(_("unknown method '%s'") % t)
109
109
110 # template evaluation
110 # template evaluation
111
111
112 def getsymbol(exp):
112 def getsymbol(exp):
113 if exp[0] == 'symbol':
113 if exp[0] == 'symbol':
114 return exp[1]
114 return exp[1]
115 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
115 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
116
116
117 def getlist(x):
117 def getlist(x):
118 if not x:
118 if not x:
119 return []
119 return []
120 if x[0] == 'list':
120 if x[0] == 'list':
121 return getlist(x[1]) + [x[2]]
121 return getlist(x[1]) + [x[2]]
122 return [x]
122 return [x]
123
123
124 def getfilter(exp, context):
124 def getfilter(exp, context):
125 f = getsymbol(exp)
125 f = getsymbol(exp)
126 if f not in context._filters:
126 if f not in context._filters:
127 raise error.ParseError(_("unknown function '%s'") % f)
127 raise error.ParseError(_("unknown function '%s'") % f)
128 return context._filters[f]
128 return context._filters[f]
129
129
130 def gettemplate(exp, context):
130 def gettemplate(exp, context):
131 if exp[0] == 'string' or exp[0] == 'rawstring':
131 if exp[0] == 'string' or exp[0] == 'rawstring':
132 return compiletemplate(exp[1], context, strtoken=exp[0])
132 return compiletemplate(exp[1], context, strtoken=exp[0])
133 if exp[0] == 'symbol':
133 if exp[0] == 'symbol':
134 return context._load(exp[1])
134 return context._load(exp[1])
135 raise error.ParseError(_("expected template specifier"))
135 raise error.ParseError(_("expected template specifier"))
136
136
137 def runstring(context, mapping, data):
137 def runstring(context, mapping, data):
138 return data.decode("string-escape")
138 return data.decode("string-escape")
139
139
140 def runrawstring(context, mapping, data):
140 def runrawstring(context, mapping, data):
141 return data
141 return data
142
142
143 def runsymbol(context, mapping, key):
143 def runsymbol(context, mapping, key):
144 v = mapping.get(key)
144 v = mapping.get(key)
145 if v is None:
145 if v is None:
146 v = context._defaults.get(key)
146 v = context._defaults.get(key)
147 if v is None:
147 if v is None:
148 try:
148 try:
149 v = context.process(key, mapping)
149 v = context.process(key, mapping)
150 except TemplateNotFound:
150 except TemplateNotFound:
151 v = ''
151 v = ''
152 if callable(v):
152 if callable(v):
153 return v(**mapping)
153 return v(**mapping)
154 if isinstance(v, types.GeneratorType):
154 if isinstance(v, types.GeneratorType):
155 v = list(v)
155 v = list(v)
156 return v
156 return v
157
157
158 def buildfilter(exp, context):
158 def buildfilter(exp, context):
159 func, data = compileexp(exp[1], context)
159 func, data = compileexp(exp[1], context)
160 filt = getfilter(exp[2], context)
160 filt = getfilter(exp[2], context)
161 return (runfilter, (func, data, filt))
161 return (runfilter, (func, data, filt))
162
162
163 def runfilter(context, mapping, data):
163 def runfilter(context, mapping, data):
164 func, data, filt = data
164 func, data, filt = data
165 # func() may return string, generator of strings or arbitrary object such
165 # func() may return string, generator of strings or arbitrary object such
166 # as date tuple, but filter does not want generator.
166 # as date tuple, but filter does not want generator.
167 thing = func(context, mapping, data)
167 thing = func(context, mapping, data)
168 if isinstance(thing, types.GeneratorType):
168 if isinstance(thing, types.GeneratorType):
169 thing = stringify(thing)
169 thing = stringify(thing)
170 try:
170 try:
171 return filt(thing)
171 return filt(thing)
172 except (ValueError, AttributeError, TypeError):
172 except (ValueError, AttributeError, TypeError):
173 if isinstance(data, tuple):
173 if isinstance(data, tuple):
174 dt = data[1]
174 dt = data[1]
175 else:
175 else:
176 dt = data
176 dt = data
177 raise util.Abort(_("template filter '%s' is not compatible with "
177 raise util.Abort(_("template filter '%s' is not compatible with "
178 "keyword '%s'") % (filt.func_name, dt))
178 "keyword '%s'") % (filt.func_name, dt))
179
179
180 def buildmap(exp, context):
180 def buildmap(exp, context):
181 func, data = compileexp(exp[1], context)
181 func, data = compileexp(exp[1], context)
182 ctmpl = gettemplate(exp[2], context)
182 ctmpl = gettemplate(exp[2], context)
183 return (runmap, (func, data, ctmpl))
183 return (runmap, (func, data, ctmpl))
184
184
185 def runtemplate(context, mapping, template):
185 def runtemplate(context, mapping, template):
186 for func, data in template:
186 for func, data in template:
187 yield func(context, mapping, data)
187 yield func(context, mapping, data)
188
188
189 def runmap(context, mapping, data):
189 def runmap(context, mapping, data):
190 func, data, ctmpl = data
190 func, data, ctmpl = data
191 d = func(context, mapping, data)
191 d = func(context, mapping, data)
192 if callable(d):
192 if callable(d):
193 d = d()
193 d = d()
194
194
195 lm = mapping.copy()
195 lm = mapping.copy()
196
196
197 for i in d:
197 for i in d:
198 if isinstance(i, dict):
198 if isinstance(i, dict):
199 lm.update(i)
199 lm.update(i)
200 lm['originalnode'] = mapping.get('node')
200 lm['originalnode'] = mapping.get('node')
201 yield runtemplate(context, lm, ctmpl)
201 yield runtemplate(context, lm, ctmpl)
202 else:
202 else:
203 # v is not an iterable of dicts, this happen when 'key'
203 # v is not an iterable of dicts, this happen when 'key'
204 # has been fully expanded already and format is useless.
204 # has been fully expanded already and format is useless.
205 # If so, return the expanded value.
205 # If so, return the expanded value.
206 yield i
206 yield i
207
207
208 def buildfunc(exp, context):
208 def buildfunc(exp, context):
209 n = getsymbol(exp[1])
209 n = getsymbol(exp[1])
210 args = [compileexp(x, context) for x in getlist(exp[2])]
210 args = [compileexp(x, context) for x in getlist(exp[2])]
211 if n in funcs:
211 if n in funcs:
212 f = funcs[n]
212 f = funcs[n]
213 return (f, args)
213 return (f, args)
214 if n in context._filters:
214 if n in context._filters:
215 if len(args) != 1:
215 if len(args) != 1:
216 raise error.ParseError(_("filter %s expects one argument") % n)
216 raise error.ParseError(_("filter %s expects one argument") % n)
217 f = context._filters[n]
217 f = context._filters[n]
218 return (runfilter, (args[0][0], args[0][1], f))
218 return (runfilter, (args[0][0], args[0][1], f))
219 raise error.ParseError(_("unknown function '%s'") % n)
219 raise error.ParseError(_("unknown function '%s'") % n)
220
220
221 def date(context, mapping, args):
221 def date(context, mapping, args):
222 """:date(date[, fmt]): Format a date. See :hg:`help dates` for formatting
222 """:date(date[, fmt]): Format a date. See :hg:`help dates` for formatting
223 strings."""
223 strings."""
224 if not (1 <= len(args) <= 2):
224 if not (1 <= len(args) <= 2):
225 # i18n: "date" is a keyword
225 # i18n: "date" is a keyword
226 raise error.ParseError(_("date expects one or two arguments"))
226 raise error.ParseError(_("date expects one or two arguments"))
227
227
228 date = args[0][0](context, mapping, args[0][1])
228 date = args[0][0](context, mapping, args[0][1])
229 fmt = None
229 fmt = None
230 if len(args) == 2:
230 if len(args) == 2:
231 fmt = stringify(args[1][0](context, mapping, args[1][1]))
231 fmt = stringify(args[1][0](context, mapping, args[1][1]))
232 try:
232 try:
233 if fmt is None:
233 if fmt is None:
234 return util.datestr(date)
234 return util.datestr(date)
235 else:
235 else:
236 return util.datestr(date, fmt)
236 return util.datestr(date, fmt)
237 except (TypeError, ValueError):
237 except (TypeError, ValueError):
238 # i18n: "date" is a keyword
238 # i18n: "date" is a keyword
239 raise error.ParseError(_("date expects a date information"))
239 raise error.ParseError(_("date expects a date information"))
240
240
241 def diff(context, mapping, args):
241 def diff(context, mapping, args):
242 """:diff([includepattern [, excludepattern]]): Show a diff, optionally
242 """:diff([includepattern [, excludepattern]]): Show a diff, optionally
243 specifying files to include or exclude."""
243 specifying files to include or exclude."""
244 if len(args) > 2:
244 if len(args) > 2:
245 # i18n: "diff" is a keyword
245 # i18n: "diff" is a keyword
246 raise error.ParseError(_("diff expects one, two or no arguments"))
246 raise error.ParseError(_("diff expects one, two or no arguments"))
247
247
248 def getpatterns(i):
248 def getpatterns(i):
249 if i < len(args):
249 if i < len(args):
250 s = args[i][1].strip()
250 s = args[i][1].strip()
251 if s:
251 if s:
252 return [s]
252 return [s]
253 return []
253 return []
254
254
255 ctx = mapping['ctx']
255 ctx = mapping['ctx']
256 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
256 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
257
257
258 return ''.join(chunks)
258 return ''.join(chunks)
259
259
260 def fill(context, mapping, args):
260 def fill(context, mapping, args):
261 """:fill(text[, width[, initialident[, hangindent]]]): Fill many
261 """:fill(text[, width[, initialident[, hangindent]]]): Fill many
262 paragraphs with optional indentation. See the "fill" filter."""
262 paragraphs with optional indentation. See the "fill" filter."""
263 if not (1 <= len(args) <= 4):
263 if not (1 <= len(args) <= 4):
264 # i18n: "fill" is a keyword
264 # i18n: "fill" is a keyword
265 raise error.ParseError(_("fill expects one to four arguments"))
265 raise error.ParseError(_("fill expects one to four arguments"))
266
266
267 text = stringify(args[0][0](context, mapping, args[0][1]))
267 text = stringify(args[0][0](context, mapping, args[0][1]))
268 width = 76
268 width = 76
269 initindent = ''
269 initindent = ''
270 hangindent = ''
270 hangindent = ''
271 if 2 <= len(args) <= 4:
271 if 2 <= len(args) <= 4:
272 try:
272 try:
273 width = int(stringify(args[1][0](context, mapping, args[1][1])))
273 width = int(stringify(args[1][0](context, mapping, args[1][1])))
274 except ValueError:
274 except ValueError:
275 # i18n: "fill" is a keyword
275 # i18n: "fill" is a keyword
276 raise error.ParseError(_("fill expects an integer width"))
276 raise error.ParseError(_("fill expects an integer width"))
277 try:
277 try:
278 initindent = stringify(_evalifliteral(args[2], context, mapping))
278 initindent = stringify(_evalifliteral(args[2], context, mapping))
279 hangindent = stringify(_evalifliteral(args[3], context, mapping))
279 hangindent = stringify(_evalifliteral(args[3], context, mapping))
280 except IndexError:
280 except IndexError:
281 pass
281 pass
282
282
283 return templatefilters.fill(text, width, initindent, hangindent)
283 return templatefilters.fill(text, width, initindent, hangindent)
284
284
285 def pad(context, mapping, args):
285 def pad(context, mapping, args):
286 """:pad(text, width[, fillchar=' '[, right=False]]): Pad text with a
286 """:pad(text, width[, fillchar=' '[, right=False]]): Pad text with a
287 fill character."""
287 fill character."""
288 if not (2 <= len(args) <= 4):
288 if not (2 <= len(args) <= 4):
289 # i18n: "pad" is a keyword
289 # i18n: "pad" is a keyword
290 raise error.ParseError(_("pad() expects two to four arguments"))
290 raise error.ParseError(_("pad() expects two to four arguments"))
291
291
292 width = int(args[1][1])
292 width = int(args[1][1])
293
293
294 text = stringify(args[0][0](context, mapping, args[0][1]))
294 text = stringify(args[0][0](context, mapping, args[0][1]))
295 if args[0][0] == runstring:
295 if args[0][0] == runstring:
296 text = stringify(runtemplate(context, mapping,
296 text = stringify(runtemplate(context, mapping,
297 compiletemplate(text, context)))
297 compiletemplate(text, context)))
298
298
299 right = False
299 right = False
300 fillchar = ' '
300 fillchar = ' '
301 if len(args) > 2:
301 if len(args) > 2:
302 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
302 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
303 if len(args) > 3:
303 if len(args) > 3:
304 right = util.parsebool(args[3][1])
304 right = util.parsebool(args[3][1])
305
305
306 if right:
306 if right:
307 return text.rjust(width, fillchar)
307 return text.rjust(width, fillchar)
308 else:
308 else:
309 return text.ljust(width, fillchar)
309 return text.ljust(width, fillchar)
310
310
311 def get(context, mapping, args):
311 def get(context, mapping, args):
312 """:get(dict, key): Get an attribute/key from an object. Some keywords
312 """:get(dict, key): Get an attribute/key from an object. Some keywords
313 are complex types. This function allows you to obtain the value of an
313 are complex types. This function allows you to obtain the value of an
314 attribute on these type."""
314 attribute on these type."""
315 if len(args) != 2:
315 if len(args) != 2:
316 # i18n: "get" is a keyword
316 # i18n: "get" is a keyword
317 raise error.ParseError(_("get() expects two arguments"))
317 raise error.ParseError(_("get() expects two arguments"))
318
318
319 dictarg = args[0][0](context, mapping, args[0][1])
319 dictarg = args[0][0](context, mapping, args[0][1])
320 if not util.safehasattr(dictarg, 'get'):
320 if not util.safehasattr(dictarg, 'get'):
321 # i18n: "get" is a keyword
321 # i18n: "get" is a keyword
322 raise error.ParseError(_("get() expects a dict as first argument"))
322 raise error.ParseError(_("get() expects a dict as first argument"))
323
323
324 key = args[1][0](context, mapping, args[1][1])
324 key = args[1][0](context, mapping, args[1][1])
325 yield dictarg.get(key)
325 yield dictarg.get(key)
326
326
327 def _evalifliteral(arg, context, mapping):
327 def _evalifliteral(arg, context, mapping):
328 t = stringify(arg[0](context, mapping, arg[1]))
328 t = stringify(arg[0](context, mapping, arg[1]))
329 if arg[0] == runstring or arg[0] == runrawstring:
329 if arg[0] == runstring or arg[0] == runrawstring:
330 yield runtemplate(context, mapping,
330 yield runtemplate(context, mapping,
331 compiletemplate(t, context, strtoken='rawstring'))
331 compiletemplate(t, context, strtoken='rawstring'))
332 else:
332 else:
333 yield t
333 yield t
334
334
335 def if_(context, mapping, args):
335 def if_(context, mapping, args):
336 """:if(expr, then[, else]): Conditionally execute based on the result of
336 """:if(expr, then[, else]): Conditionally execute based on the result of
337 an expression."""
337 an expression."""
338 if not (2 <= len(args) <= 3):
338 if not (2 <= len(args) <= 3):
339 # i18n: "if" is a keyword
339 # i18n: "if" is a keyword
340 raise error.ParseError(_("if expects two or three arguments"))
340 raise error.ParseError(_("if expects two or three arguments"))
341
341
342 test = stringify(args[0][0](context, mapping, args[0][1]))
342 test = stringify(args[0][0](context, mapping, args[0][1]))
343 if test:
343 if test:
344 yield _evalifliteral(args[1], context, mapping)
344 yield _evalifliteral(args[1], context, mapping)
345 elif len(args) == 3:
345 elif len(args) == 3:
346 yield _evalifliteral(args[2], context, mapping)
346 yield _evalifliteral(args[2], context, mapping)
347
347
348 def ifcontains(context, mapping, args):
348 def ifcontains(context, mapping, args):
349 """:ifcontains(search, thing, then[, else]): Conditionally execute based
349 """:ifcontains(search, thing, then[, else]): Conditionally execute based
350 on whether the item "search" is in "thing"."""
350 on whether the item "search" is in "thing"."""
351 if not (3 <= len(args) <= 4):
351 if not (3 <= len(args) <= 4):
352 # i18n: "ifcontains" is a keyword
352 # i18n: "ifcontains" is a keyword
353 raise error.ParseError(_("ifcontains expects three or four arguments"))
353 raise error.ParseError(_("ifcontains expects three or four arguments"))
354
354
355 item = stringify(args[0][0](context, mapping, args[0][1]))
355 item = stringify(args[0][0](context, mapping, args[0][1]))
356 items = args[1][0](context, mapping, args[1][1])
356 items = args[1][0](context, mapping, args[1][1])
357
357
358 if item in items:
358 if item in items:
359 yield _evalifliteral(args[2], context, mapping)
359 yield _evalifliteral(args[2], context, mapping)
360 elif len(args) == 4:
360 elif len(args) == 4:
361 yield _evalifliteral(args[3], context, mapping)
361 yield _evalifliteral(args[3], context, mapping)
362
362
363 def ifeq(context, mapping, args):
363 def ifeq(context, mapping, args):
364 """:ifeq(expr1, expr2, then[, else]): Conditionally execute based on
364 """:ifeq(expr1, expr2, then[, else]): Conditionally execute based on
365 whether 2 items are equivalent."""
365 whether 2 items are equivalent."""
366 if not (3 <= len(args) <= 4):
366 if not (3 <= len(args) <= 4):
367 # i18n: "ifeq" is a keyword
367 # i18n: "ifeq" is a keyword
368 raise error.ParseError(_("ifeq expects three or four arguments"))
368 raise error.ParseError(_("ifeq expects three or four arguments"))
369
369
370 test = stringify(args[0][0](context, mapping, args[0][1]))
370 test = stringify(args[0][0](context, mapping, args[0][1]))
371 match = stringify(args[1][0](context, mapping, args[1][1]))
371 match = stringify(args[1][0](context, mapping, args[1][1]))
372 if test == match:
372 if test == match:
373 yield _evalifliteral(args[2], context, mapping)
373 yield _evalifliteral(args[2], context, mapping)
374 elif len(args) == 4:
374 elif len(args) == 4:
375 yield _evalifliteral(args[3], context, mapping)
375 yield _evalifliteral(args[3], context, mapping)
376
376
377 def join(context, mapping, args):
377 def join(context, mapping, args):
378 """:join(list, sep): Join items in a list with a delimiter."""
378 """:join(list, sep): Join items in a list with a delimiter."""
379 if not (1 <= len(args) <= 2):
379 if not (1 <= len(args) <= 2):
380 # i18n: "join" is a keyword
380 # i18n: "join" is a keyword
381 raise error.ParseError(_("join expects one or two arguments"))
381 raise error.ParseError(_("join expects one or two arguments"))
382
382
383 joinset = args[0][0](context, mapping, args[0][1])
383 joinset = args[0][0](context, mapping, args[0][1])
384 if callable(joinset):
384 if callable(joinset):
385 jf = joinset.joinfmt
385 jf = joinset.joinfmt
386 joinset = [jf(x) for x in joinset()]
386 joinset = [jf(x) for x in joinset()]
387
387
388 joiner = " "
388 joiner = " "
389 if len(args) > 1:
389 if len(args) > 1:
390 joiner = stringify(args[1][0](context, mapping, args[1][1]))
390 joiner = stringify(args[1][0](context, mapping, args[1][1]))
391
391
392 first = True
392 first = True
393 for x in joinset:
393 for x in joinset:
394 if first:
394 if first:
395 first = False
395 first = False
396 else:
396 else:
397 yield joiner
397 yield joiner
398 yield x
398 yield x
399
399
400 def label(context, mapping, args):
400 def label(context, mapping, args):
401 """:label(label, expr): Apply a label to generated content. Content with
401 """:label(label, expr): Apply a label to generated content. Content with
402 a label applied can result in additional post-processing, such as
402 a label applied can result in additional post-processing, such as
403 automatic colorization."""
403 automatic colorization."""
404 if len(args) != 2:
404 if len(args) != 2:
405 # i18n: "label" is a keyword
405 # i18n: "label" is a keyword
406 raise error.ParseError(_("label expects two arguments"))
406 raise error.ParseError(_("label expects two arguments"))
407
407
408 # ignore args[0] (the label string) since this is supposed to be a a no-op
408 # ignore args[0] (the label string) since this is supposed to be a a no-op
409 yield _evalifliteral(args[1], context, mapping)
409 yield _evalifliteral(args[1], context, mapping)
410
410
411 def revset(context, mapping, args):
411 def revset(context, mapping, args):
412 """:revset(query[, formatargs...]): Execute a revision set query. See
412 """:revset(query[, formatargs...]): Execute a revision set query. See
413 :hg:`help revset`."""
413 :hg:`help revset`."""
414 if not len(args) > 0:
414 if not len(args) > 0:
415 # i18n: "revset" is a keyword
415 # i18n: "revset" is a keyword
416 raise error.ParseError(_("revset expects one or more arguments"))
416 raise error.ParseError(_("revset expects one or more arguments"))
417
417
418 raw = args[0][1]
418 raw = args[0][1]
419 ctx = mapping['ctx']
419 ctx = mapping['ctx']
420 repo = ctx.repo()
420 repo = ctx.repo()
421
421
422 def query(expr):
422 def query(expr):
423 m = revsetmod.match(repo.ui, expr)
423 m = revsetmod.match(repo.ui, expr)
424 return m(repo)
424 return m(repo)
425
425
426 if len(args) > 1:
426 if len(args) > 1:
427 formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
427 formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
428 revs = query(revsetmod.formatspec(raw, *formatargs))
428 revs = query(revsetmod.formatspec(raw, *formatargs))
429 revs = list([str(r) for r in revs])
429 revs = list([str(r) for r in revs])
430 else:
430 else:
431 revsetcache = mapping['cache'].setdefault("revsetcache", {})
431 revsetcache = mapping['cache'].setdefault("revsetcache", {})
432 if raw in revsetcache:
432 if raw in revsetcache:
433 revs = revsetcache[raw]
433 revs = revsetcache[raw]
434 else:
434 else:
435 revs = query(raw)
435 revs = query(raw)
436 revs = list([str(r) for r in revs])
436 revs = list([str(r) for r in revs])
437 revsetcache[raw] = revs
437 revsetcache[raw] = revs
438
438
439 return templatekw.showlist("revision", revs, **mapping)
439 return templatekw.showlist("revision", revs, **mapping)
440
440
441 def rstdoc(context, mapping, args):
441 def rstdoc(context, mapping, args):
442 """:rstdoc(text, style): Format ReStructuredText."""
442 """:rstdoc(text, style): Format ReStructuredText."""
443 if len(args) != 2:
443 if len(args) != 2:
444 # i18n: "rstdoc" is a keyword
444 # i18n: "rstdoc" is a keyword
445 raise error.ParseError(_("rstdoc expects two arguments"))
445 raise error.ParseError(_("rstdoc expects two arguments"))
446
446
447 text = stringify(args[0][0](context, mapping, args[0][1]))
447 text = stringify(args[0][0](context, mapping, args[0][1]))
448 style = stringify(args[1][0](context, mapping, args[1][1]))
448 style = stringify(args[1][0](context, mapping, args[1][1]))
449
449
450 return minirst.format(text, style=style, keep=['verbose'])
450 return minirst.format(text, style=style, keep=['verbose'])
451
451
452 def shortest(context, mapping, args):
452 def shortest(context, mapping, args):
453 """:shortest(node, minlength=4): Obtain the shortest representation of
453 """:shortest(node, minlength=4): Obtain the shortest representation of
454 a node."""
454 a node."""
455 if not (1 <= len(args) <= 2):
455 if not (1 <= len(args) <= 2):
456 # i18n: "shortest" is a keyword
456 # i18n: "shortest" is a keyword
457 raise error.ParseError(_("shortest() expects one or two arguments"))
457 raise error.ParseError(_("shortest() expects one or two arguments"))
458
458
459 node = stringify(args[0][0](context, mapping, args[0][1]))
459 node = stringify(args[0][0](context, mapping, args[0][1]))
460
460
461 minlength = 4
461 minlength = 4
462 if len(args) > 1:
462 if len(args) > 1:
463 minlength = int(args[1][1])
463 minlength = int(args[1][1])
464
464
465 cl = mapping['ctx']._repo.changelog
465 cl = mapping['ctx']._repo.changelog
466 def isvalid(test):
466 def isvalid(test):
467 try:
467 try:
468 try:
468 try:
469 cl.index.partialmatch(test)
469 cl.index.partialmatch(test)
470 except AttributeError:
470 except AttributeError:
471 # Pure mercurial doesn't support partialmatch on the index.
471 # Pure mercurial doesn't support partialmatch on the index.
472 # Fallback to the slow way.
472 # Fallback to the slow way.
473 if cl._partialmatch(test) is None:
473 if cl._partialmatch(test) is None:
474 return False
474 return False
475
475
476 try:
476 try:
477 i = int(test)
477 i = int(test)
478 # if we are a pure int, then starting with zero will not be
478 # if we are a pure int, then starting with zero will not be
479 # confused as a rev; or, obviously, if the int is larger than
479 # confused as a rev; or, obviously, if the int is larger than
480 # the value of the tip rev
480 # the value of the tip rev
481 if test[0] == '0' or i > len(cl):
481 if test[0] == '0' or i > len(cl):
482 return True
482 return True
483 return False
483 return False
484 except ValueError:
484 except ValueError:
485 return True
485 return True
486 except error.RevlogError:
486 except error.RevlogError:
487 return False
487 return False
488
488
489 shortest = node
489 shortest = node
490 startlength = max(6, minlength)
490 startlength = max(6, minlength)
491 length = startlength
491 length = startlength
492 while True:
492 while True:
493 test = node[:length]
493 test = node[:length]
494 if isvalid(test):
494 if isvalid(test):
495 shortest = test
495 shortest = test
496 if length == minlength or length > startlength:
496 if length == minlength or length > startlength:
497 return shortest
497 return shortest
498 length -= 1
498 length -= 1
499 else:
499 else:
500 length += 1
500 length += 1
501 if len(shortest) <= length:
501 if len(shortest) <= length:
502 return shortest
502 return shortest
503
503
504 def strip(context, mapping, args):
504 def strip(context, mapping, args):
505 """:strip(text[, chars]): Strip characters from a string."""
505 """:strip(text[, chars]): Strip characters from a string."""
506 if not (1 <= len(args) <= 2):
506 if not (1 <= len(args) <= 2):
507 # i18n: "strip" is a keyword
507 # i18n: "strip" is a keyword
508 raise error.ParseError(_("strip expects one or two arguments"))
508 raise error.ParseError(_("strip expects one or two arguments"))
509
509
510 text = stringify(args[0][0](context, mapping, args[0][1]))
510 text = stringify(args[0][0](context, mapping, args[0][1]))
511 if len(args) == 2:
511 if len(args) == 2:
512 chars = stringify(args[1][0](context, mapping, args[1][1]))
512 chars = stringify(args[1][0](context, mapping, args[1][1]))
513 return text.strip(chars)
513 return text.strip(chars)
514 return text.strip()
514 return text.strip()
515
515
516 def sub(context, mapping, args):
516 def sub(context, mapping, args):
517 """:sub(pattern, replacement, expression): Perform text substitution
517 """:sub(pattern, replacement, expression): Perform text substitution
518 using regular expressions."""
518 using regular expressions."""
519 if len(args) != 3:
519 if len(args) != 3:
520 # i18n: "sub" is a keyword
520 # i18n: "sub" is a keyword
521 raise error.ParseError(_("sub expects three arguments"))
521 raise error.ParseError(_("sub expects three arguments"))
522
522
523 pat = stringify(args[0][0](context, mapping, args[0][1]))
523 pat = stringify(args[0][0](context, mapping, args[0][1]))
524 rpl = stringify(args[1][0](context, mapping, args[1][1]))
524 rpl = stringify(args[1][0](context, mapping, args[1][1]))
525 src = stringify(_evalifliteral(args[2], context, mapping))
525 src = stringify(_evalifliteral(args[2], context, mapping))
526 yield re.sub(pat, rpl, src)
526 yield re.sub(pat, rpl, src)
527
527
528 def startswith(context, mapping, args):
528 def startswith(context, mapping, args):
529 """:startswith(pattern, text): Returns the value from the "text" argument
529 """:startswith(pattern, text): Returns the value from the "text" argument
530 if it begins with the content from the "pattern" argument."""
530 if it begins with the content from the "pattern" argument."""
531 if len(args) != 2:
531 if len(args) != 2:
532 # i18n: "startswith" is a keyword
532 # i18n: "startswith" is a keyword
533 raise error.ParseError(_("startswith expects two arguments"))
533 raise error.ParseError(_("startswith expects two arguments"))
534
534
535 patn = stringify(args[0][0](context, mapping, args[0][1]))
535 patn = stringify(args[0][0](context, mapping, args[0][1]))
536 text = stringify(args[1][0](context, mapping, args[1][1]))
536 text = stringify(args[1][0](context, mapping, args[1][1]))
537 if text.startswith(patn):
537 if text.startswith(patn):
538 return text
538 return text
539 return ''
539 return ''
540
540
541
541
542 def word(context, mapping, args):
542 def word(context, mapping, args):
543 """:word(number, text[, separator]): Return the nth word from a string."""
543 """:word(number, text[, separator]): Return the nth word from a string."""
544 if not (2 <= len(args) <= 3):
544 if not (2 <= len(args) <= 3):
545 # i18n: "word" is a keyword
545 # i18n: "word" is a keyword
546 raise error.ParseError(_("word expects two or three arguments, got %d")
546 raise error.ParseError(_("word expects two or three arguments, got %d")
547 % len(args))
547 % len(args))
548
548
549 try:
549 try:
550 num = int(stringify(args[0][0](context, mapping, args[0][1])))
550 num = int(stringify(args[0][0](context, mapping, args[0][1])))
551 except ValueError:
551 except ValueError:
552 # i18n: "word" is a keyword
552 # i18n: "word" is a keyword
553 raise error.ParseError(
553 raise error.ParseError(
554 _("Use strings like '3' for numbers passed to word function"))
554 _("Use strings like '3' for numbers passed to word function"))
555 text = stringify(args[1][0](context, mapping, args[1][1]))
555 text = stringify(args[1][0](context, mapping, args[1][1]))
556 if len(args) == 3:
556 if len(args) == 3:
557 splitter = stringify(args[2][0](context, mapping, args[2][1]))
557 splitter = stringify(args[2][0](context, mapping, args[2][1]))
558 else:
558 else:
559 splitter = None
559 splitter = None
560
560
561 tokens = text.split(splitter)
561 tokens = text.split(splitter)
562 if num >= len(tokens):
562 if num >= len(tokens):
563 return ''
563 return ''
564 else:
564 else:
565 return tokens[num]
565 return tokens[num]
566
566
567 methods = {
567 methods = {
568 "string": lambda e, c: (runstring, e[1]),
568 "string": lambda e, c: (runstring, e[1]),
569 "rawstring": lambda e, c: (runrawstring, e[1]),
569 "rawstring": lambda e, c: (runrawstring, e[1]),
570 "symbol": lambda e, c: (runsymbol, e[1]),
570 "symbol": lambda e, c: (runsymbol, e[1]),
571 "group": lambda e, c: compileexp(e[1], c),
571 "group": lambda e, c: compileexp(e[1], c),
572 # ".": buildmember,
572 # ".": buildmember,
573 "|": buildfilter,
573 "|": buildfilter,
574 "%": buildmap,
574 "%": buildmap,
575 "func": buildfunc,
575 "func": buildfunc,
576 }
576 }
577
577
578 funcs = {
578 funcs = {
579 "date": date,
579 "date": date,
580 "diff": diff,
580 "diff": diff,
581 "fill": fill,
581 "fill": fill,
582 "get": get,
582 "get": get,
583 "if": if_,
583 "if": if_,
584 "ifcontains": ifcontains,
584 "ifcontains": ifcontains,
585 "ifeq": ifeq,
585 "ifeq": ifeq,
586 "join": join,
586 "join": join,
587 "label": label,
587 "label": label,
588 "pad": pad,
588 "pad": pad,
589 "revset": revset,
589 "revset": revset,
590 "rstdoc": rstdoc,
590 "rstdoc": rstdoc,
591 "shortest": shortest,
591 "shortest": shortest,
592 "startswith": startswith,
592 "startswith": startswith,
593 "strip": strip,
593 "strip": strip,
594 "sub": sub,
594 "sub": sub,
595 "word": word,
595 "word": word,
596 }
596 }
597
597
598 # template engine
598 # template engine
599
599
600 stringify = templatefilters.stringify
600 stringify = templatefilters.stringify
601
601
602 def _flatten(thing):
602 def _flatten(thing):
603 '''yield a single stream from a possibly nested set of iterators'''
603 '''yield a single stream from a possibly nested set of iterators'''
604 if isinstance(thing, str):
604 if isinstance(thing, str):
605 yield thing
605 yield thing
606 elif not util.safehasattr(thing, '__iter__'):
606 elif not util.safehasattr(thing, '__iter__'):
607 if thing is not None:
607 if thing is not None:
608 yield str(thing)
608 yield str(thing)
609 else:
609 else:
610 for i in thing:
610 for i in thing:
611 if isinstance(i, str):
611 if isinstance(i, str):
612 yield i
612 yield i
613 elif not util.safehasattr(i, '__iter__'):
613 elif not util.safehasattr(i, '__iter__'):
614 if i is not None:
614 if i is not None:
615 yield str(i)
615 yield str(i)
616 elif i is not None:
616 elif i is not None:
617 for j in _flatten(i):
617 for j in _flatten(i):
618 yield j
618 yield j
619
619
620 def parsestring(s, quoted=True):
620 def parsestring(s, quoted=True):
621 '''parse a string using simple c-like syntax.
621 '''unwrap quotes if quoted is True'''
622 string must be in quotes if quoted is True.'''
623 if quoted:
622 if quoted:
624 if len(s) < 2 or s[0] != s[-1]:
623 if len(s) < 2 or s[0] != s[-1]:
625 raise SyntaxError(_('unmatched quotes'))
624 raise SyntaxError(_('unmatched quotes'))
626 return s[1:-1].decode('string_escape')
625 return s[1:-1]
627
626
628 return s.decode('string_escape')
627 return s
629
628
630 class engine(object):
629 class engine(object):
631 '''template expansion engine.
630 '''template expansion engine.
632
631
633 template expansion works like this. a map file contains key=value
632 template expansion works like this. a map file contains key=value
634 pairs. if value is quoted, it is treated as string. otherwise, it
633 pairs. if value is quoted, it is treated as string. otherwise, it
635 is treated as name of template file.
634 is treated as name of template file.
636
635
637 templater is asked to expand a key in map. it looks up key, and
636 templater is asked to expand a key in map. it looks up key, and
638 looks for strings like this: {foo}. it expands {foo} by looking up
637 looks for strings like this: {foo}. it expands {foo} by looking up
639 foo in map, and substituting it. expansion is recursive: it stops
638 foo in map, and substituting it. expansion is recursive: it stops
640 when there is no more {foo} to replace.
639 when there is no more {foo} to replace.
641
640
642 expansion also allows formatting and filtering.
641 expansion also allows formatting and filtering.
643
642
644 format uses key to expand each item in list. syntax is
643 format uses key to expand each item in list. syntax is
645 {key%format}.
644 {key%format}.
646
645
647 filter uses function to transform value. syntax is
646 filter uses function to transform value. syntax is
648 {key|filter1|filter2|...}.'''
647 {key|filter1|filter2|...}.'''
649
648
650 def __init__(self, loader, filters={}, defaults={}):
649 def __init__(self, loader, filters={}, defaults={}):
651 self._loader = loader
650 self._loader = loader
652 self._filters = filters
651 self._filters = filters
653 self._defaults = defaults
652 self._defaults = defaults
654 self._cache = {}
653 self._cache = {}
655
654
656 def _load(self, t):
655 def _load(self, t):
657 '''load, parse, and cache a template'''
656 '''load, parse, and cache a template'''
658 if t not in self._cache:
657 if t not in self._cache:
659 self._cache[t] = compiletemplate(self._loader(t), self)
658 self._cache[t] = compiletemplate(self._loader(t), self)
660 return self._cache[t]
659 return self._cache[t]
661
660
662 def process(self, t, mapping):
661 def process(self, t, mapping):
663 '''Perform expansion. t is name of map element to expand.
662 '''Perform expansion. t is name of map element to expand.
664 mapping contains added elements for use during expansion. Is a
663 mapping contains added elements for use during expansion. Is a
665 generator.'''
664 generator.'''
666 return _flatten(runtemplate(self, mapping, self._load(t)))
665 return _flatten(runtemplate(self, mapping, self._load(t)))
667
666
668 engines = {'default': engine}
667 engines = {'default': engine}
669
668
670 def stylelist():
669 def stylelist():
671 paths = templatepaths()
670 paths = templatepaths()
672 if not paths:
671 if not paths:
673 return _('no templates found, try `hg debuginstall` for more info')
672 return _('no templates found, try `hg debuginstall` for more info')
674 dirlist = os.listdir(paths[0])
673 dirlist = os.listdir(paths[0])
675 stylelist = []
674 stylelist = []
676 for file in dirlist:
675 for file in dirlist:
677 split = file.split(".")
676 split = file.split(".")
678 if split[0] == "map-cmdline":
677 if split[0] == "map-cmdline":
679 stylelist.append(split[1])
678 stylelist.append(split[1])
680 return ", ".join(sorted(stylelist))
679 return ", ".join(sorted(stylelist))
681
680
682 class TemplateNotFound(util.Abort):
681 class TemplateNotFound(util.Abort):
683 pass
682 pass
684
683
685 class templater(object):
684 class templater(object):
686
685
687 def __init__(self, mapfile, filters={}, defaults={}, cache={},
686 def __init__(self, mapfile, filters={}, defaults={}, cache={},
688 minchunk=1024, maxchunk=65536):
687 minchunk=1024, maxchunk=65536):
689 '''set up template engine.
688 '''set up template engine.
690 mapfile is name of file to read map definitions from.
689 mapfile is name of file to read map definitions from.
691 filters is dict of functions. each transforms a value into another.
690 filters is dict of functions. each transforms a value into another.
692 defaults is dict of default map definitions.'''
691 defaults is dict of default map definitions.'''
693 self.mapfile = mapfile or 'template'
692 self.mapfile = mapfile or 'template'
694 self.cache = cache.copy()
693 self.cache = cache.copy()
695 self.map = {}
694 self.map = {}
696 if mapfile:
695 if mapfile:
697 self.base = os.path.dirname(mapfile)
696 self.base = os.path.dirname(mapfile)
698 else:
697 else:
699 self.base = ''
698 self.base = ''
700 self.filters = templatefilters.filters.copy()
699 self.filters = templatefilters.filters.copy()
701 self.filters.update(filters)
700 self.filters.update(filters)
702 self.defaults = defaults
701 self.defaults = defaults
703 self.minchunk, self.maxchunk = minchunk, maxchunk
702 self.minchunk, self.maxchunk = minchunk, maxchunk
704 self.ecache = {}
703 self.ecache = {}
705
704
706 if not mapfile:
705 if not mapfile:
707 return
706 return
708 if not os.path.exists(mapfile):
707 if not os.path.exists(mapfile):
709 raise util.Abort(_("style '%s' not found") % mapfile,
708 raise util.Abort(_("style '%s' not found") % mapfile,
710 hint=_("available styles: %s") % stylelist())
709 hint=_("available styles: %s") % stylelist())
711
710
712 conf = config.config()
711 conf = config.config()
713 conf.read(mapfile)
712 conf.read(mapfile)
714
713
715 for key, val in conf[''].items():
714 for key, val in conf[''].items():
716 if not val:
715 if not val:
717 raise SyntaxError(_('%s: missing value') % conf.source('', key))
716 raise SyntaxError(_('%s: missing value') % conf.source('', key))
718 if val[0] in "'\"":
717 if val[0] in "'\"":
719 try:
718 try:
720 self.cache[key] = parsestring(val)
719 self.cache[key] = parsestring(val)
721 except SyntaxError, inst:
720 except SyntaxError, inst:
722 raise SyntaxError('%s: %s' %
721 raise SyntaxError('%s: %s' %
723 (conf.source('', key), inst.args[0]))
722 (conf.source('', key), inst.args[0]))
724 else:
723 else:
725 val = 'default', val
724 val = 'default', val
726 if ':' in val[1]:
725 if ':' in val[1]:
727 val = val[1].split(':', 1)
726 val = val[1].split(':', 1)
728 self.map[key] = val[0], os.path.join(self.base, val[1])
727 self.map[key] = val[0], os.path.join(self.base, val[1])
729
728
730 def __contains__(self, key):
729 def __contains__(self, key):
731 return key in self.cache or key in self.map
730 return key in self.cache or key in self.map
732
731
733 def load(self, t):
732 def load(self, t):
734 '''Get the template for the given template name. Use a local cache.'''
733 '''Get the template for the given template name. Use a local cache.'''
735 if t not in self.cache:
734 if t not in self.cache:
736 try:
735 try:
737 self.cache[t] = util.readfile(self.map[t][1])
736 self.cache[t] = util.readfile(self.map[t][1])
738 except KeyError, inst:
737 except KeyError, inst:
739 raise TemplateNotFound(_('"%s" not in template map') %
738 raise TemplateNotFound(_('"%s" not in template map') %
740 inst.args[0])
739 inst.args[0])
741 except IOError, inst:
740 except IOError, inst:
742 raise IOError(inst.args[0], _('template file %s: %s') %
741 raise IOError(inst.args[0], _('template file %s: %s') %
743 (self.map[t][1], inst.args[1]))
742 (self.map[t][1], inst.args[1]))
744 return self.cache[t]
743 return self.cache[t]
745
744
746 def __call__(self, t, **mapping):
745 def __call__(self, t, **mapping):
747 ttype = t in self.map and self.map[t][0] or 'default'
746 ttype = t in self.map and self.map[t][0] or 'default'
748 if ttype not in self.ecache:
747 if ttype not in self.ecache:
749 self.ecache[ttype] = engines[ttype](self.load,
748 self.ecache[ttype] = engines[ttype](self.load,
750 self.filters, self.defaults)
749 self.filters, self.defaults)
751 proc = self.ecache[ttype]
750 proc = self.ecache[ttype]
752
751
753 stream = proc.process(t, mapping)
752 stream = proc.process(t, mapping)
754 if self.minchunk:
753 if self.minchunk:
755 stream = util.increasingchunks(stream, min=self.minchunk,
754 stream = util.increasingchunks(stream, min=self.minchunk,
756 max=self.maxchunk)
755 max=self.maxchunk)
757 return stream
756 return stream
758
757
759 def templatepaths():
758 def templatepaths():
760 '''return locations used for template files.'''
759 '''return locations used for template files.'''
761 pathsrel = ['templates']
760 pathsrel = ['templates']
762 paths = [os.path.normpath(os.path.join(util.datapath, f))
761 paths = [os.path.normpath(os.path.join(util.datapath, f))
763 for f in pathsrel]
762 for f in pathsrel]
764 return [p for p in paths if os.path.isdir(p)]
763 return [p for p in paths if os.path.isdir(p)]
765
764
766 def templatepath(name):
765 def templatepath(name):
767 '''return location of template file. returns None if not found.'''
766 '''return location of template file. returns None if not found.'''
768 for p in templatepaths():
767 for p in templatepaths():
769 f = os.path.join(p, name)
768 f = os.path.join(p, name)
770 if os.path.exists(f):
769 if os.path.exists(f):
771 return f
770 return f
772 return None
771 return None
773
772
774 def stylemap(styles, paths=None):
773 def stylemap(styles, paths=None):
775 """Return path to mapfile for a given style.
774 """Return path to mapfile for a given style.
776
775
777 Searches mapfile in the following locations:
776 Searches mapfile in the following locations:
778 1. templatepath/style/map
777 1. templatepath/style/map
779 2. templatepath/map-style
778 2. templatepath/map-style
780 3. templatepath/map
779 3. templatepath/map
781 """
780 """
782
781
783 if paths is None:
782 if paths is None:
784 paths = templatepaths()
783 paths = templatepaths()
785 elif isinstance(paths, str):
784 elif isinstance(paths, str):
786 paths = [paths]
785 paths = [paths]
787
786
788 if isinstance(styles, str):
787 if isinstance(styles, str):
789 styles = [styles]
788 styles = [styles]
790
789
791 for style in styles:
790 for style in styles:
792 # only plain name is allowed to honor template paths
791 # only plain name is allowed to honor template paths
793 if (not style
792 if (not style
794 or style in (os.curdir, os.pardir)
793 or style in (os.curdir, os.pardir)
795 or os.sep in style
794 or os.sep in style
796 or os.altsep and os.altsep in style):
795 or os.altsep and os.altsep in style):
797 continue
796 continue
798 locations = [os.path.join(style, 'map'), 'map-' + style]
797 locations = [os.path.join(style, 'map'), 'map-' + style]
799 locations.append('map')
798 locations.append('map')
800
799
801 for path in paths:
800 for path in paths:
802 for location in locations:
801 for location in locations:
803 mapfile = os.path.join(path, location)
802 mapfile = os.path.join(path, location)
804 if os.path.isfile(mapfile):
803 if os.path.isfile(mapfile):
805 return style, mapfile
804 return style, mapfile
806
805
807 raise RuntimeError("No hgweb templates found in %r" % paths)
806 raise RuntimeError("No hgweb templates found in %r" % paths)
808
807
809 # tell hggettext to extract docstrings from these functions:
808 # tell hggettext to extract docstrings from these functions:
810 i18nfunctions = funcs.values()
809 i18nfunctions = funcs.values()
@@ -1,2634 +1,2657 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 Quoting for ui.logtemplate
54 Quoting for ui.logtemplate
55
55
56 $ hg tip --config "ui.logtemplate={rev}\n"
56 $ hg tip --config "ui.logtemplate={rev}\n"
57 8
57 8
58 $ hg tip --config "ui.logtemplate='{rev}\n'"
58 $ hg tip --config "ui.logtemplate='{rev}\n'"
59 8
59 8
60 $ hg tip --config 'ui.logtemplate="{rev}\n"'
60 $ hg tip --config 'ui.logtemplate="{rev}\n"'
61 8
61 8
62
62
63 Make sure user/global hgrc does not affect tests
63 Make sure user/global hgrc does not affect tests
64
64
65 $ echo '[ui]' > .hg/hgrc
65 $ echo '[ui]' > .hg/hgrc
66 $ echo 'logtemplate =' >> .hg/hgrc
66 $ echo 'logtemplate =' >> .hg/hgrc
67 $ echo 'style =' >> .hg/hgrc
67 $ echo 'style =' >> .hg/hgrc
68
68
69 Add some simple styles to settings
69 Add some simple styles to settings
70
70
71 $ echo '[templates]' >> .hg/hgrc
71 $ echo '[templates]' >> .hg/hgrc
72 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
72 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
73 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
73 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
74
74
75 $ hg log -l1 -Tsimple
75 $ hg log -l1 -Tsimple
76 8
76 8
77 $ hg log -l1 -Tsimple2
77 $ hg log -l1 -Tsimple2
78 8
78 8
79
79
80 Test templates and style maps in files:
80 Test templates and style maps in files:
81
81
82 $ echo "{rev}" > tmpl
82 $ echo "{rev}" > tmpl
83 $ hg log -l1 -T./tmpl
83 $ hg log -l1 -T./tmpl
84 8
84 8
85 $ hg log -l1 -Tblah/blah
85 $ hg log -l1 -Tblah/blah
86 blah/blah (no-eol)
86 blah/blah (no-eol)
87
87
88 $ printf 'changeset = "{rev}\\n"\n' > map-simple
88 $ printf 'changeset = "{rev}\\n"\n' > map-simple
89 $ hg log -l1 -T./map-simple
89 $ hg log -l1 -T./map-simple
90 8
90 8
91
91
92 Template should precede style option
92 Template should precede style option
93
93
94 $ hg log -l1 --style default -T '{rev}\n'
94 $ hg log -l1 --style default -T '{rev}\n'
95 8
95 8
96
96
97 Add a commit with empty description, to ensure that the templates
97 Add a commit with empty description, to ensure that the templates
98 following below omit it properly.
98 following below omit it properly.
99
99
100 $ echo c >> c
100 $ echo c >> c
101 $ hg add c
101 $ hg add c
102 $ hg commit -qm ' '
102 $ hg commit -qm ' '
103
103
104 Default style is like normal output. Phases style should be the same
104 Default style is like normal output. Phases style should be the same
105 as default style, except for extra phase lines.
105 as default style, except for extra phase lines.
106
106
107 $ hg log > log.out
107 $ hg log > log.out
108 $ hg log --style default > style.out
108 $ hg log --style default > style.out
109 $ cmp log.out style.out || diff -u log.out style.out
109 $ cmp log.out style.out || diff -u log.out style.out
110 $ hg log -T phases > phases.out
110 $ hg log -T phases > phases.out
111 $ diff -u log.out phases.out | grep "phase:"
111 $ diff -u log.out phases.out | grep "phase:"
112 +phase: draft
112 +phase: draft
113 +phase: draft
113 +phase: draft
114 +phase: draft
114 +phase: draft
115 +phase: draft
115 +phase: draft
116 +phase: draft
116 +phase: draft
117 +phase: draft
117 +phase: draft
118 +phase: draft
118 +phase: draft
119 +phase: draft
119 +phase: draft
120 +phase: draft
120 +phase: draft
121 +phase: draft
121 +phase: draft
122
122
123 $ hg log -v > log.out
123 $ hg log -v > log.out
124 $ hg log -v --style default > style.out
124 $ hg log -v --style default > style.out
125 $ cmp log.out style.out || diff -u log.out style.out
125 $ cmp log.out style.out || diff -u log.out style.out
126 $ hg log -v -T phases > phases.out
126 $ hg log -v -T phases > phases.out
127 $ diff -u log.out phases.out | grep phase:
127 $ diff -u log.out phases.out | grep phase:
128 +phase: draft
128 +phase: draft
129 +phase: draft
129 +phase: draft
130 +phase: draft
130 +phase: draft
131 +phase: draft
131 +phase: draft
132 +phase: draft
132 +phase: draft
133 +phase: draft
133 +phase: draft
134 +phase: draft
134 +phase: draft
135 +phase: draft
135 +phase: draft
136 +phase: draft
136 +phase: draft
137 +phase: draft
137 +phase: draft
138
138
139 $ hg log -q > log.out
139 $ hg log -q > log.out
140 $ hg log -q --style default > style.out
140 $ hg log -q --style default > style.out
141 $ cmp log.out style.out || diff -u log.out style.out
141 $ cmp log.out style.out || diff -u log.out style.out
142 $ hg log -q -T phases > phases.out
142 $ hg log -q -T phases > phases.out
143 $ cmp log.out phases.out || diff -u log.out phases.out
143 $ cmp log.out phases.out || diff -u log.out phases.out
144
144
145 $ hg log --debug > log.out
145 $ hg log --debug > log.out
146 $ hg log --debug --style default > style.out
146 $ hg log --debug --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 --debug -T phases > phases.out
148 $ hg log --debug -T phases > phases.out
149 $ cmp log.out phases.out || diff -u log.out phases.out
149 $ cmp log.out phases.out || diff -u log.out phases.out
150
150
151 Default style should also preserve color information (issue2866):
151 Default style should also preserve color information (issue2866):
152
152
153 $ cp $HGRCPATH $HGRCPATH-bak
153 $ cp $HGRCPATH $HGRCPATH-bak
154 $ cat <<EOF >> $HGRCPATH
154 $ cat <<EOF >> $HGRCPATH
155 > [extensions]
155 > [extensions]
156 > color=
156 > color=
157 > EOF
157 > EOF
158
158
159 $ hg --color=debug log > log.out
159 $ hg --color=debug log > log.out
160 $ hg --color=debug log --style default > style.out
160 $ hg --color=debug log --style default > style.out
161 $ cmp log.out style.out || diff -u log.out style.out
161 $ cmp log.out style.out || diff -u log.out style.out
162 $ hg --color=debug log -T phases > phases.out
162 $ hg --color=debug log -T phases > phases.out
163 $ diff -u log.out phases.out | grep phase:
163 $ diff -u log.out phases.out | grep phase:
164 +[log.phase|phase: draft]
164 +[log.phase|phase: draft]
165 +[log.phase|phase: draft]
165 +[log.phase|phase: draft]
166 +[log.phase|phase: draft]
166 +[log.phase|phase: draft]
167 +[log.phase|phase: draft]
167 +[log.phase|phase: draft]
168 +[log.phase|phase: draft]
168 +[log.phase|phase: draft]
169 +[log.phase|phase: draft]
169 +[log.phase|phase: draft]
170 +[log.phase|phase: draft]
170 +[log.phase|phase: draft]
171 +[log.phase|phase: draft]
171 +[log.phase|phase: draft]
172 +[log.phase|phase: draft]
172 +[log.phase|phase: draft]
173 +[log.phase|phase: draft]
173 +[log.phase|phase: draft]
174
174
175 $ hg --color=debug -v log > log.out
175 $ hg --color=debug -v log > log.out
176 $ hg --color=debug -v log --style default > style.out
176 $ hg --color=debug -v log --style default > style.out
177 $ cmp log.out style.out || diff -u log.out style.out
177 $ cmp log.out style.out || diff -u log.out style.out
178 $ hg --color=debug -v log -T phases > phases.out
178 $ hg --color=debug -v log -T phases > phases.out
179 $ diff -u log.out phases.out | grep phase:
179 $ diff -u log.out phases.out | grep phase:
180 +[log.phase|phase: draft]
180 +[log.phase|phase: draft]
181 +[log.phase|phase: draft]
181 +[log.phase|phase: draft]
182 +[log.phase|phase: draft]
182 +[log.phase|phase: draft]
183 +[log.phase|phase: draft]
183 +[log.phase|phase: draft]
184 +[log.phase|phase: draft]
184 +[log.phase|phase: draft]
185 +[log.phase|phase: draft]
185 +[log.phase|phase: draft]
186 +[log.phase|phase: draft]
186 +[log.phase|phase: draft]
187 +[log.phase|phase: draft]
187 +[log.phase|phase: draft]
188 +[log.phase|phase: draft]
188 +[log.phase|phase: draft]
189 +[log.phase|phase: draft]
189 +[log.phase|phase: draft]
190
190
191 $ hg --color=debug -q log > log.out
191 $ hg --color=debug -q log > log.out
192 $ hg --color=debug -q log --style default > style.out
192 $ hg --color=debug -q log --style default > style.out
193 $ cmp log.out style.out || diff -u log.out style.out
193 $ cmp log.out style.out || diff -u log.out style.out
194 $ hg --color=debug -q log -T phases > phases.out
194 $ hg --color=debug -q log -T phases > phases.out
195 $ cmp log.out phases.out || diff -u log.out phases.out
195 $ cmp log.out phases.out || diff -u log.out phases.out
196
196
197 $ hg --color=debug --debug log > log.out
197 $ hg --color=debug --debug log > log.out
198 $ hg --color=debug --debug log --style default > style.out
198 $ hg --color=debug --debug log --style default > style.out
199 $ cmp log.out style.out || diff -u log.out style.out
199 $ cmp log.out style.out || diff -u log.out style.out
200 $ hg --color=debug --debug log -T phases > phases.out
200 $ hg --color=debug --debug log -T phases > phases.out
201 $ cmp log.out phases.out || diff -u log.out phases.out
201 $ cmp log.out phases.out || diff -u log.out phases.out
202
202
203 $ mv $HGRCPATH-bak $HGRCPATH
203 $ mv $HGRCPATH-bak $HGRCPATH
204
204
205 Remove commit with empty commit message, so as to not pollute further
205 Remove commit with empty commit message, so as to not pollute further
206 tests.
206 tests.
207
207
208 $ hg --config extensions.strip= strip -q .
208 $ hg --config extensions.strip= strip -q .
209
209
210 Revision with no copies (used to print a traceback):
210 Revision with no copies (used to print a traceback):
211
211
212 $ hg tip -v --template '\n'
212 $ hg tip -v --template '\n'
213
213
214
214
215 Compact style works:
215 Compact style works:
216
216
217 $ hg log -Tcompact
217 $ hg log -Tcompact
218 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
218 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
219 third
219 third
220
220
221 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
221 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
222 second
222 second
223
223
224 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
224 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
225 merge
225 merge
226
226
227 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
227 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
228 new head
228 new head
229
229
230 4 bbe44766e73d 1970-01-17 04:53 +0000 person
230 4 bbe44766e73d 1970-01-17 04:53 +0000 person
231 new branch
231 new branch
232
232
233 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
233 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
234 no user, no domain
234 no user, no domain
235
235
236 2 97054abb4ab8 1970-01-14 21:20 +0000 other
236 2 97054abb4ab8 1970-01-14 21:20 +0000 other
237 no person
237 no person
238
238
239 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
239 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
240 other 1
240 other 1
241
241
242 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
242 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
243 line 1
243 line 1
244
244
245
245
246 $ hg log -v --style compact
246 $ hg log -v --style compact
247 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
247 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
248 third
248 third
249
249
250 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
250 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
251 second
251 second
252
252
253 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
253 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
254 merge
254 merge
255
255
256 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
256 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
257 new head
257 new head
258
258
259 4 bbe44766e73d 1970-01-17 04:53 +0000 person
259 4 bbe44766e73d 1970-01-17 04:53 +0000 person
260 new branch
260 new branch
261
261
262 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
262 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
263 no user, no domain
263 no user, no domain
264
264
265 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
265 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
266 no person
266 no person
267
267
268 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
268 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
269 other 1
269 other 1
270 other 2
270 other 2
271
271
272 other 3
272 other 3
273
273
274 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
274 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
275 line 1
275 line 1
276 line 2
276 line 2
277
277
278
278
279 $ hg log --debug --style compact
279 $ hg log --debug --style compact
280 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
280 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
281 third
281 third
282
282
283 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
283 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
284 second
284 second
285
285
286 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
286 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
287 merge
287 merge
288
288
289 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
289 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
290 new head
290 new head
291
291
292 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
292 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
293 new branch
293 new branch
294
294
295 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
295 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
296 no user, no domain
296 no user, no domain
297
297
298 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
298 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
299 no person
299 no person
300
300
301 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
301 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
302 other 1
302 other 1
303 other 2
303 other 2
304
304
305 other 3
305 other 3
306
306
307 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
307 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
308 line 1
308 line 1
309 line 2
309 line 2
310
310
311
311
312 Test xml styles:
312 Test xml styles:
313
313
314 $ hg log --style xml
314 $ hg log --style xml
315 <?xml version="1.0"?>
315 <?xml version="1.0"?>
316 <log>
316 <log>
317 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
317 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
318 <tag>tip</tag>
318 <tag>tip</tag>
319 <author email="test">test</author>
319 <author email="test">test</author>
320 <date>2020-01-01T10:01:00+00:00</date>
320 <date>2020-01-01T10:01:00+00:00</date>
321 <msg xml:space="preserve">third</msg>
321 <msg xml:space="preserve">third</msg>
322 </logentry>
322 </logentry>
323 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
323 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
324 <parent revision="-1" node="0000000000000000000000000000000000000000" />
324 <parent revision="-1" node="0000000000000000000000000000000000000000" />
325 <author email="user@hostname">User Name</author>
325 <author email="user@hostname">User Name</author>
326 <date>1970-01-12T13:46:40+00:00</date>
326 <date>1970-01-12T13:46:40+00:00</date>
327 <msg xml:space="preserve">second</msg>
327 <msg xml:space="preserve">second</msg>
328 </logentry>
328 </logentry>
329 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
329 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
330 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
330 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
331 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
331 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
332 <author email="person">person</author>
332 <author email="person">person</author>
333 <date>1970-01-18T08:40:01+00:00</date>
333 <date>1970-01-18T08:40:01+00:00</date>
334 <msg xml:space="preserve">merge</msg>
334 <msg xml:space="preserve">merge</msg>
335 </logentry>
335 </logentry>
336 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
336 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
337 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
337 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
338 <author email="person">person</author>
338 <author email="person">person</author>
339 <date>1970-01-18T08:40:00+00:00</date>
339 <date>1970-01-18T08:40:00+00:00</date>
340 <msg xml:space="preserve">new head</msg>
340 <msg xml:space="preserve">new head</msg>
341 </logentry>
341 </logentry>
342 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
342 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
343 <branch>foo</branch>
343 <branch>foo</branch>
344 <author email="person">person</author>
344 <author email="person">person</author>
345 <date>1970-01-17T04:53:20+00:00</date>
345 <date>1970-01-17T04:53:20+00:00</date>
346 <msg xml:space="preserve">new branch</msg>
346 <msg xml:space="preserve">new branch</msg>
347 </logentry>
347 </logentry>
348 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
348 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
349 <author email="person">person</author>
349 <author email="person">person</author>
350 <date>1970-01-16T01:06:40+00:00</date>
350 <date>1970-01-16T01:06:40+00:00</date>
351 <msg xml:space="preserve">no user, no domain</msg>
351 <msg xml:space="preserve">no user, no domain</msg>
352 </logentry>
352 </logentry>
353 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
353 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
354 <author email="other@place">other</author>
354 <author email="other@place">other</author>
355 <date>1970-01-14T21:20:00+00:00</date>
355 <date>1970-01-14T21:20:00+00:00</date>
356 <msg xml:space="preserve">no person</msg>
356 <msg xml:space="preserve">no person</msg>
357 </logentry>
357 </logentry>
358 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
358 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
359 <author email="other@place">A. N. Other</author>
359 <author email="other@place">A. N. Other</author>
360 <date>1970-01-13T17:33:20+00:00</date>
360 <date>1970-01-13T17:33:20+00:00</date>
361 <msg xml:space="preserve">other 1
361 <msg xml:space="preserve">other 1
362 other 2
362 other 2
363
363
364 other 3</msg>
364 other 3</msg>
365 </logentry>
365 </logentry>
366 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
366 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
367 <author email="user@hostname">User Name</author>
367 <author email="user@hostname">User Name</author>
368 <date>1970-01-12T13:46:40+00:00</date>
368 <date>1970-01-12T13:46:40+00:00</date>
369 <msg xml:space="preserve">line 1
369 <msg xml:space="preserve">line 1
370 line 2</msg>
370 line 2</msg>
371 </logentry>
371 </logentry>
372 </log>
372 </log>
373
373
374 $ hg log -v --style xml
374 $ hg log -v --style xml
375 <?xml version="1.0"?>
375 <?xml version="1.0"?>
376 <log>
376 <log>
377 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
377 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
378 <tag>tip</tag>
378 <tag>tip</tag>
379 <author email="test">test</author>
379 <author email="test">test</author>
380 <date>2020-01-01T10:01:00+00:00</date>
380 <date>2020-01-01T10:01:00+00:00</date>
381 <msg xml:space="preserve">third</msg>
381 <msg xml:space="preserve">third</msg>
382 <paths>
382 <paths>
383 <path action="A">fourth</path>
383 <path action="A">fourth</path>
384 <path action="A">third</path>
384 <path action="A">third</path>
385 <path action="R">second</path>
385 <path action="R">second</path>
386 </paths>
386 </paths>
387 <copies>
387 <copies>
388 <copy source="second">fourth</copy>
388 <copy source="second">fourth</copy>
389 </copies>
389 </copies>
390 </logentry>
390 </logentry>
391 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
391 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
392 <parent revision="-1" node="0000000000000000000000000000000000000000" />
392 <parent revision="-1" node="0000000000000000000000000000000000000000" />
393 <author email="user@hostname">User Name</author>
393 <author email="user@hostname">User Name</author>
394 <date>1970-01-12T13:46:40+00:00</date>
394 <date>1970-01-12T13:46:40+00:00</date>
395 <msg xml:space="preserve">second</msg>
395 <msg xml:space="preserve">second</msg>
396 <paths>
396 <paths>
397 <path action="A">second</path>
397 <path action="A">second</path>
398 </paths>
398 </paths>
399 </logentry>
399 </logentry>
400 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
400 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
401 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
401 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
402 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
402 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
403 <author email="person">person</author>
403 <author email="person">person</author>
404 <date>1970-01-18T08:40:01+00:00</date>
404 <date>1970-01-18T08:40:01+00:00</date>
405 <msg xml:space="preserve">merge</msg>
405 <msg xml:space="preserve">merge</msg>
406 <paths>
406 <paths>
407 </paths>
407 </paths>
408 </logentry>
408 </logentry>
409 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
409 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
410 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
410 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
411 <author email="person">person</author>
411 <author email="person">person</author>
412 <date>1970-01-18T08:40:00+00:00</date>
412 <date>1970-01-18T08:40:00+00:00</date>
413 <msg xml:space="preserve">new head</msg>
413 <msg xml:space="preserve">new head</msg>
414 <paths>
414 <paths>
415 <path action="A">d</path>
415 <path action="A">d</path>
416 </paths>
416 </paths>
417 </logentry>
417 </logentry>
418 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
418 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
419 <branch>foo</branch>
419 <branch>foo</branch>
420 <author email="person">person</author>
420 <author email="person">person</author>
421 <date>1970-01-17T04:53:20+00:00</date>
421 <date>1970-01-17T04:53:20+00:00</date>
422 <msg xml:space="preserve">new branch</msg>
422 <msg xml:space="preserve">new branch</msg>
423 <paths>
423 <paths>
424 </paths>
424 </paths>
425 </logentry>
425 </logentry>
426 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
426 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
427 <author email="person">person</author>
427 <author email="person">person</author>
428 <date>1970-01-16T01:06:40+00:00</date>
428 <date>1970-01-16T01:06:40+00:00</date>
429 <msg xml:space="preserve">no user, no domain</msg>
429 <msg xml:space="preserve">no user, no domain</msg>
430 <paths>
430 <paths>
431 <path action="M">c</path>
431 <path action="M">c</path>
432 </paths>
432 </paths>
433 </logentry>
433 </logentry>
434 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
434 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
435 <author email="other@place">other</author>
435 <author email="other@place">other</author>
436 <date>1970-01-14T21:20:00+00:00</date>
436 <date>1970-01-14T21:20:00+00:00</date>
437 <msg xml:space="preserve">no person</msg>
437 <msg xml:space="preserve">no person</msg>
438 <paths>
438 <paths>
439 <path action="A">c</path>
439 <path action="A">c</path>
440 </paths>
440 </paths>
441 </logentry>
441 </logentry>
442 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
442 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
443 <author email="other@place">A. N. Other</author>
443 <author email="other@place">A. N. Other</author>
444 <date>1970-01-13T17:33:20+00:00</date>
444 <date>1970-01-13T17:33:20+00:00</date>
445 <msg xml:space="preserve">other 1
445 <msg xml:space="preserve">other 1
446 other 2
446 other 2
447
447
448 other 3</msg>
448 other 3</msg>
449 <paths>
449 <paths>
450 <path action="A">b</path>
450 <path action="A">b</path>
451 </paths>
451 </paths>
452 </logentry>
452 </logentry>
453 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
453 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
454 <author email="user@hostname">User Name</author>
454 <author email="user@hostname">User Name</author>
455 <date>1970-01-12T13:46:40+00:00</date>
455 <date>1970-01-12T13:46:40+00:00</date>
456 <msg xml:space="preserve">line 1
456 <msg xml:space="preserve">line 1
457 line 2</msg>
457 line 2</msg>
458 <paths>
458 <paths>
459 <path action="A">a</path>
459 <path action="A">a</path>
460 </paths>
460 </paths>
461 </logentry>
461 </logentry>
462 </log>
462 </log>
463
463
464 $ hg log --debug --style xml
464 $ hg log --debug --style xml
465 <?xml version="1.0"?>
465 <?xml version="1.0"?>
466 <log>
466 <log>
467 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
467 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
468 <tag>tip</tag>
468 <tag>tip</tag>
469 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
469 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
470 <parent revision="-1" node="0000000000000000000000000000000000000000" />
470 <parent revision="-1" node="0000000000000000000000000000000000000000" />
471 <author email="test">test</author>
471 <author email="test">test</author>
472 <date>2020-01-01T10:01:00+00:00</date>
472 <date>2020-01-01T10:01:00+00:00</date>
473 <msg xml:space="preserve">third</msg>
473 <msg xml:space="preserve">third</msg>
474 <paths>
474 <paths>
475 <path action="A">fourth</path>
475 <path action="A">fourth</path>
476 <path action="A">third</path>
476 <path action="A">third</path>
477 <path action="R">second</path>
477 <path action="R">second</path>
478 </paths>
478 </paths>
479 <copies>
479 <copies>
480 <copy source="second">fourth</copy>
480 <copy source="second">fourth</copy>
481 </copies>
481 </copies>
482 <extra key="branch">default</extra>
482 <extra key="branch">default</extra>
483 </logentry>
483 </logentry>
484 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
484 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
485 <parent revision="-1" node="0000000000000000000000000000000000000000" />
485 <parent revision="-1" node="0000000000000000000000000000000000000000" />
486 <parent revision="-1" node="0000000000000000000000000000000000000000" />
486 <parent revision="-1" node="0000000000000000000000000000000000000000" />
487 <author email="user@hostname">User Name</author>
487 <author email="user@hostname">User Name</author>
488 <date>1970-01-12T13:46:40+00:00</date>
488 <date>1970-01-12T13:46:40+00:00</date>
489 <msg xml:space="preserve">second</msg>
489 <msg xml:space="preserve">second</msg>
490 <paths>
490 <paths>
491 <path action="A">second</path>
491 <path action="A">second</path>
492 </paths>
492 </paths>
493 <extra key="branch">default</extra>
493 <extra key="branch">default</extra>
494 </logentry>
494 </logentry>
495 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
495 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
496 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
496 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
497 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
497 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
498 <author email="person">person</author>
498 <author email="person">person</author>
499 <date>1970-01-18T08:40:01+00:00</date>
499 <date>1970-01-18T08:40:01+00:00</date>
500 <msg xml:space="preserve">merge</msg>
500 <msg xml:space="preserve">merge</msg>
501 <paths>
501 <paths>
502 </paths>
502 </paths>
503 <extra key="branch">default</extra>
503 <extra key="branch">default</extra>
504 </logentry>
504 </logentry>
505 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
505 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
506 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
506 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
507 <parent revision="-1" node="0000000000000000000000000000000000000000" />
507 <parent revision="-1" node="0000000000000000000000000000000000000000" />
508 <author email="person">person</author>
508 <author email="person">person</author>
509 <date>1970-01-18T08:40:00+00:00</date>
509 <date>1970-01-18T08:40:00+00:00</date>
510 <msg xml:space="preserve">new head</msg>
510 <msg xml:space="preserve">new head</msg>
511 <paths>
511 <paths>
512 <path action="A">d</path>
512 <path action="A">d</path>
513 </paths>
513 </paths>
514 <extra key="branch">default</extra>
514 <extra key="branch">default</extra>
515 </logentry>
515 </logentry>
516 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
516 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
517 <branch>foo</branch>
517 <branch>foo</branch>
518 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
518 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
519 <parent revision="-1" node="0000000000000000000000000000000000000000" />
519 <parent revision="-1" node="0000000000000000000000000000000000000000" />
520 <author email="person">person</author>
520 <author email="person">person</author>
521 <date>1970-01-17T04:53:20+00:00</date>
521 <date>1970-01-17T04:53:20+00:00</date>
522 <msg xml:space="preserve">new branch</msg>
522 <msg xml:space="preserve">new branch</msg>
523 <paths>
523 <paths>
524 </paths>
524 </paths>
525 <extra key="branch">foo</extra>
525 <extra key="branch">foo</extra>
526 </logentry>
526 </logentry>
527 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
527 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
528 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
528 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
529 <parent revision="-1" node="0000000000000000000000000000000000000000" />
529 <parent revision="-1" node="0000000000000000000000000000000000000000" />
530 <author email="person">person</author>
530 <author email="person">person</author>
531 <date>1970-01-16T01:06:40+00:00</date>
531 <date>1970-01-16T01:06:40+00:00</date>
532 <msg xml:space="preserve">no user, no domain</msg>
532 <msg xml:space="preserve">no user, no domain</msg>
533 <paths>
533 <paths>
534 <path action="M">c</path>
534 <path action="M">c</path>
535 </paths>
535 </paths>
536 <extra key="branch">default</extra>
536 <extra key="branch">default</extra>
537 </logentry>
537 </logentry>
538 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
538 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
539 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
539 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
540 <parent revision="-1" node="0000000000000000000000000000000000000000" />
540 <parent revision="-1" node="0000000000000000000000000000000000000000" />
541 <author email="other@place">other</author>
541 <author email="other@place">other</author>
542 <date>1970-01-14T21:20:00+00:00</date>
542 <date>1970-01-14T21:20:00+00:00</date>
543 <msg xml:space="preserve">no person</msg>
543 <msg xml:space="preserve">no person</msg>
544 <paths>
544 <paths>
545 <path action="A">c</path>
545 <path action="A">c</path>
546 </paths>
546 </paths>
547 <extra key="branch">default</extra>
547 <extra key="branch">default</extra>
548 </logentry>
548 </logentry>
549 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
549 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
550 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
550 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
551 <parent revision="-1" node="0000000000000000000000000000000000000000" />
551 <parent revision="-1" node="0000000000000000000000000000000000000000" />
552 <author email="other@place">A. N. Other</author>
552 <author email="other@place">A. N. Other</author>
553 <date>1970-01-13T17:33:20+00:00</date>
553 <date>1970-01-13T17:33:20+00:00</date>
554 <msg xml:space="preserve">other 1
554 <msg xml:space="preserve">other 1
555 other 2
555 other 2
556
556
557 other 3</msg>
557 other 3</msg>
558 <paths>
558 <paths>
559 <path action="A">b</path>
559 <path action="A">b</path>
560 </paths>
560 </paths>
561 <extra key="branch">default</extra>
561 <extra key="branch">default</extra>
562 </logentry>
562 </logentry>
563 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
563 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
564 <parent revision="-1" node="0000000000000000000000000000000000000000" />
564 <parent revision="-1" node="0000000000000000000000000000000000000000" />
565 <parent revision="-1" node="0000000000000000000000000000000000000000" />
565 <parent revision="-1" node="0000000000000000000000000000000000000000" />
566 <author email="user@hostname">User Name</author>
566 <author email="user@hostname">User Name</author>
567 <date>1970-01-12T13:46:40+00:00</date>
567 <date>1970-01-12T13:46:40+00:00</date>
568 <msg xml:space="preserve">line 1
568 <msg xml:space="preserve">line 1
569 line 2</msg>
569 line 2</msg>
570 <paths>
570 <paths>
571 <path action="A">a</path>
571 <path action="A">a</path>
572 </paths>
572 </paths>
573 <extra key="branch">default</extra>
573 <extra key="branch">default</extra>
574 </logentry>
574 </logentry>
575 </log>
575 </log>
576
576
577
577
578 Test JSON style:
578 Test JSON style:
579
579
580 $ hg log -k nosuch -Tjson
580 $ hg log -k nosuch -Tjson
581 []
581 []
582
582
583 $ hg log -qr . -Tjson
583 $ hg log -qr . -Tjson
584 [
584 [
585 {
585 {
586 "rev": 8,
586 "rev": 8,
587 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
587 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
588 }
588 }
589 ]
589 ]
590
590
591 $ hg log -vpr . -Tjson --stat
591 $ hg log -vpr . -Tjson --stat
592 [
592 [
593 {
593 {
594 "rev": 8,
594 "rev": 8,
595 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
595 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
596 "branch": "default",
596 "branch": "default",
597 "phase": "draft",
597 "phase": "draft",
598 "user": "test",
598 "user": "test",
599 "date": [1577872860, 0],
599 "date": [1577872860, 0],
600 "desc": "third",
600 "desc": "third",
601 "bookmarks": [],
601 "bookmarks": [],
602 "tags": ["tip"],
602 "tags": ["tip"],
603 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
603 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
604 "files": ["fourth", "second", "third"],
604 "files": ["fourth", "second", "third"],
605 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
605 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
606 "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"
606 "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"
607 }
607 }
608 ]
608 ]
609
609
610 honor --git but not format-breaking diffopts
610 honor --git but not format-breaking diffopts
611 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
611 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
612 [
612 [
613 {
613 {
614 "rev": 8,
614 "rev": 8,
615 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
615 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
616 "branch": "default",
616 "branch": "default",
617 "phase": "draft",
617 "phase": "draft",
618 "user": "test",
618 "user": "test",
619 "date": [1577872860, 0],
619 "date": [1577872860, 0],
620 "desc": "third",
620 "desc": "third",
621 "bookmarks": [],
621 "bookmarks": [],
622 "tags": ["tip"],
622 "tags": ["tip"],
623 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
623 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
624 "files": ["fourth", "second", "third"],
624 "files": ["fourth", "second", "third"],
625 "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"
625 "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"
626 }
626 }
627 ]
627 ]
628
628
629 $ hg log -T json
629 $ hg log -T json
630 [
630 [
631 {
631 {
632 "rev": 8,
632 "rev": 8,
633 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
633 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
634 "branch": "default",
634 "branch": "default",
635 "phase": "draft",
635 "phase": "draft",
636 "user": "test",
636 "user": "test",
637 "date": [1577872860, 0],
637 "date": [1577872860, 0],
638 "desc": "third",
638 "desc": "third",
639 "bookmarks": [],
639 "bookmarks": [],
640 "tags": ["tip"],
640 "tags": ["tip"],
641 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
641 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
642 },
642 },
643 {
643 {
644 "rev": 7,
644 "rev": 7,
645 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
645 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
646 "branch": "default",
646 "branch": "default",
647 "phase": "draft",
647 "phase": "draft",
648 "user": "User Name <user@hostname>",
648 "user": "User Name <user@hostname>",
649 "date": [1000000, 0],
649 "date": [1000000, 0],
650 "desc": "second",
650 "desc": "second",
651 "bookmarks": [],
651 "bookmarks": [],
652 "tags": [],
652 "tags": [],
653 "parents": ["0000000000000000000000000000000000000000"]
653 "parents": ["0000000000000000000000000000000000000000"]
654 },
654 },
655 {
655 {
656 "rev": 6,
656 "rev": 6,
657 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
657 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
658 "branch": "default",
658 "branch": "default",
659 "phase": "draft",
659 "phase": "draft",
660 "user": "person",
660 "user": "person",
661 "date": [1500001, 0],
661 "date": [1500001, 0],
662 "desc": "merge",
662 "desc": "merge",
663 "bookmarks": [],
663 "bookmarks": [],
664 "tags": [],
664 "tags": [],
665 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
665 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
666 },
666 },
667 {
667 {
668 "rev": 5,
668 "rev": 5,
669 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
669 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
670 "branch": "default",
670 "branch": "default",
671 "phase": "draft",
671 "phase": "draft",
672 "user": "person",
672 "user": "person",
673 "date": [1500000, 0],
673 "date": [1500000, 0],
674 "desc": "new head",
674 "desc": "new head",
675 "bookmarks": [],
675 "bookmarks": [],
676 "tags": [],
676 "tags": [],
677 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
677 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
678 },
678 },
679 {
679 {
680 "rev": 4,
680 "rev": 4,
681 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
681 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
682 "branch": "foo",
682 "branch": "foo",
683 "phase": "draft",
683 "phase": "draft",
684 "user": "person",
684 "user": "person",
685 "date": [1400000, 0],
685 "date": [1400000, 0],
686 "desc": "new branch",
686 "desc": "new branch",
687 "bookmarks": [],
687 "bookmarks": [],
688 "tags": [],
688 "tags": [],
689 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
689 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
690 },
690 },
691 {
691 {
692 "rev": 3,
692 "rev": 3,
693 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
693 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
694 "branch": "default",
694 "branch": "default",
695 "phase": "draft",
695 "phase": "draft",
696 "user": "person",
696 "user": "person",
697 "date": [1300000, 0],
697 "date": [1300000, 0],
698 "desc": "no user, no domain",
698 "desc": "no user, no domain",
699 "bookmarks": [],
699 "bookmarks": [],
700 "tags": [],
700 "tags": [],
701 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
701 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
702 },
702 },
703 {
703 {
704 "rev": 2,
704 "rev": 2,
705 "node": "97054abb4ab824450e9164180baf491ae0078465",
705 "node": "97054abb4ab824450e9164180baf491ae0078465",
706 "branch": "default",
706 "branch": "default",
707 "phase": "draft",
707 "phase": "draft",
708 "user": "other@place",
708 "user": "other@place",
709 "date": [1200000, 0],
709 "date": [1200000, 0],
710 "desc": "no person",
710 "desc": "no person",
711 "bookmarks": [],
711 "bookmarks": [],
712 "tags": [],
712 "tags": [],
713 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
713 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
714 },
714 },
715 {
715 {
716 "rev": 1,
716 "rev": 1,
717 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
717 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
718 "branch": "default",
718 "branch": "default",
719 "phase": "draft",
719 "phase": "draft",
720 "user": "A. N. Other <other@place>",
720 "user": "A. N. Other <other@place>",
721 "date": [1100000, 0],
721 "date": [1100000, 0],
722 "desc": "other 1\nother 2\n\nother 3",
722 "desc": "other 1\nother 2\n\nother 3",
723 "bookmarks": [],
723 "bookmarks": [],
724 "tags": [],
724 "tags": [],
725 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
725 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
726 },
726 },
727 {
727 {
728 "rev": 0,
728 "rev": 0,
729 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
729 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
730 "branch": "default",
730 "branch": "default",
731 "phase": "draft",
731 "phase": "draft",
732 "user": "User Name <user@hostname>",
732 "user": "User Name <user@hostname>",
733 "date": [1000000, 0],
733 "date": [1000000, 0],
734 "desc": "line 1\nline 2",
734 "desc": "line 1\nline 2",
735 "bookmarks": [],
735 "bookmarks": [],
736 "tags": [],
736 "tags": [],
737 "parents": ["0000000000000000000000000000000000000000"]
737 "parents": ["0000000000000000000000000000000000000000"]
738 }
738 }
739 ]
739 ]
740
740
741 $ hg heads -v -Tjson
741 $ hg heads -v -Tjson
742 [
742 [
743 {
743 {
744 "rev": 8,
744 "rev": 8,
745 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
745 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
746 "branch": "default",
746 "branch": "default",
747 "phase": "draft",
747 "phase": "draft",
748 "user": "test",
748 "user": "test",
749 "date": [1577872860, 0],
749 "date": [1577872860, 0],
750 "desc": "third",
750 "desc": "third",
751 "bookmarks": [],
751 "bookmarks": [],
752 "tags": ["tip"],
752 "tags": ["tip"],
753 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
753 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
754 "files": ["fourth", "second", "third"]
754 "files": ["fourth", "second", "third"]
755 },
755 },
756 {
756 {
757 "rev": 6,
757 "rev": 6,
758 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
758 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
759 "branch": "default",
759 "branch": "default",
760 "phase": "draft",
760 "phase": "draft",
761 "user": "person",
761 "user": "person",
762 "date": [1500001, 0],
762 "date": [1500001, 0],
763 "desc": "merge",
763 "desc": "merge",
764 "bookmarks": [],
764 "bookmarks": [],
765 "tags": [],
765 "tags": [],
766 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
766 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
767 "files": []
767 "files": []
768 },
768 },
769 {
769 {
770 "rev": 4,
770 "rev": 4,
771 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
771 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
772 "branch": "foo",
772 "branch": "foo",
773 "phase": "draft",
773 "phase": "draft",
774 "user": "person",
774 "user": "person",
775 "date": [1400000, 0],
775 "date": [1400000, 0],
776 "desc": "new branch",
776 "desc": "new branch",
777 "bookmarks": [],
777 "bookmarks": [],
778 "tags": [],
778 "tags": [],
779 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
779 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
780 "files": []
780 "files": []
781 }
781 }
782 ]
782 ]
783
783
784 $ hg log --debug -Tjson
784 $ hg log --debug -Tjson
785 [
785 [
786 {
786 {
787 "rev": 8,
787 "rev": 8,
788 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
788 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
789 "branch": "default",
789 "branch": "default",
790 "phase": "draft",
790 "phase": "draft",
791 "user": "test",
791 "user": "test",
792 "date": [1577872860, 0],
792 "date": [1577872860, 0],
793 "desc": "third",
793 "desc": "third",
794 "bookmarks": [],
794 "bookmarks": [],
795 "tags": ["tip"],
795 "tags": ["tip"],
796 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
796 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
797 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
797 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
798 "extra": {"branch": "default"},
798 "extra": {"branch": "default"},
799 "modified": [],
799 "modified": [],
800 "added": ["fourth", "third"],
800 "added": ["fourth", "third"],
801 "removed": ["second"]
801 "removed": ["second"]
802 },
802 },
803 {
803 {
804 "rev": 7,
804 "rev": 7,
805 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
805 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
806 "branch": "default",
806 "branch": "default",
807 "phase": "draft",
807 "phase": "draft",
808 "user": "User Name <user@hostname>",
808 "user": "User Name <user@hostname>",
809 "date": [1000000, 0],
809 "date": [1000000, 0],
810 "desc": "second",
810 "desc": "second",
811 "bookmarks": [],
811 "bookmarks": [],
812 "tags": [],
812 "tags": [],
813 "parents": ["0000000000000000000000000000000000000000"],
813 "parents": ["0000000000000000000000000000000000000000"],
814 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
814 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
815 "extra": {"branch": "default"},
815 "extra": {"branch": "default"},
816 "modified": [],
816 "modified": [],
817 "added": ["second"],
817 "added": ["second"],
818 "removed": []
818 "removed": []
819 },
819 },
820 {
820 {
821 "rev": 6,
821 "rev": 6,
822 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
822 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
823 "branch": "default",
823 "branch": "default",
824 "phase": "draft",
824 "phase": "draft",
825 "user": "person",
825 "user": "person",
826 "date": [1500001, 0],
826 "date": [1500001, 0],
827 "desc": "merge",
827 "desc": "merge",
828 "bookmarks": [],
828 "bookmarks": [],
829 "tags": [],
829 "tags": [],
830 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
830 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
831 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
831 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
832 "extra": {"branch": "default"},
832 "extra": {"branch": "default"},
833 "modified": [],
833 "modified": [],
834 "added": [],
834 "added": [],
835 "removed": []
835 "removed": []
836 },
836 },
837 {
837 {
838 "rev": 5,
838 "rev": 5,
839 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
839 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
840 "branch": "default",
840 "branch": "default",
841 "phase": "draft",
841 "phase": "draft",
842 "user": "person",
842 "user": "person",
843 "date": [1500000, 0],
843 "date": [1500000, 0],
844 "desc": "new head",
844 "desc": "new head",
845 "bookmarks": [],
845 "bookmarks": [],
846 "tags": [],
846 "tags": [],
847 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
847 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
848 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
848 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
849 "extra": {"branch": "default"},
849 "extra": {"branch": "default"},
850 "modified": [],
850 "modified": [],
851 "added": ["d"],
851 "added": ["d"],
852 "removed": []
852 "removed": []
853 },
853 },
854 {
854 {
855 "rev": 4,
855 "rev": 4,
856 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
856 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
857 "branch": "foo",
857 "branch": "foo",
858 "phase": "draft",
858 "phase": "draft",
859 "user": "person",
859 "user": "person",
860 "date": [1400000, 0],
860 "date": [1400000, 0],
861 "desc": "new branch",
861 "desc": "new branch",
862 "bookmarks": [],
862 "bookmarks": [],
863 "tags": [],
863 "tags": [],
864 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
864 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
865 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
865 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
866 "extra": {"branch": "foo"},
866 "extra": {"branch": "foo"},
867 "modified": [],
867 "modified": [],
868 "added": [],
868 "added": [],
869 "removed": []
869 "removed": []
870 },
870 },
871 {
871 {
872 "rev": 3,
872 "rev": 3,
873 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
873 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
874 "branch": "default",
874 "branch": "default",
875 "phase": "draft",
875 "phase": "draft",
876 "user": "person",
876 "user": "person",
877 "date": [1300000, 0],
877 "date": [1300000, 0],
878 "desc": "no user, no domain",
878 "desc": "no user, no domain",
879 "bookmarks": [],
879 "bookmarks": [],
880 "tags": [],
880 "tags": [],
881 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
881 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
882 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
882 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
883 "extra": {"branch": "default"},
883 "extra": {"branch": "default"},
884 "modified": ["c"],
884 "modified": ["c"],
885 "added": [],
885 "added": [],
886 "removed": []
886 "removed": []
887 },
887 },
888 {
888 {
889 "rev": 2,
889 "rev": 2,
890 "node": "97054abb4ab824450e9164180baf491ae0078465",
890 "node": "97054abb4ab824450e9164180baf491ae0078465",
891 "branch": "default",
891 "branch": "default",
892 "phase": "draft",
892 "phase": "draft",
893 "user": "other@place",
893 "user": "other@place",
894 "date": [1200000, 0],
894 "date": [1200000, 0],
895 "desc": "no person",
895 "desc": "no person",
896 "bookmarks": [],
896 "bookmarks": [],
897 "tags": [],
897 "tags": [],
898 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
898 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
899 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
899 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
900 "extra": {"branch": "default"},
900 "extra": {"branch": "default"},
901 "modified": [],
901 "modified": [],
902 "added": ["c"],
902 "added": ["c"],
903 "removed": []
903 "removed": []
904 },
904 },
905 {
905 {
906 "rev": 1,
906 "rev": 1,
907 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
907 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
908 "branch": "default",
908 "branch": "default",
909 "phase": "draft",
909 "phase": "draft",
910 "user": "A. N. Other <other@place>",
910 "user": "A. N. Other <other@place>",
911 "date": [1100000, 0],
911 "date": [1100000, 0],
912 "desc": "other 1\nother 2\n\nother 3",
912 "desc": "other 1\nother 2\n\nother 3",
913 "bookmarks": [],
913 "bookmarks": [],
914 "tags": [],
914 "tags": [],
915 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
915 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
916 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
916 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
917 "extra": {"branch": "default"},
917 "extra": {"branch": "default"},
918 "modified": [],
918 "modified": [],
919 "added": ["b"],
919 "added": ["b"],
920 "removed": []
920 "removed": []
921 },
921 },
922 {
922 {
923 "rev": 0,
923 "rev": 0,
924 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
924 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
925 "branch": "default",
925 "branch": "default",
926 "phase": "draft",
926 "phase": "draft",
927 "user": "User Name <user@hostname>",
927 "user": "User Name <user@hostname>",
928 "date": [1000000, 0],
928 "date": [1000000, 0],
929 "desc": "line 1\nline 2",
929 "desc": "line 1\nline 2",
930 "bookmarks": [],
930 "bookmarks": [],
931 "tags": [],
931 "tags": [],
932 "parents": ["0000000000000000000000000000000000000000"],
932 "parents": ["0000000000000000000000000000000000000000"],
933 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
933 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
934 "extra": {"branch": "default"},
934 "extra": {"branch": "default"},
935 "modified": [],
935 "modified": [],
936 "added": ["a"],
936 "added": ["a"],
937 "removed": []
937 "removed": []
938 }
938 }
939 ]
939 ]
940
940
941 Error if style not readable:
941 Error if style not readable:
942
942
943 #if unix-permissions no-root
943 #if unix-permissions no-root
944 $ touch q
944 $ touch q
945 $ chmod 0 q
945 $ chmod 0 q
946 $ hg log --style ./q
946 $ hg log --style ./q
947 abort: Permission denied: ./q
947 abort: Permission denied: ./q
948 [255]
948 [255]
949 #endif
949 #endif
950
950
951 Error if no style:
951 Error if no style:
952
952
953 $ hg log --style notexist
953 $ hg log --style notexist
954 abort: style 'notexist' not found
954 abort: style 'notexist' not found
955 (available styles: bisect, changelog, compact, default, phases, xml)
955 (available styles: bisect, changelog, compact, default, phases, xml)
956 [255]
956 [255]
957
957
958 $ hg log -T list
958 $ hg log -T list
959 available styles: bisect, changelog, compact, default, phases, xml
959 available styles: bisect, changelog, compact, default, phases, xml
960 abort: specify a template
960 abort: specify a template
961 [255]
961 [255]
962
962
963 Error if style missing key:
963 Error if style missing key:
964
964
965 $ echo 'q = q' > t
965 $ echo 'q = q' > t
966 $ hg log --style ./t
966 $ hg log --style ./t
967 abort: "changeset" not in template map
967 abort: "changeset" not in template map
968 [255]
968 [255]
969
969
970 Error if style missing value:
970 Error if style missing value:
971
971
972 $ echo 'changeset =' > t
972 $ echo 'changeset =' > t
973 $ hg log --style t
973 $ hg log --style t
974 abort: t:1: missing value
974 abort: t:1: missing value
975 [255]
975 [255]
976
976
977 Error if include fails:
977 Error if include fails:
978
978
979 $ echo 'changeset = q' >> t
979 $ echo 'changeset = q' >> t
980 #if unix-permissions no-root
980 #if unix-permissions no-root
981 $ hg log --style ./t
981 $ hg log --style ./t
982 abort: template file ./q: Permission denied
982 abort: template file ./q: Permission denied
983 [255]
983 [255]
984 $ rm q
984 $ rm q
985 #endif
985 #endif
986
986
987 Include works:
987 Include works:
988
988
989 $ echo '{rev}' > q
989 $ echo '{rev}' > q
990 $ hg log --style ./t
990 $ hg log --style ./t
991 8
991 8
992 7
992 7
993 6
993 6
994 5
994 5
995 4
995 4
996 3
996 3
997 2
997 2
998 1
998 1
999 0
999 0
1000
1000
1001 Check that {phase} works correctly on parents:
1001 Check that {phase} works correctly on parents:
1002
1002
1003 $ cat << EOF > parentphase
1003 $ cat << EOF > parentphase
1004 > changeset_debug = '{rev} ({phase}):{parents}\n'
1004 > changeset_debug = '{rev} ({phase}):{parents}\n'
1005 > parent = ' {rev} ({phase})'
1005 > parent = ' {rev} ({phase})'
1006 > EOF
1006 > EOF
1007 $ hg phase -r 5 --public
1007 $ hg phase -r 5 --public
1008 $ hg phase -r 7 --secret --force
1008 $ hg phase -r 7 --secret --force
1009 $ hg log --debug -G --style ./parentphase
1009 $ hg log --debug -G --style ./parentphase
1010 @ 8 (secret): 7 (secret) -1 (public)
1010 @ 8 (secret): 7 (secret) -1 (public)
1011 |
1011 |
1012 o 7 (secret): -1 (public) -1 (public)
1012 o 7 (secret): -1 (public) -1 (public)
1013
1013
1014 o 6 (draft): 5 (public) 4 (draft)
1014 o 6 (draft): 5 (public) 4 (draft)
1015 |\
1015 |\
1016 | o 5 (public): 3 (public) -1 (public)
1016 | o 5 (public): 3 (public) -1 (public)
1017 | |
1017 | |
1018 o | 4 (draft): 3 (public) -1 (public)
1018 o | 4 (draft): 3 (public) -1 (public)
1019 |/
1019 |/
1020 o 3 (public): 2 (public) -1 (public)
1020 o 3 (public): 2 (public) -1 (public)
1021 |
1021 |
1022 o 2 (public): 1 (public) -1 (public)
1022 o 2 (public): 1 (public) -1 (public)
1023 |
1023 |
1024 o 1 (public): 0 (public) -1 (public)
1024 o 1 (public): 0 (public) -1 (public)
1025 |
1025 |
1026 o 0 (public): -1 (public) -1 (public)
1026 o 0 (public): -1 (public) -1 (public)
1027
1027
1028
1028
1029 Missing non-standard names give no error (backward compatibility):
1029 Missing non-standard names give no error (backward compatibility):
1030
1030
1031 $ echo "changeset = '{c}'" > t
1031 $ echo "changeset = '{c}'" > t
1032 $ hg log --style ./t
1032 $ hg log --style ./t
1033
1033
1034 Defining non-standard name works:
1034 Defining non-standard name works:
1035
1035
1036 $ cat <<EOF > t
1036 $ cat <<EOF > t
1037 > changeset = '{c}'
1037 > changeset = '{c}'
1038 > c = q
1038 > c = q
1039 > EOF
1039 > EOF
1040 $ hg log --style ./t
1040 $ hg log --style ./t
1041 8
1041 8
1042 7
1042 7
1043 6
1043 6
1044 5
1044 5
1045 4
1045 4
1046 3
1046 3
1047 2
1047 2
1048 1
1048 1
1049 0
1049 0
1050
1050
1051 ui.style works:
1051 ui.style works:
1052
1052
1053 $ echo '[ui]' > .hg/hgrc
1053 $ echo '[ui]' > .hg/hgrc
1054 $ echo 'style = t' >> .hg/hgrc
1054 $ echo 'style = t' >> .hg/hgrc
1055 $ hg log
1055 $ hg log
1056 8
1056 8
1057 7
1057 7
1058 6
1058 6
1059 5
1059 5
1060 4
1060 4
1061 3
1061 3
1062 2
1062 2
1063 1
1063 1
1064 0
1064 0
1065
1065
1066
1066
1067 Issue338:
1067 Issue338:
1068
1068
1069 $ hg log --style=changelog > changelog
1069 $ hg log --style=changelog > changelog
1070
1070
1071 $ cat changelog
1071 $ cat changelog
1072 2020-01-01 test <test>
1072 2020-01-01 test <test>
1073
1073
1074 * fourth, second, third:
1074 * fourth, second, third:
1075 third
1075 third
1076 [95c24699272e] [tip]
1076 [95c24699272e] [tip]
1077
1077
1078 1970-01-12 User Name <user@hostname>
1078 1970-01-12 User Name <user@hostname>
1079
1079
1080 * second:
1080 * second:
1081 second
1081 second
1082 [29114dbae42b]
1082 [29114dbae42b]
1083
1083
1084 1970-01-18 person <person>
1084 1970-01-18 person <person>
1085
1085
1086 * merge
1086 * merge
1087 [d41e714fe50d]
1087 [d41e714fe50d]
1088
1088
1089 * d:
1089 * d:
1090 new head
1090 new head
1091 [13207e5a10d9]
1091 [13207e5a10d9]
1092
1092
1093 1970-01-17 person <person>
1093 1970-01-17 person <person>
1094
1094
1095 * new branch
1095 * new branch
1096 [bbe44766e73d] <foo>
1096 [bbe44766e73d] <foo>
1097
1097
1098 1970-01-16 person <person>
1098 1970-01-16 person <person>
1099
1099
1100 * c:
1100 * c:
1101 no user, no domain
1101 no user, no domain
1102 [10e46f2dcbf4]
1102 [10e46f2dcbf4]
1103
1103
1104 1970-01-14 other <other@place>
1104 1970-01-14 other <other@place>
1105
1105
1106 * c:
1106 * c:
1107 no person
1107 no person
1108 [97054abb4ab8]
1108 [97054abb4ab8]
1109
1109
1110 1970-01-13 A. N. Other <other@place>
1110 1970-01-13 A. N. Other <other@place>
1111
1111
1112 * b:
1112 * b:
1113 other 1 other 2
1113 other 1 other 2
1114
1114
1115 other 3
1115 other 3
1116 [b608e9d1a3f0]
1116 [b608e9d1a3f0]
1117
1117
1118 1970-01-12 User Name <user@hostname>
1118 1970-01-12 User Name <user@hostname>
1119
1119
1120 * a:
1120 * a:
1121 line 1 line 2
1121 line 1 line 2
1122 [1e4e1b8f71e0]
1122 [1e4e1b8f71e0]
1123
1123
1124
1124
1125 Issue2130: xml output for 'hg heads' is malformed
1125 Issue2130: xml output for 'hg heads' is malformed
1126
1126
1127 $ hg heads --style changelog
1127 $ hg heads --style changelog
1128 2020-01-01 test <test>
1128 2020-01-01 test <test>
1129
1129
1130 * fourth, second, third:
1130 * fourth, second, third:
1131 third
1131 third
1132 [95c24699272e] [tip]
1132 [95c24699272e] [tip]
1133
1133
1134 1970-01-18 person <person>
1134 1970-01-18 person <person>
1135
1135
1136 * merge
1136 * merge
1137 [d41e714fe50d]
1137 [d41e714fe50d]
1138
1138
1139 1970-01-17 person <person>
1139 1970-01-17 person <person>
1140
1140
1141 * new branch
1141 * new branch
1142 [bbe44766e73d] <foo>
1142 [bbe44766e73d] <foo>
1143
1143
1144
1144
1145 Keys work:
1145 Keys work:
1146
1146
1147 $ for key in author branch branches date desc file_adds file_dels file_mods \
1147 $ for key in author branch branches date desc file_adds file_dels file_mods \
1148 > file_copies file_copies_switch files \
1148 > file_copies file_copies_switch files \
1149 > manifest node parents rev tags diffstat extras \
1149 > manifest node parents rev tags diffstat extras \
1150 > p1rev p2rev p1node p2node; do
1150 > p1rev p2rev p1node p2node; do
1151 > for mode in '' --verbose --debug; do
1151 > for mode in '' --verbose --debug; do
1152 > hg log $mode --template "$key$mode: {$key}\n"
1152 > hg log $mode --template "$key$mode: {$key}\n"
1153 > done
1153 > done
1154 > done
1154 > done
1155 author: test
1155 author: test
1156 author: User Name <user@hostname>
1156 author: User Name <user@hostname>
1157 author: person
1157 author: person
1158 author: person
1158 author: person
1159 author: person
1159 author: person
1160 author: person
1160 author: person
1161 author: other@place
1161 author: other@place
1162 author: A. N. Other <other@place>
1162 author: A. N. Other <other@place>
1163 author: User Name <user@hostname>
1163 author: User Name <user@hostname>
1164 author--verbose: test
1164 author--verbose: test
1165 author--verbose: User Name <user@hostname>
1165 author--verbose: User Name <user@hostname>
1166 author--verbose: person
1166 author--verbose: person
1167 author--verbose: person
1167 author--verbose: person
1168 author--verbose: person
1168 author--verbose: person
1169 author--verbose: person
1169 author--verbose: person
1170 author--verbose: other@place
1170 author--verbose: other@place
1171 author--verbose: A. N. Other <other@place>
1171 author--verbose: A. N. Other <other@place>
1172 author--verbose: User Name <user@hostname>
1172 author--verbose: User Name <user@hostname>
1173 author--debug: test
1173 author--debug: test
1174 author--debug: User Name <user@hostname>
1174 author--debug: User Name <user@hostname>
1175 author--debug: person
1175 author--debug: person
1176 author--debug: person
1176 author--debug: person
1177 author--debug: person
1177 author--debug: person
1178 author--debug: person
1178 author--debug: person
1179 author--debug: other@place
1179 author--debug: other@place
1180 author--debug: A. N. Other <other@place>
1180 author--debug: A. N. Other <other@place>
1181 author--debug: User Name <user@hostname>
1181 author--debug: User Name <user@hostname>
1182 branch: default
1182 branch: default
1183 branch: default
1183 branch: default
1184 branch: default
1184 branch: default
1185 branch: default
1185 branch: default
1186 branch: foo
1186 branch: foo
1187 branch: default
1187 branch: default
1188 branch: default
1188 branch: default
1189 branch: default
1189 branch: default
1190 branch: default
1190 branch: default
1191 branch--verbose: default
1191 branch--verbose: default
1192 branch--verbose: default
1192 branch--verbose: default
1193 branch--verbose: default
1193 branch--verbose: default
1194 branch--verbose: default
1194 branch--verbose: default
1195 branch--verbose: foo
1195 branch--verbose: foo
1196 branch--verbose: default
1196 branch--verbose: default
1197 branch--verbose: default
1197 branch--verbose: default
1198 branch--verbose: default
1198 branch--verbose: default
1199 branch--verbose: default
1199 branch--verbose: default
1200 branch--debug: default
1200 branch--debug: default
1201 branch--debug: default
1201 branch--debug: default
1202 branch--debug: default
1202 branch--debug: default
1203 branch--debug: default
1203 branch--debug: default
1204 branch--debug: foo
1204 branch--debug: foo
1205 branch--debug: default
1205 branch--debug: default
1206 branch--debug: default
1206 branch--debug: default
1207 branch--debug: default
1207 branch--debug: default
1208 branch--debug: default
1208 branch--debug: default
1209 branches:
1209 branches:
1210 branches:
1210 branches:
1211 branches:
1211 branches:
1212 branches:
1212 branches:
1213 branches: foo
1213 branches: foo
1214 branches:
1214 branches:
1215 branches:
1215 branches:
1216 branches:
1216 branches:
1217 branches:
1217 branches:
1218 branches--verbose:
1218 branches--verbose:
1219 branches--verbose:
1219 branches--verbose:
1220 branches--verbose:
1220 branches--verbose:
1221 branches--verbose:
1221 branches--verbose:
1222 branches--verbose: foo
1222 branches--verbose: foo
1223 branches--verbose:
1223 branches--verbose:
1224 branches--verbose:
1224 branches--verbose:
1225 branches--verbose:
1225 branches--verbose:
1226 branches--verbose:
1226 branches--verbose:
1227 branches--debug:
1227 branches--debug:
1228 branches--debug:
1228 branches--debug:
1229 branches--debug:
1229 branches--debug:
1230 branches--debug:
1230 branches--debug:
1231 branches--debug: foo
1231 branches--debug: foo
1232 branches--debug:
1232 branches--debug:
1233 branches--debug:
1233 branches--debug:
1234 branches--debug:
1234 branches--debug:
1235 branches--debug:
1235 branches--debug:
1236 date: 1577872860.00
1236 date: 1577872860.00
1237 date: 1000000.00
1237 date: 1000000.00
1238 date: 1500001.00
1238 date: 1500001.00
1239 date: 1500000.00
1239 date: 1500000.00
1240 date: 1400000.00
1240 date: 1400000.00
1241 date: 1300000.00
1241 date: 1300000.00
1242 date: 1200000.00
1242 date: 1200000.00
1243 date: 1100000.00
1243 date: 1100000.00
1244 date: 1000000.00
1244 date: 1000000.00
1245 date--verbose: 1577872860.00
1245 date--verbose: 1577872860.00
1246 date--verbose: 1000000.00
1246 date--verbose: 1000000.00
1247 date--verbose: 1500001.00
1247 date--verbose: 1500001.00
1248 date--verbose: 1500000.00
1248 date--verbose: 1500000.00
1249 date--verbose: 1400000.00
1249 date--verbose: 1400000.00
1250 date--verbose: 1300000.00
1250 date--verbose: 1300000.00
1251 date--verbose: 1200000.00
1251 date--verbose: 1200000.00
1252 date--verbose: 1100000.00
1252 date--verbose: 1100000.00
1253 date--verbose: 1000000.00
1253 date--verbose: 1000000.00
1254 date--debug: 1577872860.00
1254 date--debug: 1577872860.00
1255 date--debug: 1000000.00
1255 date--debug: 1000000.00
1256 date--debug: 1500001.00
1256 date--debug: 1500001.00
1257 date--debug: 1500000.00
1257 date--debug: 1500000.00
1258 date--debug: 1400000.00
1258 date--debug: 1400000.00
1259 date--debug: 1300000.00
1259 date--debug: 1300000.00
1260 date--debug: 1200000.00
1260 date--debug: 1200000.00
1261 date--debug: 1100000.00
1261 date--debug: 1100000.00
1262 date--debug: 1000000.00
1262 date--debug: 1000000.00
1263 desc: third
1263 desc: third
1264 desc: second
1264 desc: second
1265 desc: merge
1265 desc: merge
1266 desc: new head
1266 desc: new head
1267 desc: new branch
1267 desc: new branch
1268 desc: no user, no domain
1268 desc: no user, no domain
1269 desc: no person
1269 desc: no person
1270 desc: other 1
1270 desc: other 1
1271 other 2
1271 other 2
1272
1272
1273 other 3
1273 other 3
1274 desc: line 1
1274 desc: line 1
1275 line 2
1275 line 2
1276 desc--verbose: third
1276 desc--verbose: third
1277 desc--verbose: second
1277 desc--verbose: second
1278 desc--verbose: merge
1278 desc--verbose: merge
1279 desc--verbose: new head
1279 desc--verbose: new head
1280 desc--verbose: new branch
1280 desc--verbose: new branch
1281 desc--verbose: no user, no domain
1281 desc--verbose: no user, no domain
1282 desc--verbose: no person
1282 desc--verbose: no person
1283 desc--verbose: other 1
1283 desc--verbose: other 1
1284 other 2
1284 other 2
1285
1285
1286 other 3
1286 other 3
1287 desc--verbose: line 1
1287 desc--verbose: line 1
1288 line 2
1288 line 2
1289 desc--debug: third
1289 desc--debug: third
1290 desc--debug: second
1290 desc--debug: second
1291 desc--debug: merge
1291 desc--debug: merge
1292 desc--debug: new head
1292 desc--debug: new head
1293 desc--debug: new branch
1293 desc--debug: new branch
1294 desc--debug: no user, no domain
1294 desc--debug: no user, no domain
1295 desc--debug: no person
1295 desc--debug: no person
1296 desc--debug: other 1
1296 desc--debug: other 1
1297 other 2
1297 other 2
1298
1298
1299 other 3
1299 other 3
1300 desc--debug: line 1
1300 desc--debug: line 1
1301 line 2
1301 line 2
1302 file_adds: fourth third
1302 file_adds: fourth third
1303 file_adds: second
1303 file_adds: second
1304 file_adds:
1304 file_adds:
1305 file_adds: d
1305 file_adds: d
1306 file_adds:
1306 file_adds:
1307 file_adds:
1307 file_adds:
1308 file_adds: c
1308 file_adds: c
1309 file_adds: b
1309 file_adds: b
1310 file_adds: a
1310 file_adds: a
1311 file_adds--verbose: fourth third
1311 file_adds--verbose: fourth third
1312 file_adds--verbose: second
1312 file_adds--verbose: second
1313 file_adds--verbose:
1313 file_adds--verbose:
1314 file_adds--verbose: d
1314 file_adds--verbose: d
1315 file_adds--verbose:
1315 file_adds--verbose:
1316 file_adds--verbose:
1316 file_adds--verbose:
1317 file_adds--verbose: c
1317 file_adds--verbose: c
1318 file_adds--verbose: b
1318 file_adds--verbose: b
1319 file_adds--verbose: a
1319 file_adds--verbose: a
1320 file_adds--debug: fourth third
1320 file_adds--debug: fourth third
1321 file_adds--debug: second
1321 file_adds--debug: second
1322 file_adds--debug:
1322 file_adds--debug:
1323 file_adds--debug: d
1323 file_adds--debug: d
1324 file_adds--debug:
1324 file_adds--debug:
1325 file_adds--debug:
1325 file_adds--debug:
1326 file_adds--debug: c
1326 file_adds--debug: c
1327 file_adds--debug: b
1327 file_adds--debug: b
1328 file_adds--debug: a
1328 file_adds--debug: a
1329 file_dels: second
1329 file_dels: second
1330 file_dels:
1330 file_dels:
1331 file_dels:
1331 file_dels:
1332 file_dels:
1332 file_dels:
1333 file_dels:
1333 file_dels:
1334 file_dels:
1334 file_dels:
1335 file_dels:
1335 file_dels:
1336 file_dels:
1336 file_dels:
1337 file_dels:
1337 file_dels:
1338 file_dels--verbose: second
1338 file_dels--verbose: second
1339 file_dels--verbose:
1339 file_dels--verbose:
1340 file_dels--verbose:
1340 file_dels--verbose:
1341 file_dels--verbose:
1341 file_dels--verbose:
1342 file_dels--verbose:
1342 file_dels--verbose:
1343 file_dels--verbose:
1343 file_dels--verbose:
1344 file_dels--verbose:
1344 file_dels--verbose:
1345 file_dels--verbose:
1345 file_dels--verbose:
1346 file_dels--verbose:
1346 file_dels--verbose:
1347 file_dels--debug: second
1347 file_dels--debug: second
1348 file_dels--debug:
1348 file_dels--debug:
1349 file_dels--debug:
1349 file_dels--debug:
1350 file_dels--debug:
1350 file_dels--debug:
1351 file_dels--debug:
1351 file_dels--debug:
1352 file_dels--debug:
1352 file_dels--debug:
1353 file_dels--debug:
1353 file_dels--debug:
1354 file_dels--debug:
1354 file_dels--debug:
1355 file_dels--debug:
1355 file_dels--debug:
1356 file_mods:
1356 file_mods:
1357 file_mods:
1357 file_mods:
1358 file_mods:
1358 file_mods:
1359 file_mods:
1359 file_mods:
1360 file_mods:
1360 file_mods:
1361 file_mods: c
1361 file_mods: c
1362 file_mods:
1362 file_mods:
1363 file_mods:
1363 file_mods:
1364 file_mods:
1364 file_mods:
1365 file_mods--verbose:
1365 file_mods--verbose:
1366 file_mods--verbose:
1366 file_mods--verbose:
1367 file_mods--verbose:
1367 file_mods--verbose:
1368 file_mods--verbose:
1368 file_mods--verbose:
1369 file_mods--verbose:
1369 file_mods--verbose:
1370 file_mods--verbose: c
1370 file_mods--verbose: c
1371 file_mods--verbose:
1371 file_mods--verbose:
1372 file_mods--verbose:
1372 file_mods--verbose:
1373 file_mods--verbose:
1373 file_mods--verbose:
1374 file_mods--debug:
1374 file_mods--debug:
1375 file_mods--debug:
1375 file_mods--debug:
1376 file_mods--debug:
1376 file_mods--debug:
1377 file_mods--debug:
1377 file_mods--debug:
1378 file_mods--debug:
1378 file_mods--debug:
1379 file_mods--debug: c
1379 file_mods--debug: c
1380 file_mods--debug:
1380 file_mods--debug:
1381 file_mods--debug:
1381 file_mods--debug:
1382 file_mods--debug:
1382 file_mods--debug:
1383 file_copies: fourth (second)
1383 file_copies: fourth (second)
1384 file_copies:
1384 file_copies:
1385 file_copies:
1385 file_copies:
1386 file_copies:
1386 file_copies:
1387 file_copies:
1387 file_copies:
1388 file_copies:
1388 file_copies:
1389 file_copies:
1389 file_copies:
1390 file_copies:
1390 file_copies:
1391 file_copies:
1391 file_copies:
1392 file_copies--verbose: fourth (second)
1392 file_copies--verbose: fourth (second)
1393 file_copies--verbose:
1393 file_copies--verbose:
1394 file_copies--verbose:
1394 file_copies--verbose:
1395 file_copies--verbose:
1395 file_copies--verbose:
1396 file_copies--verbose:
1396 file_copies--verbose:
1397 file_copies--verbose:
1397 file_copies--verbose:
1398 file_copies--verbose:
1398 file_copies--verbose:
1399 file_copies--verbose:
1399 file_copies--verbose:
1400 file_copies--verbose:
1400 file_copies--verbose:
1401 file_copies--debug: fourth (second)
1401 file_copies--debug: fourth (second)
1402 file_copies--debug:
1402 file_copies--debug:
1403 file_copies--debug:
1403 file_copies--debug:
1404 file_copies--debug:
1404 file_copies--debug:
1405 file_copies--debug:
1405 file_copies--debug:
1406 file_copies--debug:
1406 file_copies--debug:
1407 file_copies--debug:
1407 file_copies--debug:
1408 file_copies--debug:
1408 file_copies--debug:
1409 file_copies--debug:
1409 file_copies--debug:
1410 file_copies_switch:
1410 file_copies_switch:
1411 file_copies_switch:
1411 file_copies_switch:
1412 file_copies_switch:
1412 file_copies_switch:
1413 file_copies_switch:
1413 file_copies_switch:
1414 file_copies_switch:
1414 file_copies_switch:
1415 file_copies_switch:
1415 file_copies_switch:
1416 file_copies_switch:
1416 file_copies_switch:
1417 file_copies_switch:
1417 file_copies_switch:
1418 file_copies_switch:
1418 file_copies_switch:
1419 file_copies_switch--verbose:
1419 file_copies_switch--verbose:
1420 file_copies_switch--verbose:
1420 file_copies_switch--verbose:
1421 file_copies_switch--verbose:
1421 file_copies_switch--verbose:
1422 file_copies_switch--verbose:
1422 file_copies_switch--verbose:
1423 file_copies_switch--verbose:
1423 file_copies_switch--verbose:
1424 file_copies_switch--verbose:
1424 file_copies_switch--verbose:
1425 file_copies_switch--verbose:
1425 file_copies_switch--verbose:
1426 file_copies_switch--verbose:
1426 file_copies_switch--verbose:
1427 file_copies_switch--verbose:
1427 file_copies_switch--verbose:
1428 file_copies_switch--debug:
1428 file_copies_switch--debug:
1429 file_copies_switch--debug:
1429 file_copies_switch--debug:
1430 file_copies_switch--debug:
1430 file_copies_switch--debug:
1431 file_copies_switch--debug:
1431 file_copies_switch--debug:
1432 file_copies_switch--debug:
1432 file_copies_switch--debug:
1433 file_copies_switch--debug:
1433 file_copies_switch--debug:
1434 file_copies_switch--debug:
1434 file_copies_switch--debug:
1435 file_copies_switch--debug:
1435 file_copies_switch--debug:
1436 file_copies_switch--debug:
1436 file_copies_switch--debug:
1437 files: fourth second third
1437 files: fourth second third
1438 files: second
1438 files: second
1439 files:
1439 files:
1440 files: d
1440 files: d
1441 files:
1441 files:
1442 files: c
1442 files: c
1443 files: c
1443 files: c
1444 files: b
1444 files: b
1445 files: a
1445 files: a
1446 files--verbose: fourth second third
1446 files--verbose: fourth second third
1447 files--verbose: second
1447 files--verbose: second
1448 files--verbose:
1448 files--verbose:
1449 files--verbose: d
1449 files--verbose: d
1450 files--verbose:
1450 files--verbose:
1451 files--verbose: c
1451 files--verbose: c
1452 files--verbose: c
1452 files--verbose: c
1453 files--verbose: b
1453 files--verbose: b
1454 files--verbose: a
1454 files--verbose: a
1455 files--debug: fourth second third
1455 files--debug: fourth second third
1456 files--debug: second
1456 files--debug: second
1457 files--debug:
1457 files--debug:
1458 files--debug: d
1458 files--debug: d
1459 files--debug:
1459 files--debug:
1460 files--debug: c
1460 files--debug: c
1461 files--debug: c
1461 files--debug: c
1462 files--debug: b
1462 files--debug: b
1463 files--debug: a
1463 files--debug: a
1464 manifest: 6:94961b75a2da
1464 manifest: 6:94961b75a2da
1465 manifest: 5:f2dbc354b94e
1465 manifest: 5:f2dbc354b94e
1466 manifest: 4:4dc3def4f9b4
1466 manifest: 4:4dc3def4f9b4
1467 manifest: 4:4dc3def4f9b4
1467 manifest: 4:4dc3def4f9b4
1468 manifest: 3:cb5a1327723b
1468 manifest: 3:cb5a1327723b
1469 manifest: 3:cb5a1327723b
1469 manifest: 3:cb5a1327723b
1470 manifest: 2:6e0e82995c35
1470 manifest: 2:6e0e82995c35
1471 manifest: 1:4e8d705b1e53
1471 manifest: 1:4e8d705b1e53
1472 manifest: 0:a0c8bcbbb45c
1472 manifest: 0:a0c8bcbbb45c
1473 manifest--verbose: 6:94961b75a2da
1473 manifest--verbose: 6:94961b75a2da
1474 manifest--verbose: 5:f2dbc354b94e
1474 manifest--verbose: 5:f2dbc354b94e
1475 manifest--verbose: 4:4dc3def4f9b4
1475 manifest--verbose: 4:4dc3def4f9b4
1476 manifest--verbose: 4:4dc3def4f9b4
1476 manifest--verbose: 4:4dc3def4f9b4
1477 manifest--verbose: 3:cb5a1327723b
1477 manifest--verbose: 3:cb5a1327723b
1478 manifest--verbose: 3:cb5a1327723b
1478 manifest--verbose: 3:cb5a1327723b
1479 manifest--verbose: 2:6e0e82995c35
1479 manifest--verbose: 2:6e0e82995c35
1480 manifest--verbose: 1:4e8d705b1e53
1480 manifest--verbose: 1:4e8d705b1e53
1481 manifest--verbose: 0:a0c8bcbbb45c
1481 manifest--verbose: 0:a0c8bcbbb45c
1482 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1482 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1483 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1483 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1484 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1484 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1485 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1485 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1486 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1486 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1487 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1487 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1488 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1488 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1489 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1489 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1490 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1490 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1491 node: 95c24699272ef57d062b8bccc32c878bf841784a
1491 node: 95c24699272ef57d062b8bccc32c878bf841784a
1492 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1492 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1493 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1493 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1494 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1494 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1495 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1495 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1496 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1496 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1497 node: 97054abb4ab824450e9164180baf491ae0078465
1497 node: 97054abb4ab824450e9164180baf491ae0078465
1498 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1498 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1499 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1499 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1500 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1500 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1501 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1501 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1502 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1502 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1503 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1503 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1504 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1504 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1505 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1505 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1506 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1506 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1507 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1507 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1508 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1508 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1509 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1509 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1510 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1510 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1511 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1511 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1512 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1512 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1513 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1513 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1514 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1514 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1515 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1515 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1516 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1516 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1517 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1517 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1518 parents:
1518 parents:
1519 parents: -1:000000000000
1519 parents: -1:000000000000
1520 parents: 5:13207e5a10d9 4:bbe44766e73d
1520 parents: 5:13207e5a10d9 4:bbe44766e73d
1521 parents: 3:10e46f2dcbf4
1521 parents: 3:10e46f2dcbf4
1522 parents:
1522 parents:
1523 parents:
1523 parents:
1524 parents:
1524 parents:
1525 parents:
1525 parents:
1526 parents:
1526 parents:
1527 parents--verbose:
1527 parents--verbose:
1528 parents--verbose: -1:000000000000
1528 parents--verbose: -1:000000000000
1529 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1529 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1530 parents--verbose: 3:10e46f2dcbf4
1530 parents--verbose: 3:10e46f2dcbf4
1531 parents--verbose:
1531 parents--verbose:
1532 parents--verbose:
1532 parents--verbose:
1533 parents--verbose:
1533 parents--verbose:
1534 parents--verbose:
1534 parents--verbose:
1535 parents--verbose:
1535 parents--verbose:
1536 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1536 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1537 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1537 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1538 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1538 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1539 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1539 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1540 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1540 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1541 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1541 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1542 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1542 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1543 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1543 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1544 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1544 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1545 rev: 8
1545 rev: 8
1546 rev: 7
1546 rev: 7
1547 rev: 6
1547 rev: 6
1548 rev: 5
1548 rev: 5
1549 rev: 4
1549 rev: 4
1550 rev: 3
1550 rev: 3
1551 rev: 2
1551 rev: 2
1552 rev: 1
1552 rev: 1
1553 rev: 0
1553 rev: 0
1554 rev--verbose: 8
1554 rev--verbose: 8
1555 rev--verbose: 7
1555 rev--verbose: 7
1556 rev--verbose: 6
1556 rev--verbose: 6
1557 rev--verbose: 5
1557 rev--verbose: 5
1558 rev--verbose: 4
1558 rev--verbose: 4
1559 rev--verbose: 3
1559 rev--verbose: 3
1560 rev--verbose: 2
1560 rev--verbose: 2
1561 rev--verbose: 1
1561 rev--verbose: 1
1562 rev--verbose: 0
1562 rev--verbose: 0
1563 rev--debug: 8
1563 rev--debug: 8
1564 rev--debug: 7
1564 rev--debug: 7
1565 rev--debug: 6
1565 rev--debug: 6
1566 rev--debug: 5
1566 rev--debug: 5
1567 rev--debug: 4
1567 rev--debug: 4
1568 rev--debug: 3
1568 rev--debug: 3
1569 rev--debug: 2
1569 rev--debug: 2
1570 rev--debug: 1
1570 rev--debug: 1
1571 rev--debug: 0
1571 rev--debug: 0
1572 tags: tip
1572 tags: tip
1573 tags:
1573 tags:
1574 tags:
1574 tags:
1575 tags:
1575 tags:
1576 tags:
1576 tags:
1577 tags:
1577 tags:
1578 tags:
1578 tags:
1579 tags:
1579 tags:
1580 tags:
1580 tags:
1581 tags--verbose: tip
1581 tags--verbose: tip
1582 tags--verbose:
1582 tags--verbose:
1583 tags--verbose:
1583 tags--verbose:
1584 tags--verbose:
1584 tags--verbose:
1585 tags--verbose:
1585 tags--verbose:
1586 tags--verbose:
1586 tags--verbose:
1587 tags--verbose:
1587 tags--verbose:
1588 tags--verbose:
1588 tags--verbose:
1589 tags--verbose:
1589 tags--verbose:
1590 tags--debug: tip
1590 tags--debug: tip
1591 tags--debug:
1591 tags--debug:
1592 tags--debug:
1592 tags--debug:
1593 tags--debug:
1593 tags--debug:
1594 tags--debug:
1594 tags--debug:
1595 tags--debug:
1595 tags--debug:
1596 tags--debug:
1596 tags--debug:
1597 tags--debug:
1597 tags--debug:
1598 tags--debug:
1598 tags--debug:
1599 diffstat: 3: +2/-1
1599 diffstat: 3: +2/-1
1600 diffstat: 1: +1/-0
1600 diffstat: 1: +1/-0
1601 diffstat: 0: +0/-0
1601 diffstat: 0: +0/-0
1602 diffstat: 1: +1/-0
1602 diffstat: 1: +1/-0
1603 diffstat: 0: +0/-0
1603 diffstat: 0: +0/-0
1604 diffstat: 1: +1/-0
1604 diffstat: 1: +1/-0
1605 diffstat: 1: +4/-0
1605 diffstat: 1: +4/-0
1606 diffstat: 1: +2/-0
1606 diffstat: 1: +2/-0
1607 diffstat: 1: +1/-0
1607 diffstat: 1: +1/-0
1608 diffstat--verbose: 3: +2/-1
1608 diffstat--verbose: 3: +2/-1
1609 diffstat--verbose: 1: +1/-0
1609 diffstat--verbose: 1: +1/-0
1610 diffstat--verbose: 0: +0/-0
1610 diffstat--verbose: 0: +0/-0
1611 diffstat--verbose: 1: +1/-0
1611 diffstat--verbose: 1: +1/-0
1612 diffstat--verbose: 0: +0/-0
1612 diffstat--verbose: 0: +0/-0
1613 diffstat--verbose: 1: +1/-0
1613 diffstat--verbose: 1: +1/-0
1614 diffstat--verbose: 1: +4/-0
1614 diffstat--verbose: 1: +4/-0
1615 diffstat--verbose: 1: +2/-0
1615 diffstat--verbose: 1: +2/-0
1616 diffstat--verbose: 1: +1/-0
1616 diffstat--verbose: 1: +1/-0
1617 diffstat--debug: 3: +2/-1
1617 diffstat--debug: 3: +2/-1
1618 diffstat--debug: 1: +1/-0
1618 diffstat--debug: 1: +1/-0
1619 diffstat--debug: 0: +0/-0
1619 diffstat--debug: 0: +0/-0
1620 diffstat--debug: 1: +1/-0
1620 diffstat--debug: 1: +1/-0
1621 diffstat--debug: 0: +0/-0
1621 diffstat--debug: 0: +0/-0
1622 diffstat--debug: 1: +1/-0
1622 diffstat--debug: 1: +1/-0
1623 diffstat--debug: 1: +4/-0
1623 diffstat--debug: 1: +4/-0
1624 diffstat--debug: 1: +2/-0
1624 diffstat--debug: 1: +2/-0
1625 diffstat--debug: 1: +1/-0
1625 diffstat--debug: 1: +1/-0
1626 extras: branch=default
1626 extras: branch=default
1627 extras: branch=default
1627 extras: branch=default
1628 extras: branch=default
1628 extras: branch=default
1629 extras: branch=default
1629 extras: branch=default
1630 extras: branch=foo
1630 extras: branch=foo
1631 extras: branch=default
1631 extras: branch=default
1632 extras: branch=default
1632 extras: branch=default
1633 extras: branch=default
1633 extras: branch=default
1634 extras: branch=default
1634 extras: branch=default
1635 extras--verbose: branch=default
1635 extras--verbose: branch=default
1636 extras--verbose: branch=default
1636 extras--verbose: branch=default
1637 extras--verbose: branch=default
1637 extras--verbose: branch=default
1638 extras--verbose: branch=default
1638 extras--verbose: branch=default
1639 extras--verbose: branch=foo
1639 extras--verbose: branch=foo
1640 extras--verbose: branch=default
1640 extras--verbose: branch=default
1641 extras--verbose: branch=default
1641 extras--verbose: branch=default
1642 extras--verbose: branch=default
1642 extras--verbose: branch=default
1643 extras--verbose: branch=default
1643 extras--verbose: branch=default
1644 extras--debug: branch=default
1644 extras--debug: branch=default
1645 extras--debug: branch=default
1645 extras--debug: branch=default
1646 extras--debug: branch=default
1646 extras--debug: branch=default
1647 extras--debug: branch=default
1647 extras--debug: branch=default
1648 extras--debug: branch=foo
1648 extras--debug: branch=foo
1649 extras--debug: branch=default
1649 extras--debug: branch=default
1650 extras--debug: branch=default
1650 extras--debug: branch=default
1651 extras--debug: branch=default
1651 extras--debug: branch=default
1652 extras--debug: branch=default
1652 extras--debug: branch=default
1653 p1rev: 7
1653 p1rev: 7
1654 p1rev: -1
1654 p1rev: -1
1655 p1rev: 5
1655 p1rev: 5
1656 p1rev: 3
1656 p1rev: 3
1657 p1rev: 3
1657 p1rev: 3
1658 p1rev: 2
1658 p1rev: 2
1659 p1rev: 1
1659 p1rev: 1
1660 p1rev: 0
1660 p1rev: 0
1661 p1rev: -1
1661 p1rev: -1
1662 p1rev--verbose: 7
1662 p1rev--verbose: 7
1663 p1rev--verbose: -1
1663 p1rev--verbose: -1
1664 p1rev--verbose: 5
1664 p1rev--verbose: 5
1665 p1rev--verbose: 3
1665 p1rev--verbose: 3
1666 p1rev--verbose: 3
1666 p1rev--verbose: 3
1667 p1rev--verbose: 2
1667 p1rev--verbose: 2
1668 p1rev--verbose: 1
1668 p1rev--verbose: 1
1669 p1rev--verbose: 0
1669 p1rev--verbose: 0
1670 p1rev--verbose: -1
1670 p1rev--verbose: -1
1671 p1rev--debug: 7
1671 p1rev--debug: 7
1672 p1rev--debug: -1
1672 p1rev--debug: -1
1673 p1rev--debug: 5
1673 p1rev--debug: 5
1674 p1rev--debug: 3
1674 p1rev--debug: 3
1675 p1rev--debug: 3
1675 p1rev--debug: 3
1676 p1rev--debug: 2
1676 p1rev--debug: 2
1677 p1rev--debug: 1
1677 p1rev--debug: 1
1678 p1rev--debug: 0
1678 p1rev--debug: 0
1679 p1rev--debug: -1
1679 p1rev--debug: -1
1680 p2rev: -1
1680 p2rev: -1
1681 p2rev: -1
1681 p2rev: -1
1682 p2rev: 4
1682 p2rev: 4
1683 p2rev: -1
1683 p2rev: -1
1684 p2rev: -1
1684 p2rev: -1
1685 p2rev: -1
1685 p2rev: -1
1686 p2rev: -1
1686 p2rev: -1
1687 p2rev: -1
1687 p2rev: -1
1688 p2rev: -1
1688 p2rev: -1
1689 p2rev--verbose: -1
1689 p2rev--verbose: -1
1690 p2rev--verbose: -1
1690 p2rev--verbose: -1
1691 p2rev--verbose: 4
1691 p2rev--verbose: 4
1692 p2rev--verbose: -1
1692 p2rev--verbose: -1
1693 p2rev--verbose: -1
1693 p2rev--verbose: -1
1694 p2rev--verbose: -1
1694 p2rev--verbose: -1
1695 p2rev--verbose: -1
1695 p2rev--verbose: -1
1696 p2rev--verbose: -1
1696 p2rev--verbose: -1
1697 p2rev--verbose: -1
1697 p2rev--verbose: -1
1698 p2rev--debug: -1
1698 p2rev--debug: -1
1699 p2rev--debug: -1
1699 p2rev--debug: -1
1700 p2rev--debug: 4
1700 p2rev--debug: 4
1701 p2rev--debug: -1
1701 p2rev--debug: -1
1702 p2rev--debug: -1
1702 p2rev--debug: -1
1703 p2rev--debug: -1
1703 p2rev--debug: -1
1704 p2rev--debug: -1
1704 p2rev--debug: -1
1705 p2rev--debug: -1
1705 p2rev--debug: -1
1706 p2rev--debug: -1
1706 p2rev--debug: -1
1707 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1707 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1708 p1node: 0000000000000000000000000000000000000000
1708 p1node: 0000000000000000000000000000000000000000
1709 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1709 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1710 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1710 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1711 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1711 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1712 p1node: 97054abb4ab824450e9164180baf491ae0078465
1712 p1node: 97054abb4ab824450e9164180baf491ae0078465
1713 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1713 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1714 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1714 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1715 p1node: 0000000000000000000000000000000000000000
1715 p1node: 0000000000000000000000000000000000000000
1716 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1716 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1717 p1node--verbose: 0000000000000000000000000000000000000000
1717 p1node--verbose: 0000000000000000000000000000000000000000
1718 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1718 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1719 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1719 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1720 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1720 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1721 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1721 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1722 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1722 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1723 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1723 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1724 p1node--verbose: 0000000000000000000000000000000000000000
1724 p1node--verbose: 0000000000000000000000000000000000000000
1725 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1725 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1726 p1node--debug: 0000000000000000000000000000000000000000
1726 p1node--debug: 0000000000000000000000000000000000000000
1727 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1727 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1728 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1728 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1729 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1729 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1730 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1730 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1731 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1731 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1732 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1732 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1733 p1node--debug: 0000000000000000000000000000000000000000
1733 p1node--debug: 0000000000000000000000000000000000000000
1734 p2node: 0000000000000000000000000000000000000000
1734 p2node: 0000000000000000000000000000000000000000
1735 p2node: 0000000000000000000000000000000000000000
1735 p2node: 0000000000000000000000000000000000000000
1736 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1736 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1737 p2node: 0000000000000000000000000000000000000000
1737 p2node: 0000000000000000000000000000000000000000
1738 p2node: 0000000000000000000000000000000000000000
1738 p2node: 0000000000000000000000000000000000000000
1739 p2node: 0000000000000000000000000000000000000000
1739 p2node: 0000000000000000000000000000000000000000
1740 p2node: 0000000000000000000000000000000000000000
1740 p2node: 0000000000000000000000000000000000000000
1741 p2node: 0000000000000000000000000000000000000000
1741 p2node: 0000000000000000000000000000000000000000
1742 p2node: 0000000000000000000000000000000000000000
1742 p2node: 0000000000000000000000000000000000000000
1743 p2node--verbose: 0000000000000000000000000000000000000000
1743 p2node--verbose: 0000000000000000000000000000000000000000
1744 p2node--verbose: 0000000000000000000000000000000000000000
1744 p2node--verbose: 0000000000000000000000000000000000000000
1745 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1745 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1746 p2node--verbose: 0000000000000000000000000000000000000000
1746 p2node--verbose: 0000000000000000000000000000000000000000
1747 p2node--verbose: 0000000000000000000000000000000000000000
1747 p2node--verbose: 0000000000000000000000000000000000000000
1748 p2node--verbose: 0000000000000000000000000000000000000000
1748 p2node--verbose: 0000000000000000000000000000000000000000
1749 p2node--verbose: 0000000000000000000000000000000000000000
1749 p2node--verbose: 0000000000000000000000000000000000000000
1750 p2node--verbose: 0000000000000000000000000000000000000000
1750 p2node--verbose: 0000000000000000000000000000000000000000
1751 p2node--verbose: 0000000000000000000000000000000000000000
1751 p2node--verbose: 0000000000000000000000000000000000000000
1752 p2node--debug: 0000000000000000000000000000000000000000
1752 p2node--debug: 0000000000000000000000000000000000000000
1753 p2node--debug: 0000000000000000000000000000000000000000
1753 p2node--debug: 0000000000000000000000000000000000000000
1754 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1754 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1755 p2node--debug: 0000000000000000000000000000000000000000
1755 p2node--debug: 0000000000000000000000000000000000000000
1756 p2node--debug: 0000000000000000000000000000000000000000
1756 p2node--debug: 0000000000000000000000000000000000000000
1757 p2node--debug: 0000000000000000000000000000000000000000
1757 p2node--debug: 0000000000000000000000000000000000000000
1758 p2node--debug: 0000000000000000000000000000000000000000
1758 p2node--debug: 0000000000000000000000000000000000000000
1759 p2node--debug: 0000000000000000000000000000000000000000
1759 p2node--debug: 0000000000000000000000000000000000000000
1760 p2node--debug: 0000000000000000000000000000000000000000
1760 p2node--debug: 0000000000000000000000000000000000000000
1761
1761
1762 Filters work:
1762 Filters work:
1763
1763
1764 $ hg log --template '{author|domain}\n'
1764 $ hg log --template '{author|domain}\n'
1765
1765
1766 hostname
1766 hostname
1767
1767
1768
1768
1769
1769
1770
1770
1771 place
1771 place
1772 place
1772 place
1773 hostname
1773 hostname
1774
1774
1775 $ hg log --template '{author|person}\n'
1775 $ hg log --template '{author|person}\n'
1776 test
1776 test
1777 User Name
1777 User Name
1778 person
1778 person
1779 person
1779 person
1780 person
1780 person
1781 person
1781 person
1782 other
1782 other
1783 A. N. Other
1783 A. N. Other
1784 User Name
1784 User Name
1785
1785
1786 $ hg log --template '{author|user}\n'
1786 $ hg log --template '{author|user}\n'
1787 test
1787 test
1788 user
1788 user
1789 person
1789 person
1790 person
1790 person
1791 person
1791 person
1792 person
1792 person
1793 other
1793 other
1794 other
1794 other
1795 user
1795 user
1796
1796
1797 $ hg log --template '{date|date}\n'
1797 $ hg log --template '{date|date}\n'
1798 Wed Jan 01 10:01:00 2020 +0000
1798 Wed Jan 01 10:01:00 2020 +0000
1799 Mon Jan 12 13:46:40 1970 +0000
1799 Mon Jan 12 13:46:40 1970 +0000
1800 Sun Jan 18 08:40:01 1970 +0000
1800 Sun Jan 18 08:40:01 1970 +0000
1801 Sun Jan 18 08:40:00 1970 +0000
1801 Sun Jan 18 08:40:00 1970 +0000
1802 Sat Jan 17 04:53:20 1970 +0000
1802 Sat Jan 17 04:53:20 1970 +0000
1803 Fri Jan 16 01:06:40 1970 +0000
1803 Fri Jan 16 01:06:40 1970 +0000
1804 Wed Jan 14 21:20:00 1970 +0000
1804 Wed Jan 14 21:20:00 1970 +0000
1805 Tue Jan 13 17:33:20 1970 +0000
1805 Tue Jan 13 17:33:20 1970 +0000
1806 Mon Jan 12 13:46:40 1970 +0000
1806 Mon Jan 12 13:46:40 1970 +0000
1807
1807
1808 $ hg log --template '{date|isodate}\n'
1808 $ hg log --template '{date|isodate}\n'
1809 2020-01-01 10:01 +0000
1809 2020-01-01 10:01 +0000
1810 1970-01-12 13:46 +0000
1810 1970-01-12 13:46 +0000
1811 1970-01-18 08:40 +0000
1811 1970-01-18 08:40 +0000
1812 1970-01-18 08:40 +0000
1812 1970-01-18 08:40 +0000
1813 1970-01-17 04:53 +0000
1813 1970-01-17 04:53 +0000
1814 1970-01-16 01:06 +0000
1814 1970-01-16 01:06 +0000
1815 1970-01-14 21:20 +0000
1815 1970-01-14 21:20 +0000
1816 1970-01-13 17:33 +0000
1816 1970-01-13 17:33 +0000
1817 1970-01-12 13:46 +0000
1817 1970-01-12 13:46 +0000
1818
1818
1819 $ hg log --template '{date|isodatesec}\n'
1819 $ hg log --template '{date|isodatesec}\n'
1820 2020-01-01 10:01:00 +0000
1820 2020-01-01 10:01:00 +0000
1821 1970-01-12 13:46:40 +0000
1821 1970-01-12 13:46:40 +0000
1822 1970-01-18 08:40:01 +0000
1822 1970-01-18 08:40:01 +0000
1823 1970-01-18 08:40:00 +0000
1823 1970-01-18 08:40:00 +0000
1824 1970-01-17 04:53:20 +0000
1824 1970-01-17 04:53:20 +0000
1825 1970-01-16 01:06:40 +0000
1825 1970-01-16 01:06:40 +0000
1826 1970-01-14 21:20:00 +0000
1826 1970-01-14 21:20:00 +0000
1827 1970-01-13 17:33:20 +0000
1827 1970-01-13 17:33:20 +0000
1828 1970-01-12 13:46:40 +0000
1828 1970-01-12 13:46:40 +0000
1829
1829
1830 $ hg log --template '{date|rfc822date}\n'
1830 $ hg log --template '{date|rfc822date}\n'
1831 Wed, 01 Jan 2020 10:01:00 +0000
1831 Wed, 01 Jan 2020 10:01:00 +0000
1832 Mon, 12 Jan 1970 13:46:40 +0000
1832 Mon, 12 Jan 1970 13:46:40 +0000
1833 Sun, 18 Jan 1970 08:40:01 +0000
1833 Sun, 18 Jan 1970 08:40:01 +0000
1834 Sun, 18 Jan 1970 08:40:00 +0000
1834 Sun, 18 Jan 1970 08:40:00 +0000
1835 Sat, 17 Jan 1970 04:53:20 +0000
1835 Sat, 17 Jan 1970 04:53:20 +0000
1836 Fri, 16 Jan 1970 01:06:40 +0000
1836 Fri, 16 Jan 1970 01:06:40 +0000
1837 Wed, 14 Jan 1970 21:20:00 +0000
1837 Wed, 14 Jan 1970 21:20:00 +0000
1838 Tue, 13 Jan 1970 17:33:20 +0000
1838 Tue, 13 Jan 1970 17:33:20 +0000
1839 Mon, 12 Jan 1970 13:46:40 +0000
1839 Mon, 12 Jan 1970 13:46:40 +0000
1840
1840
1841 $ hg log --template '{desc|firstline}\n'
1841 $ hg log --template '{desc|firstline}\n'
1842 third
1842 third
1843 second
1843 second
1844 merge
1844 merge
1845 new head
1845 new head
1846 new branch
1846 new branch
1847 no user, no domain
1847 no user, no domain
1848 no person
1848 no person
1849 other 1
1849 other 1
1850 line 1
1850 line 1
1851
1851
1852 $ hg log --template '{node|short}\n'
1852 $ hg log --template '{node|short}\n'
1853 95c24699272e
1853 95c24699272e
1854 29114dbae42b
1854 29114dbae42b
1855 d41e714fe50d
1855 d41e714fe50d
1856 13207e5a10d9
1856 13207e5a10d9
1857 bbe44766e73d
1857 bbe44766e73d
1858 10e46f2dcbf4
1858 10e46f2dcbf4
1859 97054abb4ab8
1859 97054abb4ab8
1860 b608e9d1a3f0
1860 b608e9d1a3f0
1861 1e4e1b8f71e0
1861 1e4e1b8f71e0
1862
1862
1863 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1863 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1864 <changeset author="test"/>
1864 <changeset author="test"/>
1865 <changeset author="User Name &lt;user@hostname&gt;"/>
1865 <changeset author="User Name &lt;user@hostname&gt;"/>
1866 <changeset author="person"/>
1866 <changeset author="person"/>
1867 <changeset author="person"/>
1867 <changeset author="person"/>
1868 <changeset author="person"/>
1868 <changeset author="person"/>
1869 <changeset author="person"/>
1869 <changeset author="person"/>
1870 <changeset author="other@place"/>
1870 <changeset author="other@place"/>
1871 <changeset author="A. N. Other &lt;other@place&gt;"/>
1871 <changeset author="A. N. Other &lt;other@place&gt;"/>
1872 <changeset author="User Name &lt;user@hostname&gt;"/>
1872 <changeset author="User Name &lt;user@hostname&gt;"/>
1873
1873
1874 $ hg log --template '{rev}: {children}\n'
1874 $ hg log --template '{rev}: {children}\n'
1875 8:
1875 8:
1876 7: 8:95c24699272e
1876 7: 8:95c24699272e
1877 6:
1877 6:
1878 5: 6:d41e714fe50d
1878 5: 6:d41e714fe50d
1879 4: 6:d41e714fe50d
1879 4: 6:d41e714fe50d
1880 3: 4:bbe44766e73d 5:13207e5a10d9
1880 3: 4:bbe44766e73d 5:13207e5a10d9
1881 2: 3:10e46f2dcbf4
1881 2: 3:10e46f2dcbf4
1882 1: 2:97054abb4ab8
1882 1: 2:97054abb4ab8
1883 0: 1:b608e9d1a3f0
1883 0: 1:b608e9d1a3f0
1884
1884
1885 Formatnode filter works:
1885 Formatnode filter works:
1886
1886
1887 $ hg -q log -r 0 --template '{node|formatnode}\n'
1887 $ hg -q log -r 0 --template '{node|formatnode}\n'
1888 1e4e1b8f71e0
1888 1e4e1b8f71e0
1889
1889
1890 $ hg log -r 0 --template '{node|formatnode}\n'
1890 $ hg log -r 0 --template '{node|formatnode}\n'
1891 1e4e1b8f71e0
1891 1e4e1b8f71e0
1892
1892
1893 $ hg -v log -r 0 --template '{node|formatnode}\n'
1893 $ hg -v log -r 0 --template '{node|formatnode}\n'
1894 1e4e1b8f71e0
1894 1e4e1b8f71e0
1895
1895
1896 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1896 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1897 1e4e1b8f71e05681d422154f5421e385fec3454f
1897 1e4e1b8f71e05681d422154f5421e385fec3454f
1898
1898
1899 Age filter:
1899 Age filter:
1900
1900
1901 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1901 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1902
1902
1903 >>> from datetime import datetime, timedelta
1903 >>> from datetime import datetime, timedelta
1904 >>> fp = open('a', 'w')
1904 >>> fp = open('a', 'w')
1905 >>> n = datetime.now() + timedelta(366 * 7)
1905 >>> n = datetime.now() + timedelta(366 * 7)
1906 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1906 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1907 >>> fp.close()
1907 >>> fp.close()
1908 $ hg add a
1908 $ hg add a
1909 $ hg commit -m future -d "`cat a`"
1909 $ hg commit -m future -d "`cat a`"
1910
1910
1911 $ hg log -l1 --template '{date|age}\n'
1911 $ hg log -l1 --template '{date|age}\n'
1912 7 years from now
1912 7 years from now
1913
1913
1914 Count filter:
1914 Count filter:
1915
1915
1916 $ hg log -l1 --template '{node|count} {node|short|count}\n'
1916 $ hg log -l1 --template '{node|count} {node|short|count}\n'
1917 40 12
1917 40 12
1918
1918
1919 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
1919 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
1920 0 1 4
1920 0 1 4
1921
1921
1922 $ hg log -G --template '{rev}: children: {children|count}, \
1922 $ hg log -G --template '{rev}: children: {children|count}, \
1923 > tags: {tags|count}, file_adds: {file_adds|count}, \
1923 > tags: {tags|count}, file_adds: {file_adds|count}, \
1924 > ancestors: {revset("ancestors(%s)", rev)|count}'
1924 > ancestors: {revset("ancestors(%s)", rev)|count}'
1925 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
1925 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
1926 |
1926 |
1927 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
1927 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
1928 |
1928 |
1929 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
1929 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
1930
1930
1931 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
1931 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
1932 |\
1932 |\
1933 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
1933 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
1934 | |
1934 | |
1935 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
1935 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
1936 |/
1936 |/
1937 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
1937 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
1938 |
1938 |
1939 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
1939 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
1940 |
1940 |
1941 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
1941 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
1942 |
1942 |
1943 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
1943 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
1944
1944
1945
1945
1946 Upper/lower filters:
1946 Upper/lower filters:
1947
1947
1948 $ hg log -r0 --template '{branch|upper}\n'
1948 $ hg log -r0 --template '{branch|upper}\n'
1949 DEFAULT
1949 DEFAULT
1950 $ hg log -r0 --template '{author|lower}\n'
1950 $ hg log -r0 --template '{author|lower}\n'
1951 user name <user@hostname>
1951 user name <user@hostname>
1952 $ hg log -r0 --template '{date|upper}\n'
1952 $ hg log -r0 --template '{date|upper}\n'
1953 abort: template filter 'upper' is not compatible with keyword 'date'
1953 abort: template filter 'upper' is not compatible with keyword 'date'
1954 [255]
1954 [255]
1955
1955
1956 Error on syntax:
1956 Error on syntax:
1957
1957
1958 $ echo 'x = "f' >> t
1958 $ echo 'x = "f' >> t
1959 $ hg log
1959 $ hg log
1960 abort: t:3: unmatched quotes
1960 abort: t:3: unmatched quotes
1961 [255]
1961 [255]
1962
1962
1963 Behind the scenes, this will throw TypeError
1963 Behind the scenes, this will throw TypeError
1964
1964
1965 $ hg log -l 3 --template '{date|obfuscate}\n'
1965 $ hg log -l 3 --template '{date|obfuscate}\n'
1966 abort: template filter 'obfuscate' is not compatible with keyword 'date'
1966 abort: template filter 'obfuscate' is not compatible with keyword 'date'
1967 [255]
1967 [255]
1968
1968
1969 Behind the scenes, this will throw a ValueError
1969 Behind the scenes, this will throw a ValueError
1970
1970
1971 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1971 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1972 abort: template filter 'shortdate' is not compatible with keyword 'desc'
1972 abort: template filter 'shortdate' is not compatible with keyword 'desc'
1973 [255]
1973 [255]
1974
1974
1975 Behind the scenes, this will throw AttributeError
1975 Behind the scenes, this will throw AttributeError
1976
1976
1977 $ hg log -l 3 --template 'line: {date|escape}\n'
1977 $ hg log -l 3 --template 'line: {date|escape}\n'
1978 abort: template filter 'escape' is not compatible with keyword 'date'
1978 abort: template filter 'escape' is not compatible with keyword 'date'
1979 [255]
1979 [255]
1980
1980
1981 Behind the scenes, this will throw ValueError
1981 Behind the scenes, this will throw ValueError
1982
1982
1983 $ hg tip --template '{author|email|date}\n'
1983 $ hg tip --template '{author|email|date}\n'
1984 abort: template filter 'datefilter' is not compatible with keyword 'author'
1984 abort: template filter 'datefilter' is not compatible with keyword 'author'
1985 [255]
1985 [255]
1986
1986
1987 Thrown an error if a template function doesn't exist
1987 Thrown an error if a template function doesn't exist
1988
1988
1989 $ hg tip --template '{foo()}\n'
1989 $ hg tip --template '{foo()}\n'
1990 hg: parse error: unknown function 'foo'
1990 hg: parse error: unknown function 'foo'
1991 [255]
1991 [255]
1992
1992
1993 Pass generator object created by template function to filter
1993 Pass generator object created by template function to filter
1994
1994
1995 $ hg log -l 1 --template '{if(author, author)|user}\n'
1995 $ hg log -l 1 --template '{if(author, author)|user}\n'
1996 test
1996 test
1997
1997
1998 Test diff function:
1998 Test diff function:
1999
1999
2000 $ hg diff -c 8
2000 $ hg diff -c 8
2001 diff -r 29114dbae42b -r 95c24699272e fourth
2001 diff -r 29114dbae42b -r 95c24699272e fourth
2002 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2002 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2003 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2003 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2004 @@ -0,0 +1,1 @@
2004 @@ -0,0 +1,1 @@
2005 +second
2005 +second
2006 diff -r 29114dbae42b -r 95c24699272e second
2006 diff -r 29114dbae42b -r 95c24699272e second
2007 --- a/second Mon Jan 12 13:46:40 1970 +0000
2007 --- a/second Mon Jan 12 13:46:40 1970 +0000
2008 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2008 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2009 @@ -1,1 +0,0 @@
2009 @@ -1,1 +0,0 @@
2010 -second
2010 -second
2011 diff -r 29114dbae42b -r 95c24699272e third
2011 diff -r 29114dbae42b -r 95c24699272e third
2012 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2012 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2013 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2013 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2014 @@ -0,0 +1,1 @@
2014 @@ -0,0 +1,1 @@
2015 +third
2015 +third
2016
2016
2017 $ hg log -r 8 -T "{diff()}"
2017 $ hg log -r 8 -T "{diff()}"
2018 diff -r 29114dbae42b -r 95c24699272e fourth
2018 diff -r 29114dbae42b -r 95c24699272e fourth
2019 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2019 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2020 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2020 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2021 @@ -0,0 +1,1 @@
2021 @@ -0,0 +1,1 @@
2022 +second
2022 +second
2023 diff -r 29114dbae42b -r 95c24699272e second
2023 diff -r 29114dbae42b -r 95c24699272e second
2024 --- a/second Mon Jan 12 13:46:40 1970 +0000
2024 --- a/second Mon Jan 12 13:46:40 1970 +0000
2025 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2025 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2026 @@ -1,1 +0,0 @@
2026 @@ -1,1 +0,0 @@
2027 -second
2027 -second
2028 diff -r 29114dbae42b -r 95c24699272e third
2028 diff -r 29114dbae42b -r 95c24699272e third
2029 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2029 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2030 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2030 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2031 @@ -0,0 +1,1 @@
2031 @@ -0,0 +1,1 @@
2032 +third
2032 +third
2033
2033
2034 $ hg log -r 8 -T "{diff('glob:f*')}"
2034 $ hg log -r 8 -T "{diff('glob:f*')}"
2035 diff -r 29114dbae42b -r 95c24699272e fourth
2035 diff -r 29114dbae42b -r 95c24699272e fourth
2036 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2036 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2037 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2037 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2038 @@ -0,0 +1,1 @@
2038 @@ -0,0 +1,1 @@
2039 +second
2039 +second
2040
2040
2041 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2041 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2042 diff -r 29114dbae42b -r 95c24699272e second
2042 diff -r 29114dbae42b -r 95c24699272e second
2043 --- a/second Mon Jan 12 13:46:40 1970 +0000
2043 --- a/second Mon Jan 12 13:46:40 1970 +0000
2044 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2044 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2045 @@ -1,1 +0,0 @@
2045 @@ -1,1 +0,0 @@
2046 -second
2046 -second
2047 diff -r 29114dbae42b -r 95c24699272e third
2047 diff -r 29114dbae42b -r 95c24699272e third
2048 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2048 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2049 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2049 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2050 @@ -0,0 +1,1 @@
2050 @@ -0,0 +1,1 @@
2051 +third
2051 +third
2052
2052
2053 $ cd ..
2053 $ cd ..
2054
2054
2055
2055
2056 latesttag:
2056 latesttag:
2057
2057
2058 $ hg init latesttag
2058 $ hg init latesttag
2059 $ cd latesttag
2059 $ cd latesttag
2060
2060
2061 $ echo a > file
2061 $ echo a > file
2062 $ hg ci -Am a -d '0 0'
2062 $ hg ci -Am a -d '0 0'
2063 adding file
2063 adding file
2064
2064
2065 $ echo b >> file
2065 $ echo b >> file
2066 $ hg ci -m b -d '1 0'
2066 $ hg ci -m b -d '1 0'
2067
2067
2068 $ echo c >> head1
2068 $ echo c >> head1
2069 $ hg ci -Am h1c -d '2 0'
2069 $ hg ci -Am h1c -d '2 0'
2070 adding head1
2070 adding head1
2071
2071
2072 $ hg update -q 1
2072 $ hg update -q 1
2073 $ echo d >> head2
2073 $ echo d >> head2
2074 $ hg ci -Am h2d -d '3 0'
2074 $ hg ci -Am h2d -d '3 0'
2075 adding head2
2075 adding head2
2076 created new head
2076 created new head
2077
2077
2078 $ echo e >> head2
2078 $ echo e >> head2
2079 $ hg ci -m h2e -d '4 0'
2079 $ hg ci -m h2e -d '4 0'
2080
2080
2081 $ hg merge -q
2081 $ hg merge -q
2082 $ hg ci -m merge -d '5 -3600'
2082 $ hg ci -m merge -d '5 -3600'
2083
2083
2084 No tag set:
2084 No tag set:
2085
2085
2086 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2086 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2087 5: null+5
2087 5: null+5
2088 4: null+4
2088 4: null+4
2089 3: null+3
2089 3: null+3
2090 2: null+3
2090 2: null+3
2091 1: null+2
2091 1: null+2
2092 0: null+1
2092 0: null+1
2093
2093
2094 One common tag: longest path wins:
2094 One common tag: longest path wins:
2095
2095
2096 $ hg tag -r 1 -m t1 -d '6 0' t1
2096 $ hg tag -r 1 -m t1 -d '6 0' t1
2097 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2097 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2098 6: t1+4
2098 6: t1+4
2099 5: t1+3
2099 5: t1+3
2100 4: t1+2
2100 4: t1+2
2101 3: t1+1
2101 3: t1+1
2102 2: t1+1
2102 2: t1+1
2103 1: t1+0
2103 1: t1+0
2104 0: null+1
2104 0: null+1
2105
2105
2106 One ancestor tag: more recent wins:
2106 One ancestor tag: more recent wins:
2107
2107
2108 $ hg tag -r 2 -m t2 -d '7 0' t2
2108 $ hg tag -r 2 -m t2 -d '7 0' t2
2109 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2109 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2110 7: t2+3
2110 7: t2+3
2111 6: t2+2
2111 6: t2+2
2112 5: t2+1
2112 5: t2+1
2113 4: t1+2
2113 4: t1+2
2114 3: t1+1
2114 3: t1+1
2115 2: t2+0
2115 2: t2+0
2116 1: t1+0
2116 1: t1+0
2117 0: null+1
2117 0: null+1
2118
2118
2119 Two branch tags: more recent wins:
2119 Two branch tags: more recent wins:
2120
2120
2121 $ hg tag -r 3 -m t3 -d '8 0' t3
2121 $ hg tag -r 3 -m t3 -d '8 0' t3
2122 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2122 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2123 8: t3+5
2123 8: t3+5
2124 7: t3+4
2124 7: t3+4
2125 6: t3+3
2125 6: t3+3
2126 5: t3+2
2126 5: t3+2
2127 4: t3+1
2127 4: t3+1
2128 3: t3+0
2128 3: t3+0
2129 2: t2+0
2129 2: t2+0
2130 1: t1+0
2130 1: t1+0
2131 0: null+1
2131 0: null+1
2132
2132
2133 Merged tag overrides:
2133 Merged tag overrides:
2134
2134
2135 $ hg tag -r 5 -m t5 -d '9 0' t5
2135 $ hg tag -r 5 -m t5 -d '9 0' t5
2136 $ hg tag -r 3 -m at3 -d '10 0' at3
2136 $ hg tag -r 3 -m at3 -d '10 0' at3
2137 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2137 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2138 10: t5+5
2138 10: t5+5
2139 9: t5+4
2139 9: t5+4
2140 8: t5+3
2140 8: t5+3
2141 7: t5+2
2141 7: t5+2
2142 6: t5+1
2142 6: t5+1
2143 5: t5+0
2143 5: t5+0
2144 4: at3:t3+1
2144 4: at3:t3+1
2145 3: at3:t3+0
2145 3: at3:t3+0
2146 2: t2+0
2146 2: t2+0
2147 1: t1+0
2147 1: t1+0
2148 0: null+1
2148 0: null+1
2149
2149
2150 $ cd ..
2150 $ cd ..
2151
2151
2152
2152
2153 Style path expansion: issue1948 - ui.style option doesn't work on OSX
2153 Style path expansion: issue1948 - ui.style option doesn't work on OSX
2154 if it is a relative path
2154 if it is a relative path
2155
2155
2156 $ mkdir -p home/styles
2156 $ mkdir -p home/styles
2157
2157
2158 $ cat > home/styles/teststyle <<EOF
2158 $ cat > home/styles/teststyle <<EOF
2159 > changeset = 'test {rev}:{node|short}\n'
2159 > changeset = 'test {rev}:{node|short}\n'
2160 > EOF
2160 > EOF
2161
2161
2162 $ HOME=`pwd`/home; export HOME
2162 $ HOME=`pwd`/home; export HOME
2163
2163
2164 $ cat > latesttag/.hg/hgrc <<EOF
2164 $ cat > latesttag/.hg/hgrc <<EOF
2165 > [ui]
2165 > [ui]
2166 > style = ~/styles/teststyle
2166 > style = ~/styles/teststyle
2167 > EOF
2167 > EOF
2168
2168
2169 $ hg -R latesttag tip
2169 $ hg -R latesttag tip
2170 test 10:9b4a630e5f5f
2170 test 10:9b4a630e5f5f
2171
2171
2172 Test recursive showlist template (issue1989):
2172 Test recursive showlist template (issue1989):
2173
2173
2174 $ cat > style1989 <<EOF
2174 $ cat > style1989 <<EOF
2175 > changeset = '{file_mods}{manifest}{extras}'
2175 > changeset = '{file_mods}{manifest}{extras}'
2176 > file_mod = 'M|{author|person}\n'
2176 > file_mod = 'M|{author|person}\n'
2177 > manifest = '{rev},{author}\n'
2177 > manifest = '{rev},{author}\n'
2178 > extra = '{key}: {author}\n'
2178 > extra = '{key}: {author}\n'
2179 > EOF
2179 > EOF
2180
2180
2181 $ hg -R latesttag log -r tip --style=style1989
2181 $ hg -R latesttag log -r tip --style=style1989
2182 M|test
2182 M|test
2183 10,test
2183 10,test
2184 branch: test
2184 branch: test
2185
2185
2186 Test new-style inline templating:
2186 Test new-style inline templating:
2187
2187
2188 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
2188 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
2189 modified files: .hgtags
2189 modified files: .hgtags
2190
2190
2191 Test the sub function of templating for expansion:
2191 Test the sub function of templating for expansion:
2192
2192
2193 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
2193 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
2194 xx
2194 xx
2195
2195
2196 Test the strip function with chars specified:
2196 Test the strip function with chars specified:
2197
2197
2198 $ hg log -R latesttag --template '{desc}\n'
2198 $ hg log -R latesttag --template '{desc}\n'
2199 at3
2199 at3
2200 t5
2200 t5
2201 t3
2201 t3
2202 t2
2202 t2
2203 t1
2203 t1
2204 merge
2204 merge
2205 h2e
2205 h2e
2206 h2d
2206 h2d
2207 h1c
2207 h1c
2208 b
2208 b
2209 a
2209 a
2210
2210
2211 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2211 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2212 at3
2212 at3
2213 5
2213 5
2214 3
2214 3
2215 2
2215 2
2216 1
2216 1
2217 merg
2217 merg
2218 h2
2218 h2
2219 h2d
2219 h2d
2220 h1c
2220 h1c
2221 b
2221 b
2222 a
2222 a
2223
2223
2224 Test date format:
2224 Test date format:
2225
2225
2226 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2226 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2227 date: 70 01 01 10 +0000
2227 date: 70 01 01 10 +0000
2228 date: 70 01 01 09 +0000
2228 date: 70 01 01 09 +0000
2229 date: 70 01 01 08 +0000
2229 date: 70 01 01 08 +0000
2230 date: 70 01 01 07 +0000
2230 date: 70 01 01 07 +0000
2231 date: 70 01 01 06 +0000
2231 date: 70 01 01 06 +0000
2232 date: 70 01 01 05 +0100
2232 date: 70 01 01 05 +0100
2233 date: 70 01 01 04 +0000
2233 date: 70 01 01 04 +0000
2234 date: 70 01 01 03 +0000
2234 date: 70 01 01 03 +0000
2235 date: 70 01 01 02 +0000
2235 date: 70 01 01 02 +0000
2236 date: 70 01 01 01 +0000
2236 date: 70 01 01 01 +0000
2237 date: 70 01 01 00 +0000
2237 date: 70 01 01 00 +0000
2238
2238
2239 Test invalid date:
2239 Test invalid date:
2240
2240
2241 $ hg log -R latesttag -T '{date(rev)}\n'
2241 $ hg log -R latesttag -T '{date(rev)}\n'
2242 hg: parse error: date expects a date information
2242 hg: parse error: date expects a date information
2243 [255]
2243 [255]
2244
2244
2245 Test string escaping:
2245 Test string escaping:
2246
2246
2247 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2247 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2248 >
2248 >
2249 <>\n<[>
2249 <>\n<[>
2250 <>\n<]>
2250 <>\n<]>
2251 <>\n<
2251 <>\n<
2252
2252
2253 $ hg log -R latesttag -r 0 \
2254 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2255 >
2256 <>\n<[>
2257 <>\n<]>
2258 <>\n<
2259
2260 $ hg log -R latesttag -r 0 -T esc \
2261 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2262 >
2263 <>\n<[>
2264 <>\n<]>
2265 <>\n<
2266
2267 $ cat <<'EOF' > esctmpl
2268 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2269 > EOF
2270 $ hg log -R latesttag -r 0 --style ./esctmpl
2271 >
2272 <>\n<[>
2273 <>\n<]>
2274 <>\n<
2275
2253 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
2276 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
2254
2277
2255 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
2278 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
2256 \x6e
2279 \x6e
2257 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
2280 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
2258 \x5c\x786e
2281 \x5c\x786e
2259 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
2282 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
2260 \x6e
2283 \x6e
2261 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
2284 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
2262 \x5c\x786e
2285 \x5c\x786e
2263
2286
2264 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
2287 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
2265 \x6e
2288 \x6e
2266 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
2289 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
2267 \x5c\x786e
2290 \x5c\x786e
2268 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
2291 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
2269 \x6e
2292 \x6e
2270 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
2293 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
2271 \x5c\x786e
2294 \x5c\x786e
2272
2295
2273 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
2296 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
2274 fourth
2297 fourth
2275 second
2298 second
2276 third
2299 third
2277 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
2300 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
2278 fourth\nsecond\nthird
2301 fourth\nsecond\nthird
2279
2302
2280 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
2303 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
2281 <p>
2304 <p>
2282 1st
2305 1st
2283 </p>
2306 </p>
2284 <p>
2307 <p>
2285 2nd
2308 2nd
2286 </p>
2309 </p>
2287 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
2310 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
2288 <p>
2311 <p>
2289 1st\n\n2nd
2312 1st\n\n2nd
2290 </p>
2313 </p>
2291 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
2314 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
2292 1st
2315 1st
2293
2316
2294 2nd
2317 2nd
2295
2318
2296 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
2319 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
2297 o perso
2320 o perso
2298 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
2321 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
2299 no person
2322 no person
2300 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
2323 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
2301 o perso
2324 o perso
2302 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
2325 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
2303 no perso
2326 no perso
2304
2327
2305 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
2328 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
2306 -o perso-
2329 -o perso-
2307 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
2330 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
2308 no person
2331 no person
2309 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
2332 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
2310 \x2do perso\x2d
2333 \x2do perso\x2d
2311 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
2334 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
2312 -o perso-
2335 -o perso-
2313 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
2336 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
2314 \x2do perso\x6e
2337 \x2do perso\x6e
2315
2338
2316 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
2339 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
2317 fourth
2340 fourth
2318 second
2341 second
2319 third
2342 third
2320 $ hg log -R a -r 8 --template '{files % r"{file}\n"}\n'
2343 $ hg log -R a -r 8 --template '{files % r"{file}\n"}\n'
2321 fourth\nsecond\nthird\n
2344 fourth\nsecond\nthird\n
2322
2345
2323 Test string escaping in nested expression:
2346 Test string escaping in nested expression:
2324
2347
2325 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
2348 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
2326 fourth\x6esecond\x6ethird
2349 fourth\x6esecond\x6ethird
2327 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
2350 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
2328 fourth\x6esecond\x6ethird
2351 fourth\x6esecond\x6ethird
2329
2352
2330 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
2353 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
2331 fourth\x6esecond\x6ethird
2354 fourth\x6esecond\x6ethird
2332 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
2355 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
2333 fourth\x5c\x786esecond\x5c\x786ethird
2356 fourth\x5c\x786esecond\x5c\x786ethird
2334
2357
2335 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
2358 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
2336 3:\x6eo user, \x6eo domai\x6e
2359 3:\x6eo user, \x6eo domai\x6e
2337 4:\x5c\x786eew bra\x5c\x786ech
2360 4:\x5c\x786eew bra\x5c\x786ech
2338
2361
2339 Test recursive evaluation:
2362 Test recursive evaluation:
2340
2363
2341 $ hg init r
2364 $ hg init r
2342 $ cd r
2365 $ cd r
2343 $ echo a > a
2366 $ echo a > a
2344 $ hg ci -Am '{rev}'
2367 $ hg ci -Am '{rev}'
2345 adding a
2368 adding a
2346 $ hg log -r 0 --template '{if(rev, desc)}\n'
2369 $ hg log -r 0 --template '{if(rev, desc)}\n'
2347 {rev}
2370 {rev}
2348 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
2371 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
2349 test 0
2372 test 0
2350
2373
2351 $ hg branch -q 'text.{rev}'
2374 $ hg branch -q 'text.{rev}'
2352 $ echo aa >> aa
2375 $ echo aa >> aa
2353 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
2376 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
2354
2377
2355 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
2378 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
2356 {node|short}desc to
2379 {node|short}desc to
2357 text.{rev}be wrapped
2380 text.{rev}be wrapped
2358 text.{rev}desc to be
2381 text.{rev}desc to be
2359 text.{rev}wrapped (no-eol)
2382 text.{rev}wrapped (no-eol)
2360 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
2383 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
2361 bcc7ff960b8e:desc to
2384 bcc7ff960b8e:desc to
2362 text.1:be wrapped
2385 text.1:be wrapped
2363 text.1:desc to be
2386 text.1:desc to be
2364 text.1:wrapped (no-eol)
2387 text.1:wrapped (no-eol)
2365
2388
2366 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
2389 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
2367 {node|short} (no-eol)
2390 {node|short} (no-eol)
2368 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
2391 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
2369 bcc-ff---b-e (no-eol)
2392 bcc-ff---b-e (no-eol)
2370
2393
2371 $ cat >> .hg/hgrc <<EOF
2394 $ cat >> .hg/hgrc <<EOF
2372 > [extensions]
2395 > [extensions]
2373 > color=
2396 > color=
2374 > [color]
2397 > [color]
2375 > mode=ansi
2398 > mode=ansi
2376 > text.{rev} = red
2399 > text.{rev} = red
2377 > text.1 = green
2400 > text.1 = green
2378 > EOF
2401 > EOF
2379 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
2402 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
2380 \x1b[0;31mtext\x1b[0m (esc)
2403 \x1b[0;31mtext\x1b[0m (esc)
2381 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
2404 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
2382 \x1b[0;32mtext\x1b[0m (esc)
2405 \x1b[0;32mtext\x1b[0m (esc)
2383
2406
2384 Test branches inside if statement:
2407 Test branches inside if statement:
2385
2408
2386 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
2409 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
2387 no
2410 no
2388
2411
2389 Test get function:
2412 Test get function:
2390
2413
2391 $ hg log -r 0 --template '{get(extras, "branch")}\n'
2414 $ hg log -r 0 --template '{get(extras, "branch")}\n'
2392 default
2415 default
2393 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
2416 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
2394 hg: parse error: get() expects a dict as first argument
2417 hg: parse error: get() expects a dict as first argument
2395 [255]
2418 [255]
2396
2419
2397 Test shortest(node) function:
2420 Test shortest(node) function:
2398
2421
2399 $ echo b > b
2422 $ echo b > b
2400 $ hg ci -qAm b
2423 $ hg ci -qAm b
2401 $ hg log --template '{shortest(node)}\n'
2424 $ hg log --template '{shortest(node)}\n'
2402 e777
2425 e777
2403 bcc7
2426 bcc7
2404 f776
2427 f776
2405 $ hg log --template '{shortest(node, 10)}\n'
2428 $ hg log --template '{shortest(node, 10)}\n'
2406 e777603221
2429 e777603221
2407 bcc7ff960b
2430 bcc7ff960b
2408 f7769ec2ab
2431 f7769ec2ab
2409
2432
2410 Test pad function
2433 Test pad function
2411
2434
2412 $ hg log --template '{pad(rev, 20)} {author|user}\n'
2435 $ hg log --template '{pad(rev, 20)} {author|user}\n'
2413 2 test
2436 2 test
2414 1 {node|short}
2437 1 {node|short}
2415 0 test
2438 0 test
2416
2439
2417 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
2440 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
2418 2 test
2441 2 test
2419 1 {node|short}
2442 1 {node|short}
2420 0 test
2443 0 test
2421
2444
2422 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
2445 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
2423 2------------------- test
2446 2------------------- test
2424 1------------------- {node|short}
2447 1------------------- {node|short}
2425 0------------------- test
2448 0------------------- test
2426
2449
2427 Test ifcontains function
2450 Test ifcontains function
2428
2451
2429 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
2452 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
2430 2 is in the string
2453 2 is in the string
2431 1 is not
2454 1 is not
2432 0 is in the string
2455 0 is in the string
2433
2456
2434 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
2457 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
2435 2 did not add a
2458 2 did not add a
2436 1 did not add a
2459 1 did not add a
2437 0 added a
2460 0 added a
2438
2461
2439 Test revset function
2462 Test revset function
2440
2463
2441 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
2464 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
2442 2 current rev
2465 2 current rev
2443 1 not current rev
2466 1 not current rev
2444 0 not current rev
2467 0 not current rev
2445
2468
2446 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
2469 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
2447 2 match rev
2470 2 match rev
2448 1 match rev
2471 1 match rev
2449 0 not match rev
2472 0 not match rev
2450
2473
2451 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
2474 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
2452 2 Parents: 1
2475 2 Parents: 1
2453 1 Parents: 0
2476 1 Parents: 0
2454 0 Parents:
2477 0 Parents:
2455
2478
2456 $ cat >> .hg/hgrc <<EOF
2479 $ cat >> .hg/hgrc <<EOF
2457 > [revsetalias]
2480 > [revsetalias]
2458 > myparents(\$1) = parents(\$1)
2481 > myparents(\$1) = parents(\$1)
2459 > EOF
2482 > EOF
2460 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
2483 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
2461 2 Parents: 1
2484 2 Parents: 1
2462 1 Parents: 0
2485 1 Parents: 0
2463 0 Parents:
2486 0 Parents:
2464
2487
2465 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
2488 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
2466 Rev: 2
2489 Rev: 2
2467 Ancestor: 0
2490 Ancestor: 0
2468 Ancestor: 1
2491 Ancestor: 1
2469 Ancestor: 2
2492 Ancestor: 2
2470
2493
2471 Rev: 1
2494 Rev: 1
2472 Ancestor: 0
2495 Ancestor: 0
2473 Ancestor: 1
2496 Ancestor: 1
2474
2497
2475 Rev: 0
2498 Rev: 0
2476 Ancestor: 0
2499 Ancestor: 0
2477
2500
2478 Test current bookmark templating
2501 Test current bookmark templating
2479
2502
2480 $ hg book foo
2503 $ hg book foo
2481 $ hg book bar
2504 $ hg book bar
2482 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}\n"
2505 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}\n"
2483 2 bar* foo
2506 2 bar* foo
2484 1
2507 1
2485 0
2508 0
2486 $ hg log --template "{rev} {currentbookmark}\n"
2509 $ hg log --template "{rev} {currentbookmark}\n"
2487 2 bar
2510 2 bar
2488 1
2511 1
2489 0
2512 0
2490 $ hg bookmarks --inactive bar
2513 $ hg bookmarks --inactive bar
2491 $ hg log --template "{rev} {currentbookmark}\n"
2514 $ hg log --template "{rev} {currentbookmark}\n"
2492 2
2515 2
2493 1
2516 1
2494 0
2517 0
2495 $ hg book -r1 baz
2518 $ hg book -r1 baz
2496 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
2519 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
2497 2 bar foo
2520 2 bar foo
2498 1 baz
2521 1 baz
2499 0
2522 0
2500 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
2523 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
2501 2 t
2524 2 t
2502 1 f
2525 1 f
2503 0 f
2526 0 f
2504
2527
2505 Test stringify on sub expressions
2528 Test stringify on sub expressions
2506
2529
2507 $ cd ..
2530 $ cd ..
2508 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
2531 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
2509 fourth, second, third
2532 fourth, second, third
2510 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
2533 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
2511 abc
2534 abc
2512
2535
2513 Test splitlines
2536 Test splitlines
2514
2537
2515 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
2538 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
2516 @ foo future
2539 @ foo future
2517 |
2540 |
2518 o foo third
2541 o foo third
2519 |
2542 |
2520 o foo second
2543 o foo second
2521
2544
2522 o foo merge
2545 o foo merge
2523 |\
2546 |\
2524 | o foo new head
2547 | o foo new head
2525 | |
2548 | |
2526 o | foo new branch
2549 o | foo new branch
2527 |/
2550 |/
2528 o foo no user, no domain
2551 o foo no user, no domain
2529 |
2552 |
2530 o foo no person
2553 o foo no person
2531 |
2554 |
2532 o foo other 1
2555 o foo other 1
2533 | foo other 2
2556 | foo other 2
2534 | foo
2557 | foo
2535 | foo other 3
2558 | foo other 3
2536 o foo line 1
2559 o foo line 1
2537 foo line 2
2560 foo line 2
2538
2561
2539 Test startswith
2562 Test startswith
2540 $ hg log -Gv -R a --template "{startswith(desc)}"
2563 $ hg log -Gv -R a --template "{startswith(desc)}"
2541 hg: parse error: startswith expects two arguments
2564 hg: parse error: startswith expects two arguments
2542 [255]
2565 [255]
2543
2566
2544 $ hg log -Gv -R a --template "{startswith('line', desc)}"
2567 $ hg log -Gv -R a --template "{startswith('line', desc)}"
2545 @
2568 @
2546 |
2569 |
2547 o
2570 o
2548 |
2571 |
2549 o
2572 o
2550
2573
2551 o
2574 o
2552 |\
2575 |\
2553 | o
2576 | o
2554 | |
2577 | |
2555 o |
2578 o |
2556 |/
2579 |/
2557 o
2580 o
2558 |
2581 |
2559 o
2582 o
2560 |
2583 |
2561 o
2584 o
2562 |
2585 |
2563 o line 1
2586 o line 1
2564 line 2
2587 line 2
2565
2588
2566 Test bad template with better error message
2589 Test bad template with better error message
2567
2590
2568 $ hg log -Gv -R a --template '{desc|user()}'
2591 $ hg log -Gv -R a --template '{desc|user()}'
2569 hg: parse error: expected a symbol, got 'func'
2592 hg: parse error: expected a symbol, got 'func'
2570 [255]
2593 [255]
2571
2594
2572 Test word function (including index out of bounds graceful failure)
2595 Test word function (including index out of bounds graceful failure)
2573
2596
2574 $ hg log -Gv -R a --template "{word('1', desc)}"
2597 $ hg log -Gv -R a --template "{word('1', desc)}"
2575 @
2598 @
2576 |
2599 |
2577 o
2600 o
2578 |
2601 |
2579 o
2602 o
2580
2603
2581 o
2604 o
2582 |\
2605 |\
2583 | o head
2606 | o head
2584 | |
2607 | |
2585 o | branch
2608 o | branch
2586 |/
2609 |/
2587 o user,
2610 o user,
2588 |
2611 |
2589 o person
2612 o person
2590 |
2613 |
2591 o 1
2614 o 1
2592 |
2615 |
2593 o 1
2616 o 1
2594
2617
2595
2618
2596 Test word third parameter used as splitter
2619 Test word third parameter used as splitter
2597
2620
2598 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
2621 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
2599 @ future
2622 @ future
2600 |
2623 |
2601 o third
2624 o third
2602 |
2625 |
2603 o sec
2626 o sec
2604
2627
2605 o merge
2628 o merge
2606 |\
2629 |\
2607 | o new head
2630 | o new head
2608 | |
2631 | |
2609 o | new branch
2632 o | new branch
2610 |/
2633 |/
2611 o n
2634 o n
2612 |
2635 |
2613 o n
2636 o n
2614 |
2637 |
2615 o
2638 o
2616 |
2639 |
2617 o line 1
2640 o line 1
2618 line 2
2641 line 2
2619
2642
2620 Test word error messages for not enough and too many arguments
2643 Test word error messages for not enough and too many arguments
2621
2644
2622 $ hg log -Gv -R a --template "{word('0')}"
2645 $ hg log -Gv -R a --template "{word('0')}"
2623 hg: parse error: word expects two or three arguments, got 1
2646 hg: parse error: word expects two or three arguments, got 1
2624 [255]
2647 [255]
2625
2648
2626 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
2649 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
2627 hg: parse error: word expects two or three arguments, got 7
2650 hg: parse error: word expects two or three arguments, got 7
2628 [255]
2651 [255]
2629
2652
2630 Test word for invalid numbers
2653 Test word for invalid numbers
2631
2654
2632 $ hg log -Gv -R a --template "{word(2, desc)}"
2655 $ hg log -Gv -R a --template "{word(2, desc)}"
2633 hg: parse error: Use strings like '3' for numbers passed to word function
2656 hg: parse error: Use strings like '3' for numbers passed to word function
2634 [255]
2657 [255]
General Comments 0
You need to be logged in to leave comments. Login now