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