##// END OF EJS Templates
template: call runtemplate on the src argument to sub...
Sean Farley -
r19058:d8d548d8 default
parent child Browse files
Show More
@@ -1,518 +1,520 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 sys, os, re
9 import sys, os, re
10 import util, config, templatefilters, parser, error
10 import util, config, templatefilters, parser, error
11 import types
11 import types
12 import minirst
12 import minirst
13
13
14 # template parsing
14 # template parsing
15
15
16 elements = {
16 elements = {
17 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
17 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
18 ",": (2, None, ("list", 2)),
18 ",": (2, None, ("list", 2)),
19 "|": (5, None, ("|", 5)),
19 "|": (5, None, ("|", 5)),
20 "%": (6, None, ("%", 6)),
20 "%": (6, None, ("%", 6)),
21 ")": (0, None, None),
21 ")": (0, None, None),
22 "symbol": (0, ("symbol",), None),
22 "symbol": (0, ("symbol",), None),
23 "string": (0, ("string",), None),
23 "string": (0, ("string",), None),
24 "end": (0, None, None),
24 "end": (0, None, None),
25 }
25 }
26
26
27 def tokenizer(data):
27 def tokenizer(data):
28 program, start, end = data
28 program, start, end = data
29 pos = start
29 pos = start
30 while pos < end:
30 while pos < end:
31 c = program[pos]
31 c = program[pos]
32 if c.isspace(): # skip inter-token whitespace
32 if c.isspace(): # skip inter-token whitespace
33 pass
33 pass
34 elif c in "(,)%|": # handle simple operators
34 elif c in "(,)%|": # handle simple operators
35 yield (c, None, pos)
35 yield (c, None, pos)
36 elif (c in '"\'' or c == 'r' and
36 elif (c in '"\'' or c == 'r' and
37 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
37 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
38 if c == 'r':
38 if c == 'r':
39 pos += 1
39 pos += 1
40 c = program[pos]
40 c = program[pos]
41 decode = False
41 decode = False
42 else:
42 else:
43 decode = True
43 decode = True
44 pos += 1
44 pos += 1
45 s = pos
45 s = pos
46 while pos < end: # find closing quote
46 while pos < end: # find closing quote
47 d = program[pos]
47 d = program[pos]
48 if decode and d == '\\': # skip over escaped characters
48 if decode and d == '\\': # skip over escaped characters
49 pos += 2
49 pos += 2
50 continue
50 continue
51 if d == c:
51 if d == c:
52 if not decode:
52 if not decode:
53 yield ('string', program[s:pos].replace('\\', r'\\'), s)
53 yield ('string', program[s:pos].replace('\\', r'\\'), s)
54 break
54 break
55 yield ('string', program[s:pos].decode('string-escape'), s)
55 yield ('string', program[s:pos].decode('string-escape'), s)
56 break
56 break
57 pos += 1
57 pos += 1
58 else:
58 else:
59 raise error.ParseError(_("unterminated string"), s)
59 raise error.ParseError(_("unterminated string"), s)
60 elif c.isalnum() or c in '_':
60 elif c.isalnum() or c in '_':
61 s = pos
61 s = pos
62 pos += 1
62 pos += 1
63 while pos < end: # find end of symbol
63 while pos < end: # find end of symbol
64 d = program[pos]
64 d = program[pos]
65 if not (d.isalnum() or d == "_"):
65 if not (d.isalnum() or d == "_"):
66 break
66 break
67 pos += 1
67 pos += 1
68 sym = program[s:pos]
68 sym = program[s:pos]
69 yield ('symbol', sym, s)
69 yield ('symbol', sym, s)
70 pos -= 1
70 pos -= 1
71 elif c == '}':
71 elif c == '}':
72 pos += 1
72 pos += 1
73 break
73 break
74 else:
74 else:
75 raise error.ParseError(_("syntax error"), pos)
75 raise error.ParseError(_("syntax error"), pos)
76 pos += 1
76 pos += 1
77 yield ('end', None, pos)
77 yield ('end', None, pos)
78
78
79 def compiletemplate(tmpl, context):
79 def compiletemplate(tmpl, context):
80 parsed = []
80 parsed = []
81 pos, stop = 0, len(tmpl)
81 pos, stop = 0, len(tmpl)
82 p = parser.parser(tokenizer, elements)
82 p = parser.parser(tokenizer, elements)
83
83
84 while pos < stop:
84 while pos < stop:
85 n = tmpl.find('{', pos)
85 n = tmpl.find('{', pos)
86 if n < 0:
86 if n < 0:
87 parsed.append(("string", tmpl[pos:]))
87 parsed.append(("string", tmpl[pos:]))
88 break
88 break
89 if n > 0 and tmpl[n - 1] == '\\':
89 if n > 0 and tmpl[n - 1] == '\\':
90 # escaped
90 # escaped
91 parsed.append(("string", tmpl[pos:n - 1] + "{"))
91 parsed.append(("string", tmpl[pos:n - 1] + "{"))
92 pos = n + 1
92 pos = n + 1
93 continue
93 continue
94 if n > pos:
94 if n > pos:
95 parsed.append(("string", tmpl[pos:n]))
95 parsed.append(("string", tmpl[pos:n]))
96
96
97 pd = [tmpl, n + 1, stop]
97 pd = [tmpl, n + 1, stop]
98 parseres, pos = p.parse(pd)
98 parseres, pos = p.parse(pd)
99 parsed.append(parseres)
99 parsed.append(parseres)
100
100
101 return [compileexp(e, context) for e in parsed]
101 return [compileexp(e, context) for e in parsed]
102
102
103 def compileexp(exp, context):
103 def compileexp(exp, context):
104 t = exp[0]
104 t = exp[0]
105 if t in methods:
105 if t in methods:
106 return methods[t](exp, context)
106 return methods[t](exp, context)
107 raise error.ParseError(_("unknown method '%s'") % t)
107 raise error.ParseError(_("unknown method '%s'") % t)
108
108
109 # template evaluation
109 # template evaluation
110
110
111 def getsymbol(exp):
111 def getsymbol(exp):
112 if exp[0] == 'symbol':
112 if exp[0] == 'symbol':
113 return exp[1]
113 return exp[1]
114 raise error.ParseError(_("expected a symbol"))
114 raise error.ParseError(_("expected a symbol"))
115
115
116 def getlist(x):
116 def getlist(x):
117 if not x:
117 if not x:
118 return []
118 return []
119 if x[0] == 'list':
119 if x[0] == 'list':
120 return getlist(x[1]) + [x[2]]
120 return getlist(x[1]) + [x[2]]
121 return [x]
121 return [x]
122
122
123 def getfilter(exp, context):
123 def getfilter(exp, context):
124 f = getsymbol(exp)
124 f = getsymbol(exp)
125 if f not in context._filters:
125 if f not in context._filters:
126 raise error.ParseError(_("unknown function '%s'") % f)
126 raise error.ParseError(_("unknown function '%s'") % f)
127 return context._filters[f]
127 return context._filters[f]
128
128
129 def gettemplate(exp, context):
129 def gettemplate(exp, context):
130 if exp[0] == 'string':
130 if exp[0] == 'string':
131 return compiletemplate(exp[1], context)
131 return compiletemplate(exp[1], context)
132 if exp[0] == 'symbol':
132 if exp[0] == 'symbol':
133 return context._load(exp[1])
133 return context._load(exp[1])
134 raise error.ParseError(_("expected template specifier"))
134 raise error.ParseError(_("expected template specifier"))
135
135
136 def runstring(context, mapping, data):
136 def runstring(context, mapping, data):
137 return data
137 return data
138
138
139 def runsymbol(context, mapping, key):
139 def runsymbol(context, mapping, key):
140 v = mapping.get(key)
140 v = mapping.get(key)
141 if v is None:
141 if v is None:
142 v = context._defaults.get(key, '')
142 v = context._defaults.get(key, '')
143 if util.safehasattr(v, '__call__'):
143 if util.safehasattr(v, '__call__'):
144 return v(**mapping)
144 return v(**mapping)
145 if isinstance(v, types.GeneratorType):
145 if isinstance(v, types.GeneratorType):
146 v = list(v)
146 v = list(v)
147 mapping[key] = v
147 mapping[key] = v
148 return v
148 return v
149 return v
149 return v
150
150
151 def buildfilter(exp, context):
151 def buildfilter(exp, context):
152 func, data = compileexp(exp[1], context)
152 func, data = compileexp(exp[1], context)
153 filt = getfilter(exp[2], context)
153 filt = getfilter(exp[2], context)
154 return (runfilter, (func, data, filt))
154 return (runfilter, (func, data, filt))
155
155
156 def runfilter(context, mapping, data):
156 def runfilter(context, mapping, data):
157 func, data, filt = data
157 func, data, filt = data
158 try:
158 try:
159 return filt(func(context, mapping, data))
159 return filt(func(context, mapping, data))
160 except (ValueError, AttributeError, TypeError):
160 except (ValueError, AttributeError, TypeError):
161 if isinstance(data, tuple):
161 if isinstance(data, tuple):
162 dt = data[1]
162 dt = data[1]
163 else:
163 else:
164 dt = data
164 dt = data
165 raise util.Abort(_("template filter '%s' is not compatible with "
165 raise util.Abort(_("template filter '%s' is not compatible with "
166 "keyword '%s'") % (filt.func_name, dt))
166 "keyword '%s'") % (filt.func_name, dt))
167
167
168 def buildmap(exp, context):
168 def buildmap(exp, context):
169 func, data = compileexp(exp[1], context)
169 func, data = compileexp(exp[1], context)
170 ctmpl = gettemplate(exp[2], context)
170 ctmpl = gettemplate(exp[2], context)
171 return (runmap, (func, data, ctmpl))
171 return (runmap, (func, data, ctmpl))
172
172
173 def runtemplate(context, mapping, template):
173 def runtemplate(context, mapping, template):
174 for func, data in template:
174 for func, data in template:
175 yield func(context, mapping, data)
175 yield func(context, mapping, data)
176
176
177 def runmap(context, mapping, data):
177 def runmap(context, mapping, data):
178 func, data, ctmpl = data
178 func, data, ctmpl = data
179 d = func(context, mapping, data)
179 d = func(context, mapping, data)
180 if util.safehasattr(d, '__call__'):
180 if util.safehasattr(d, '__call__'):
181 d = d()
181 d = d()
182
182
183 lm = mapping.copy()
183 lm = mapping.copy()
184
184
185 for i in d:
185 for i in d:
186 if isinstance(i, dict):
186 if isinstance(i, dict):
187 lm.update(i)
187 lm.update(i)
188 lm['originalnode'] = mapping.get('node')
188 lm['originalnode'] = mapping.get('node')
189 yield runtemplate(context, lm, ctmpl)
189 yield runtemplate(context, lm, ctmpl)
190 else:
190 else:
191 # v is not an iterable of dicts, this happen when 'key'
191 # v is not an iterable of dicts, this happen when 'key'
192 # has been fully expanded already and format is useless.
192 # has been fully expanded already and format is useless.
193 # If so, return the expanded value.
193 # If so, return the expanded value.
194 yield i
194 yield i
195
195
196 def buildfunc(exp, context):
196 def buildfunc(exp, context):
197 n = getsymbol(exp[1])
197 n = getsymbol(exp[1])
198 args = [compileexp(x, context) for x in getlist(exp[2])]
198 args = [compileexp(x, context) for x in getlist(exp[2])]
199 if n in funcs:
199 if n in funcs:
200 f = funcs[n]
200 f = funcs[n]
201 return (f, args)
201 return (f, args)
202 if n in templatefilters.funcs:
202 if n in templatefilters.funcs:
203 f = templatefilters.funcs[n]
203 f = templatefilters.funcs[n]
204 return (f, args)
204 return (f, args)
205 if n in context._filters:
205 if n in context._filters:
206 if len(args) != 1:
206 if len(args) != 1:
207 raise error.ParseError(_("filter %s expects one argument") % n)
207 raise error.ParseError(_("filter %s expects one argument") % n)
208 f = context._filters[n]
208 f = context._filters[n]
209 return (runfilter, (args[0][0], args[0][1], f))
209 return (runfilter, (args[0][0], args[0][1], f))
210
210
211 def get(context, mapping, args):
211 def get(context, mapping, args):
212 if len(args) != 2:
212 if len(args) != 2:
213 # i18n: "get" is a keyword
213 # i18n: "get" is a keyword
214 raise error.ParseError(_("get() expects two arguments"))
214 raise error.ParseError(_("get() expects two arguments"))
215
215
216 dictarg = args[0][0](context, mapping, args[0][1])
216 dictarg = args[0][0](context, mapping, args[0][1])
217 if not util.safehasattr(dictarg, 'get'):
217 if not util.safehasattr(dictarg, 'get'):
218 # i18n: "get" is a keyword
218 # i18n: "get" is a keyword
219 raise error.ParseError(_("get() expects a dict as first argument"))
219 raise error.ParseError(_("get() expects a dict as first argument"))
220
220
221 key = args[1][0](context, mapping, args[1][1])
221 key = args[1][0](context, mapping, args[1][1])
222 yield dictarg.get(key)
222 yield dictarg.get(key)
223
223
224 def join(context, mapping, args):
224 def join(context, mapping, args):
225 if not (1 <= len(args) <= 2):
225 if not (1 <= len(args) <= 2):
226 # i18n: "join" is a keyword
226 # i18n: "join" is a keyword
227 raise error.ParseError(_("join expects one or two arguments"))
227 raise error.ParseError(_("join expects one or two arguments"))
228
228
229 joinset = args[0][0](context, mapping, args[0][1])
229 joinset = args[0][0](context, mapping, args[0][1])
230 if util.safehasattr(joinset, '__call__'):
230 if util.safehasattr(joinset, '__call__'):
231 jf = joinset.joinfmt
231 jf = joinset.joinfmt
232 joinset = [jf(x) for x in joinset()]
232 joinset = [jf(x) for x in joinset()]
233
233
234 joiner = " "
234 joiner = " "
235 if len(args) > 1:
235 if len(args) > 1:
236 joiner = args[1][0](context, mapping, args[1][1])
236 joiner = args[1][0](context, mapping, args[1][1])
237
237
238 first = True
238 first = True
239 for x in joinset:
239 for x in joinset:
240 if first:
240 if first:
241 first = False
241 first = False
242 else:
242 else:
243 yield joiner
243 yield joiner
244 yield x
244 yield x
245
245
246 def sub(context, mapping, args):
246 def sub(context, mapping, args):
247 if len(args) != 3:
247 if len(args) != 3:
248 # i18n: "sub" is a keyword
248 # i18n: "sub" is a keyword
249 raise error.ParseError(_("sub expects three arguments"))
249 raise error.ParseError(_("sub expects three arguments"))
250
250
251 pat = stringify(args[0][0](context, mapping, args[0][1]))
251 pat = stringify(args[0][0](context, mapping, args[0][1]))
252 rpl = stringify(args[1][0](context, mapping, args[1][1]))
252 rpl = stringify(args[1][0](context, mapping, args[1][1]))
253 src = stringify(args[2][0](context, mapping, args[2][1]))
253 src = stringify(args[2][0](context, mapping, args[2][1]))
254 src = stringify(runtemplate(context, mapping,
255 compiletemplate(src, context)))
254 yield re.sub(pat, rpl, src)
256 yield re.sub(pat, rpl, src)
255
257
256 def if_(context, mapping, args):
258 def if_(context, mapping, args):
257 if not (2 <= len(args) <= 3):
259 if not (2 <= len(args) <= 3):
258 # i18n: "if" is a keyword
260 # i18n: "if" is a keyword
259 raise error.ParseError(_("if expects two or three arguments"))
261 raise error.ParseError(_("if expects two or three arguments"))
260
262
261 test = stringify(args[0][0](context, mapping, args[0][1]))
263 test = stringify(args[0][0](context, mapping, args[0][1]))
262 if test:
264 if test:
263 t = stringify(args[1][0](context, mapping, args[1][1]))
265 t = stringify(args[1][0](context, mapping, args[1][1]))
264 yield runtemplate(context, mapping, compiletemplate(t, context))
266 yield runtemplate(context, mapping, compiletemplate(t, context))
265 elif len(args) == 3:
267 elif len(args) == 3:
266 t = stringify(args[2][0](context, mapping, args[2][1]))
268 t = stringify(args[2][0](context, mapping, args[2][1]))
267 yield runtemplate(context, mapping, compiletemplate(t, context))
269 yield runtemplate(context, mapping, compiletemplate(t, context))
268
270
269 def ifeq(context, mapping, args):
271 def ifeq(context, mapping, args):
270 if not (3 <= len(args) <= 4):
272 if not (3 <= len(args) <= 4):
271 # i18n: "ifeq" is a keyword
273 # i18n: "ifeq" is a keyword
272 raise error.ParseError(_("ifeq expects three or four arguments"))
274 raise error.ParseError(_("ifeq expects three or four arguments"))
273
275
274 test = stringify(args[0][0](context, mapping, args[0][1]))
276 test = stringify(args[0][0](context, mapping, args[0][1]))
275 match = stringify(args[1][0](context, mapping, args[1][1]))
277 match = stringify(args[1][0](context, mapping, args[1][1]))
276 if test == match:
278 if test == match:
277 t = stringify(args[2][0](context, mapping, args[2][1]))
279 t = stringify(args[2][0](context, mapping, args[2][1]))
278 yield runtemplate(context, mapping, compiletemplate(t, context))
280 yield runtemplate(context, mapping, compiletemplate(t, context))
279 elif len(args) == 4:
281 elif len(args) == 4:
280 t = stringify(args[3][0](context, mapping, args[3][1]))
282 t = stringify(args[3][0](context, mapping, args[3][1]))
281 yield runtemplate(context, mapping, compiletemplate(t, context))
283 yield runtemplate(context, mapping, compiletemplate(t, context))
282
284
283 def label(context, mapping, args):
285 def label(context, mapping, args):
284 if len(args) != 2:
286 if len(args) != 2:
285 # i18n: "label" is a keyword
287 # i18n: "label" is a keyword
286 raise error.ParseError(_("label expects two arguments"))
288 raise error.ParseError(_("label expects two arguments"))
287
289
288 # ignore args[0] (the label string) since this is supposed to be a a no-op
290 # ignore args[0] (the label string) since this is supposed to be a a no-op
289 t = stringify(args[1][0](context, mapping, args[1][1]))
291 t = stringify(args[1][0](context, mapping, args[1][1]))
290 yield runtemplate(context, mapping, compiletemplate(t, context))
292 yield runtemplate(context, mapping, compiletemplate(t, context))
291
293
292 def rstdoc(context, mapping, args):
294 def rstdoc(context, mapping, args):
293 if len(args) != 2:
295 if len(args) != 2:
294 # i18n: "rstdoc" is a keyword
296 # i18n: "rstdoc" is a keyword
295 raise error.ParseError(_("rstdoc expects two arguments"))
297 raise error.ParseError(_("rstdoc expects two arguments"))
296
298
297 text = stringify(args[0][0](context, mapping, args[0][1]))
299 text = stringify(args[0][0](context, mapping, args[0][1]))
298 style = stringify(args[1][0](context, mapping, args[1][1]))
300 style = stringify(args[1][0](context, mapping, args[1][1]))
299
301
300 return minirst.format(text, style=style)
302 return minirst.format(text, style=style)
301
303
302 methods = {
304 methods = {
303 "string": lambda e, c: (runstring, e[1]),
305 "string": lambda e, c: (runstring, e[1]),
304 "symbol": lambda e, c: (runsymbol, e[1]),
306 "symbol": lambda e, c: (runsymbol, e[1]),
305 "group": lambda e, c: compileexp(e[1], c),
307 "group": lambda e, c: compileexp(e[1], c),
306 # ".": buildmember,
308 # ".": buildmember,
307 "|": buildfilter,
309 "|": buildfilter,
308 "%": buildmap,
310 "%": buildmap,
309 "func": buildfunc,
311 "func": buildfunc,
310 }
312 }
311
313
312 funcs = {
314 funcs = {
313 "get": get,
315 "get": get,
314 "if": if_,
316 "if": if_,
315 "ifeq": ifeq,
317 "ifeq": ifeq,
316 "join": join,
318 "join": join,
317 "label": label,
319 "label": label,
318 "rstdoc": rstdoc,
320 "rstdoc": rstdoc,
319 "sub": sub,
321 "sub": sub,
320 }
322 }
321
323
322 # template engine
324 # template engine
323
325
324 path = ['templates', '../templates']
326 path = ['templates', '../templates']
325 stringify = templatefilters.stringify
327 stringify = templatefilters.stringify
326
328
327 def _flatten(thing):
329 def _flatten(thing):
328 '''yield a single stream from a possibly nested set of iterators'''
330 '''yield a single stream from a possibly nested set of iterators'''
329 if isinstance(thing, str):
331 if isinstance(thing, str):
330 yield thing
332 yield thing
331 elif not util.safehasattr(thing, '__iter__'):
333 elif not util.safehasattr(thing, '__iter__'):
332 if thing is not None:
334 if thing is not None:
333 yield str(thing)
335 yield str(thing)
334 else:
336 else:
335 for i in thing:
337 for i in thing:
336 if isinstance(i, str):
338 if isinstance(i, str):
337 yield i
339 yield i
338 elif not util.safehasattr(i, '__iter__'):
340 elif not util.safehasattr(i, '__iter__'):
339 if i is not None:
341 if i is not None:
340 yield str(i)
342 yield str(i)
341 elif i is not None:
343 elif i is not None:
342 for j in _flatten(i):
344 for j in _flatten(i):
343 yield j
345 yield j
344
346
345 def parsestring(s, quoted=True):
347 def parsestring(s, quoted=True):
346 '''parse a string using simple c-like syntax.
348 '''parse a string using simple c-like syntax.
347 string must be in quotes if quoted is True.'''
349 string must be in quotes if quoted is True.'''
348 if quoted:
350 if quoted:
349 if len(s) < 2 or s[0] != s[-1]:
351 if len(s) < 2 or s[0] != s[-1]:
350 raise SyntaxError(_('unmatched quotes'))
352 raise SyntaxError(_('unmatched quotes'))
351 return s[1:-1].decode('string_escape')
353 return s[1:-1].decode('string_escape')
352
354
353 return s.decode('string_escape')
355 return s.decode('string_escape')
354
356
355 class engine(object):
357 class engine(object):
356 '''template expansion engine.
358 '''template expansion engine.
357
359
358 template expansion works like this. a map file contains key=value
360 template expansion works like this. a map file contains key=value
359 pairs. if value is quoted, it is treated as string. otherwise, it
361 pairs. if value is quoted, it is treated as string. otherwise, it
360 is treated as name of template file.
362 is treated as name of template file.
361
363
362 templater is asked to expand a key in map. it looks up key, and
364 templater is asked to expand a key in map. it looks up key, and
363 looks for strings like this: {foo}. it expands {foo} by looking up
365 looks for strings like this: {foo}. it expands {foo} by looking up
364 foo in map, and substituting it. expansion is recursive: it stops
366 foo in map, and substituting it. expansion is recursive: it stops
365 when there is no more {foo} to replace.
367 when there is no more {foo} to replace.
366
368
367 expansion also allows formatting and filtering.
369 expansion also allows formatting and filtering.
368
370
369 format uses key to expand each item in list. syntax is
371 format uses key to expand each item in list. syntax is
370 {key%format}.
372 {key%format}.
371
373
372 filter uses function to transform value. syntax is
374 filter uses function to transform value. syntax is
373 {key|filter1|filter2|...}.'''
375 {key|filter1|filter2|...}.'''
374
376
375 def __init__(self, loader, filters={}, defaults={}):
377 def __init__(self, loader, filters={}, defaults={}):
376 self._loader = loader
378 self._loader = loader
377 self._filters = filters
379 self._filters = filters
378 self._defaults = defaults
380 self._defaults = defaults
379 self._cache = {}
381 self._cache = {}
380
382
381 def _load(self, t):
383 def _load(self, t):
382 '''load, parse, and cache a template'''
384 '''load, parse, and cache a template'''
383 if t not in self._cache:
385 if t not in self._cache:
384 self._cache[t] = compiletemplate(self._loader(t), self)
386 self._cache[t] = compiletemplate(self._loader(t), self)
385 return self._cache[t]
387 return self._cache[t]
386
388
387 def process(self, t, mapping):
389 def process(self, t, mapping):
388 '''Perform expansion. t is name of map element to expand.
390 '''Perform expansion. t is name of map element to expand.
389 mapping contains added elements for use during expansion. Is a
391 mapping contains added elements for use during expansion. Is a
390 generator.'''
392 generator.'''
391 return _flatten(runtemplate(self, mapping, self._load(t)))
393 return _flatten(runtemplate(self, mapping, self._load(t)))
392
394
393 engines = {'default': engine}
395 engines = {'default': engine}
394
396
395 class templater(object):
397 class templater(object):
396
398
397 def __init__(self, mapfile, filters={}, defaults={}, cache={},
399 def __init__(self, mapfile, filters={}, defaults={}, cache={},
398 minchunk=1024, maxchunk=65536):
400 minchunk=1024, maxchunk=65536):
399 '''set up template engine.
401 '''set up template engine.
400 mapfile is name of file to read map definitions from.
402 mapfile is name of file to read map definitions from.
401 filters is dict of functions. each transforms a value into another.
403 filters is dict of functions. each transforms a value into another.
402 defaults is dict of default map definitions.'''
404 defaults is dict of default map definitions.'''
403 self.mapfile = mapfile or 'template'
405 self.mapfile = mapfile or 'template'
404 self.cache = cache.copy()
406 self.cache = cache.copy()
405 self.map = {}
407 self.map = {}
406 self.base = (mapfile and os.path.dirname(mapfile)) or ''
408 self.base = (mapfile and os.path.dirname(mapfile)) or ''
407 self.filters = templatefilters.filters.copy()
409 self.filters = templatefilters.filters.copy()
408 self.filters.update(filters)
410 self.filters.update(filters)
409 self.defaults = defaults
411 self.defaults = defaults
410 self.minchunk, self.maxchunk = minchunk, maxchunk
412 self.minchunk, self.maxchunk = minchunk, maxchunk
411 self.ecache = {}
413 self.ecache = {}
412
414
413 if not mapfile:
415 if not mapfile:
414 return
416 return
415 if not os.path.exists(mapfile):
417 if not os.path.exists(mapfile):
416 raise util.Abort(_('style not found: %s') % mapfile)
418 raise util.Abort(_('style not found: %s') % mapfile)
417
419
418 conf = config.config()
420 conf = config.config()
419 conf.read(mapfile)
421 conf.read(mapfile)
420
422
421 for key, val in conf[''].items():
423 for key, val in conf[''].items():
422 if not val:
424 if not val:
423 raise SyntaxError(_('%s: missing value') % conf.source('', key))
425 raise SyntaxError(_('%s: missing value') % conf.source('', key))
424 if val[0] in "'\"":
426 if val[0] in "'\"":
425 try:
427 try:
426 self.cache[key] = parsestring(val)
428 self.cache[key] = parsestring(val)
427 except SyntaxError, inst:
429 except SyntaxError, inst:
428 raise SyntaxError('%s: %s' %
430 raise SyntaxError('%s: %s' %
429 (conf.source('', key), inst.args[0]))
431 (conf.source('', key), inst.args[0]))
430 else:
432 else:
431 val = 'default', val
433 val = 'default', val
432 if ':' in val[1]:
434 if ':' in val[1]:
433 val = val[1].split(':', 1)
435 val = val[1].split(':', 1)
434 self.map[key] = val[0], os.path.join(self.base, val[1])
436 self.map[key] = val[0], os.path.join(self.base, val[1])
435
437
436 def __contains__(self, key):
438 def __contains__(self, key):
437 return key in self.cache or key in self.map
439 return key in self.cache or key in self.map
438
440
439 def load(self, t):
441 def load(self, t):
440 '''Get the template for the given template name. Use a local cache.'''
442 '''Get the template for the given template name. Use a local cache.'''
441 if t not in self.cache:
443 if t not in self.cache:
442 try:
444 try:
443 self.cache[t] = util.readfile(self.map[t][1])
445 self.cache[t] = util.readfile(self.map[t][1])
444 except KeyError, inst:
446 except KeyError, inst:
445 raise util.Abort(_('"%s" not in template map') % inst.args[0])
447 raise util.Abort(_('"%s" not in template map') % inst.args[0])
446 except IOError, inst:
448 except IOError, inst:
447 raise IOError(inst.args[0], _('template file %s: %s') %
449 raise IOError(inst.args[0], _('template file %s: %s') %
448 (self.map[t][1], inst.args[1]))
450 (self.map[t][1], inst.args[1]))
449 return self.cache[t]
451 return self.cache[t]
450
452
451 def __call__(self, t, **mapping):
453 def __call__(self, t, **mapping):
452 ttype = t in self.map and self.map[t][0] or 'default'
454 ttype = t in self.map and self.map[t][0] or 'default'
453 if ttype not in self.ecache:
455 if ttype not in self.ecache:
454 self.ecache[ttype] = engines[ttype](self.load,
456 self.ecache[ttype] = engines[ttype](self.load,
455 self.filters, self.defaults)
457 self.filters, self.defaults)
456 proc = self.ecache[ttype]
458 proc = self.ecache[ttype]
457
459
458 stream = proc.process(t, mapping)
460 stream = proc.process(t, mapping)
459 if self.minchunk:
461 if self.minchunk:
460 stream = util.increasingchunks(stream, min=self.minchunk,
462 stream = util.increasingchunks(stream, min=self.minchunk,
461 max=self.maxchunk)
463 max=self.maxchunk)
462 return stream
464 return stream
463
465
464 def templatepath(name=None):
466 def templatepath(name=None):
465 '''return location of template file or directory (if no name).
467 '''return location of template file or directory (if no name).
466 returns None if not found.'''
468 returns None if not found.'''
467 normpaths = []
469 normpaths = []
468
470
469 # executable version (py2exe) doesn't support __file__
471 # executable version (py2exe) doesn't support __file__
470 if util.mainfrozen():
472 if util.mainfrozen():
471 module = sys.executable
473 module = sys.executable
472 else:
474 else:
473 module = __file__
475 module = __file__
474 for f in path:
476 for f in path:
475 if f.startswith('/'):
477 if f.startswith('/'):
476 p = f
478 p = f
477 else:
479 else:
478 fl = f.split('/')
480 fl = f.split('/')
479 p = os.path.join(os.path.dirname(module), *fl)
481 p = os.path.join(os.path.dirname(module), *fl)
480 if name:
482 if name:
481 p = os.path.join(p, name)
483 p = os.path.join(p, name)
482 if name and os.path.exists(p):
484 if name and os.path.exists(p):
483 return os.path.normpath(p)
485 return os.path.normpath(p)
484 elif os.path.isdir(p):
486 elif os.path.isdir(p):
485 normpaths.append(os.path.normpath(p))
487 normpaths.append(os.path.normpath(p))
486
488
487 return normpaths
489 return normpaths
488
490
489 def stylemap(styles, paths=None):
491 def stylemap(styles, paths=None):
490 """Return path to mapfile for a given style.
492 """Return path to mapfile for a given style.
491
493
492 Searches mapfile in the following locations:
494 Searches mapfile in the following locations:
493 1. templatepath/style/map
495 1. templatepath/style/map
494 2. templatepath/map-style
496 2. templatepath/map-style
495 3. templatepath/map
497 3. templatepath/map
496 """
498 """
497
499
498 if paths is None:
500 if paths is None:
499 paths = templatepath()
501 paths = templatepath()
500 elif isinstance(paths, str):
502 elif isinstance(paths, str):
501 paths = [paths]
503 paths = [paths]
502
504
503 if isinstance(styles, str):
505 if isinstance(styles, str):
504 styles = [styles]
506 styles = [styles]
505
507
506 for style in styles:
508 for style in styles:
507 if not style:
509 if not style:
508 continue
510 continue
509 locations = [os.path.join(style, 'map'), 'map-' + style]
511 locations = [os.path.join(style, 'map'), 'map-' + style]
510 locations.append('map')
512 locations.append('map')
511
513
512 for path in paths:
514 for path in paths:
513 for location in locations:
515 for location in locations:
514 mapfile = os.path.join(path, location)
516 mapfile = os.path.join(path, location)
515 if os.path.isfile(mapfile):
517 if os.path.isfile(mapfile):
516 return style, mapfile
518 return style, mapfile
517
519
518 raise RuntimeError("No hgweb templates found in %r" % paths)
520 raise RuntimeError("No hgweb templates found in %r" % paths)
@@ -1,1533 +1,1537 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 --template '{file_copies % "{source} -> {name}\n"}' -r .
48 $ hg log --template '{file_copies % "{source} -> {name}\n"}' -r .
49 second -> fourth
49 second -> fourth
50
50
51 Quoting for ui.logtemplate
51 Quoting for ui.logtemplate
52
52
53 $ hg tip --config "ui.logtemplate={rev}\n"
53 $ hg tip --config "ui.logtemplate={rev}\n"
54 8
54 8
55 $ hg tip --config "ui.logtemplate='{rev}\n'"
55 $ hg tip --config "ui.logtemplate='{rev}\n'"
56 8
56 8
57 $ hg tip --config 'ui.logtemplate="{rev}\n"'
57 $ hg tip --config 'ui.logtemplate="{rev}\n"'
58 8
58 8
59
59
60 Make sure user/global hgrc does not affect tests
60 Make sure user/global hgrc does not affect tests
61
61
62 $ echo '[ui]' > .hg/hgrc
62 $ echo '[ui]' > .hg/hgrc
63 $ echo 'logtemplate =' >> .hg/hgrc
63 $ echo 'logtemplate =' >> .hg/hgrc
64 $ echo 'style =' >> .hg/hgrc
64 $ echo 'style =' >> .hg/hgrc
65
65
66 Default style is like normal output:
66 Default style is like normal output:
67
67
68 $ hg log > log.out
68 $ hg log > log.out
69 $ hg log --style default > style.out
69 $ hg log --style default > style.out
70 $ cmp log.out style.out || diff -u log.out style.out
70 $ cmp log.out style.out || diff -u log.out style.out
71
71
72 $ hg log -v > log.out
72 $ hg log -v > log.out
73 $ hg log -v --style default > style.out
73 $ hg log -v --style default > style.out
74 $ cmp log.out style.out || diff -u log.out style.out
74 $ cmp log.out style.out || diff -u log.out style.out
75
75
76 $ hg log --debug > log.out
76 $ hg log --debug > log.out
77 $ hg log --debug --style default > style.out
77 $ hg log --debug --style default > style.out
78 $ cmp log.out style.out || diff -u log.out style.out
78 $ cmp log.out style.out || diff -u log.out style.out
79
79
80 Revision with no copies (used to print a traceback):
80 Revision with no copies (used to print a traceback):
81
81
82 $ hg tip -v --template '\n'
82 $ hg tip -v --template '\n'
83
83
84
84
85 Compact style works:
85 Compact style works:
86
86
87 $ hg log --style compact
87 $ hg log --style compact
88 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
88 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
89 third
89 third
90
90
91 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
91 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
92 second
92 second
93
93
94 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
94 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
95 merge
95 merge
96
96
97 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
97 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
98 new head
98 new head
99
99
100 4 bbe44766e73d 1970-01-17 04:53 +0000 person
100 4 bbe44766e73d 1970-01-17 04:53 +0000 person
101 new branch
101 new branch
102
102
103 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
103 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
104 no user, no domain
104 no user, no domain
105
105
106 2 97054abb4ab8 1970-01-14 21:20 +0000 other
106 2 97054abb4ab8 1970-01-14 21:20 +0000 other
107 no person
107 no person
108
108
109 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
109 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
110 other 1
110 other 1
111
111
112 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
112 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
113 line 1
113 line 1
114
114
115
115
116 $ hg log -v --style compact
116 $ hg log -v --style compact
117 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
117 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
118 third
118 third
119
119
120 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
120 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
121 second
121 second
122
122
123 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
123 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
124 merge
124 merge
125
125
126 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
126 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
127 new head
127 new head
128
128
129 4 bbe44766e73d 1970-01-17 04:53 +0000 person
129 4 bbe44766e73d 1970-01-17 04:53 +0000 person
130 new branch
130 new branch
131
131
132 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
132 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
133 no user, no domain
133 no user, no domain
134
134
135 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
135 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
136 no person
136 no person
137
137
138 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
138 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
139 other 1
139 other 1
140 other 2
140 other 2
141
141
142 other 3
142 other 3
143
143
144 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
144 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
145 line 1
145 line 1
146 line 2
146 line 2
147
147
148
148
149 $ hg log --debug --style compact
149 $ hg log --debug --style compact
150 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
150 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
151 third
151 third
152
152
153 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
153 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
154 second
154 second
155
155
156 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
156 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
157 merge
157 merge
158
158
159 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
159 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
160 new head
160 new head
161
161
162 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
162 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
163 new branch
163 new branch
164
164
165 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
165 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
166 no user, no domain
166 no user, no domain
167
167
168 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
168 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
169 no person
169 no person
170
170
171 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
171 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
172 other 1
172 other 1
173 other 2
173 other 2
174
174
175 other 3
175 other 3
176
176
177 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
177 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
178 line 1
178 line 1
179 line 2
179 line 2
180
180
181
181
182 Test xml styles:
182 Test xml styles:
183
183
184 $ hg log --style xml
184 $ hg log --style xml
185 <?xml version="1.0"?>
185 <?xml version="1.0"?>
186 <log>
186 <log>
187 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
187 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
188 <tag>tip</tag>
188 <tag>tip</tag>
189 <author email="test">test</author>
189 <author email="test">test</author>
190 <date>2020-01-01T10:01:00+00:00</date>
190 <date>2020-01-01T10:01:00+00:00</date>
191 <msg xml:space="preserve">third</msg>
191 <msg xml:space="preserve">third</msg>
192 </logentry>
192 </logentry>
193 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
193 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
194 <parent revision="-1" node="0000000000000000000000000000000000000000" />
194 <parent revision="-1" node="0000000000000000000000000000000000000000" />
195 <author email="user@hostname">User Name</author>
195 <author email="user@hostname">User Name</author>
196 <date>1970-01-12T13:46:40+00:00</date>
196 <date>1970-01-12T13:46:40+00:00</date>
197 <msg xml:space="preserve">second</msg>
197 <msg xml:space="preserve">second</msg>
198 </logentry>
198 </logentry>
199 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
199 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
200 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
200 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
201 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
201 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
202 <author email="person">person</author>
202 <author email="person">person</author>
203 <date>1970-01-18T08:40:01+00:00</date>
203 <date>1970-01-18T08:40:01+00:00</date>
204 <msg xml:space="preserve">merge</msg>
204 <msg xml:space="preserve">merge</msg>
205 </logentry>
205 </logentry>
206 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
206 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
207 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
207 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
208 <author email="person">person</author>
208 <author email="person">person</author>
209 <date>1970-01-18T08:40:00+00:00</date>
209 <date>1970-01-18T08:40:00+00:00</date>
210 <msg xml:space="preserve">new head</msg>
210 <msg xml:space="preserve">new head</msg>
211 </logentry>
211 </logentry>
212 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
212 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
213 <branch>foo</branch>
213 <branch>foo</branch>
214 <author email="person">person</author>
214 <author email="person">person</author>
215 <date>1970-01-17T04:53:20+00:00</date>
215 <date>1970-01-17T04:53:20+00:00</date>
216 <msg xml:space="preserve">new branch</msg>
216 <msg xml:space="preserve">new branch</msg>
217 </logentry>
217 </logentry>
218 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
218 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
219 <author email="person">person</author>
219 <author email="person">person</author>
220 <date>1970-01-16T01:06:40+00:00</date>
220 <date>1970-01-16T01:06:40+00:00</date>
221 <msg xml:space="preserve">no user, no domain</msg>
221 <msg xml:space="preserve">no user, no domain</msg>
222 </logentry>
222 </logentry>
223 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
223 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
224 <author email="other@place">other</author>
224 <author email="other@place">other</author>
225 <date>1970-01-14T21:20:00+00:00</date>
225 <date>1970-01-14T21:20:00+00:00</date>
226 <msg xml:space="preserve">no person</msg>
226 <msg xml:space="preserve">no person</msg>
227 </logentry>
227 </logentry>
228 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
228 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
229 <author email="other@place">A. N. Other</author>
229 <author email="other@place">A. N. Other</author>
230 <date>1970-01-13T17:33:20+00:00</date>
230 <date>1970-01-13T17:33:20+00:00</date>
231 <msg xml:space="preserve">other 1
231 <msg xml:space="preserve">other 1
232 other 2
232 other 2
233
233
234 other 3</msg>
234 other 3</msg>
235 </logentry>
235 </logentry>
236 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
236 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
237 <author email="user@hostname">User Name</author>
237 <author email="user@hostname">User Name</author>
238 <date>1970-01-12T13:46:40+00:00</date>
238 <date>1970-01-12T13:46:40+00:00</date>
239 <msg xml:space="preserve">line 1
239 <msg xml:space="preserve">line 1
240 line 2</msg>
240 line 2</msg>
241 </logentry>
241 </logentry>
242 </log>
242 </log>
243
243
244 $ hg log -v --style xml
244 $ hg log -v --style xml
245 <?xml version="1.0"?>
245 <?xml version="1.0"?>
246 <log>
246 <log>
247 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
247 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
248 <tag>tip</tag>
248 <tag>tip</tag>
249 <author email="test">test</author>
249 <author email="test">test</author>
250 <date>2020-01-01T10:01:00+00:00</date>
250 <date>2020-01-01T10:01:00+00:00</date>
251 <msg xml:space="preserve">third</msg>
251 <msg xml:space="preserve">third</msg>
252 <paths>
252 <paths>
253 <path action="A">fourth</path>
253 <path action="A">fourth</path>
254 <path action="A">third</path>
254 <path action="A">third</path>
255 <path action="R">second</path>
255 <path action="R">second</path>
256 </paths>
256 </paths>
257 <copies>
257 <copies>
258 <copy source="second">fourth</copy>
258 <copy source="second">fourth</copy>
259 </copies>
259 </copies>
260 </logentry>
260 </logentry>
261 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
261 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
262 <parent revision="-1" node="0000000000000000000000000000000000000000" />
262 <parent revision="-1" node="0000000000000000000000000000000000000000" />
263 <author email="user@hostname">User Name</author>
263 <author email="user@hostname">User Name</author>
264 <date>1970-01-12T13:46:40+00:00</date>
264 <date>1970-01-12T13:46:40+00:00</date>
265 <msg xml:space="preserve">second</msg>
265 <msg xml:space="preserve">second</msg>
266 <paths>
266 <paths>
267 <path action="A">second</path>
267 <path action="A">second</path>
268 </paths>
268 </paths>
269 </logentry>
269 </logentry>
270 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
270 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
271 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
271 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
272 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
272 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
273 <author email="person">person</author>
273 <author email="person">person</author>
274 <date>1970-01-18T08:40:01+00:00</date>
274 <date>1970-01-18T08:40:01+00:00</date>
275 <msg xml:space="preserve">merge</msg>
275 <msg xml:space="preserve">merge</msg>
276 <paths>
276 <paths>
277 </paths>
277 </paths>
278 </logentry>
278 </logentry>
279 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
279 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
280 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
280 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
281 <author email="person">person</author>
281 <author email="person">person</author>
282 <date>1970-01-18T08:40:00+00:00</date>
282 <date>1970-01-18T08:40:00+00:00</date>
283 <msg xml:space="preserve">new head</msg>
283 <msg xml:space="preserve">new head</msg>
284 <paths>
284 <paths>
285 <path action="A">d</path>
285 <path action="A">d</path>
286 </paths>
286 </paths>
287 </logentry>
287 </logentry>
288 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
288 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
289 <branch>foo</branch>
289 <branch>foo</branch>
290 <author email="person">person</author>
290 <author email="person">person</author>
291 <date>1970-01-17T04:53:20+00:00</date>
291 <date>1970-01-17T04:53:20+00:00</date>
292 <msg xml:space="preserve">new branch</msg>
292 <msg xml:space="preserve">new branch</msg>
293 <paths>
293 <paths>
294 </paths>
294 </paths>
295 </logentry>
295 </logentry>
296 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
296 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
297 <author email="person">person</author>
297 <author email="person">person</author>
298 <date>1970-01-16T01:06:40+00:00</date>
298 <date>1970-01-16T01:06:40+00:00</date>
299 <msg xml:space="preserve">no user, no domain</msg>
299 <msg xml:space="preserve">no user, no domain</msg>
300 <paths>
300 <paths>
301 <path action="M">c</path>
301 <path action="M">c</path>
302 </paths>
302 </paths>
303 </logentry>
303 </logentry>
304 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
304 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
305 <author email="other@place">other</author>
305 <author email="other@place">other</author>
306 <date>1970-01-14T21:20:00+00:00</date>
306 <date>1970-01-14T21:20:00+00:00</date>
307 <msg xml:space="preserve">no person</msg>
307 <msg xml:space="preserve">no person</msg>
308 <paths>
308 <paths>
309 <path action="A">c</path>
309 <path action="A">c</path>
310 </paths>
310 </paths>
311 </logentry>
311 </logentry>
312 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
312 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
313 <author email="other@place">A. N. Other</author>
313 <author email="other@place">A. N. Other</author>
314 <date>1970-01-13T17:33:20+00:00</date>
314 <date>1970-01-13T17:33:20+00:00</date>
315 <msg xml:space="preserve">other 1
315 <msg xml:space="preserve">other 1
316 other 2
316 other 2
317
317
318 other 3</msg>
318 other 3</msg>
319 <paths>
319 <paths>
320 <path action="A">b</path>
320 <path action="A">b</path>
321 </paths>
321 </paths>
322 </logentry>
322 </logentry>
323 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
323 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
324 <author email="user@hostname">User Name</author>
324 <author email="user@hostname">User Name</author>
325 <date>1970-01-12T13:46:40+00:00</date>
325 <date>1970-01-12T13:46:40+00:00</date>
326 <msg xml:space="preserve">line 1
326 <msg xml:space="preserve">line 1
327 line 2</msg>
327 line 2</msg>
328 <paths>
328 <paths>
329 <path action="A">a</path>
329 <path action="A">a</path>
330 </paths>
330 </paths>
331 </logentry>
331 </logentry>
332 </log>
332 </log>
333
333
334 $ hg log --debug --style xml
334 $ hg log --debug --style xml
335 <?xml version="1.0"?>
335 <?xml version="1.0"?>
336 <log>
336 <log>
337 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
337 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
338 <tag>tip</tag>
338 <tag>tip</tag>
339 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
339 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
340 <parent revision="-1" node="0000000000000000000000000000000000000000" />
340 <parent revision="-1" node="0000000000000000000000000000000000000000" />
341 <author email="test">test</author>
341 <author email="test">test</author>
342 <date>2020-01-01T10:01:00+00:00</date>
342 <date>2020-01-01T10:01:00+00:00</date>
343 <msg xml:space="preserve">third</msg>
343 <msg xml:space="preserve">third</msg>
344 <paths>
344 <paths>
345 <path action="A">fourth</path>
345 <path action="A">fourth</path>
346 <path action="A">third</path>
346 <path action="A">third</path>
347 <path action="R">second</path>
347 <path action="R">second</path>
348 </paths>
348 </paths>
349 <copies>
349 <copies>
350 <copy source="second">fourth</copy>
350 <copy source="second">fourth</copy>
351 </copies>
351 </copies>
352 <extra key="branch">default</extra>
352 <extra key="branch">default</extra>
353 </logentry>
353 </logentry>
354 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
354 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
355 <parent revision="-1" node="0000000000000000000000000000000000000000" />
355 <parent revision="-1" node="0000000000000000000000000000000000000000" />
356 <parent revision="-1" node="0000000000000000000000000000000000000000" />
356 <parent revision="-1" node="0000000000000000000000000000000000000000" />
357 <author email="user@hostname">User Name</author>
357 <author email="user@hostname">User Name</author>
358 <date>1970-01-12T13:46:40+00:00</date>
358 <date>1970-01-12T13:46:40+00:00</date>
359 <msg xml:space="preserve">second</msg>
359 <msg xml:space="preserve">second</msg>
360 <paths>
360 <paths>
361 <path action="A">second</path>
361 <path action="A">second</path>
362 </paths>
362 </paths>
363 <extra key="branch">default</extra>
363 <extra key="branch">default</extra>
364 </logentry>
364 </logentry>
365 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
365 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
366 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
366 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
367 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
367 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
368 <author email="person">person</author>
368 <author email="person">person</author>
369 <date>1970-01-18T08:40:01+00:00</date>
369 <date>1970-01-18T08:40:01+00:00</date>
370 <msg xml:space="preserve">merge</msg>
370 <msg xml:space="preserve">merge</msg>
371 <paths>
371 <paths>
372 </paths>
372 </paths>
373 <extra key="branch">default</extra>
373 <extra key="branch">default</extra>
374 </logentry>
374 </logentry>
375 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
375 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
376 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
376 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
377 <parent revision="-1" node="0000000000000000000000000000000000000000" />
377 <parent revision="-1" node="0000000000000000000000000000000000000000" />
378 <author email="person">person</author>
378 <author email="person">person</author>
379 <date>1970-01-18T08:40:00+00:00</date>
379 <date>1970-01-18T08:40:00+00:00</date>
380 <msg xml:space="preserve">new head</msg>
380 <msg xml:space="preserve">new head</msg>
381 <paths>
381 <paths>
382 <path action="A">d</path>
382 <path action="A">d</path>
383 </paths>
383 </paths>
384 <extra key="branch">default</extra>
384 <extra key="branch">default</extra>
385 </logentry>
385 </logentry>
386 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
386 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
387 <branch>foo</branch>
387 <branch>foo</branch>
388 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
388 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
389 <parent revision="-1" node="0000000000000000000000000000000000000000" />
389 <parent revision="-1" node="0000000000000000000000000000000000000000" />
390 <author email="person">person</author>
390 <author email="person">person</author>
391 <date>1970-01-17T04:53:20+00:00</date>
391 <date>1970-01-17T04:53:20+00:00</date>
392 <msg xml:space="preserve">new branch</msg>
392 <msg xml:space="preserve">new branch</msg>
393 <paths>
393 <paths>
394 </paths>
394 </paths>
395 <extra key="branch">foo</extra>
395 <extra key="branch">foo</extra>
396 </logentry>
396 </logentry>
397 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
397 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
398 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
398 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
399 <parent revision="-1" node="0000000000000000000000000000000000000000" />
399 <parent revision="-1" node="0000000000000000000000000000000000000000" />
400 <author email="person">person</author>
400 <author email="person">person</author>
401 <date>1970-01-16T01:06:40+00:00</date>
401 <date>1970-01-16T01:06:40+00:00</date>
402 <msg xml:space="preserve">no user, no domain</msg>
402 <msg xml:space="preserve">no user, no domain</msg>
403 <paths>
403 <paths>
404 <path action="M">c</path>
404 <path action="M">c</path>
405 </paths>
405 </paths>
406 <extra key="branch">default</extra>
406 <extra key="branch">default</extra>
407 </logentry>
407 </logentry>
408 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
408 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
409 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
409 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
410 <parent revision="-1" node="0000000000000000000000000000000000000000" />
410 <parent revision="-1" node="0000000000000000000000000000000000000000" />
411 <author email="other@place">other</author>
411 <author email="other@place">other</author>
412 <date>1970-01-14T21:20:00+00:00</date>
412 <date>1970-01-14T21:20:00+00:00</date>
413 <msg xml:space="preserve">no person</msg>
413 <msg xml:space="preserve">no person</msg>
414 <paths>
414 <paths>
415 <path action="A">c</path>
415 <path action="A">c</path>
416 </paths>
416 </paths>
417 <extra key="branch">default</extra>
417 <extra key="branch">default</extra>
418 </logentry>
418 </logentry>
419 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
419 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
420 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
420 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
421 <parent revision="-1" node="0000000000000000000000000000000000000000" />
421 <parent revision="-1" node="0000000000000000000000000000000000000000" />
422 <author email="other@place">A. N. Other</author>
422 <author email="other@place">A. N. Other</author>
423 <date>1970-01-13T17:33:20+00:00</date>
423 <date>1970-01-13T17:33:20+00:00</date>
424 <msg xml:space="preserve">other 1
424 <msg xml:space="preserve">other 1
425 other 2
425 other 2
426
426
427 other 3</msg>
427 other 3</msg>
428 <paths>
428 <paths>
429 <path action="A">b</path>
429 <path action="A">b</path>
430 </paths>
430 </paths>
431 <extra key="branch">default</extra>
431 <extra key="branch">default</extra>
432 </logentry>
432 </logentry>
433 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
433 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
434 <parent revision="-1" node="0000000000000000000000000000000000000000" />
434 <parent revision="-1" node="0000000000000000000000000000000000000000" />
435 <parent revision="-1" node="0000000000000000000000000000000000000000" />
435 <parent revision="-1" node="0000000000000000000000000000000000000000" />
436 <author email="user@hostname">User Name</author>
436 <author email="user@hostname">User Name</author>
437 <date>1970-01-12T13:46:40+00:00</date>
437 <date>1970-01-12T13:46:40+00:00</date>
438 <msg xml:space="preserve">line 1
438 <msg xml:space="preserve">line 1
439 line 2</msg>
439 line 2</msg>
440 <paths>
440 <paths>
441 <path action="A">a</path>
441 <path action="A">a</path>
442 </paths>
442 </paths>
443 <extra key="branch">default</extra>
443 <extra key="branch">default</extra>
444 </logentry>
444 </logentry>
445 </log>
445 </log>
446
446
447
447
448 Error if style not readable:
448 Error if style not readable:
449
449
450 #if unix-permissions
450 #if unix-permissions
451 $ touch q
451 $ touch q
452 $ chmod 0 q
452 $ chmod 0 q
453 $ hg log --style ./q
453 $ hg log --style ./q
454 abort: Permission denied: ./q
454 abort: Permission denied: ./q
455 [255]
455 [255]
456 #endif
456 #endif
457
457
458 Error if no style:
458 Error if no style:
459
459
460 $ hg log --style notexist
460 $ hg log --style notexist
461 abort: style not found: notexist
461 abort: style not found: notexist
462 [255]
462 [255]
463
463
464 Error if style missing key:
464 Error if style missing key:
465
465
466 $ echo 'q = q' > t
466 $ echo 'q = q' > t
467 $ hg log --style ./t
467 $ hg log --style ./t
468 abort: "changeset" not in template map
468 abort: "changeset" not in template map
469 [255]
469 [255]
470
470
471 Error if style missing value:
471 Error if style missing value:
472
472
473 $ echo 'changeset =' > t
473 $ echo 'changeset =' > t
474 $ hg log --style t
474 $ hg log --style t
475 abort: t:1: missing value
475 abort: t:1: missing value
476 [255]
476 [255]
477
477
478 Error if include fails:
478 Error if include fails:
479
479
480 $ echo 'changeset = q' >> t
480 $ echo 'changeset = q' >> t
481 #if unix-permissions
481 #if unix-permissions
482 $ hg log --style ./t
482 $ hg log --style ./t
483 abort: template file ./q: Permission denied
483 abort: template file ./q: Permission denied
484 [255]
484 [255]
485 $ rm q
485 $ rm q
486 #endif
486 #endif
487
487
488 Include works:
488 Include works:
489
489
490 $ echo '{rev}' > q
490 $ echo '{rev}' > q
491 $ hg log --style ./t
491 $ hg log --style ./t
492 8
492 8
493 7
493 7
494 6
494 6
495 5
495 5
496 4
496 4
497 3
497 3
498 2
498 2
499 1
499 1
500 0
500 0
501
501
502 ui.style works:
502 ui.style works:
503
503
504 $ echo '[ui]' > .hg/hgrc
504 $ echo '[ui]' > .hg/hgrc
505 $ echo 'style = t' >> .hg/hgrc
505 $ echo 'style = t' >> .hg/hgrc
506 $ hg log
506 $ hg log
507 8
507 8
508 7
508 7
509 6
509 6
510 5
510 5
511 4
511 4
512 3
512 3
513 2
513 2
514 1
514 1
515 0
515 0
516
516
517
517
518 Issue338:
518 Issue338:
519
519
520 $ hg log --style=changelog > changelog
520 $ hg log --style=changelog > changelog
521
521
522 $ cat changelog
522 $ cat changelog
523 2020-01-01 test <test>
523 2020-01-01 test <test>
524
524
525 * fourth, second, third:
525 * fourth, second, third:
526 third
526 third
527 [95c24699272e] [tip]
527 [95c24699272e] [tip]
528
528
529 1970-01-12 User Name <user@hostname>
529 1970-01-12 User Name <user@hostname>
530
530
531 * second:
531 * second:
532 second
532 second
533 [29114dbae42b]
533 [29114dbae42b]
534
534
535 1970-01-18 person <person>
535 1970-01-18 person <person>
536
536
537 * merge
537 * merge
538 [d41e714fe50d]
538 [d41e714fe50d]
539
539
540 * d:
540 * d:
541 new head
541 new head
542 [13207e5a10d9]
542 [13207e5a10d9]
543
543
544 1970-01-17 person <person>
544 1970-01-17 person <person>
545
545
546 * new branch
546 * new branch
547 [bbe44766e73d] <foo>
547 [bbe44766e73d] <foo>
548
548
549 1970-01-16 person <person>
549 1970-01-16 person <person>
550
550
551 * c:
551 * c:
552 no user, no domain
552 no user, no domain
553 [10e46f2dcbf4]
553 [10e46f2dcbf4]
554
554
555 1970-01-14 other <other@place>
555 1970-01-14 other <other@place>
556
556
557 * c:
557 * c:
558 no person
558 no person
559 [97054abb4ab8]
559 [97054abb4ab8]
560
560
561 1970-01-13 A. N. Other <other@place>
561 1970-01-13 A. N. Other <other@place>
562
562
563 * b:
563 * b:
564 other 1 other 2
564 other 1 other 2
565
565
566 other 3
566 other 3
567 [b608e9d1a3f0]
567 [b608e9d1a3f0]
568
568
569 1970-01-12 User Name <user@hostname>
569 1970-01-12 User Name <user@hostname>
570
570
571 * a:
571 * a:
572 line 1 line 2
572 line 1 line 2
573 [1e4e1b8f71e0]
573 [1e4e1b8f71e0]
574
574
575
575
576 Issue2130: xml output for 'hg heads' is malformed
576 Issue2130: xml output for 'hg heads' is malformed
577
577
578 $ hg heads --style changelog
578 $ hg heads --style changelog
579 2020-01-01 test <test>
579 2020-01-01 test <test>
580
580
581 * fourth, second, third:
581 * fourth, second, third:
582 third
582 third
583 [95c24699272e] [tip]
583 [95c24699272e] [tip]
584
584
585 1970-01-18 person <person>
585 1970-01-18 person <person>
586
586
587 * merge
587 * merge
588 [d41e714fe50d]
588 [d41e714fe50d]
589
589
590 1970-01-17 person <person>
590 1970-01-17 person <person>
591
591
592 * new branch
592 * new branch
593 [bbe44766e73d] <foo>
593 [bbe44766e73d] <foo>
594
594
595
595
596 Keys work:
596 Keys work:
597
597
598 $ for key in author branch branches date desc file_adds file_dels file_mods \
598 $ for key in author branch branches date desc file_adds file_dels file_mods \
599 > file_copies file_copies_switch files \
599 > file_copies file_copies_switch files \
600 > manifest node parents rev tags diffstat extras \
600 > manifest node parents rev tags diffstat extras \
601 > p1rev p2rev p1node p2node; do
601 > p1rev p2rev p1node p2node; do
602 > for mode in '' --verbose --debug; do
602 > for mode in '' --verbose --debug; do
603 > hg log $mode --template "$key$mode: {$key}\n"
603 > hg log $mode --template "$key$mode: {$key}\n"
604 > done
604 > done
605 > done
605 > done
606 author: test
606 author: test
607 author: User Name <user@hostname>
607 author: User Name <user@hostname>
608 author: person
608 author: person
609 author: person
609 author: person
610 author: person
610 author: person
611 author: person
611 author: person
612 author: other@place
612 author: other@place
613 author: A. N. Other <other@place>
613 author: A. N. Other <other@place>
614 author: User Name <user@hostname>
614 author: User Name <user@hostname>
615 author--verbose: test
615 author--verbose: test
616 author--verbose: User Name <user@hostname>
616 author--verbose: User Name <user@hostname>
617 author--verbose: person
617 author--verbose: person
618 author--verbose: person
618 author--verbose: person
619 author--verbose: person
619 author--verbose: person
620 author--verbose: person
620 author--verbose: person
621 author--verbose: other@place
621 author--verbose: other@place
622 author--verbose: A. N. Other <other@place>
622 author--verbose: A. N. Other <other@place>
623 author--verbose: User Name <user@hostname>
623 author--verbose: User Name <user@hostname>
624 author--debug: test
624 author--debug: test
625 author--debug: User Name <user@hostname>
625 author--debug: User Name <user@hostname>
626 author--debug: person
626 author--debug: person
627 author--debug: person
627 author--debug: person
628 author--debug: person
628 author--debug: person
629 author--debug: person
629 author--debug: person
630 author--debug: other@place
630 author--debug: other@place
631 author--debug: A. N. Other <other@place>
631 author--debug: A. N. Other <other@place>
632 author--debug: User Name <user@hostname>
632 author--debug: User Name <user@hostname>
633 branch: default
633 branch: default
634 branch: default
634 branch: default
635 branch: default
635 branch: default
636 branch: default
636 branch: default
637 branch: foo
637 branch: foo
638 branch: default
638 branch: default
639 branch: default
639 branch: default
640 branch: default
640 branch: default
641 branch: default
641 branch: default
642 branch--verbose: default
642 branch--verbose: default
643 branch--verbose: default
643 branch--verbose: default
644 branch--verbose: default
644 branch--verbose: default
645 branch--verbose: default
645 branch--verbose: default
646 branch--verbose: foo
646 branch--verbose: foo
647 branch--verbose: default
647 branch--verbose: default
648 branch--verbose: default
648 branch--verbose: default
649 branch--verbose: default
649 branch--verbose: default
650 branch--verbose: default
650 branch--verbose: default
651 branch--debug: default
651 branch--debug: default
652 branch--debug: default
652 branch--debug: default
653 branch--debug: default
653 branch--debug: default
654 branch--debug: default
654 branch--debug: default
655 branch--debug: foo
655 branch--debug: foo
656 branch--debug: default
656 branch--debug: default
657 branch--debug: default
657 branch--debug: default
658 branch--debug: default
658 branch--debug: default
659 branch--debug: default
659 branch--debug: default
660 branches:
660 branches:
661 branches:
661 branches:
662 branches:
662 branches:
663 branches:
663 branches:
664 branches: foo
664 branches: foo
665 branches:
665 branches:
666 branches:
666 branches:
667 branches:
667 branches:
668 branches:
668 branches:
669 branches--verbose:
669 branches--verbose:
670 branches--verbose:
670 branches--verbose:
671 branches--verbose:
671 branches--verbose:
672 branches--verbose:
672 branches--verbose:
673 branches--verbose: foo
673 branches--verbose: foo
674 branches--verbose:
674 branches--verbose:
675 branches--verbose:
675 branches--verbose:
676 branches--verbose:
676 branches--verbose:
677 branches--verbose:
677 branches--verbose:
678 branches--debug:
678 branches--debug:
679 branches--debug:
679 branches--debug:
680 branches--debug:
680 branches--debug:
681 branches--debug:
681 branches--debug:
682 branches--debug: foo
682 branches--debug: foo
683 branches--debug:
683 branches--debug:
684 branches--debug:
684 branches--debug:
685 branches--debug:
685 branches--debug:
686 branches--debug:
686 branches--debug:
687 date: 1577872860.00
687 date: 1577872860.00
688 date: 1000000.00
688 date: 1000000.00
689 date: 1500001.00
689 date: 1500001.00
690 date: 1500000.00
690 date: 1500000.00
691 date: 1400000.00
691 date: 1400000.00
692 date: 1300000.00
692 date: 1300000.00
693 date: 1200000.00
693 date: 1200000.00
694 date: 1100000.00
694 date: 1100000.00
695 date: 1000000.00
695 date: 1000000.00
696 date--verbose: 1577872860.00
696 date--verbose: 1577872860.00
697 date--verbose: 1000000.00
697 date--verbose: 1000000.00
698 date--verbose: 1500001.00
698 date--verbose: 1500001.00
699 date--verbose: 1500000.00
699 date--verbose: 1500000.00
700 date--verbose: 1400000.00
700 date--verbose: 1400000.00
701 date--verbose: 1300000.00
701 date--verbose: 1300000.00
702 date--verbose: 1200000.00
702 date--verbose: 1200000.00
703 date--verbose: 1100000.00
703 date--verbose: 1100000.00
704 date--verbose: 1000000.00
704 date--verbose: 1000000.00
705 date--debug: 1577872860.00
705 date--debug: 1577872860.00
706 date--debug: 1000000.00
706 date--debug: 1000000.00
707 date--debug: 1500001.00
707 date--debug: 1500001.00
708 date--debug: 1500000.00
708 date--debug: 1500000.00
709 date--debug: 1400000.00
709 date--debug: 1400000.00
710 date--debug: 1300000.00
710 date--debug: 1300000.00
711 date--debug: 1200000.00
711 date--debug: 1200000.00
712 date--debug: 1100000.00
712 date--debug: 1100000.00
713 date--debug: 1000000.00
713 date--debug: 1000000.00
714 desc: third
714 desc: third
715 desc: second
715 desc: second
716 desc: merge
716 desc: merge
717 desc: new head
717 desc: new head
718 desc: new branch
718 desc: new branch
719 desc: no user, no domain
719 desc: no user, no domain
720 desc: no person
720 desc: no person
721 desc: other 1
721 desc: other 1
722 other 2
722 other 2
723
723
724 other 3
724 other 3
725 desc: line 1
725 desc: line 1
726 line 2
726 line 2
727 desc--verbose: third
727 desc--verbose: third
728 desc--verbose: second
728 desc--verbose: second
729 desc--verbose: merge
729 desc--verbose: merge
730 desc--verbose: new head
730 desc--verbose: new head
731 desc--verbose: new branch
731 desc--verbose: new branch
732 desc--verbose: no user, no domain
732 desc--verbose: no user, no domain
733 desc--verbose: no person
733 desc--verbose: no person
734 desc--verbose: other 1
734 desc--verbose: other 1
735 other 2
735 other 2
736
736
737 other 3
737 other 3
738 desc--verbose: line 1
738 desc--verbose: line 1
739 line 2
739 line 2
740 desc--debug: third
740 desc--debug: third
741 desc--debug: second
741 desc--debug: second
742 desc--debug: merge
742 desc--debug: merge
743 desc--debug: new head
743 desc--debug: new head
744 desc--debug: new branch
744 desc--debug: new branch
745 desc--debug: no user, no domain
745 desc--debug: no user, no domain
746 desc--debug: no person
746 desc--debug: no person
747 desc--debug: other 1
747 desc--debug: other 1
748 other 2
748 other 2
749
749
750 other 3
750 other 3
751 desc--debug: line 1
751 desc--debug: line 1
752 line 2
752 line 2
753 file_adds: fourth third
753 file_adds: fourth third
754 file_adds: second
754 file_adds: second
755 file_adds:
755 file_adds:
756 file_adds: d
756 file_adds: d
757 file_adds:
757 file_adds:
758 file_adds:
758 file_adds:
759 file_adds: c
759 file_adds: c
760 file_adds: b
760 file_adds: b
761 file_adds: a
761 file_adds: a
762 file_adds--verbose: fourth third
762 file_adds--verbose: fourth third
763 file_adds--verbose: second
763 file_adds--verbose: second
764 file_adds--verbose:
764 file_adds--verbose:
765 file_adds--verbose: d
765 file_adds--verbose: d
766 file_adds--verbose:
766 file_adds--verbose:
767 file_adds--verbose:
767 file_adds--verbose:
768 file_adds--verbose: c
768 file_adds--verbose: c
769 file_adds--verbose: b
769 file_adds--verbose: b
770 file_adds--verbose: a
770 file_adds--verbose: a
771 file_adds--debug: fourth third
771 file_adds--debug: fourth third
772 file_adds--debug: second
772 file_adds--debug: second
773 file_adds--debug:
773 file_adds--debug:
774 file_adds--debug: d
774 file_adds--debug: d
775 file_adds--debug:
775 file_adds--debug:
776 file_adds--debug:
776 file_adds--debug:
777 file_adds--debug: c
777 file_adds--debug: c
778 file_adds--debug: b
778 file_adds--debug: b
779 file_adds--debug: a
779 file_adds--debug: a
780 file_dels: second
780 file_dels: second
781 file_dels:
781 file_dels:
782 file_dels:
782 file_dels:
783 file_dels:
783 file_dels:
784 file_dels:
784 file_dels:
785 file_dels:
785 file_dels:
786 file_dels:
786 file_dels:
787 file_dels:
787 file_dels:
788 file_dels:
788 file_dels:
789 file_dels--verbose: second
789 file_dels--verbose: second
790 file_dels--verbose:
790 file_dels--verbose:
791 file_dels--verbose:
791 file_dels--verbose:
792 file_dels--verbose:
792 file_dels--verbose:
793 file_dels--verbose:
793 file_dels--verbose:
794 file_dels--verbose:
794 file_dels--verbose:
795 file_dels--verbose:
795 file_dels--verbose:
796 file_dels--verbose:
796 file_dels--verbose:
797 file_dels--verbose:
797 file_dels--verbose:
798 file_dels--debug: second
798 file_dels--debug: second
799 file_dels--debug:
799 file_dels--debug:
800 file_dels--debug:
800 file_dels--debug:
801 file_dels--debug:
801 file_dels--debug:
802 file_dels--debug:
802 file_dels--debug:
803 file_dels--debug:
803 file_dels--debug:
804 file_dels--debug:
804 file_dels--debug:
805 file_dels--debug:
805 file_dels--debug:
806 file_dels--debug:
806 file_dels--debug:
807 file_mods:
807 file_mods:
808 file_mods:
808 file_mods:
809 file_mods:
809 file_mods:
810 file_mods:
810 file_mods:
811 file_mods:
811 file_mods:
812 file_mods: c
812 file_mods: c
813 file_mods:
813 file_mods:
814 file_mods:
814 file_mods:
815 file_mods:
815 file_mods:
816 file_mods--verbose:
816 file_mods--verbose:
817 file_mods--verbose:
817 file_mods--verbose:
818 file_mods--verbose:
818 file_mods--verbose:
819 file_mods--verbose:
819 file_mods--verbose:
820 file_mods--verbose:
820 file_mods--verbose:
821 file_mods--verbose: c
821 file_mods--verbose: c
822 file_mods--verbose:
822 file_mods--verbose:
823 file_mods--verbose:
823 file_mods--verbose:
824 file_mods--verbose:
824 file_mods--verbose:
825 file_mods--debug:
825 file_mods--debug:
826 file_mods--debug:
826 file_mods--debug:
827 file_mods--debug:
827 file_mods--debug:
828 file_mods--debug:
828 file_mods--debug:
829 file_mods--debug:
829 file_mods--debug:
830 file_mods--debug: c
830 file_mods--debug: c
831 file_mods--debug:
831 file_mods--debug:
832 file_mods--debug:
832 file_mods--debug:
833 file_mods--debug:
833 file_mods--debug:
834 file_copies: fourth (second)
834 file_copies: fourth (second)
835 file_copies:
835 file_copies:
836 file_copies:
836 file_copies:
837 file_copies:
837 file_copies:
838 file_copies:
838 file_copies:
839 file_copies:
839 file_copies:
840 file_copies:
840 file_copies:
841 file_copies:
841 file_copies:
842 file_copies:
842 file_copies:
843 file_copies--verbose: fourth (second)
843 file_copies--verbose: fourth (second)
844 file_copies--verbose:
844 file_copies--verbose:
845 file_copies--verbose:
845 file_copies--verbose:
846 file_copies--verbose:
846 file_copies--verbose:
847 file_copies--verbose:
847 file_copies--verbose:
848 file_copies--verbose:
848 file_copies--verbose:
849 file_copies--verbose:
849 file_copies--verbose:
850 file_copies--verbose:
850 file_copies--verbose:
851 file_copies--verbose:
851 file_copies--verbose:
852 file_copies--debug: fourth (second)
852 file_copies--debug: fourth (second)
853 file_copies--debug:
853 file_copies--debug:
854 file_copies--debug:
854 file_copies--debug:
855 file_copies--debug:
855 file_copies--debug:
856 file_copies--debug:
856 file_copies--debug:
857 file_copies--debug:
857 file_copies--debug:
858 file_copies--debug:
858 file_copies--debug:
859 file_copies--debug:
859 file_copies--debug:
860 file_copies--debug:
860 file_copies--debug:
861 file_copies_switch:
861 file_copies_switch:
862 file_copies_switch:
862 file_copies_switch:
863 file_copies_switch:
863 file_copies_switch:
864 file_copies_switch:
864 file_copies_switch:
865 file_copies_switch:
865 file_copies_switch:
866 file_copies_switch:
866 file_copies_switch:
867 file_copies_switch:
867 file_copies_switch:
868 file_copies_switch:
868 file_copies_switch:
869 file_copies_switch:
869 file_copies_switch:
870 file_copies_switch--verbose:
870 file_copies_switch--verbose:
871 file_copies_switch--verbose:
871 file_copies_switch--verbose:
872 file_copies_switch--verbose:
872 file_copies_switch--verbose:
873 file_copies_switch--verbose:
873 file_copies_switch--verbose:
874 file_copies_switch--verbose:
874 file_copies_switch--verbose:
875 file_copies_switch--verbose:
875 file_copies_switch--verbose:
876 file_copies_switch--verbose:
876 file_copies_switch--verbose:
877 file_copies_switch--verbose:
877 file_copies_switch--verbose:
878 file_copies_switch--verbose:
878 file_copies_switch--verbose:
879 file_copies_switch--debug:
879 file_copies_switch--debug:
880 file_copies_switch--debug:
880 file_copies_switch--debug:
881 file_copies_switch--debug:
881 file_copies_switch--debug:
882 file_copies_switch--debug:
882 file_copies_switch--debug:
883 file_copies_switch--debug:
883 file_copies_switch--debug:
884 file_copies_switch--debug:
884 file_copies_switch--debug:
885 file_copies_switch--debug:
885 file_copies_switch--debug:
886 file_copies_switch--debug:
886 file_copies_switch--debug:
887 file_copies_switch--debug:
887 file_copies_switch--debug:
888 files: fourth second third
888 files: fourth second third
889 files: second
889 files: second
890 files:
890 files:
891 files: d
891 files: d
892 files:
892 files:
893 files: c
893 files: c
894 files: c
894 files: c
895 files: b
895 files: b
896 files: a
896 files: a
897 files--verbose: fourth second third
897 files--verbose: fourth second third
898 files--verbose: second
898 files--verbose: second
899 files--verbose:
899 files--verbose:
900 files--verbose: d
900 files--verbose: d
901 files--verbose:
901 files--verbose:
902 files--verbose: c
902 files--verbose: c
903 files--verbose: c
903 files--verbose: c
904 files--verbose: b
904 files--verbose: b
905 files--verbose: a
905 files--verbose: a
906 files--debug: fourth second third
906 files--debug: fourth second third
907 files--debug: second
907 files--debug: second
908 files--debug:
908 files--debug:
909 files--debug: d
909 files--debug: d
910 files--debug:
910 files--debug:
911 files--debug: c
911 files--debug: c
912 files--debug: c
912 files--debug: c
913 files--debug: b
913 files--debug: b
914 files--debug: a
914 files--debug: a
915 manifest: 6:94961b75a2da
915 manifest: 6:94961b75a2da
916 manifest: 5:f2dbc354b94e
916 manifest: 5:f2dbc354b94e
917 manifest: 4:4dc3def4f9b4
917 manifest: 4:4dc3def4f9b4
918 manifest: 4:4dc3def4f9b4
918 manifest: 4:4dc3def4f9b4
919 manifest: 3:cb5a1327723b
919 manifest: 3:cb5a1327723b
920 manifest: 3:cb5a1327723b
920 manifest: 3:cb5a1327723b
921 manifest: 2:6e0e82995c35
921 manifest: 2:6e0e82995c35
922 manifest: 1:4e8d705b1e53
922 manifest: 1:4e8d705b1e53
923 manifest: 0:a0c8bcbbb45c
923 manifest: 0:a0c8bcbbb45c
924 manifest--verbose: 6:94961b75a2da
924 manifest--verbose: 6:94961b75a2da
925 manifest--verbose: 5:f2dbc354b94e
925 manifest--verbose: 5:f2dbc354b94e
926 manifest--verbose: 4:4dc3def4f9b4
926 manifest--verbose: 4:4dc3def4f9b4
927 manifest--verbose: 4:4dc3def4f9b4
927 manifest--verbose: 4:4dc3def4f9b4
928 manifest--verbose: 3:cb5a1327723b
928 manifest--verbose: 3:cb5a1327723b
929 manifest--verbose: 3:cb5a1327723b
929 manifest--verbose: 3:cb5a1327723b
930 manifest--verbose: 2:6e0e82995c35
930 manifest--verbose: 2:6e0e82995c35
931 manifest--verbose: 1:4e8d705b1e53
931 manifest--verbose: 1:4e8d705b1e53
932 manifest--verbose: 0:a0c8bcbbb45c
932 manifest--verbose: 0:a0c8bcbbb45c
933 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
933 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
934 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
934 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
935 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
935 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
936 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
936 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
937 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
937 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
938 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
938 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
939 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
939 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
940 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
940 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
941 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
941 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
942 node: 95c24699272ef57d062b8bccc32c878bf841784a
942 node: 95c24699272ef57d062b8bccc32c878bf841784a
943 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
943 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
944 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
944 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
945 node: 13207e5a10d9fd28ec424934298e176197f2c67f
945 node: 13207e5a10d9fd28ec424934298e176197f2c67f
946 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
946 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
947 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
947 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
948 node: 97054abb4ab824450e9164180baf491ae0078465
948 node: 97054abb4ab824450e9164180baf491ae0078465
949 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
949 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
950 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
950 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
951 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
951 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
952 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
952 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
953 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
953 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
954 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
954 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
955 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
955 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
956 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
956 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
957 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
957 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
958 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
958 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
959 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
959 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
960 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
960 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
961 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
961 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
962 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
962 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
963 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
963 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
964 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
964 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
965 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
965 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
966 node--debug: 97054abb4ab824450e9164180baf491ae0078465
966 node--debug: 97054abb4ab824450e9164180baf491ae0078465
967 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
967 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
968 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
968 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
969 parents:
969 parents:
970 parents: -1:000000000000
970 parents: -1:000000000000
971 parents: 5:13207e5a10d9 4:bbe44766e73d
971 parents: 5:13207e5a10d9 4:bbe44766e73d
972 parents: 3:10e46f2dcbf4
972 parents: 3:10e46f2dcbf4
973 parents:
973 parents:
974 parents:
974 parents:
975 parents:
975 parents:
976 parents:
976 parents:
977 parents:
977 parents:
978 parents--verbose:
978 parents--verbose:
979 parents--verbose: -1:000000000000
979 parents--verbose: -1:000000000000
980 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
980 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
981 parents--verbose: 3:10e46f2dcbf4
981 parents--verbose: 3:10e46f2dcbf4
982 parents--verbose:
982 parents--verbose:
983 parents--verbose:
983 parents--verbose:
984 parents--verbose:
984 parents--verbose:
985 parents--verbose:
985 parents--verbose:
986 parents--verbose:
986 parents--verbose:
987 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
987 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
988 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
988 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
989 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
989 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
990 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
990 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
991 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
991 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
992 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
992 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
993 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
993 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
994 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
994 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
995 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
995 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
996 rev: 8
996 rev: 8
997 rev: 7
997 rev: 7
998 rev: 6
998 rev: 6
999 rev: 5
999 rev: 5
1000 rev: 4
1000 rev: 4
1001 rev: 3
1001 rev: 3
1002 rev: 2
1002 rev: 2
1003 rev: 1
1003 rev: 1
1004 rev: 0
1004 rev: 0
1005 rev--verbose: 8
1005 rev--verbose: 8
1006 rev--verbose: 7
1006 rev--verbose: 7
1007 rev--verbose: 6
1007 rev--verbose: 6
1008 rev--verbose: 5
1008 rev--verbose: 5
1009 rev--verbose: 4
1009 rev--verbose: 4
1010 rev--verbose: 3
1010 rev--verbose: 3
1011 rev--verbose: 2
1011 rev--verbose: 2
1012 rev--verbose: 1
1012 rev--verbose: 1
1013 rev--verbose: 0
1013 rev--verbose: 0
1014 rev--debug: 8
1014 rev--debug: 8
1015 rev--debug: 7
1015 rev--debug: 7
1016 rev--debug: 6
1016 rev--debug: 6
1017 rev--debug: 5
1017 rev--debug: 5
1018 rev--debug: 4
1018 rev--debug: 4
1019 rev--debug: 3
1019 rev--debug: 3
1020 rev--debug: 2
1020 rev--debug: 2
1021 rev--debug: 1
1021 rev--debug: 1
1022 rev--debug: 0
1022 rev--debug: 0
1023 tags: tip
1023 tags: tip
1024 tags:
1024 tags:
1025 tags:
1025 tags:
1026 tags:
1026 tags:
1027 tags:
1027 tags:
1028 tags:
1028 tags:
1029 tags:
1029 tags:
1030 tags:
1030 tags:
1031 tags:
1031 tags:
1032 tags--verbose: tip
1032 tags--verbose: tip
1033 tags--verbose:
1033 tags--verbose:
1034 tags--verbose:
1034 tags--verbose:
1035 tags--verbose:
1035 tags--verbose:
1036 tags--verbose:
1036 tags--verbose:
1037 tags--verbose:
1037 tags--verbose:
1038 tags--verbose:
1038 tags--verbose:
1039 tags--verbose:
1039 tags--verbose:
1040 tags--verbose:
1040 tags--verbose:
1041 tags--debug: tip
1041 tags--debug: tip
1042 tags--debug:
1042 tags--debug:
1043 tags--debug:
1043 tags--debug:
1044 tags--debug:
1044 tags--debug:
1045 tags--debug:
1045 tags--debug:
1046 tags--debug:
1046 tags--debug:
1047 tags--debug:
1047 tags--debug:
1048 tags--debug:
1048 tags--debug:
1049 tags--debug:
1049 tags--debug:
1050 diffstat: 3: +2/-1
1050 diffstat: 3: +2/-1
1051 diffstat: 1: +1/-0
1051 diffstat: 1: +1/-0
1052 diffstat: 0: +0/-0
1052 diffstat: 0: +0/-0
1053 diffstat: 1: +1/-0
1053 diffstat: 1: +1/-0
1054 diffstat: 0: +0/-0
1054 diffstat: 0: +0/-0
1055 diffstat: 1: +1/-0
1055 diffstat: 1: +1/-0
1056 diffstat: 1: +4/-0
1056 diffstat: 1: +4/-0
1057 diffstat: 1: +2/-0
1057 diffstat: 1: +2/-0
1058 diffstat: 1: +1/-0
1058 diffstat: 1: +1/-0
1059 diffstat--verbose: 3: +2/-1
1059 diffstat--verbose: 3: +2/-1
1060 diffstat--verbose: 1: +1/-0
1060 diffstat--verbose: 1: +1/-0
1061 diffstat--verbose: 0: +0/-0
1061 diffstat--verbose: 0: +0/-0
1062 diffstat--verbose: 1: +1/-0
1062 diffstat--verbose: 1: +1/-0
1063 diffstat--verbose: 0: +0/-0
1063 diffstat--verbose: 0: +0/-0
1064 diffstat--verbose: 1: +1/-0
1064 diffstat--verbose: 1: +1/-0
1065 diffstat--verbose: 1: +4/-0
1065 diffstat--verbose: 1: +4/-0
1066 diffstat--verbose: 1: +2/-0
1066 diffstat--verbose: 1: +2/-0
1067 diffstat--verbose: 1: +1/-0
1067 diffstat--verbose: 1: +1/-0
1068 diffstat--debug: 3: +2/-1
1068 diffstat--debug: 3: +2/-1
1069 diffstat--debug: 1: +1/-0
1069 diffstat--debug: 1: +1/-0
1070 diffstat--debug: 0: +0/-0
1070 diffstat--debug: 0: +0/-0
1071 diffstat--debug: 1: +1/-0
1071 diffstat--debug: 1: +1/-0
1072 diffstat--debug: 0: +0/-0
1072 diffstat--debug: 0: +0/-0
1073 diffstat--debug: 1: +1/-0
1073 diffstat--debug: 1: +1/-0
1074 diffstat--debug: 1: +4/-0
1074 diffstat--debug: 1: +4/-0
1075 diffstat--debug: 1: +2/-0
1075 diffstat--debug: 1: +2/-0
1076 diffstat--debug: 1: +1/-0
1076 diffstat--debug: 1: +1/-0
1077 extras: branch=default
1077 extras: branch=default
1078 extras: branch=default
1078 extras: branch=default
1079 extras: branch=default
1079 extras: branch=default
1080 extras: branch=default
1080 extras: branch=default
1081 extras: branch=foo
1081 extras: branch=foo
1082 extras: branch=default
1082 extras: branch=default
1083 extras: branch=default
1083 extras: branch=default
1084 extras: branch=default
1084 extras: branch=default
1085 extras: branch=default
1085 extras: branch=default
1086 extras--verbose: branch=default
1086 extras--verbose: branch=default
1087 extras--verbose: branch=default
1087 extras--verbose: branch=default
1088 extras--verbose: branch=default
1088 extras--verbose: branch=default
1089 extras--verbose: branch=default
1089 extras--verbose: branch=default
1090 extras--verbose: branch=foo
1090 extras--verbose: branch=foo
1091 extras--verbose: branch=default
1091 extras--verbose: branch=default
1092 extras--verbose: branch=default
1092 extras--verbose: branch=default
1093 extras--verbose: branch=default
1093 extras--verbose: branch=default
1094 extras--verbose: branch=default
1094 extras--verbose: branch=default
1095 extras--debug: branch=default
1095 extras--debug: branch=default
1096 extras--debug: branch=default
1096 extras--debug: branch=default
1097 extras--debug: branch=default
1097 extras--debug: branch=default
1098 extras--debug: branch=default
1098 extras--debug: branch=default
1099 extras--debug: branch=foo
1099 extras--debug: branch=foo
1100 extras--debug: branch=default
1100 extras--debug: branch=default
1101 extras--debug: branch=default
1101 extras--debug: branch=default
1102 extras--debug: branch=default
1102 extras--debug: branch=default
1103 extras--debug: branch=default
1103 extras--debug: branch=default
1104 p1rev: 7
1104 p1rev: 7
1105 p1rev: -1
1105 p1rev: -1
1106 p1rev: 5
1106 p1rev: 5
1107 p1rev: 3
1107 p1rev: 3
1108 p1rev: 3
1108 p1rev: 3
1109 p1rev: 2
1109 p1rev: 2
1110 p1rev: 1
1110 p1rev: 1
1111 p1rev: 0
1111 p1rev: 0
1112 p1rev: -1
1112 p1rev: -1
1113 p1rev--verbose: 7
1113 p1rev--verbose: 7
1114 p1rev--verbose: -1
1114 p1rev--verbose: -1
1115 p1rev--verbose: 5
1115 p1rev--verbose: 5
1116 p1rev--verbose: 3
1116 p1rev--verbose: 3
1117 p1rev--verbose: 3
1117 p1rev--verbose: 3
1118 p1rev--verbose: 2
1118 p1rev--verbose: 2
1119 p1rev--verbose: 1
1119 p1rev--verbose: 1
1120 p1rev--verbose: 0
1120 p1rev--verbose: 0
1121 p1rev--verbose: -1
1121 p1rev--verbose: -1
1122 p1rev--debug: 7
1122 p1rev--debug: 7
1123 p1rev--debug: -1
1123 p1rev--debug: -1
1124 p1rev--debug: 5
1124 p1rev--debug: 5
1125 p1rev--debug: 3
1125 p1rev--debug: 3
1126 p1rev--debug: 3
1126 p1rev--debug: 3
1127 p1rev--debug: 2
1127 p1rev--debug: 2
1128 p1rev--debug: 1
1128 p1rev--debug: 1
1129 p1rev--debug: 0
1129 p1rev--debug: 0
1130 p1rev--debug: -1
1130 p1rev--debug: -1
1131 p2rev: -1
1131 p2rev: -1
1132 p2rev: -1
1132 p2rev: -1
1133 p2rev: 4
1133 p2rev: 4
1134 p2rev: -1
1134 p2rev: -1
1135 p2rev: -1
1135 p2rev: -1
1136 p2rev: -1
1136 p2rev: -1
1137 p2rev: -1
1137 p2rev: -1
1138 p2rev: -1
1138 p2rev: -1
1139 p2rev: -1
1139 p2rev: -1
1140 p2rev--verbose: -1
1140 p2rev--verbose: -1
1141 p2rev--verbose: -1
1141 p2rev--verbose: -1
1142 p2rev--verbose: 4
1142 p2rev--verbose: 4
1143 p2rev--verbose: -1
1143 p2rev--verbose: -1
1144 p2rev--verbose: -1
1144 p2rev--verbose: -1
1145 p2rev--verbose: -1
1145 p2rev--verbose: -1
1146 p2rev--verbose: -1
1146 p2rev--verbose: -1
1147 p2rev--verbose: -1
1147 p2rev--verbose: -1
1148 p2rev--verbose: -1
1148 p2rev--verbose: -1
1149 p2rev--debug: -1
1149 p2rev--debug: -1
1150 p2rev--debug: -1
1150 p2rev--debug: -1
1151 p2rev--debug: 4
1151 p2rev--debug: 4
1152 p2rev--debug: -1
1152 p2rev--debug: -1
1153 p2rev--debug: -1
1153 p2rev--debug: -1
1154 p2rev--debug: -1
1154 p2rev--debug: -1
1155 p2rev--debug: -1
1155 p2rev--debug: -1
1156 p2rev--debug: -1
1156 p2rev--debug: -1
1157 p2rev--debug: -1
1157 p2rev--debug: -1
1158 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1158 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1159 p1node: 0000000000000000000000000000000000000000
1159 p1node: 0000000000000000000000000000000000000000
1160 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1160 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1161 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1161 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1162 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1162 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1163 p1node: 97054abb4ab824450e9164180baf491ae0078465
1163 p1node: 97054abb4ab824450e9164180baf491ae0078465
1164 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1164 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1165 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1165 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1166 p1node: 0000000000000000000000000000000000000000
1166 p1node: 0000000000000000000000000000000000000000
1167 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1167 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1168 p1node--verbose: 0000000000000000000000000000000000000000
1168 p1node--verbose: 0000000000000000000000000000000000000000
1169 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1169 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1170 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1170 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1171 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1171 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1172 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1172 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1173 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1173 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1174 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1174 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1175 p1node--verbose: 0000000000000000000000000000000000000000
1175 p1node--verbose: 0000000000000000000000000000000000000000
1176 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1176 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1177 p1node--debug: 0000000000000000000000000000000000000000
1177 p1node--debug: 0000000000000000000000000000000000000000
1178 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1178 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1179 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1179 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1180 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1180 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1181 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1181 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1182 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1182 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1183 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1183 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1184 p1node--debug: 0000000000000000000000000000000000000000
1184 p1node--debug: 0000000000000000000000000000000000000000
1185 p2node: 0000000000000000000000000000000000000000
1185 p2node: 0000000000000000000000000000000000000000
1186 p2node: 0000000000000000000000000000000000000000
1186 p2node: 0000000000000000000000000000000000000000
1187 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1187 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1188 p2node: 0000000000000000000000000000000000000000
1188 p2node: 0000000000000000000000000000000000000000
1189 p2node: 0000000000000000000000000000000000000000
1189 p2node: 0000000000000000000000000000000000000000
1190 p2node: 0000000000000000000000000000000000000000
1190 p2node: 0000000000000000000000000000000000000000
1191 p2node: 0000000000000000000000000000000000000000
1191 p2node: 0000000000000000000000000000000000000000
1192 p2node: 0000000000000000000000000000000000000000
1192 p2node: 0000000000000000000000000000000000000000
1193 p2node: 0000000000000000000000000000000000000000
1193 p2node: 0000000000000000000000000000000000000000
1194 p2node--verbose: 0000000000000000000000000000000000000000
1194 p2node--verbose: 0000000000000000000000000000000000000000
1195 p2node--verbose: 0000000000000000000000000000000000000000
1195 p2node--verbose: 0000000000000000000000000000000000000000
1196 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1196 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1197 p2node--verbose: 0000000000000000000000000000000000000000
1197 p2node--verbose: 0000000000000000000000000000000000000000
1198 p2node--verbose: 0000000000000000000000000000000000000000
1198 p2node--verbose: 0000000000000000000000000000000000000000
1199 p2node--verbose: 0000000000000000000000000000000000000000
1199 p2node--verbose: 0000000000000000000000000000000000000000
1200 p2node--verbose: 0000000000000000000000000000000000000000
1200 p2node--verbose: 0000000000000000000000000000000000000000
1201 p2node--verbose: 0000000000000000000000000000000000000000
1201 p2node--verbose: 0000000000000000000000000000000000000000
1202 p2node--verbose: 0000000000000000000000000000000000000000
1202 p2node--verbose: 0000000000000000000000000000000000000000
1203 p2node--debug: 0000000000000000000000000000000000000000
1203 p2node--debug: 0000000000000000000000000000000000000000
1204 p2node--debug: 0000000000000000000000000000000000000000
1204 p2node--debug: 0000000000000000000000000000000000000000
1205 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1205 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1206 p2node--debug: 0000000000000000000000000000000000000000
1206 p2node--debug: 0000000000000000000000000000000000000000
1207 p2node--debug: 0000000000000000000000000000000000000000
1207 p2node--debug: 0000000000000000000000000000000000000000
1208 p2node--debug: 0000000000000000000000000000000000000000
1208 p2node--debug: 0000000000000000000000000000000000000000
1209 p2node--debug: 0000000000000000000000000000000000000000
1209 p2node--debug: 0000000000000000000000000000000000000000
1210 p2node--debug: 0000000000000000000000000000000000000000
1210 p2node--debug: 0000000000000000000000000000000000000000
1211 p2node--debug: 0000000000000000000000000000000000000000
1211 p2node--debug: 0000000000000000000000000000000000000000
1212
1212
1213 Filters work:
1213 Filters work:
1214
1214
1215 $ hg log --template '{author|domain}\n'
1215 $ hg log --template '{author|domain}\n'
1216
1216
1217 hostname
1217 hostname
1218
1218
1219
1219
1220
1220
1221
1221
1222 place
1222 place
1223 place
1223 place
1224 hostname
1224 hostname
1225
1225
1226 $ hg log --template '{author|person}\n'
1226 $ hg log --template '{author|person}\n'
1227 test
1227 test
1228 User Name
1228 User Name
1229 person
1229 person
1230 person
1230 person
1231 person
1231 person
1232 person
1232 person
1233 other
1233 other
1234 A. N. Other
1234 A. N. Other
1235 User Name
1235 User Name
1236
1236
1237 $ hg log --template '{author|user}\n'
1237 $ hg log --template '{author|user}\n'
1238 test
1238 test
1239 user
1239 user
1240 person
1240 person
1241 person
1241 person
1242 person
1242 person
1243 person
1243 person
1244 other
1244 other
1245 other
1245 other
1246 user
1246 user
1247
1247
1248 $ hg log --template '{date|date}\n'
1248 $ hg log --template '{date|date}\n'
1249 Wed Jan 01 10:01:00 2020 +0000
1249 Wed Jan 01 10:01:00 2020 +0000
1250 Mon Jan 12 13:46:40 1970 +0000
1250 Mon Jan 12 13:46:40 1970 +0000
1251 Sun Jan 18 08:40:01 1970 +0000
1251 Sun Jan 18 08:40:01 1970 +0000
1252 Sun Jan 18 08:40:00 1970 +0000
1252 Sun Jan 18 08:40:00 1970 +0000
1253 Sat Jan 17 04:53:20 1970 +0000
1253 Sat Jan 17 04:53:20 1970 +0000
1254 Fri Jan 16 01:06:40 1970 +0000
1254 Fri Jan 16 01:06:40 1970 +0000
1255 Wed Jan 14 21:20:00 1970 +0000
1255 Wed Jan 14 21:20:00 1970 +0000
1256 Tue Jan 13 17:33:20 1970 +0000
1256 Tue Jan 13 17:33:20 1970 +0000
1257 Mon Jan 12 13:46:40 1970 +0000
1257 Mon Jan 12 13:46:40 1970 +0000
1258
1258
1259 $ hg log --template '{date|isodate}\n'
1259 $ hg log --template '{date|isodate}\n'
1260 2020-01-01 10:01 +0000
1260 2020-01-01 10:01 +0000
1261 1970-01-12 13:46 +0000
1261 1970-01-12 13:46 +0000
1262 1970-01-18 08:40 +0000
1262 1970-01-18 08:40 +0000
1263 1970-01-18 08:40 +0000
1263 1970-01-18 08:40 +0000
1264 1970-01-17 04:53 +0000
1264 1970-01-17 04:53 +0000
1265 1970-01-16 01:06 +0000
1265 1970-01-16 01:06 +0000
1266 1970-01-14 21:20 +0000
1266 1970-01-14 21:20 +0000
1267 1970-01-13 17:33 +0000
1267 1970-01-13 17:33 +0000
1268 1970-01-12 13:46 +0000
1268 1970-01-12 13:46 +0000
1269
1269
1270 $ hg log --template '{date|isodatesec}\n'
1270 $ hg log --template '{date|isodatesec}\n'
1271 2020-01-01 10:01:00 +0000
1271 2020-01-01 10:01:00 +0000
1272 1970-01-12 13:46:40 +0000
1272 1970-01-12 13:46:40 +0000
1273 1970-01-18 08:40:01 +0000
1273 1970-01-18 08:40:01 +0000
1274 1970-01-18 08:40:00 +0000
1274 1970-01-18 08:40:00 +0000
1275 1970-01-17 04:53:20 +0000
1275 1970-01-17 04:53:20 +0000
1276 1970-01-16 01:06:40 +0000
1276 1970-01-16 01:06:40 +0000
1277 1970-01-14 21:20:00 +0000
1277 1970-01-14 21:20:00 +0000
1278 1970-01-13 17:33:20 +0000
1278 1970-01-13 17:33:20 +0000
1279 1970-01-12 13:46:40 +0000
1279 1970-01-12 13:46:40 +0000
1280
1280
1281 $ hg log --template '{date|rfc822date}\n'
1281 $ hg log --template '{date|rfc822date}\n'
1282 Wed, 01 Jan 2020 10:01:00 +0000
1282 Wed, 01 Jan 2020 10:01:00 +0000
1283 Mon, 12 Jan 1970 13:46:40 +0000
1283 Mon, 12 Jan 1970 13:46:40 +0000
1284 Sun, 18 Jan 1970 08:40:01 +0000
1284 Sun, 18 Jan 1970 08:40:01 +0000
1285 Sun, 18 Jan 1970 08:40:00 +0000
1285 Sun, 18 Jan 1970 08:40:00 +0000
1286 Sat, 17 Jan 1970 04:53:20 +0000
1286 Sat, 17 Jan 1970 04:53:20 +0000
1287 Fri, 16 Jan 1970 01:06:40 +0000
1287 Fri, 16 Jan 1970 01:06:40 +0000
1288 Wed, 14 Jan 1970 21:20:00 +0000
1288 Wed, 14 Jan 1970 21:20:00 +0000
1289 Tue, 13 Jan 1970 17:33:20 +0000
1289 Tue, 13 Jan 1970 17:33:20 +0000
1290 Mon, 12 Jan 1970 13:46:40 +0000
1290 Mon, 12 Jan 1970 13:46:40 +0000
1291
1291
1292 $ hg log --template '{desc|firstline}\n'
1292 $ hg log --template '{desc|firstline}\n'
1293 third
1293 third
1294 second
1294 second
1295 merge
1295 merge
1296 new head
1296 new head
1297 new branch
1297 new branch
1298 no user, no domain
1298 no user, no domain
1299 no person
1299 no person
1300 other 1
1300 other 1
1301 line 1
1301 line 1
1302
1302
1303 $ hg log --template '{node|short}\n'
1303 $ hg log --template '{node|short}\n'
1304 95c24699272e
1304 95c24699272e
1305 29114dbae42b
1305 29114dbae42b
1306 d41e714fe50d
1306 d41e714fe50d
1307 13207e5a10d9
1307 13207e5a10d9
1308 bbe44766e73d
1308 bbe44766e73d
1309 10e46f2dcbf4
1309 10e46f2dcbf4
1310 97054abb4ab8
1310 97054abb4ab8
1311 b608e9d1a3f0
1311 b608e9d1a3f0
1312 1e4e1b8f71e0
1312 1e4e1b8f71e0
1313
1313
1314 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1314 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1315 <changeset author="test"/>
1315 <changeset author="test"/>
1316 <changeset author="User Name &lt;user@hostname&gt;"/>
1316 <changeset author="User Name &lt;user@hostname&gt;"/>
1317 <changeset author="person"/>
1317 <changeset author="person"/>
1318 <changeset author="person"/>
1318 <changeset author="person"/>
1319 <changeset author="person"/>
1319 <changeset author="person"/>
1320 <changeset author="person"/>
1320 <changeset author="person"/>
1321 <changeset author="other@place"/>
1321 <changeset author="other@place"/>
1322 <changeset author="A. N. Other &lt;other@place&gt;"/>
1322 <changeset author="A. N. Other &lt;other@place&gt;"/>
1323 <changeset author="User Name &lt;user@hostname&gt;"/>
1323 <changeset author="User Name &lt;user@hostname&gt;"/>
1324
1324
1325 $ hg log --template '{rev}: {children}\n'
1325 $ hg log --template '{rev}: {children}\n'
1326 8:
1326 8:
1327 7: 8:95c24699272e
1327 7: 8:95c24699272e
1328 6:
1328 6:
1329 5: 6:d41e714fe50d
1329 5: 6:d41e714fe50d
1330 4: 6:d41e714fe50d
1330 4: 6:d41e714fe50d
1331 3: 4:bbe44766e73d 5:13207e5a10d9
1331 3: 4:bbe44766e73d 5:13207e5a10d9
1332 2: 3:10e46f2dcbf4
1332 2: 3:10e46f2dcbf4
1333 1: 2:97054abb4ab8
1333 1: 2:97054abb4ab8
1334 0: 1:b608e9d1a3f0
1334 0: 1:b608e9d1a3f0
1335
1335
1336 Formatnode filter works:
1336 Formatnode filter works:
1337
1337
1338 $ hg -q log -r 0 --template '{node|formatnode}\n'
1338 $ hg -q log -r 0 --template '{node|formatnode}\n'
1339 1e4e1b8f71e0
1339 1e4e1b8f71e0
1340
1340
1341 $ hg log -r 0 --template '{node|formatnode}\n'
1341 $ hg log -r 0 --template '{node|formatnode}\n'
1342 1e4e1b8f71e0
1342 1e4e1b8f71e0
1343
1343
1344 $ hg -v log -r 0 --template '{node|formatnode}\n'
1344 $ hg -v log -r 0 --template '{node|formatnode}\n'
1345 1e4e1b8f71e0
1345 1e4e1b8f71e0
1346
1346
1347 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1347 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1348 1e4e1b8f71e05681d422154f5421e385fec3454f
1348 1e4e1b8f71e05681d422154f5421e385fec3454f
1349
1349
1350 Age filter:
1350 Age filter:
1351
1351
1352 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1352 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1353
1353
1354 >>> from datetime import datetime, timedelta
1354 >>> from datetime import datetime, timedelta
1355 >>> fp = open('a', 'w')
1355 >>> fp = open('a', 'w')
1356 >>> n = datetime.now() + timedelta(366 * 7)
1356 >>> n = datetime.now() + timedelta(366 * 7)
1357 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1357 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1358 >>> fp.close()
1358 >>> fp.close()
1359 $ hg add a
1359 $ hg add a
1360 $ hg commit -m future -d "`cat a`"
1360 $ hg commit -m future -d "`cat a`"
1361
1361
1362 $ hg log -l1 --template '{date|age}\n'
1362 $ hg log -l1 --template '{date|age}\n'
1363 7 years from now
1363 7 years from now
1364
1364
1365 Error on syntax:
1365 Error on syntax:
1366
1366
1367 $ echo 'x = "f' >> t
1367 $ echo 'x = "f' >> t
1368 $ hg log
1368 $ hg log
1369 abort: t:3: unmatched quotes
1369 abort: t:3: unmatched quotes
1370 [255]
1370 [255]
1371
1371
1372 Behind the scenes, this will throw TypeError
1372 Behind the scenes, this will throw TypeError
1373
1373
1374 $ hg log -l 3 --template '{date|obfuscate}\n'
1374 $ hg log -l 3 --template '{date|obfuscate}\n'
1375 abort: template filter 'obfuscate' is not compatible with keyword 'date'
1375 abort: template filter 'obfuscate' is not compatible with keyword 'date'
1376 [255]
1376 [255]
1377
1377
1378 Behind the scenes, this will throw a ValueError
1378 Behind the scenes, this will throw a ValueError
1379
1379
1380 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1380 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1381 abort: template filter 'shortdate' is not compatible with keyword 'desc'
1381 abort: template filter 'shortdate' is not compatible with keyword 'desc'
1382 [255]
1382 [255]
1383
1383
1384 Behind the scenes, this will throw AttributeError
1384 Behind the scenes, this will throw AttributeError
1385
1385
1386 $ hg log -l 3 --template 'line: {date|escape}\n'
1386 $ hg log -l 3 --template 'line: {date|escape}\n'
1387 abort: template filter 'escape' is not compatible with keyword 'date'
1387 abort: template filter 'escape' is not compatible with keyword 'date'
1388 [255]
1388 [255]
1389
1389
1390 Behind the scenes, this will throw ValueError
1390 Behind the scenes, this will throw ValueError
1391
1391
1392 $ hg tip --template '{author|email|date}\n'
1392 $ hg tip --template '{author|email|date}\n'
1393 abort: template filter 'datefilter' is not compatible with keyword 'author'
1393 abort: template filter 'datefilter' is not compatible with keyword 'author'
1394 [255]
1394 [255]
1395
1395
1396 $ cd ..
1396 $ cd ..
1397
1397
1398
1398
1399 latesttag:
1399 latesttag:
1400
1400
1401 $ hg init latesttag
1401 $ hg init latesttag
1402 $ cd latesttag
1402 $ cd latesttag
1403
1403
1404 $ echo a > file
1404 $ echo a > file
1405 $ hg ci -Am a -d '0 0'
1405 $ hg ci -Am a -d '0 0'
1406 adding file
1406 adding file
1407
1407
1408 $ echo b >> file
1408 $ echo b >> file
1409 $ hg ci -m b -d '1 0'
1409 $ hg ci -m b -d '1 0'
1410
1410
1411 $ echo c >> head1
1411 $ echo c >> head1
1412 $ hg ci -Am h1c -d '2 0'
1412 $ hg ci -Am h1c -d '2 0'
1413 adding head1
1413 adding head1
1414
1414
1415 $ hg update -q 1
1415 $ hg update -q 1
1416 $ echo d >> head2
1416 $ echo d >> head2
1417 $ hg ci -Am h2d -d '3 0'
1417 $ hg ci -Am h2d -d '3 0'
1418 adding head2
1418 adding head2
1419 created new head
1419 created new head
1420
1420
1421 $ echo e >> head2
1421 $ echo e >> head2
1422 $ hg ci -m h2e -d '4 0'
1422 $ hg ci -m h2e -d '4 0'
1423
1423
1424 $ hg merge -q
1424 $ hg merge -q
1425 $ hg ci -m merge -d '5 0'
1425 $ hg ci -m merge -d '5 0'
1426
1426
1427 No tag set:
1427 No tag set:
1428
1428
1429 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1429 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1430 5: null+5
1430 5: null+5
1431 4: null+4
1431 4: null+4
1432 3: null+3
1432 3: null+3
1433 2: null+3
1433 2: null+3
1434 1: null+2
1434 1: null+2
1435 0: null+1
1435 0: null+1
1436
1436
1437 One common tag: longuest path wins:
1437 One common tag: longuest path wins:
1438
1438
1439 $ hg tag -r 1 -m t1 -d '6 0' t1
1439 $ hg tag -r 1 -m t1 -d '6 0' t1
1440 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1440 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1441 6: t1+4
1441 6: t1+4
1442 5: t1+3
1442 5: t1+3
1443 4: t1+2
1443 4: t1+2
1444 3: t1+1
1444 3: t1+1
1445 2: t1+1
1445 2: t1+1
1446 1: t1+0
1446 1: t1+0
1447 0: null+1
1447 0: null+1
1448
1448
1449 One ancestor tag: more recent wins:
1449 One ancestor tag: more recent wins:
1450
1450
1451 $ hg tag -r 2 -m t2 -d '7 0' t2
1451 $ hg tag -r 2 -m t2 -d '7 0' t2
1452 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1452 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1453 7: t2+3
1453 7: t2+3
1454 6: t2+2
1454 6: t2+2
1455 5: t2+1
1455 5: t2+1
1456 4: t1+2
1456 4: t1+2
1457 3: t1+1
1457 3: t1+1
1458 2: t2+0
1458 2: t2+0
1459 1: t1+0
1459 1: t1+0
1460 0: null+1
1460 0: null+1
1461
1461
1462 Two branch tags: more recent wins:
1462 Two branch tags: more recent wins:
1463
1463
1464 $ hg tag -r 3 -m t3 -d '8 0' t3
1464 $ hg tag -r 3 -m t3 -d '8 0' t3
1465 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1465 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1466 8: t3+5
1466 8: t3+5
1467 7: t3+4
1467 7: t3+4
1468 6: t3+3
1468 6: t3+3
1469 5: t3+2
1469 5: t3+2
1470 4: t3+1
1470 4: t3+1
1471 3: t3+0
1471 3: t3+0
1472 2: t2+0
1472 2: t2+0
1473 1: t1+0
1473 1: t1+0
1474 0: null+1
1474 0: null+1
1475
1475
1476 Merged tag overrides:
1476 Merged tag overrides:
1477
1477
1478 $ hg tag -r 5 -m t5 -d '9 0' t5
1478 $ hg tag -r 5 -m t5 -d '9 0' t5
1479 $ hg tag -r 3 -m at3 -d '10 0' at3
1479 $ hg tag -r 3 -m at3 -d '10 0' at3
1480 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1480 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1481 10: t5+5
1481 10: t5+5
1482 9: t5+4
1482 9: t5+4
1483 8: t5+3
1483 8: t5+3
1484 7: t5+2
1484 7: t5+2
1485 6: t5+1
1485 6: t5+1
1486 5: t5+0
1486 5: t5+0
1487 4: at3:t3+1
1487 4: at3:t3+1
1488 3: at3:t3+0
1488 3: at3:t3+0
1489 2: t2+0
1489 2: t2+0
1490 1: t1+0
1490 1: t1+0
1491 0: null+1
1491 0: null+1
1492
1492
1493 $ cd ..
1493 $ cd ..
1494
1494
1495
1495
1496 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1496 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1497 if it is a relative path
1497 if it is a relative path
1498
1498
1499 $ mkdir -p home/styles
1499 $ mkdir -p home/styles
1500
1500
1501 $ cat > home/styles/teststyle <<EOF
1501 $ cat > home/styles/teststyle <<EOF
1502 > changeset = 'test {rev}:{node|short}\n'
1502 > changeset = 'test {rev}:{node|short}\n'
1503 > EOF
1503 > EOF
1504
1504
1505 $ HOME=`pwd`/home; export HOME
1505 $ HOME=`pwd`/home; export HOME
1506
1506
1507 $ cat > latesttag/.hg/hgrc <<EOF
1507 $ cat > latesttag/.hg/hgrc <<EOF
1508 > [ui]
1508 > [ui]
1509 > style = ~/styles/teststyle
1509 > style = ~/styles/teststyle
1510 > EOF
1510 > EOF
1511
1511
1512 $ hg -R latesttag tip
1512 $ hg -R latesttag tip
1513 test 10:dee8f28249af
1513 test 10:dee8f28249af
1514
1514
1515 Test recursive showlist template (issue1989):
1515 Test recursive showlist template (issue1989):
1516
1516
1517 $ cat > style1989 <<EOF
1517 $ cat > style1989 <<EOF
1518 > changeset = '{file_mods}{manifest}{extras}'
1518 > changeset = '{file_mods}{manifest}{extras}'
1519 > file_mod = 'M|{author|person}\n'
1519 > file_mod = 'M|{author|person}\n'
1520 > manifest = '{rev},{author}\n'
1520 > manifest = '{rev},{author}\n'
1521 > extra = '{key}: {author}\n'
1521 > extra = '{key}: {author}\n'
1522 > EOF
1522 > EOF
1523
1523
1524 $ hg -R latesttag log -r tip --style=style1989
1524 $ hg -R latesttag log -r tip --style=style1989
1525 M|test
1525 M|test
1526 10,test
1526 10,test
1527 branch: test
1527 branch: test
1528
1528
1529 Test new-style inline templating:
1529 Test new-style inline templating:
1530
1530
1531 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1531 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1532 modified files: .hgtags
1532 modified files: .hgtags
1533
1533
1534 Test the sub function of templating for expansion:
1535
1536 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
1537 xx
General Comments 0
You need to be logged in to leave comments. Login now