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