##// END OF EJS Templates
templater: add symbol to error...
Ryan McElroy -
r21822:028a4810 default
parent child Browse files
Show More
@@ -1,722 +1,722 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, templatekw, parser, error
10 import util, config, templatefilters, templatekw, 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 "rawstring": (0, ("rawstring",), None),
24 "rawstring": (0, ("rawstring",), None),
25 "end": (0, None, None),
25 "end": (0, None, None),
26 }
26 }
27
27
28 def tokenizer(data):
28 def tokenizer(data):
29 program, start, end = data
29 program, start, end = data
30 pos = start
30 pos = start
31 while pos < end:
31 while pos < end:
32 c = program[pos]
32 c = program[pos]
33 if c.isspace(): # skip inter-token whitespace
33 if c.isspace(): # skip inter-token whitespace
34 pass
34 pass
35 elif c in "(,)%|": # handle simple operators
35 elif c in "(,)%|": # handle simple operators
36 yield (c, None, pos)
36 yield (c, None, pos)
37 elif (c in '"\'' or c == 'r' and
37 elif (c in '"\'' or c == 'r' and
38 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
38 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
39 if c == 'r':
39 if c == 'r':
40 pos += 1
40 pos += 1
41 c = program[pos]
41 c = program[pos]
42 decode = False
42 decode = False
43 else:
43 else:
44 decode = True
44 decode = True
45 pos += 1
45 pos += 1
46 s = pos
46 s = pos
47 while pos < end: # find closing quote
47 while pos < end: # find closing quote
48 d = program[pos]
48 d = program[pos]
49 if decode and d == '\\': # skip over escaped characters
49 if decode and d == '\\': # skip over escaped characters
50 pos += 2
50 pos += 2
51 continue
51 continue
52 if d == c:
52 if d == c:
53 if not decode:
53 if not decode:
54 yield ('rawstring', program[s:pos], s)
54 yield ('rawstring', program[s:pos], s)
55 break
55 break
56 yield ('string', program[s:pos], s)
56 yield ('string', program[s:pos], s)
57 break
57 break
58 pos += 1
58 pos += 1
59 else:
59 else:
60 raise error.ParseError(_("unterminated string"), s)
60 raise error.ParseError(_("unterminated string"), s)
61 elif c.isalnum() or c in '_':
61 elif c.isalnum() or c in '_':
62 s = pos
62 s = pos
63 pos += 1
63 pos += 1
64 while pos < end: # find end of symbol
64 while pos < end: # find end of symbol
65 d = program[pos]
65 d = program[pos]
66 if not (d.isalnum() or d == "_"):
66 if not (d.isalnum() or d == "_"):
67 break
67 break
68 pos += 1
68 pos += 1
69 sym = program[s:pos]
69 sym = program[s:pos]
70 yield ('symbol', sym, s)
70 yield ('symbol', sym, s)
71 pos -= 1
71 pos -= 1
72 elif c == '}':
72 elif c == '}':
73 pos += 1
73 pos += 1
74 break
74 break
75 else:
75 else:
76 raise error.ParseError(_("syntax error"), pos)
76 raise error.ParseError(_("syntax error"), pos)
77 pos += 1
77 pos += 1
78 yield ('end', None, pos)
78 yield ('end', None, pos)
79
79
80 def compiletemplate(tmpl, context, strtoken="string"):
80 def compiletemplate(tmpl, context, strtoken="string"):
81 parsed = []
81 parsed = []
82 pos, stop = 0, len(tmpl)
82 pos, stop = 0, len(tmpl)
83 p = parser.parser(tokenizer, elements)
83 p = parser.parser(tokenizer, elements)
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((strtoken, tmpl[pos:]))
87 parsed.append((strtoken, 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((strtoken, (tmpl[pos:n - 1] + "{")))
91 parsed.append((strtoken, (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((strtoken, tmpl[pos:n]))
95 parsed.append((strtoken, 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, got '%s'") % exp[0])
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' or exp[0] == 'rawstring':
130 if exp[0] == 'string' or exp[0] == 'rawstring':
131 return compiletemplate(exp[1], context, strtoken=exp[0])
131 return compiletemplate(exp[1], context, strtoken=exp[0])
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.decode("string-escape")
137 return data.decode("string-escape")
138
138
139 def runrawstring(context, mapping, data):
139 def runrawstring(context, mapping, data):
140 return data
140 return data
141
141
142 def runsymbol(context, mapping, key):
142 def runsymbol(context, mapping, key):
143 v = mapping.get(key)
143 v = mapping.get(key)
144 if v is None:
144 if v is None:
145 v = context._defaults.get(key)
145 v = context._defaults.get(key)
146 if v is None:
146 if v is None:
147 try:
147 try:
148 v = context.process(key, mapping)
148 v = context.process(key, mapping)
149 except TemplateNotFound:
149 except TemplateNotFound:
150 v = ''
150 v = ''
151 if callable(v):
151 if callable(v):
152 return v(**mapping)
152 return v(**mapping)
153 if isinstance(v, types.GeneratorType):
153 if isinstance(v, types.GeneratorType):
154 v = list(v)
154 v = list(v)
155 mapping[key] = v
155 mapping[key] = v
156 return v
156 return v
157 return v
157 return v
158
158
159 def buildfilter(exp, context):
159 def buildfilter(exp, context):
160 func, data = compileexp(exp[1], context)
160 func, data = compileexp(exp[1], context)
161 filt = getfilter(exp[2], context)
161 filt = getfilter(exp[2], context)
162 return (runfilter, (func, data, filt))
162 return (runfilter, (func, data, filt))
163
163
164 def runfilter(context, mapping, data):
164 def runfilter(context, mapping, data):
165 func, data, filt = data
165 func, data, filt = data
166 try:
166 try:
167 return filt(func(context, mapping, data))
167 return filt(func(context, mapping, data))
168 except (ValueError, AttributeError, TypeError):
168 except (ValueError, AttributeError, TypeError):
169 if isinstance(data, tuple):
169 if isinstance(data, tuple):
170 dt = data[1]
170 dt = data[1]
171 else:
171 else:
172 dt = data
172 dt = data
173 raise util.Abort(_("template filter '%s' is not compatible with "
173 raise util.Abort(_("template filter '%s' is not compatible with "
174 "keyword '%s'") % (filt.func_name, dt))
174 "keyword '%s'") % (filt.func_name, dt))
175
175
176 def buildmap(exp, context):
176 def buildmap(exp, context):
177 func, data = compileexp(exp[1], context)
177 func, data = compileexp(exp[1], context)
178 ctmpl = gettemplate(exp[2], context)
178 ctmpl = gettemplate(exp[2], context)
179 return (runmap, (func, data, ctmpl))
179 return (runmap, (func, data, ctmpl))
180
180
181 def runtemplate(context, mapping, template):
181 def runtemplate(context, mapping, template):
182 for func, data in template:
182 for func, data in template:
183 yield func(context, mapping, data)
183 yield func(context, mapping, data)
184
184
185 def runmap(context, mapping, data):
185 def runmap(context, mapping, data):
186 func, data, ctmpl = data
186 func, data, ctmpl = data
187 d = func(context, mapping, data)
187 d = func(context, mapping, data)
188 if callable(d):
188 if callable(d):
189 d = d()
189 d = d()
190
190
191 lm = mapping.copy()
191 lm = mapping.copy()
192
192
193 for i in d:
193 for i in d:
194 if isinstance(i, dict):
194 if isinstance(i, dict):
195 lm.update(i)
195 lm.update(i)
196 lm['originalnode'] = mapping.get('node')
196 lm['originalnode'] = mapping.get('node')
197 yield runtemplate(context, lm, ctmpl)
197 yield runtemplate(context, lm, ctmpl)
198 else:
198 else:
199 # v is not an iterable of dicts, this happen when 'key'
199 # v is not an iterable of dicts, this happen when 'key'
200 # has been fully expanded already and format is useless.
200 # has been fully expanded already and format is useless.
201 # If so, return the expanded value.
201 # If so, return the expanded value.
202 yield i
202 yield i
203
203
204 def buildfunc(exp, context):
204 def buildfunc(exp, context):
205 n = getsymbol(exp[1])
205 n = getsymbol(exp[1])
206 args = [compileexp(x, context) for x in getlist(exp[2])]
206 args = [compileexp(x, context) for x in getlist(exp[2])]
207 if n in funcs:
207 if n in funcs:
208 f = funcs[n]
208 f = funcs[n]
209 return (f, args)
209 return (f, args)
210 if n in context._filters:
210 if n in context._filters:
211 if len(args) != 1:
211 if len(args) != 1:
212 raise error.ParseError(_("filter %s expects one argument") % n)
212 raise error.ParseError(_("filter %s expects one argument") % n)
213 f = context._filters[n]
213 f = context._filters[n]
214 return (runfilter, (args[0][0], args[0][1], f))
214 return (runfilter, (args[0][0], args[0][1], f))
215 raise error.ParseError(_("unknown function '%s'") % n)
215 raise error.ParseError(_("unknown function '%s'") % n)
216
216
217 def date(context, mapping, args):
217 def date(context, mapping, args):
218 if not (1 <= len(args) <= 2):
218 if not (1 <= len(args) <= 2):
219 raise error.ParseError(_("date expects one or two arguments"))
219 raise error.ParseError(_("date expects one or two arguments"))
220
220
221 date = args[0][0](context, mapping, args[0][1])
221 date = args[0][0](context, mapping, args[0][1])
222 if len(args) == 2:
222 if len(args) == 2:
223 fmt = stringify(args[1][0](context, mapping, args[1][1]))
223 fmt = stringify(args[1][0](context, mapping, args[1][1]))
224 return util.datestr(date, fmt)
224 return util.datestr(date, fmt)
225 return util.datestr(date)
225 return util.datestr(date)
226
226
227 def fill(context, mapping, args):
227 def fill(context, mapping, args):
228 if not (1 <= len(args) <= 4):
228 if not (1 <= len(args) <= 4):
229 raise error.ParseError(_("fill expects one to four arguments"))
229 raise error.ParseError(_("fill expects one to four arguments"))
230
230
231 text = stringify(args[0][0](context, mapping, args[0][1]))
231 text = stringify(args[0][0](context, mapping, args[0][1]))
232 width = 76
232 width = 76
233 initindent = ''
233 initindent = ''
234 hangindent = ''
234 hangindent = ''
235 if 2 <= len(args) <= 4:
235 if 2 <= len(args) <= 4:
236 try:
236 try:
237 width = int(stringify(args[1][0](context, mapping, args[1][1])))
237 width = int(stringify(args[1][0](context, mapping, args[1][1])))
238 except ValueError:
238 except ValueError:
239 raise error.ParseError(_("fill expects an integer width"))
239 raise error.ParseError(_("fill expects an integer width"))
240 try:
240 try:
241 initindent = stringify(_evalifliteral(args[2], context, mapping))
241 initindent = stringify(_evalifliteral(args[2], context, mapping))
242 hangindent = stringify(_evalifliteral(args[3], context, mapping))
242 hangindent = stringify(_evalifliteral(args[3], context, mapping))
243 except IndexError:
243 except IndexError:
244 pass
244 pass
245
245
246 return templatefilters.fill(text, width, initindent, hangindent)
246 return templatefilters.fill(text, width, initindent, hangindent)
247
247
248 def pad(context, mapping, args):
248 def pad(context, mapping, args):
249 """usage: pad(text, width, fillchar=' ', right=False)
249 """usage: pad(text, width, fillchar=' ', right=False)
250 """
250 """
251 if not (2 <= len(args) <= 4):
251 if not (2 <= len(args) <= 4):
252 raise error.ParseError(_("pad() expects two to four arguments"))
252 raise error.ParseError(_("pad() expects two to four arguments"))
253
253
254 width = int(args[1][1])
254 width = int(args[1][1])
255
255
256 text = stringify(args[0][0](context, mapping, args[0][1]))
256 text = stringify(args[0][0](context, mapping, args[0][1]))
257 if args[0][0] == runstring:
257 if args[0][0] == runstring:
258 text = stringify(runtemplate(context, mapping,
258 text = stringify(runtemplate(context, mapping,
259 compiletemplate(text, context)))
259 compiletemplate(text, context)))
260
260
261 right = False
261 right = False
262 fillchar = ' '
262 fillchar = ' '
263 if len(args) > 2:
263 if len(args) > 2:
264 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
264 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
265 if len(args) > 3:
265 if len(args) > 3:
266 right = util.parsebool(args[3][1])
266 right = util.parsebool(args[3][1])
267
267
268 if right:
268 if right:
269 return text.rjust(width, fillchar)
269 return text.rjust(width, fillchar)
270 else:
270 else:
271 return text.ljust(width, fillchar)
271 return text.ljust(width, fillchar)
272
272
273 def get(context, mapping, args):
273 def get(context, mapping, args):
274 if len(args) != 2:
274 if len(args) != 2:
275 # i18n: "get" is a keyword
275 # i18n: "get" is a keyword
276 raise error.ParseError(_("get() expects two arguments"))
276 raise error.ParseError(_("get() expects two arguments"))
277
277
278 dictarg = args[0][0](context, mapping, args[0][1])
278 dictarg = args[0][0](context, mapping, args[0][1])
279 if not util.safehasattr(dictarg, 'get'):
279 if not util.safehasattr(dictarg, 'get'):
280 # i18n: "get" is a keyword
280 # i18n: "get" is a keyword
281 raise error.ParseError(_("get() expects a dict as first argument"))
281 raise error.ParseError(_("get() expects a dict as first argument"))
282
282
283 key = args[1][0](context, mapping, args[1][1])
283 key = args[1][0](context, mapping, args[1][1])
284 yield dictarg.get(key)
284 yield dictarg.get(key)
285
285
286 def _evalifliteral(arg, context, mapping):
286 def _evalifliteral(arg, context, mapping):
287 t = stringify(arg[0](context, mapping, arg[1]))
287 t = stringify(arg[0](context, mapping, arg[1]))
288 if arg[0] == runstring or arg[0] == runrawstring:
288 if arg[0] == runstring or arg[0] == runrawstring:
289 yield runtemplate(context, mapping,
289 yield runtemplate(context, mapping,
290 compiletemplate(t, context, strtoken='rawstring'))
290 compiletemplate(t, context, strtoken='rawstring'))
291 else:
291 else:
292 yield t
292 yield t
293
293
294 def if_(context, mapping, args):
294 def if_(context, mapping, args):
295 if not (2 <= len(args) <= 3):
295 if not (2 <= len(args) <= 3):
296 # i18n: "if" is a keyword
296 # i18n: "if" is a keyword
297 raise error.ParseError(_("if expects two or three arguments"))
297 raise error.ParseError(_("if expects two or three arguments"))
298
298
299 test = stringify(args[0][0](context, mapping, args[0][1]))
299 test = stringify(args[0][0](context, mapping, args[0][1]))
300 if test:
300 if test:
301 yield _evalifliteral(args[1], context, mapping)
301 yield _evalifliteral(args[1], context, mapping)
302 elif len(args) == 3:
302 elif len(args) == 3:
303 yield _evalifliteral(args[2], context, mapping)
303 yield _evalifliteral(args[2], context, mapping)
304
304
305 def ifcontains(context, mapping, args):
305 def ifcontains(context, mapping, args):
306 if not (3 <= len(args) <= 4):
306 if not (3 <= len(args) <= 4):
307 # i18n: "ifcontains" is a keyword
307 # i18n: "ifcontains" is a keyword
308 raise error.ParseError(_("ifcontains expects three or four arguments"))
308 raise error.ParseError(_("ifcontains expects three or four arguments"))
309
309
310 item = stringify(args[0][0](context, mapping, args[0][1]))
310 item = stringify(args[0][0](context, mapping, args[0][1]))
311 items = args[1][0](context, mapping, args[1][1])
311 items = args[1][0](context, mapping, args[1][1])
312
312
313 # Iterating over items gives a formatted string, so we iterate
313 # Iterating over items gives a formatted string, so we iterate
314 # directly over the raw values.
314 # directly over the raw values.
315 if item in [i.values()[0] for i in items()]:
315 if item in [i.values()[0] for i in items()]:
316 yield _evalifliteral(args[2], context, mapping)
316 yield _evalifliteral(args[2], context, mapping)
317 elif len(args) == 4:
317 elif len(args) == 4:
318 yield _evalifliteral(args[3], context, mapping)
318 yield _evalifliteral(args[3], context, mapping)
319
319
320 def ifeq(context, mapping, args):
320 def ifeq(context, mapping, args):
321 if not (3 <= len(args) <= 4):
321 if not (3 <= len(args) <= 4):
322 # i18n: "ifeq" is a keyword
322 # i18n: "ifeq" is a keyword
323 raise error.ParseError(_("ifeq expects three or four arguments"))
323 raise error.ParseError(_("ifeq expects three or four arguments"))
324
324
325 test = stringify(args[0][0](context, mapping, args[0][1]))
325 test = stringify(args[0][0](context, mapping, args[0][1]))
326 match = stringify(args[1][0](context, mapping, args[1][1]))
326 match = stringify(args[1][0](context, mapping, args[1][1]))
327 if test == match:
327 if test == match:
328 yield _evalifliteral(args[2], context, mapping)
328 yield _evalifliteral(args[2], context, mapping)
329 elif len(args) == 4:
329 elif len(args) == 4:
330 yield _evalifliteral(args[3], context, mapping)
330 yield _evalifliteral(args[3], context, mapping)
331
331
332 def join(context, mapping, args):
332 def join(context, mapping, args):
333 if not (1 <= len(args) <= 2):
333 if not (1 <= len(args) <= 2):
334 # i18n: "join" is a keyword
334 # i18n: "join" is a keyword
335 raise error.ParseError(_("join expects one or two arguments"))
335 raise error.ParseError(_("join expects one or two arguments"))
336
336
337 joinset = args[0][0](context, mapping, args[0][1])
337 joinset = args[0][0](context, mapping, args[0][1])
338 if callable(joinset):
338 if callable(joinset):
339 jf = joinset.joinfmt
339 jf = joinset.joinfmt
340 joinset = [jf(x) for x in joinset()]
340 joinset = [jf(x) for x in joinset()]
341
341
342 joiner = " "
342 joiner = " "
343 if len(args) > 1:
343 if len(args) > 1:
344 joiner = stringify(args[1][0](context, mapping, args[1][1]))
344 joiner = stringify(args[1][0](context, mapping, args[1][1]))
345
345
346 first = True
346 first = True
347 for x in joinset:
347 for x in joinset:
348 if first:
348 if first:
349 first = False
349 first = False
350 else:
350 else:
351 yield joiner
351 yield joiner
352 yield x
352 yield x
353
353
354 def label(context, mapping, args):
354 def label(context, mapping, args):
355 if len(args) != 2:
355 if len(args) != 2:
356 # i18n: "label" is a keyword
356 # i18n: "label" is a keyword
357 raise error.ParseError(_("label expects two arguments"))
357 raise error.ParseError(_("label expects two arguments"))
358
358
359 # ignore args[0] (the label string) since this is supposed to be a a no-op
359 # ignore args[0] (the label string) since this is supposed to be a a no-op
360 yield _evalifliteral(args[1], context, mapping)
360 yield _evalifliteral(args[1], context, mapping)
361
361
362 def revset(context, mapping, args):
362 def revset(context, mapping, args):
363 """usage: revset(query[, formatargs...])
363 """usage: revset(query[, formatargs...])
364 """
364 """
365 if not len(args) > 0:
365 if not len(args) > 0:
366 # i18n: "revset" is a keyword
366 # i18n: "revset" is a keyword
367 raise error.ParseError(_("revset expects one or more arguments"))
367 raise error.ParseError(_("revset expects one or more arguments"))
368
368
369 raw = args[0][1]
369 raw = args[0][1]
370 ctx = mapping['ctx']
370 ctx = mapping['ctx']
371 repo = ctx._repo
371 repo = ctx._repo
372
372
373 if len(args) > 1:
373 if len(args) > 1:
374 formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
374 formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
375 revs = repo.revs(raw, *formatargs)
375 revs = repo.revs(raw, *formatargs)
376 revs = list([str(r) for r in revs])
376 revs = list([str(r) for r in revs])
377 else:
377 else:
378 revsetcache = mapping['cache'].setdefault("revsetcache", {})
378 revsetcache = mapping['cache'].setdefault("revsetcache", {})
379 if raw in revsetcache:
379 if raw in revsetcache:
380 revs = revsetcache[raw]
380 revs = revsetcache[raw]
381 else:
381 else:
382 revs = repo.revs(raw)
382 revs = repo.revs(raw)
383 revs = list([str(r) for r in revs])
383 revs = list([str(r) for r in revs])
384 revsetcache[raw] = revs
384 revsetcache[raw] = revs
385
385
386 return templatekw.showlist("revision", revs, **mapping)
386 return templatekw.showlist("revision", revs, **mapping)
387
387
388 def rstdoc(context, mapping, args):
388 def rstdoc(context, mapping, args):
389 if len(args) != 2:
389 if len(args) != 2:
390 # i18n: "rstdoc" is a keyword
390 # i18n: "rstdoc" is a keyword
391 raise error.ParseError(_("rstdoc expects two arguments"))
391 raise error.ParseError(_("rstdoc expects two arguments"))
392
392
393 text = stringify(args[0][0](context, mapping, args[0][1]))
393 text = stringify(args[0][0](context, mapping, args[0][1]))
394 style = stringify(args[1][0](context, mapping, args[1][1]))
394 style = stringify(args[1][0](context, mapping, args[1][1]))
395
395
396 return minirst.format(text, style=style, keep=['verbose'])
396 return minirst.format(text, style=style, keep=['verbose'])
397
397
398 def shortest(context, mapping, args):
398 def shortest(context, mapping, args):
399 """usage: shortest(node, minlength=4)
399 """usage: shortest(node, minlength=4)
400 """
400 """
401 if not (1 <= len(args) <= 2):
401 if not (1 <= len(args) <= 2):
402 raise error.ParseError(_("shortest() expects one or two arguments"))
402 raise error.ParseError(_("shortest() expects one or two arguments"))
403
403
404 node = stringify(args[0][0](context, mapping, args[0][1]))
404 node = stringify(args[0][0](context, mapping, args[0][1]))
405
405
406 minlength = 4
406 minlength = 4
407 if len(args) > 1:
407 if len(args) > 1:
408 minlength = int(args[1][1])
408 minlength = int(args[1][1])
409
409
410 cl = mapping['ctx']._repo.changelog
410 cl = mapping['ctx']._repo.changelog
411 def isvalid(test):
411 def isvalid(test):
412 try:
412 try:
413 try:
413 try:
414 cl.index.partialmatch(test)
414 cl.index.partialmatch(test)
415 except AttributeError:
415 except AttributeError:
416 # Pure mercurial doesn't support partialmatch on the index.
416 # Pure mercurial doesn't support partialmatch on the index.
417 # Fallback to the slow way.
417 # Fallback to the slow way.
418 if cl._partialmatch(test) is None:
418 if cl._partialmatch(test) is None:
419 return False
419 return False
420
420
421 try:
421 try:
422 i = int(test)
422 i = int(test)
423 # if we are a pure int, then starting with zero will not be
423 # if we are a pure int, then starting with zero will not be
424 # confused as a rev; or, obviously, if the int is larger than
424 # confused as a rev; or, obviously, if the int is larger than
425 # the value of the tip rev
425 # the value of the tip rev
426 if test[0] == '0' or i > len(cl):
426 if test[0] == '0' or i > len(cl):
427 return True
427 return True
428 return False
428 return False
429 except ValueError:
429 except ValueError:
430 return True
430 return True
431 except error.RevlogError:
431 except error.RevlogError:
432 return False
432 return False
433
433
434 shortest = node
434 shortest = node
435 startlength = max(6, minlength)
435 startlength = max(6, minlength)
436 length = startlength
436 length = startlength
437 while True:
437 while True:
438 test = node[:length]
438 test = node[:length]
439 if isvalid(test):
439 if isvalid(test):
440 shortest = test
440 shortest = test
441 if length == minlength or length > startlength:
441 if length == minlength or length > startlength:
442 return shortest
442 return shortest
443 length -= 1
443 length -= 1
444 else:
444 else:
445 length += 1
445 length += 1
446 if len(shortest) <= length:
446 if len(shortest) <= length:
447 return shortest
447 return shortest
448
448
449 def strip(context, mapping, args):
449 def strip(context, mapping, args):
450 if not (1 <= len(args) <= 2):
450 if not (1 <= len(args) <= 2):
451 raise error.ParseError(_("strip expects one or two arguments"))
451 raise error.ParseError(_("strip expects one or two arguments"))
452
452
453 text = stringify(args[0][0](context, mapping, args[0][1]))
453 text = stringify(args[0][0](context, mapping, args[0][1]))
454 if len(args) == 2:
454 if len(args) == 2:
455 chars = stringify(args[1][0](context, mapping, args[1][1]))
455 chars = stringify(args[1][0](context, mapping, args[1][1]))
456 return text.strip(chars)
456 return text.strip(chars)
457 return text.strip()
457 return text.strip()
458
458
459 def sub(context, mapping, args):
459 def sub(context, mapping, args):
460 if len(args) != 3:
460 if len(args) != 3:
461 # i18n: "sub" is a keyword
461 # i18n: "sub" is a keyword
462 raise error.ParseError(_("sub expects three arguments"))
462 raise error.ParseError(_("sub expects three arguments"))
463
463
464 pat = stringify(args[0][0](context, mapping, args[0][1]))
464 pat = stringify(args[0][0](context, mapping, args[0][1]))
465 rpl = stringify(args[1][0](context, mapping, args[1][1]))
465 rpl = stringify(args[1][0](context, mapping, args[1][1]))
466 src = stringify(_evalifliteral(args[2], context, mapping))
466 src = stringify(_evalifliteral(args[2], context, mapping))
467 yield re.sub(pat, rpl, src)
467 yield re.sub(pat, rpl, src)
468
468
469 def startswith(context, mapping, args):
469 def startswith(context, mapping, args):
470 if len(args) != 2:
470 if len(args) != 2:
471 raise error.ParseError(_("startswith expects two arguments"))
471 raise error.ParseError(_("startswith expects two arguments"))
472
472
473 patn = stringify(args[0][0](context, mapping, args[0][1]))
473 patn = stringify(args[0][0](context, mapping, args[0][1]))
474 text = stringify(args[1][0](context, mapping, args[1][1]))
474 text = stringify(args[1][0](context, mapping, args[1][1]))
475 if text.startswith(patn):
475 if text.startswith(patn):
476 return text
476 return text
477 return ''
477 return ''
478
478
479
479
480 methods = {
480 methods = {
481 "string": lambda e, c: (runstring, e[1]),
481 "string": lambda e, c: (runstring, e[1]),
482 "rawstring": lambda e, c: (runrawstring, e[1]),
482 "rawstring": lambda e, c: (runrawstring, e[1]),
483 "symbol": lambda e, c: (runsymbol, e[1]),
483 "symbol": lambda e, c: (runsymbol, e[1]),
484 "group": lambda e, c: compileexp(e[1], c),
484 "group": lambda e, c: compileexp(e[1], c),
485 # ".": buildmember,
485 # ".": buildmember,
486 "|": buildfilter,
486 "|": buildfilter,
487 "%": buildmap,
487 "%": buildmap,
488 "func": buildfunc,
488 "func": buildfunc,
489 }
489 }
490
490
491 funcs = {
491 funcs = {
492 "date": date,
492 "date": date,
493 "fill": fill,
493 "fill": fill,
494 "get": get,
494 "get": get,
495 "if": if_,
495 "if": if_,
496 "ifcontains": ifcontains,
496 "ifcontains": ifcontains,
497 "ifeq": ifeq,
497 "ifeq": ifeq,
498 "join": join,
498 "join": join,
499 "label": label,
499 "label": label,
500 "pad": pad,
500 "pad": pad,
501 "revset": revset,
501 "revset": revset,
502 "rstdoc": rstdoc,
502 "rstdoc": rstdoc,
503 "shortest": shortest,
503 "shortest": shortest,
504 "startswith": startswith,
504 "startswith": startswith,
505 "strip": strip,
505 "strip": strip,
506 "sub": sub,
506 "sub": sub,
507 }
507 }
508
508
509 # template engine
509 # template engine
510
510
511 path = ['templates', '../templates']
511 path = ['templates', '../templates']
512 stringify = templatefilters.stringify
512 stringify = templatefilters.stringify
513
513
514 def _flatten(thing):
514 def _flatten(thing):
515 '''yield a single stream from a possibly nested set of iterators'''
515 '''yield a single stream from a possibly nested set of iterators'''
516 if isinstance(thing, str):
516 if isinstance(thing, str):
517 yield thing
517 yield thing
518 elif not util.safehasattr(thing, '__iter__'):
518 elif not util.safehasattr(thing, '__iter__'):
519 if thing is not None:
519 if thing is not None:
520 yield str(thing)
520 yield str(thing)
521 else:
521 else:
522 for i in thing:
522 for i in thing:
523 if isinstance(i, str):
523 if isinstance(i, str):
524 yield i
524 yield i
525 elif not util.safehasattr(i, '__iter__'):
525 elif not util.safehasattr(i, '__iter__'):
526 if i is not None:
526 if i is not None:
527 yield str(i)
527 yield str(i)
528 elif i is not None:
528 elif i is not None:
529 for j in _flatten(i):
529 for j in _flatten(i):
530 yield j
530 yield j
531
531
532 def parsestring(s, quoted=True):
532 def parsestring(s, quoted=True):
533 '''parse a string using simple c-like syntax.
533 '''parse a string using simple c-like syntax.
534 string must be in quotes if quoted is True.'''
534 string must be in quotes if quoted is True.'''
535 if quoted:
535 if quoted:
536 if len(s) < 2 or s[0] != s[-1]:
536 if len(s) < 2 or s[0] != s[-1]:
537 raise SyntaxError(_('unmatched quotes'))
537 raise SyntaxError(_('unmatched quotes'))
538 return s[1:-1].decode('string_escape')
538 return s[1:-1].decode('string_escape')
539
539
540 return s.decode('string_escape')
540 return s.decode('string_escape')
541
541
542 class engine(object):
542 class engine(object):
543 '''template expansion engine.
543 '''template expansion engine.
544
544
545 template expansion works like this. a map file contains key=value
545 template expansion works like this. a map file contains key=value
546 pairs. if value is quoted, it is treated as string. otherwise, it
546 pairs. if value is quoted, it is treated as string. otherwise, it
547 is treated as name of template file.
547 is treated as name of template file.
548
548
549 templater is asked to expand a key in map. it looks up key, and
549 templater is asked to expand a key in map. it looks up key, and
550 looks for strings like this: {foo}. it expands {foo} by looking up
550 looks for strings like this: {foo}. it expands {foo} by looking up
551 foo in map, and substituting it. expansion is recursive: it stops
551 foo in map, and substituting it. expansion is recursive: it stops
552 when there is no more {foo} to replace.
552 when there is no more {foo} to replace.
553
553
554 expansion also allows formatting and filtering.
554 expansion also allows formatting and filtering.
555
555
556 format uses key to expand each item in list. syntax is
556 format uses key to expand each item in list. syntax is
557 {key%format}.
557 {key%format}.
558
558
559 filter uses function to transform value. syntax is
559 filter uses function to transform value. syntax is
560 {key|filter1|filter2|...}.'''
560 {key|filter1|filter2|...}.'''
561
561
562 def __init__(self, loader, filters={}, defaults={}):
562 def __init__(self, loader, filters={}, defaults={}):
563 self._loader = loader
563 self._loader = loader
564 self._filters = filters
564 self._filters = filters
565 self._defaults = defaults
565 self._defaults = defaults
566 self._cache = {}
566 self._cache = {}
567
567
568 def _load(self, t):
568 def _load(self, t):
569 '''load, parse, and cache a template'''
569 '''load, parse, and cache a template'''
570 if t not in self._cache:
570 if t not in self._cache:
571 self._cache[t] = compiletemplate(self._loader(t), self)
571 self._cache[t] = compiletemplate(self._loader(t), self)
572 return self._cache[t]
572 return self._cache[t]
573
573
574 def process(self, t, mapping):
574 def process(self, t, mapping):
575 '''Perform expansion. t is name of map element to expand.
575 '''Perform expansion. t is name of map element to expand.
576 mapping contains added elements for use during expansion. Is a
576 mapping contains added elements for use during expansion. Is a
577 generator.'''
577 generator.'''
578 return _flatten(runtemplate(self, mapping, self._load(t)))
578 return _flatten(runtemplate(self, mapping, self._load(t)))
579
579
580 engines = {'default': engine}
580 engines = {'default': engine}
581
581
582 def stylelist():
582 def stylelist():
583 paths = templatepath()
583 paths = templatepath()
584 if not paths:
584 if not paths:
585 return _('no templates found, try `hg debuginstall` for more info')
585 return _('no templates found, try `hg debuginstall` for more info')
586 dirlist = os.listdir(paths[0])
586 dirlist = os.listdir(paths[0])
587 stylelist = []
587 stylelist = []
588 for file in dirlist:
588 for file in dirlist:
589 split = file.split(".")
589 split = file.split(".")
590 if split[0] == "map-cmdline":
590 if split[0] == "map-cmdline":
591 stylelist.append(split[1])
591 stylelist.append(split[1])
592 return ", ".join(sorted(stylelist))
592 return ", ".join(sorted(stylelist))
593
593
594 class TemplateNotFound(util.Abort):
594 class TemplateNotFound(util.Abort):
595 pass
595 pass
596
596
597 class templater(object):
597 class templater(object):
598
598
599 def __init__(self, mapfile, filters={}, defaults={}, cache={},
599 def __init__(self, mapfile, filters={}, defaults={}, cache={},
600 minchunk=1024, maxchunk=65536):
600 minchunk=1024, maxchunk=65536):
601 '''set up template engine.
601 '''set up template engine.
602 mapfile is name of file to read map definitions from.
602 mapfile is name of file to read map definitions from.
603 filters is dict of functions. each transforms a value into another.
603 filters is dict of functions. each transforms a value into another.
604 defaults is dict of default map definitions.'''
604 defaults is dict of default map definitions.'''
605 self.mapfile = mapfile or 'template'
605 self.mapfile = mapfile or 'template'
606 self.cache = cache.copy()
606 self.cache = cache.copy()
607 self.map = {}
607 self.map = {}
608 self.base = (mapfile and os.path.dirname(mapfile)) or ''
608 self.base = (mapfile and os.path.dirname(mapfile)) or ''
609 self.filters = templatefilters.filters.copy()
609 self.filters = templatefilters.filters.copy()
610 self.filters.update(filters)
610 self.filters.update(filters)
611 self.defaults = defaults
611 self.defaults = defaults
612 self.minchunk, self.maxchunk = minchunk, maxchunk
612 self.minchunk, self.maxchunk = minchunk, maxchunk
613 self.ecache = {}
613 self.ecache = {}
614
614
615 if not mapfile:
615 if not mapfile:
616 return
616 return
617 if not os.path.exists(mapfile):
617 if not os.path.exists(mapfile):
618 raise util.Abort(_("style '%s' not found") % mapfile,
618 raise util.Abort(_("style '%s' not found") % mapfile,
619 hint=_("available styles: %s") % stylelist())
619 hint=_("available styles: %s") % stylelist())
620
620
621 conf = config.config()
621 conf = config.config()
622 conf.read(mapfile)
622 conf.read(mapfile)
623
623
624 for key, val in conf[''].items():
624 for key, val in conf[''].items():
625 if not val:
625 if not val:
626 raise SyntaxError(_('%s: missing value') % conf.source('', key))
626 raise SyntaxError(_('%s: missing value') % conf.source('', key))
627 if val[0] in "'\"":
627 if val[0] in "'\"":
628 try:
628 try:
629 self.cache[key] = parsestring(val)
629 self.cache[key] = parsestring(val)
630 except SyntaxError, inst:
630 except SyntaxError, inst:
631 raise SyntaxError('%s: %s' %
631 raise SyntaxError('%s: %s' %
632 (conf.source('', key), inst.args[0]))
632 (conf.source('', key), inst.args[0]))
633 else:
633 else:
634 val = 'default', val
634 val = 'default', val
635 if ':' in val[1]:
635 if ':' in val[1]:
636 val = val[1].split(':', 1)
636 val = val[1].split(':', 1)
637 self.map[key] = val[0], os.path.join(self.base, val[1])
637 self.map[key] = val[0], os.path.join(self.base, val[1])
638
638
639 def __contains__(self, key):
639 def __contains__(self, key):
640 return key in self.cache or key in self.map
640 return key in self.cache or key in self.map
641
641
642 def load(self, t):
642 def load(self, t):
643 '''Get the template for the given template name. Use a local cache.'''
643 '''Get the template for the given template name. Use a local cache.'''
644 if t not in self.cache:
644 if t not in self.cache:
645 try:
645 try:
646 self.cache[t] = util.readfile(self.map[t][1])
646 self.cache[t] = util.readfile(self.map[t][1])
647 except KeyError, inst:
647 except KeyError, inst:
648 raise TemplateNotFound(_('"%s" not in template map') %
648 raise TemplateNotFound(_('"%s" not in template map') %
649 inst.args[0])
649 inst.args[0])
650 except IOError, inst:
650 except IOError, inst:
651 raise IOError(inst.args[0], _('template file %s: %s') %
651 raise IOError(inst.args[0], _('template file %s: %s') %
652 (self.map[t][1], inst.args[1]))
652 (self.map[t][1], inst.args[1]))
653 return self.cache[t]
653 return self.cache[t]
654
654
655 def __call__(self, t, **mapping):
655 def __call__(self, t, **mapping):
656 ttype = t in self.map and self.map[t][0] or 'default'
656 ttype = t in self.map and self.map[t][0] or 'default'
657 if ttype not in self.ecache:
657 if ttype not in self.ecache:
658 self.ecache[ttype] = engines[ttype](self.load,
658 self.ecache[ttype] = engines[ttype](self.load,
659 self.filters, self.defaults)
659 self.filters, self.defaults)
660 proc = self.ecache[ttype]
660 proc = self.ecache[ttype]
661
661
662 stream = proc.process(t, mapping)
662 stream = proc.process(t, mapping)
663 if self.minchunk:
663 if self.minchunk:
664 stream = util.increasingchunks(stream, min=self.minchunk,
664 stream = util.increasingchunks(stream, min=self.minchunk,
665 max=self.maxchunk)
665 max=self.maxchunk)
666 return stream
666 return stream
667
667
668 def templatepath(name=None):
668 def templatepath(name=None):
669 '''return location of template file or directory (if no name).
669 '''return location of template file or directory (if no name).
670 returns None if not found.'''
670 returns None if not found.'''
671 normpaths = []
671 normpaths = []
672
672
673 # executable version (py2exe) doesn't support __file__
673 # executable version (py2exe) doesn't support __file__
674 if util.mainfrozen():
674 if util.mainfrozen():
675 module = sys.executable
675 module = sys.executable
676 else:
676 else:
677 module = __file__
677 module = __file__
678 for f in path:
678 for f in path:
679 if f.startswith('/'):
679 if f.startswith('/'):
680 p = f
680 p = f
681 else:
681 else:
682 fl = f.split('/')
682 fl = f.split('/')
683 p = os.path.join(os.path.dirname(module), *fl)
683 p = os.path.join(os.path.dirname(module), *fl)
684 if name:
684 if name:
685 p = os.path.join(p, name)
685 p = os.path.join(p, name)
686 if name and os.path.exists(p):
686 if name and os.path.exists(p):
687 return os.path.normpath(p)
687 return os.path.normpath(p)
688 elif os.path.isdir(p):
688 elif os.path.isdir(p):
689 normpaths.append(os.path.normpath(p))
689 normpaths.append(os.path.normpath(p))
690
690
691 return normpaths
691 return normpaths
692
692
693 def stylemap(styles, paths=None):
693 def stylemap(styles, paths=None):
694 """Return path to mapfile for a given style.
694 """Return path to mapfile for a given style.
695
695
696 Searches mapfile in the following locations:
696 Searches mapfile in the following locations:
697 1. templatepath/style/map
697 1. templatepath/style/map
698 2. templatepath/map-style
698 2. templatepath/map-style
699 3. templatepath/map
699 3. templatepath/map
700 """
700 """
701
701
702 if paths is None:
702 if paths is None:
703 paths = templatepath()
703 paths = templatepath()
704 elif isinstance(paths, str):
704 elif isinstance(paths, str):
705 paths = [paths]
705 paths = [paths]
706
706
707 if isinstance(styles, str):
707 if isinstance(styles, str):
708 styles = [styles]
708 styles = [styles]
709
709
710 for style in styles:
710 for style in styles:
711 if not style:
711 if not style:
712 continue
712 continue
713 locations = [os.path.join(style, 'map'), 'map-' + style]
713 locations = [os.path.join(style, 'map'), 'map-' + style]
714 locations.append('map')
714 locations.append('map')
715
715
716 for path in paths:
716 for path in paths:
717 for location in locations:
717 for location in locations:
718 mapfile = os.path.join(path, location)
718 mapfile = os.path.join(path, location)
719 if os.path.isfile(mapfile):
719 if os.path.isfile(mapfile):
720 return style, mapfile
720 return style, mapfile
721
721
722 raise RuntimeError("No hgweb templates found in %r" % paths)
722 raise RuntimeError("No hgweb templates found in %r" % paths)
@@ -1,1913 +1,1919 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo a > a
3 $ echo a > a
4 $ hg add a
4 $ hg add a
5 $ echo line 1 > b
5 $ echo line 1 > b
6 $ echo line 2 >> b
6 $ echo line 2 >> b
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
8
8
9 $ hg add b
9 $ hg add b
10 $ echo other 1 > c
10 $ echo other 1 > c
11 $ echo other 2 >> c
11 $ echo other 2 >> c
12 $ echo >> c
12 $ echo >> c
13 $ echo other 3 >> c
13 $ echo other 3 >> c
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
15
15
16 $ hg add c
16 $ hg add c
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
18 $ echo c >> c
18 $ echo c >> c
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
20
20
21 $ echo foo > .hg/branch
21 $ echo foo > .hg/branch
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
23
23
24 $ hg co -q 3
24 $ hg co -q 3
25 $ echo other 4 >> d
25 $ echo other 4 >> d
26 $ hg add d
26 $ hg add d
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
28
28
29 $ hg merge -q foo
29 $ hg merge -q foo
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
31
31
32 Second branch starting at nullrev:
32 Second branch starting at nullrev:
33
33
34 $ hg update null
34 $ hg update null
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
36 $ echo second > second
36 $ echo second > second
37 $ hg add second
37 $ hg add second
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
39 created new head
39 created new head
40
40
41 $ echo third > third
41 $ echo third > third
42 $ hg add third
42 $ hg add third
43 $ hg mv second fourth
43 $ hg mv second fourth
44 $ hg commit -m third -d "2020-01-01 10:01"
44 $ hg commit -m third -d "2020-01-01 10:01"
45
45
46 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
46 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
47 fourth (second)
47 fourth (second)
48 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
48 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
49 second -> fourth
49 second -> fourth
50
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 Add some simple styles to settings
66 Add some simple styles to settings
67
67
68 $ echo '[templates]' >> .hg/hgrc
68 $ echo '[templates]' >> .hg/hgrc
69 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
69 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
70 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
70 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
71
71
72 $ hg log -l1 -Tsimple
72 $ hg log -l1 -Tsimple
73 8
73 8
74 $ hg log -l1 -Tsimple2
74 $ hg log -l1 -Tsimple2
75 8
75 8
76
76
77 Test templates and style maps in files:
77 Test templates and style maps in files:
78
78
79 $ echo "{rev}" > tmpl
79 $ echo "{rev}" > tmpl
80 $ hg log -l1 -T./tmpl
80 $ hg log -l1 -T./tmpl
81 8
81 8
82 $ hg log -l1 -Tblah/blah
82 $ hg log -l1 -Tblah/blah
83 blah/blah (no-eol)
83 blah/blah (no-eol)
84
84
85 $ printf 'changeset = "{rev}\\n"\n' > map-simple
85 $ printf 'changeset = "{rev}\\n"\n' > map-simple
86 $ hg log -l1 -T./map-simple
86 $ hg log -l1 -T./map-simple
87 8
87 8
88
88
89 Default style is like normal output:
89 Default style is like normal output:
90
90
91 $ hg log > log.out
91 $ hg log > log.out
92 $ hg log --style default > style.out
92 $ hg log --style default > style.out
93 $ cmp log.out style.out || diff -u log.out style.out
93 $ cmp log.out style.out || diff -u log.out style.out
94
94
95 $ hg log -v > log.out
95 $ hg log -v > log.out
96 $ hg log -v --style default > style.out
96 $ hg log -v --style default > style.out
97 $ cmp log.out style.out || diff -u log.out style.out
97 $ cmp log.out style.out || diff -u log.out style.out
98
98
99 $ hg log --debug > log.out
99 $ hg log --debug > log.out
100 $ hg log --debug --style default > style.out
100 $ hg log --debug --style default > style.out
101 $ cmp log.out style.out || diff -u log.out style.out
101 $ cmp log.out style.out || diff -u log.out style.out
102
102
103 Revision with no copies (used to print a traceback):
103 Revision with no copies (used to print a traceback):
104
104
105 $ hg tip -v --template '\n'
105 $ hg tip -v --template '\n'
106
106
107
107
108 Compact style works:
108 Compact style works:
109
109
110 $ hg log -Tcompact
110 $ hg log -Tcompact
111 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
111 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
112 third
112 third
113
113
114 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
114 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
115 second
115 second
116
116
117 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
117 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
118 merge
118 merge
119
119
120 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
120 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
121 new head
121 new head
122
122
123 4 bbe44766e73d 1970-01-17 04:53 +0000 person
123 4 bbe44766e73d 1970-01-17 04:53 +0000 person
124 new branch
124 new branch
125
125
126 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
126 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
127 no user, no domain
127 no user, no domain
128
128
129 2 97054abb4ab8 1970-01-14 21:20 +0000 other
129 2 97054abb4ab8 1970-01-14 21:20 +0000 other
130 no person
130 no person
131
131
132 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
132 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
133 other 1
133 other 1
134
134
135 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
135 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
136 line 1
136 line 1
137
137
138
138
139 $ hg log -v --style compact
139 $ hg log -v --style compact
140 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
140 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
141 third
141 third
142
142
143 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
143 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
144 second
144 second
145
145
146 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
146 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
147 merge
147 merge
148
148
149 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
149 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
150 new head
150 new head
151
151
152 4 bbe44766e73d 1970-01-17 04:53 +0000 person
152 4 bbe44766e73d 1970-01-17 04:53 +0000 person
153 new branch
153 new branch
154
154
155 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
155 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
156 no user, no domain
156 no user, no domain
157
157
158 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
158 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
159 no person
159 no person
160
160
161 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
161 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
162 other 1
162 other 1
163 other 2
163 other 2
164
164
165 other 3
165 other 3
166
166
167 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
167 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
168 line 1
168 line 1
169 line 2
169 line 2
170
170
171
171
172 $ hg log --debug --style compact
172 $ hg log --debug --style compact
173 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
173 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
174 third
174 third
175
175
176 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
176 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
177 second
177 second
178
178
179 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
179 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
180 merge
180 merge
181
181
182 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
182 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
183 new head
183 new head
184
184
185 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
185 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
186 new branch
186 new branch
187
187
188 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
188 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
189 no user, no domain
189 no user, no domain
190
190
191 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
191 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
192 no person
192 no person
193
193
194 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
194 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
195 other 1
195 other 1
196 other 2
196 other 2
197
197
198 other 3
198 other 3
199
199
200 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
200 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
201 line 1
201 line 1
202 line 2
202 line 2
203
203
204
204
205 Test xml styles:
205 Test xml styles:
206
206
207 $ hg log --style xml
207 $ hg log --style xml
208 <?xml version="1.0"?>
208 <?xml version="1.0"?>
209 <log>
209 <log>
210 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
210 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
211 <tag>tip</tag>
211 <tag>tip</tag>
212 <author email="test">test</author>
212 <author email="test">test</author>
213 <date>2020-01-01T10:01:00+00:00</date>
213 <date>2020-01-01T10:01:00+00:00</date>
214 <msg xml:space="preserve">third</msg>
214 <msg xml:space="preserve">third</msg>
215 </logentry>
215 </logentry>
216 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
216 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
217 <parent revision="-1" node="0000000000000000000000000000000000000000" />
217 <parent revision="-1" node="0000000000000000000000000000000000000000" />
218 <author email="user@hostname">User Name</author>
218 <author email="user@hostname">User Name</author>
219 <date>1970-01-12T13:46:40+00:00</date>
219 <date>1970-01-12T13:46:40+00:00</date>
220 <msg xml:space="preserve">second</msg>
220 <msg xml:space="preserve">second</msg>
221 </logentry>
221 </logentry>
222 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
222 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
223 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
223 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
224 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
224 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
225 <author email="person">person</author>
225 <author email="person">person</author>
226 <date>1970-01-18T08:40:01+00:00</date>
226 <date>1970-01-18T08:40:01+00:00</date>
227 <msg xml:space="preserve">merge</msg>
227 <msg xml:space="preserve">merge</msg>
228 </logentry>
228 </logentry>
229 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
229 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
230 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
230 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
231 <author email="person">person</author>
231 <author email="person">person</author>
232 <date>1970-01-18T08:40:00+00:00</date>
232 <date>1970-01-18T08:40:00+00:00</date>
233 <msg xml:space="preserve">new head</msg>
233 <msg xml:space="preserve">new head</msg>
234 </logentry>
234 </logentry>
235 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
235 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
236 <branch>foo</branch>
236 <branch>foo</branch>
237 <author email="person">person</author>
237 <author email="person">person</author>
238 <date>1970-01-17T04:53:20+00:00</date>
238 <date>1970-01-17T04:53:20+00:00</date>
239 <msg xml:space="preserve">new branch</msg>
239 <msg xml:space="preserve">new branch</msg>
240 </logentry>
240 </logentry>
241 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
241 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
242 <author email="person">person</author>
242 <author email="person">person</author>
243 <date>1970-01-16T01:06:40+00:00</date>
243 <date>1970-01-16T01:06:40+00:00</date>
244 <msg xml:space="preserve">no user, no domain</msg>
244 <msg xml:space="preserve">no user, no domain</msg>
245 </logentry>
245 </logentry>
246 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
246 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
247 <author email="other@place">other</author>
247 <author email="other@place">other</author>
248 <date>1970-01-14T21:20:00+00:00</date>
248 <date>1970-01-14T21:20:00+00:00</date>
249 <msg xml:space="preserve">no person</msg>
249 <msg xml:space="preserve">no person</msg>
250 </logentry>
250 </logentry>
251 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
251 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
252 <author email="other@place">A. N. Other</author>
252 <author email="other@place">A. N. Other</author>
253 <date>1970-01-13T17:33:20+00:00</date>
253 <date>1970-01-13T17:33:20+00:00</date>
254 <msg xml:space="preserve">other 1
254 <msg xml:space="preserve">other 1
255 other 2
255 other 2
256
256
257 other 3</msg>
257 other 3</msg>
258 </logentry>
258 </logentry>
259 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
259 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
260 <author email="user@hostname">User Name</author>
260 <author email="user@hostname">User Name</author>
261 <date>1970-01-12T13:46:40+00:00</date>
261 <date>1970-01-12T13:46:40+00:00</date>
262 <msg xml:space="preserve">line 1
262 <msg xml:space="preserve">line 1
263 line 2</msg>
263 line 2</msg>
264 </logentry>
264 </logentry>
265 </log>
265 </log>
266
266
267 $ hg log -v --style xml
267 $ hg log -v --style xml
268 <?xml version="1.0"?>
268 <?xml version="1.0"?>
269 <log>
269 <log>
270 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
270 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
271 <tag>tip</tag>
271 <tag>tip</tag>
272 <author email="test">test</author>
272 <author email="test">test</author>
273 <date>2020-01-01T10:01:00+00:00</date>
273 <date>2020-01-01T10:01:00+00:00</date>
274 <msg xml:space="preserve">third</msg>
274 <msg xml:space="preserve">third</msg>
275 <paths>
275 <paths>
276 <path action="A">fourth</path>
276 <path action="A">fourth</path>
277 <path action="A">third</path>
277 <path action="A">third</path>
278 <path action="R">second</path>
278 <path action="R">second</path>
279 </paths>
279 </paths>
280 <copies>
280 <copies>
281 <copy source="second">fourth</copy>
281 <copy source="second">fourth</copy>
282 </copies>
282 </copies>
283 </logentry>
283 </logentry>
284 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
284 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
285 <parent revision="-1" node="0000000000000000000000000000000000000000" />
285 <parent revision="-1" node="0000000000000000000000000000000000000000" />
286 <author email="user@hostname">User Name</author>
286 <author email="user@hostname">User Name</author>
287 <date>1970-01-12T13:46:40+00:00</date>
287 <date>1970-01-12T13:46:40+00:00</date>
288 <msg xml:space="preserve">second</msg>
288 <msg xml:space="preserve">second</msg>
289 <paths>
289 <paths>
290 <path action="A">second</path>
290 <path action="A">second</path>
291 </paths>
291 </paths>
292 </logentry>
292 </logentry>
293 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
293 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
294 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
294 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
295 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
295 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
296 <author email="person">person</author>
296 <author email="person">person</author>
297 <date>1970-01-18T08:40:01+00:00</date>
297 <date>1970-01-18T08:40:01+00:00</date>
298 <msg xml:space="preserve">merge</msg>
298 <msg xml:space="preserve">merge</msg>
299 <paths>
299 <paths>
300 </paths>
300 </paths>
301 </logentry>
301 </logentry>
302 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
302 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
303 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
303 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
304 <author email="person">person</author>
304 <author email="person">person</author>
305 <date>1970-01-18T08:40:00+00:00</date>
305 <date>1970-01-18T08:40:00+00:00</date>
306 <msg xml:space="preserve">new head</msg>
306 <msg xml:space="preserve">new head</msg>
307 <paths>
307 <paths>
308 <path action="A">d</path>
308 <path action="A">d</path>
309 </paths>
309 </paths>
310 </logentry>
310 </logentry>
311 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
311 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
312 <branch>foo</branch>
312 <branch>foo</branch>
313 <author email="person">person</author>
313 <author email="person">person</author>
314 <date>1970-01-17T04:53:20+00:00</date>
314 <date>1970-01-17T04:53:20+00:00</date>
315 <msg xml:space="preserve">new branch</msg>
315 <msg xml:space="preserve">new branch</msg>
316 <paths>
316 <paths>
317 </paths>
317 </paths>
318 </logentry>
318 </logentry>
319 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
319 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
320 <author email="person">person</author>
320 <author email="person">person</author>
321 <date>1970-01-16T01:06:40+00:00</date>
321 <date>1970-01-16T01:06:40+00:00</date>
322 <msg xml:space="preserve">no user, no domain</msg>
322 <msg xml:space="preserve">no user, no domain</msg>
323 <paths>
323 <paths>
324 <path action="M">c</path>
324 <path action="M">c</path>
325 </paths>
325 </paths>
326 </logentry>
326 </logentry>
327 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
327 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
328 <author email="other@place">other</author>
328 <author email="other@place">other</author>
329 <date>1970-01-14T21:20:00+00:00</date>
329 <date>1970-01-14T21:20:00+00:00</date>
330 <msg xml:space="preserve">no person</msg>
330 <msg xml:space="preserve">no person</msg>
331 <paths>
331 <paths>
332 <path action="A">c</path>
332 <path action="A">c</path>
333 </paths>
333 </paths>
334 </logentry>
334 </logentry>
335 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
335 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
336 <author email="other@place">A. N. Other</author>
336 <author email="other@place">A. N. Other</author>
337 <date>1970-01-13T17:33:20+00:00</date>
337 <date>1970-01-13T17:33:20+00:00</date>
338 <msg xml:space="preserve">other 1
338 <msg xml:space="preserve">other 1
339 other 2
339 other 2
340
340
341 other 3</msg>
341 other 3</msg>
342 <paths>
342 <paths>
343 <path action="A">b</path>
343 <path action="A">b</path>
344 </paths>
344 </paths>
345 </logentry>
345 </logentry>
346 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
346 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
347 <author email="user@hostname">User Name</author>
347 <author email="user@hostname">User Name</author>
348 <date>1970-01-12T13:46:40+00:00</date>
348 <date>1970-01-12T13:46:40+00:00</date>
349 <msg xml:space="preserve">line 1
349 <msg xml:space="preserve">line 1
350 line 2</msg>
350 line 2</msg>
351 <paths>
351 <paths>
352 <path action="A">a</path>
352 <path action="A">a</path>
353 </paths>
353 </paths>
354 </logentry>
354 </logentry>
355 </log>
355 </log>
356
356
357 $ hg log --debug --style xml
357 $ hg log --debug --style xml
358 <?xml version="1.0"?>
358 <?xml version="1.0"?>
359 <log>
359 <log>
360 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
360 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
361 <tag>tip</tag>
361 <tag>tip</tag>
362 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
362 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
363 <parent revision="-1" node="0000000000000000000000000000000000000000" />
363 <parent revision="-1" node="0000000000000000000000000000000000000000" />
364 <author email="test">test</author>
364 <author email="test">test</author>
365 <date>2020-01-01T10:01:00+00:00</date>
365 <date>2020-01-01T10:01:00+00:00</date>
366 <msg xml:space="preserve">third</msg>
366 <msg xml:space="preserve">third</msg>
367 <paths>
367 <paths>
368 <path action="A">fourth</path>
368 <path action="A">fourth</path>
369 <path action="A">third</path>
369 <path action="A">third</path>
370 <path action="R">second</path>
370 <path action="R">second</path>
371 </paths>
371 </paths>
372 <copies>
372 <copies>
373 <copy source="second">fourth</copy>
373 <copy source="second">fourth</copy>
374 </copies>
374 </copies>
375 <extra key="branch">default</extra>
375 <extra key="branch">default</extra>
376 </logentry>
376 </logentry>
377 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
377 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
378 <parent revision="-1" node="0000000000000000000000000000000000000000" />
378 <parent revision="-1" node="0000000000000000000000000000000000000000" />
379 <parent revision="-1" node="0000000000000000000000000000000000000000" />
379 <parent revision="-1" node="0000000000000000000000000000000000000000" />
380 <author email="user@hostname">User Name</author>
380 <author email="user@hostname">User Name</author>
381 <date>1970-01-12T13:46:40+00:00</date>
381 <date>1970-01-12T13:46:40+00:00</date>
382 <msg xml:space="preserve">second</msg>
382 <msg xml:space="preserve">second</msg>
383 <paths>
383 <paths>
384 <path action="A">second</path>
384 <path action="A">second</path>
385 </paths>
385 </paths>
386 <extra key="branch">default</extra>
386 <extra key="branch">default</extra>
387 </logentry>
387 </logentry>
388 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
388 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
389 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
389 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
390 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
390 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
391 <author email="person">person</author>
391 <author email="person">person</author>
392 <date>1970-01-18T08:40:01+00:00</date>
392 <date>1970-01-18T08:40:01+00:00</date>
393 <msg xml:space="preserve">merge</msg>
393 <msg xml:space="preserve">merge</msg>
394 <paths>
394 <paths>
395 </paths>
395 </paths>
396 <extra key="branch">default</extra>
396 <extra key="branch">default</extra>
397 </logentry>
397 </logentry>
398 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
398 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
399 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
399 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
400 <parent revision="-1" node="0000000000000000000000000000000000000000" />
400 <parent revision="-1" node="0000000000000000000000000000000000000000" />
401 <author email="person">person</author>
401 <author email="person">person</author>
402 <date>1970-01-18T08:40:00+00:00</date>
402 <date>1970-01-18T08:40:00+00:00</date>
403 <msg xml:space="preserve">new head</msg>
403 <msg xml:space="preserve">new head</msg>
404 <paths>
404 <paths>
405 <path action="A">d</path>
405 <path action="A">d</path>
406 </paths>
406 </paths>
407 <extra key="branch">default</extra>
407 <extra key="branch">default</extra>
408 </logentry>
408 </logentry>
409 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
409 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
410 <branch>foo</branch>
410 <branch>foo</branch>
411 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
411 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
412 <parent revision="-1" node="0000000000000000000000000000000000000000" />
412 <parent revision="-1" node="0000000000000000000000000000000000000000" />
413 <author email="person">person</author>
413 <author email="person">person</author>
414 <date>1970-01-17T04:53:20+00:00</date>
414 <date>1970-01-17T04:53:20+00:00</date>
415 <msg xml:space="preserve">new branch</msg>
415 <msg xml:space="preserve">new branch</msg>
416 <paths>
416 <paths>
417 </paths>
417 </paths>
418 <extra key="branch">foo</extra>
418 <extra key="branch">foo</extra>
419 </logentry>
419 </logentry>
420 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
420 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
421 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
421 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
422 <parent revision="-1" node="0000000000000000000000000000000000000000" />
422 <parent revision="-1" node="0000000000000000000000000000000000000000" />
423 <author email="person">person</author>
423 <author email="person">person</author>
424 <date>1970-01-16T01:06:40+00:00</date>
424 <date>1970-01-16T01:06:40+00:00</date>
425 <msg xml:space="preserve">no user, no domain</msg>
425 <msg xml:space="preserve">no user, no domain</msg>
426 <paths>
426 <paths>
427 <path action="M">c</path>
427 <path action="M">c</path>
428 </paths>
428 </paths>
429 <extra key="branch">default</extra>
429 <extra key="branch">default</extra>
430 </logentry>
430 </logentry>
431 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
431 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
432 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
432 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
433 <parent revision="-1" node="0000000000000000000000000000000000000000" />
433 <parent revision="-1" node="0000000000000000000000000000000000000000" />
434 <author email="other@place">other</author>
434 <author email="other@place">other</author>
435 <date>1970-01-14T21:20:00+00:00</date>
435 <date>1970-01-14T21:20:00+00:00</date>
436 <msg xml:space="preserve">no person</msg>
436 <msg xml:space="preserve">no person</msg>
437 <paths>
437 <paths>
438 <path action="A">c</path>
438 <path action="A">c</path>
439 </paths>
439 </paths>
440 <extra key="branch">default</extra>
440 <extra key="branch">default</extra>
441 </logentry>
441 </logentry>
442 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
442 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
443 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
443 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
444 <parent revision="-1" node="0000000000000000000000000000000000000000" />
444 <parent revision="-1" node="0000000000000000000000000000000000000000" />
445 <author email="other@place">A. N. Other</author>
445 <author email="other@place">A. N. Other</author>
446 <date>1970-01-13T17:33:20+00:00</date>
446 <date>1970-01-13T17:33:20+00:00</date>
447 <msg xml:space="preserve">other 1
447 <msg xml:space="preserve">other 1
448 other 2
448 other 2
449
449
450 other 3</msg>
450 other 3</msg>
451 <paths>
451 <paths>
452 <path action="A">b</path>
452 <path action="A">b</path>
453 </paths>
453 </paths>
454 <extra key="branch">default</extra>
454 <extra key="branch">default</extra>
455 </logentry>
455 </logentry>
456 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
456 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
457 <parent revision="-1" node="0000000000000000000000000000000000000000" />
457 <parent revision="-1" node="0000000000000000000000000000000000000000" />
458 <parent revision="-1" node="0000000000000000000000000000000000000000" />
458 <parent revision="-1" node="0000000000000000000000000000000000000000" />
459 <author email="user@hostname">User Name</author>
459 <author email="user@hostname">User Name</author>
460 <date>1970-01-12T13:46:40+00:00</date>
460 <date>1970-01-12T13:46:40+00:00</date>
461 <msg xml:space="preserve">line 1
461 <msg xml:space="preserve">line 1
462 line 2</msg>
462 line 2</msg>
463 <paths>
463 <paths>
464 <path action="A">a</path>
464 <path action="A">a</path>
465 </paths>
465 </paths>
466 <extra key="branch">default</extra>
466 <extra key="branch">default</extra>
467 </logentry>
467 </logentry>
468 </log>
468 </log>
469
469
470
470
471 Error if style not readable:
471 Error if style not readable:
472
472
473 #if unix-permissions no-root
473 #if unix-permissions no-root
474 $ touch q
474 $ touch q
475 $ chmod 0 q
475 $ chmod 0 q
476 $ hg log --style ./q
476 $ hg log --style ./q
477 abort: Permission denied: ./q
477 abort: Permission denied: ./q
478 [255]
478 [255]
479 #endif
479 #endif
480
480
481 Error if no style:
481 Error if no style:
482
482
483 $ hg log --style notexist
483 $ hg log --style notexist
484 abort: style 'notexist' not found
484 abort: style 'notexist' not found
485 (available styles: bisect, changelog, compact, default, phases, xml)
485 (available styles: bisect, changelog, compact, default, phases, xml)
486 [255]
486 [255]
487
487
488 Error if style missing key:
488 Error if style missing key:
489
489
490 $ echo 'q = q' > t
490 $ echo 'q = q' > t
491 $ hg log --style ./t
491 $ hg log --style ./t
492 abort: "changeset" not in template map
492 abort: "changeset" not in template map
493 [255]
493 [255]
494
494
495 Error if style missing value:
495 Error if style missing value:
496
496
497 $ echo 'changeset =' > t
497 $ echo 'changeset =' > t
498 $ hg log --style t
498 $ hg log --style t
499 abort: t:1: missing value
499 abort: t:1: missing value
500 [255]
500 [255]
501
501
502 Error if include fails:
502 Error if include fails:
503
503
504 $ echo 'changeset = q' >> t
504 $ echo 'changeset = q' >> t
505 #if unix-permissions no-root
505 #if unix-permissions no-root
506 $ hg log --style ./t
506 $ hg log --style ./t
507 abort: template file ./q: Permission denied
507 abort: template file ./q: Permission denied
508 [255]
508 [255]
509 $ rm q
509 $ rm q
510 #endif
510 #endif
511
511
512 Include works:
512 Include works:
513
513
514 $ echo '{rev}' > q
514 $ echo '{rev}' > q
515 $ hg log --style ./t
515 $ hg log --style ./t
516 8
516 8
517 7
517 7
518 6
518 6
519 5
519 5
520 4
520 4
521 3
521 3
522 2
522 2
523 1
523 1
524 0
524 0
525
525
526 Missing non-standard names give no error (backward compatibility):
526 Missing non-standard names give no error (backward compatibility):
527
527
528 $ echo "changeset = '{c}'" > t
528 $ echo "changeset = '{c}'" > t
529 $ hg log --style ./t
529 $ hg log --style ./t
530
530
531 Defining non-standard name works:
531 Defining non-standard name works:
532
532
533 $ cat <<EOF > t
533 $ cat <<EOF > t
534 > changeset = '{c}'
534 > changeset = '{c}'
535 > c = q
535 > c = q
536 > EOF
536 > EOF
537 $ hg log --style ./t
537 $ hg log --style ./t
538 8
538 8
539 7
539 7
540 6
540 6
541 5
541 5
542 4
542 4
543 3
543 3
544 2
544 2
545 1
545 1
546 0
546 0
547
547
548 ui.style works:
548 ui.style works:
549
549
550 $ echo '[ui]' > .hg/hgrc
550 $ echo '[ui]' > .hg/hgrc
551 $ echo 'style = t' >> .hg/hgrc
551 $ echo 'style = t' >> .hg/hgrc
552 $ hg log
552 $ hg log
553 8
553 8
554 7
554 7
555 6
555 6
556 5
556 5
557 4
557 4
558 3
558 3
559 2
559 2
560 1
560 1
561 0
561 0
562
562
563
563
564 Issue338:
564 Issue338:
565
565
566 $ hg log --style=changelog > changelog
566 $ hg log --style=changelog > changelog
567
567
568 $ cat changelog
568 $ cat changelog
569 2020-01-01 test <test>
569 2020-01-01 test <test>
570
570
571 * fourth, second, third:
571 * fourth, second, third:
572 third
572 third
573 [95c24699272e] [tip]
573 [95c24699272e] [tip]
574
574
575 1970-01-12 User Name <user@hostname>
575 1970-01-12 User Name <user@hostname>
576
576
577 * second:
577 * second:
578 second
578 second
579 [29114dbae42b]
579 [29114dbae42b]
580
580
581 1970-01-18 person <person>
581 1970-01-18 person <person>
582
582
583 * merge
583 * merge
584 [d41e714fe50d]
584 [d41e714fe50d]
585
585
586 * d:
586 * d:
587 new head
587 new head
588 [13207e5a10d9]
588 [13207e5a10d9]
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 1970-01-16 person <person>
595 1970-01-16 person <person>
596
596
597 * c:
597 * c:
598 no user, no domain
598 no user, no domain
599 [10e46f2dcbf4]
599 [10e46f2dcbf4]
600
600
601 1970-01-14 other <other@place>
601 1970-01-14 other <other@place>
602
602
603 * c:
603 * c:
604 no person
604 no person
605 [97054abb4ab8]
605 [97054abb4ab8]
606
606
607 1970-01-13 A. N. Other <other@place>
607 1970-01-13 A. N. Other <other@place>
608
608
609 * b:
609 * b:
610 other 1 other 2
610 other 1 other 2
611
611
612 other 3
612 other 3
613 [b608e9d1a3f0]
613 [b608e9d1a3f0]
614
614
615 1970-01-12 User Name <user@hostname>
615 1970-01-12 User Name <user@hostname>
616
616
617 * a:
617 * a:
618 line 1 line 2
618 line 1 line 2
619 [1e4e1b8f71e0]
619 [1e4e1b8f71e0]
620
620
621
621
622 Issue2130: xml output for 'hg heads' is malformed
622 Issue2130: xml output for 'hg heads' is malformed
623
623
624 $ hg heads --style changelog
624 $ hg heads --style changelog
625 2020-01-01 test <test>
625 2020-01-01 test <test>
626
626
627 * fourth, second, third:
627 * fourth, second, third:
628 third
628 third
629 [95c24699272e] [tip]
629 [95c24699272e] [tip]
630
630
631 1970-01-18 person <person>
631 1970-01-18 person <person>
632
632
633 * merge
633 * merge
634 [d41e714fe50d]
634 [d41e714fe50d]
635
635
636 1970-01-17 person <person>
636 1970-01-17 person <person>
637
637
638 * new branch
638 * new branch
639 [bbe44766e73d] <foo>
639 [bbe44766e73d] <foo>
640
640
641
641
642 Keys work:
642 Keys work:
643
643
644 $ for key in author branch branches date desc file_adds file_dels file_mods \
644 $ for key in author branch branches date desc file_adds file_dels file_mods \
645 > file_copies file_copies_switch files \
645 > file_copies file_copies_switch files \
646 > manifest node parents rev tags diffstat extras \
646 > manifest node parents rev tags diffstat extras \
647 > p1rev p2rev p1node p2node; do
647 > p1rev p2rev p1node p2node; do
648 > for mode in '' --verbose --debug; do
648 > for mode in '' --verbose --debug; do
649 > hg log $mode --template "$key$mode: {$key}\n"
649 > hg log $mode --template "$key$mode: {$key}\n"
650 > done
650 > done
651 > done
651 > done
652 author: test
652 author: test
653 author: User Name <user@hostname>
653 author: User Name <user@hostname>
654 author: person
654 author: person
655 author: person
655 author: person
656 author: person
656 author: person
657 author: person
657 author: person
658 author: other@place
658 author: other@place
659 author: A. N. Other <other@place>
659 author: A. N. Other <other@place>
660 author: User Name <user@hostname>
660 author: User Name <user@hostname>
661 author--verbose: test
661 author--verbose: test
662 author--verbose: User Name <user@hostname>
662 author--verbose: User Name <user@hostname>
663 author--verbose: person
663 author--verbose: person
664 author--verbose: person
664 author--verbose: person
665 author--verbose: person
665 author--verbose: person
666 author--verbose: person
666 author--verbose: person
667 author--verbose: other@place
667 author--verbose: other@place
668 author--verbose: A. N. Other <other@place>
668 author--verbose: A. N. Other <other@place>
669 author--verbose: User Name <user@hostname>
669 author--verbose: User Name <user@hostname>
670 author--debug: test
670 author--debug: test
671 author--debug: User Name <user@hostname>
671 author--debug: User Name <user@hostname>
672 author--debug: person
672 author--debug: person
673 author--debug: person
673 author--debug: person
674 author--debug: person
674 author--debug: person
675 author--debug: person
675 author--debug: person
676 author--debug: other@place
676 author--debug: other@place
677 author--debug: A. N. Other <other@place>
677 author--debug: A. N. Other <other@place>
678 author--debug: User Name <user@hostname>
678 author--debug: User Name <user@hostname>
679 branch: default
679 branch: default
680 branch: default
680 branch: default
681 branch: default
681 branch: default
682 branch: default
682 branch: default
683 branch: foo
683 branch: foo
684 branch: default
684 branch: default
685 branch: default
685 branch: default
686 branch: default
686 branch: default
687 branch: default
687 branch: default
688 branch--verbose: default
688 branch--verbose: default
689 branch--verbose: default
689 branch--verbose: default
690 branch--verbose: default
690 branch--verbose: default
691 branch--verbose: default
691 branch--verbose: default
692 branch--verbose: foo
692 branch--verbose: foo
693 branch--verbose: default
693 branch--verbose: default
694 branch--verbose: default
694 branch--verbose: default
695 branch--verbose: default
695 branch--verbose: default
696 branch--verbose: default
696 branch--verbose: default
697 branch--debug: default
697 branch--debug: default
698 branch--debug: default
698 branch--debug: default
699 branch--debug: default
699 branch--debug: default
700 branch--debug: default
700 branch--debug: default
701 branch--debug: foo
701 branch--debug: foo
702 branch--debug: default
702 branch--debug: default
703 branch--debug: default
703 branch--debug: default
704 branch--debug: default
704 branch--debug: default
705 branch--debug: default
705 branch--debug: default
706 branches:
706 branches:
707 branches:
707 branches:
708 branches:
708 branches:
709 branches:
709 branches:
710 branches: foo
710 branches: foo
711 branches:
711 branches:
712 branches:
712 branches:
713 branches:
713 branches:
714 branches:
714 branches:
715 branches--verbose:
715 branches--verbose:
716 branches--verbose:
716 branches--verbose:
717 branches--verbose:
717 branches--verbose:
718 branches--verbose:
718 branches--verbose:
719 branches--verbose: foo
719 branches--verbose: foo
720 branches--verbose:
720 branches--verbose:
721 branches--verbose:
721 branches--verbose:
722 branches--verbose:
722 branches--verbose:
723 branches--verbose:
723 branches--verbose:
724 branches--debug:
724 branches--debug:
725 branches--debug:
725 branches--debug:
726 branches--debug:
726 branches--debug:
727 branches--debug:
727 branches--debug:
728 branches--debug: foo
728 branches--debug: foo
729 branches--debug:
729 branches--debug:
730 branches--debug:
730 branches--debug:
731 branches--debug:
731 branches--debug:
732 branches--debug:
732 branches--debug:
733 date: 1577872860.00
733 date: 1577872860.00
734 date: 1000000.00
734 date: 1000000.00
735 date: 1500001.00
735 date: 1500001.00
736 date: 1500000.00
736 date: 1500000.00
737 date: 1400000.00
737 date: 1400000.00
738 date: 1300000.00
738 date: 1300000.00
739 date: 1200000.00
739 date: 1200000.00
740 date: 1100000.00
740 date: 1100000.00
741 date: 1000000.00
741 date: 1000000.00
742 date--verbose: 1577872860.00
742 date--verbose: 1577872860.00
743 date--verbose: 1000000.00
743 date--verbose: 1000000.00
744 date--verbose: 1500001.00
744 date--verbose: 1500001.00
745 date--verbose: 1500000.00
745 date--verbose: 1500000.00
746 date--verbose: 1400000.00
746 date--verbose: 1400000.00
747 date--verbose: 1300000.00
747 date--verbose: 1300000.00
748 date--verbose: 1200000.00
748 date--verbose: 1200000.00
749 date--verbose: 1100000.00
749 date--verbose: 1100000.00
750 date--verbose: 1000000.00
750 date--verbose: 1000000.00
751 date--debug: 1577872860.00
751 date--debug: 1577872860.00
752 date--debug: 1000000.00
752 date--debug: 1000000.00
753 date--debug: 1500001.00
753 date--debug: 1500001.00
754 date--debug: 1500000.00
754 date--debug: 1500000.00
755 date--debug: 1400000.00
755 date--debug: 1400000.00
756 date--debug: 1300000.00
756 date--debug: 1300000.00
757 date--debug: 1200000.00
757 date--debug: 1200000.00
758 date--debug: 1100000.00
758 date--debug: 1100000.00
759 date--debug: 1000000.00
759 date--debug: 1000000.00
760 desc: third
760 desc: third
761 desc: second
761 desc: second
762 desc: merge
762 desc: merge
763 desc: new head
763 desc: new head
764 desc: new branch
764 desc: new branch
765 desc: no user, no domain
765 desc: no user, no domain
766 desc: no person
766 desc: no person
767 desc: other 1
767 desc: other 1
768 other 2
768 other 2
769
769
770 other 3
770 other 3
771 desc: line 1
771 desc: line 1
772 line 2
772 line 2
773 desc--verbose: third
773 desc--verbose: third
774 desc--verbose: second
774 desc--verbose: second
775 desc--verbose: merge
775 desc--verbose: merge
776 desc--verbose: new head
776 desc--verbose: new head
777 desc--verbose: new branch
777 desc--verbose: new branch
778 desc--verbose: no user, no domain
778 desc--verbose: no user, no domain
779 desc--verbose: no person
779 desc--verbose: no person
780 desc--verbose: other 1
780 desc--verbose: other 1
781 other 2
781 other 2
782
782
783 other 3
783 other 3
784 desc--verbose: line 1
784 desc--verbose: line 1
785 line 2
785 line 2
786 desc--debug: third
786 desc--debug: third
787 desc--debug: second
787 desc--debug: second
788 desc--debug: merge
788 desc--debug: merge
789 desc--debug: new head
789 desc--debug: new head
790 desc--debug: new branch
790 desc--debug: new branch
791 desc--debug: no user, no domain
791 desc--debug: no user, no domain
792 desc--debug: no person
792 desc--debug: no person
793 desc--debug: other 1
793 desc--debug: other 1
794 other 2
794 other 2
795
795
796 other 3
796 other 3
797 desc--debug: line 1
797 desc--debug: line 1
798 line 2
798 line 2
799 file_adds: fourth third
799 file_adds: fourth third
800 file_adds: second
800 file_adds: second
801 file_adds:
801 file_adds:
802 file_adds: d
802 file_adds: d
803 file_adds:
803 file_adds:
804 file_adds:
804 file_adds:
805 file_adds: c
805 file_adds: c
806 file_adds: b
806 file_adds: b
807 file_adds: a
807 file_adds: a
808 file_adds--verbose: fourth third
808 file_adds--verbose: fourth third
809 file_adds--verbose: second
809 file_adds--verbose: second
810 file_adds--verbose:
810 file_adds--verbose:
811 file_adds--verbose: d
811 file_adds--verbose: d
812 file_adds--verbose:
812 file_adds--verbose:
813 file_adds--verbose:
813 file_adds--verbose:
814 file_adds--verbose: c
814 file_adds--verbose: c
815 file_adds--verbose: b
815 file_adds--verbose: b
816 file_adds--verbose: a
816 file_adds--verbose: a
817 file_adds--debug: fourth third
817 file_adds--debug: fourth third
818 file_adds--debug: second
818 file_adds--debug: second
819 file_adds--debug:
819 file_adds--debug:
820 file_adds--debug: d
820 file_adds--debug: d
821 file_adds--debug:
821 file_adds--debug:
822 file_adds--debug:
822 file_adds--debug:
823 file_adds--debug: c
823 file_adds--debug: c
824 file_adds--debug: b
824 file_adds--debug: b
825 file_adds--debug: a
825 file_adds--debug: a
826 file_dels: second
826 file_dels: second
827 file_dels:
827 file_dels:
828 file_dels:
828 file_dels:
829 file_dels:
829 file_dels:
830 file_dels:
830 file_dels:
831 file_dels:
831 file_dels:
832 file_dels:
832 file_dels:
833 file_dels:
833 file_dels:
834 file_dels:
834 file_dels:
835 file_dels--verbose: second
835 file_dels--verbose: second
836 file_dels--verbose:
836 file_dels--verbose:
837 file_dels--verbose:
837 file_dels--verbose:
838 file_dels--verbose:
838 file_dels--verbose:
839 file_dels--verbose:
839 file_dels--verbose:
840 file_dels--verbose:
840 file_dels--verbose:
841 file_dels--verbose:
841 file_dels--verbose:
842 file_dels--verbose:
842 file_dels--verbose:
843 file_dels--verbose:
843 file_dels--verbose:
844 file_dels--debug: second
844 file_dels--debug: second
845 file_dels--debug:
845 file_dels--debug:
846 file_dels--debug:
846 file_dels--debug:
847 file_dels--debug:
847 file_dels--debug:
848 file_dels--debug:
848 file_dels--debug:
849 file_dels--debug:
849 file_dels--debug:
850 file_dels--debug:
850 file_dels--debug:
851 file_dels--debug:
851 file_dels--debug:
852 file_dels--debug:
852 file_dels--debug:
853 file_mods:
853 file_mods:
854 file_mods:
854 file_mods:
855 file_mods:
855 file_mods:
856 file_mods:
856 file_mods:
857 file_mods:
857 file_mods:
858 file_mods: c
858 file_mods: c
859 file_mods:
859 file_mods:
860 file_mods:
860 file_mods:
861 file_mods:
861 file_mods:
862 file_mods--verbose:
862 file_mods--verbose:
863 file_mods--verbose:
863 file_mods--verbose:
864 file_mods--verbose:
864 file_mods--verbose:
865 file_mods--verbose:
865 file_mods--verbose:
866 file_mods--verbose:
866 file_mods--verbose:
867 file_mods--verbose: c
867 file_mods--verbose: c
868 file_mods--verbose:
868 file_mods--verbose:
869 file_mods--verbose:
869 file_mods--verbose:
870 file_mods--verbose:
870 file_mods--verbose:
871 file_mods--debug:
871 file_mods--debug:
872 file_mods--debug:
872 file_mods--debug:
873 file_mods--debug:
873 file_mods--debug:
874 file_mods--debug:
874 file_mods--debug:
875 file_mods--debug:
875 file_mods--debug:
876 file_mods--debug: c
876 file_mods--debug: c
877 file_mods--debug:
877 file_mods--debug:
878 file_mods--debug:
878 file_mods--debug:
879 file_mods--debug:
879 file_mods--debug:
880 file_copies: fourth (second)
880 file_copies: fourth (second)
881 file_copies:
881 file_copies:
882 file_copies:
882 file_copies:
883 file_copies:
883 file_copies:
884 file_copies:
884 file_copies:
885 file_copies:
885 file_copies:
886 file_copies:
886 file_copies:
887 file_copies:
887 file_copies:
888 file_copies:
888 file_copies:
889 file_copies--verbose: fourth (second)
889 file_copies--verbose: fourth (second)
890 file_copies--verbose:
890 file_copies--verbose:
891 file_copies--verbose:
891 file_copies--verbose:
892 file_copies--verbose:
892 file_copies--verbose:
893 file_copies--verbose:
893 file_copies--verbose:
894 file_copies--verbose:
894 file_copies--verbose:
895 file_copies--verbose:
895 file_copies--verbose:
896 file_copies--verbose:
896 file_copies--verbose:
897 file_copies--verbose:
897 file_copies--verbose:
898 file_copies--debug: fourth (second)
898 file_copies--debug: fourth (second)
899 file_copies--debug:
899 file_copies--debug:
900 file_copies--debug:
900 file_copies--debug:
901 file_copies--debug:
901 file_copies--debug:
902 file_copies--debug:
902 file_copies--debug:
903 file_copies--debug:
903 file_copies--debug:
904 file_copies--debug:
904 file_copies--debug:
905 file_copies--debug:
905 file_copies--debug:
906 file_copies--debug:
906 file_copies--debug:
907 file_copies_switch:
907 file_copies_switch:
908 file_copies_switch:
908 file_copies_switch:
909 file_copies_switch:
909 file_copies_switch:
910 file_copies_switch:
910 file_copies_switch:
911 file_copies_switch:
911 file_copies_switch:
912 file_copies_switch:
912 file_copies_switch:
913 file_copies_switch:
913 file_copies_switch:
914 file_copies_switch:
914 file_copies_switch:
915 file_copies_switch:
915 file_copies_switch:
916 file_copies_switch--verbose:
916 file_copies_switch--verbose:
917 file_copies_switch--verbose:
917 file_copies_switch--verbose:
918 file_copies_switch--verbose:
918 file_copies_switch--verbose:
919 file_copies_switch--verbose:
919 file_copies_switch--verbose:
920 file_copies_switch--verbose:
920 file_copies_switch--verbose:
921 file_copies_switch--verbose:
921 file_copies_switch--verbose:
922 file_copies_switch--verbose:
922 file_copies_switch--verbose:
923 file_copies_switch--verbose:
923 file_copies_switch--verbose:
924 file_copies_switch--verbose:
924 file_copies_switch--verbose:
925 file_copies_switch--debug:
925 file_copies_switch--debug:
926 file_copies_switch--debug:
926 file_copies_switch--debug:
927 file_copies_switch--debug:
927 file_copies_switch--debug:
928 file_copies_switch--debug:
928 file_copies_switch--debug:
929 file_copies_switch--debug:
929 file_copies_switch--debug:
930 file_copies_switch--debug:
930 file_copies_switch--debug:
931 file_copies_switch--debug:
931 file_copies_switch--debug:
932 file_copies_switch--debug:
932 file_copies_switch--debug:
933 file_copies_switch--debug:
933 file_copies_switch--debug:
934 files: fourth second third
934 files: fourth second third
935 files: second
935 files: second
936 files:
936 files:
937 files: d
937 files: d
938 files:
938 files:
939 files: c
939 files: c
940 files: c
940 files: c
941 files: b
941 files: b
942 files: a
942 files: a
943 files--verbose: fourth second third
943 files--verbose: fourth second third
944 files--verbose: second
944 files--verbose: second
945 files--verbose:
945 files--verbose:
946 files--verbose: d
946 files--verbose: d
947 files--verbose:
947 files--verbose:
948 files--verbose: c
948 files--verbose: c
949 files--verbose: c
949 files--verbose: c
950 files--verbose: b
950 files--verbose: b
951 files--verbose: a
951 files--verbose: a
952 files--debug: fourth second third
952 files--debug: fourth second third
953 files--debug: second
953 files--debug: second
954 files--debug:
954 files--debug:
955 files--debug: d
955 files--debug: d
956 files--debug:
956 files--debug:
957 files--debug: c
957 files--debug: c
958 files--debug: c
958 files--debug: c
959 files--debug: b
959 files--debug: b
960 files--debug: a
960 files--debug: a
961 manifest: 6:94961b75a2da
961 manifest: 6:94961b75a2da
962 manifest: 5:f2dbc354b94e
962 manifest: 5:f2dbc354b94e
963 manifest: 4:4dc3def4f9b4
963 manifest: 4:4dc3def4f9b4
964 manifest: 4:4dc3def4f9b4
964 manifest: 4:4dc3def4f9b4
965 manifest: 3:cb5a1327723b
965 manifest: 3:cb5a1327723b
966 manifest: 3:cb5a1327723b
966 manifest: 3:cb5a1327723b
967 manifest: 2:6e0e82995c35
967 manifest: 2:6e0e82995c35
968 manifest: 1:4e8d705b1e53
968 manifest: 1:4e8d705b1e53
969 manifest: 0:a0c8bcbbb45c
969 manifest: 0:a0c8bcbbb45c
970 manifest--verbose: 6:94961b75a2da
970 manifest--verbose: 6:94961b75a2da
971 manifest--verbose: 5:f2dbc354b94e
971 manifest--verbose: 5:f2dbc354b94e
972 manifest--verbose: 4:4dc3def4f9b4
972 manifest--verbose: 4:4dc3def4f9b4
973 manifest--verbose: 4:4dc3def4f9b4
973 manifest--verbose: 4:4dc3def4f9b4
974 manifest--verbose: 3:cb5a1327723b
974 manifest--verbose: 3:cb5a1327723b
975 manifest--verbose: 3:cb5a1327723b
975 manifest--verbose: 3:cb5a1327723b
976 manifest--verbose: 2:6e0e82995c35
976 manifest--verbose: 2:6e0e82995c35
977 manifest--verbose: 1:4e8d705b1e53
977 manifest--verbose: 1:4e8d705b1e53
978 manifest--verbose: 0:a0c8bcbbb45c
978 manifest--verbose: 0:a0c8bcbbb45c
979 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
979 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
980 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
980 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
981 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
981 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
982 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
982 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
983 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
983 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
984 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
984 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
985 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
985 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
986 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
986 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
987 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
987 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
988 node: 95c24699272ef57d062b8bccc32c878bf841784a
988 node: 95c24699272ef57d062b8bccc32c878bf841784a
989 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
989 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
990 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
990 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
991 node: 13207e5a10d9fd28ec424934298e176197f2c67f
991 node: 13207e5a10d9fd28ec424934298e176197f2c67f
992 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
992 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
993 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
993 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
994 node: 97054abb4ab824450e9164180baf491ae0078465
994 node: 97054abb4ab824450e9164180baf491ae0078465
995 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
995 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
996 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
996 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
997 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
997 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
998 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
998 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
999 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
999 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1000 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1000 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1001 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1001 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1002 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1002 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1003 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1003 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1004 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1004 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1005 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1005 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1006 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1006 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1007 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1007 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1008 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1008 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1009 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1009 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1010 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1010 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1011 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1011 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1012 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1012 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1013 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1013 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1014 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1014 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1015 parents:
1015 parents:
1016 parents: -1:000000000000
1016 parents: -1:000000000000
1017 parents: 5:13207e5a10d9 4:bbe44766e73d
1017 parents: 5:13207e5a10d9 4:bbe44766e73d
1018 parents: 3:10e46f2dcbf4
1018 parents: 3:10e46f2dcbf4
1019 parents:
1019 parents:
1020 parents:
1020 parents:
1021 parents:
1021 parents:
1022 parents:
1022 parents:
1023 parents:
1023 parents:
1024 parents--verbose:
1024 parents--verbose:
1025 parents--verbose: -1:000000000000
1025 parents--verbose: -1:000000000000
1026 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1026 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1027 parents--verbose: 3:10e46f2dcbf4
1027 parents--verbose: 3:10e46f2dcbf4
1028 parents--verbose:
1028 parents--verbose:
1029 parents--verbose:
1029 parents--verbose:
1030 parents--verbose:
1030 parents--verbose:
1031 parents--verbose:
1031 parents--verbose:
1032 parents--verbose:
1032 parents--verbose:
1033 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1033 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1034 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1034 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1035 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1035 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1036 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1036 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1037 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1037 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1038 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1038 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1039 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1039 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1040 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1040 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1041 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1041 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1042 rev: 8
1042 rev: 8
1043 rev: 7
1043 rev: 7
1044 rev: 6
1044 rev: 6
1045 rev: 5
1045 rev: 5
1046 rev: 4
1046 rev: 4
1047 rev: 3
1047 rev: 3
1048 rev: 2
1048 rev: 2
1049 rev: 1
1049 rev: 1
1050 rev: 0
1050 rev: 0
1051 rev--verbose: 8
1051 rev--verbose: 8
1052 rev--verbose: 7
1052 rev--verbose: 7
1053 rev--verbose: 6
1053 rev--verbose: 6
1054 rev--verbose: 5
1054 rev--verbose: 5
1055 rev--verbose: 4
1055 rev--verbose: 4
1056 rev--verbose: 3
1056 rev--verbose: 3
1057 rev--verbose: 2
1057 rev--verbose: 2
1058 rev--verbose: 1
1058 rev--verbose: 1
1059 rev--verbose: 0
1059 rev--verbose: 0
1060 rev--debug: 8
1060 rev--debug: 8
1061 rev--debug: 7
1061 rev--debug: 7
1062 rev--debug: 6
1062 rev--debug: 6
1063 rev--debug: 5
1063 rev--debug: 5
1064 rev--debug: 4
1064 rev--debug: 4
1065 rev--debug: 3
1065 rev--debug: 3
1066 rev--debug: 2
1066 rev--debug: 2
1067 rev--debug: 1
1067 rev--debug: 1
1068 rev--debug: 0
1068 rev--debug: 0
1069 tags: tip
1069 tags: tip
1070 tags:
1070 tags:
1071 tags:
1071 tags:
1072 tags:
1072 tags:
1073 tags:
1073 tags:
1074 tags:
1074 tags:
1075 tags:
1075 tags:
1076 tags:
1076 tags:
1077 tags:
1077 tags:
1078 tags--verbose: tip
1078 tags--verbose: tip
1079 tags--verbose:
1079 tags--verbose:
1080 tags--verbose:
1080 tags--verbose:
1081 tags--verbose:
1081 tags--verbose:
1082 tags--verbose:
1082 tags--verbose:
1083 tags--verbose:
1083 tags--verbose:
1084 tags--verbose:
1084 tags--verbose:
1085 tags--verbose:
1085 tags--verbose:
1086 tags--verbose:
1086 tags--verbose:
1087 tags--debug: tip
1087 tags--debug: tip
1088 tags--debug:
1088 tags--debug:
1089 tags--debug:
1089 tags--debug:
1090 tags--debug:
1090 tags--debug:
1091 tags--debug:
1091 tags--debug:
1092 tags--debug:
1092 tags--debug:
1093 tags--debug:
1093 tags--debug:
1094 tags--debug:
1094 tags--debug:
1095 tags--debug:
1095 tags--debug:
1096 diffstat: 3: +2/-1
1096 diffstat: 3: +2/-1
1097 diffstat: 1: +1/-0
1097 diffstat: 1: +1/-0
1098 diffstat: 0: +0/-0
1098 diffstat: 0: +0/-0
1099 diffstat: 1: +1/-0
1099 diffstat: 1: +1/-0
1100 diffstat: 0: +0/-0
1100 diffstat: 0: +0/-0
1101 diffstat: 1: +1/-0
1101 diffstat: 1: +1/-0
1102 diffstat: 1: +4/-0
1102 diffstat: 1: +4/-0
1103 diffstat: 1: +2/-0
1103 diffstat: 1: +2/-0
1104 diffstat: 1: +1/-0
1104 diffstat: 1: +1/-0
1105 diffstat--verbose: 3: +2/-1
1105 diffstat--verbose: 3: +2/-1
1106 diffstat--verbose: 1: +1/-0
1106 diffstat--verbose: 1: +1/-0
1107 diffstat--verbose: 0: +0/-0
1107 diffstat--verbose: 0: +0/-0
1108 diffstat--verbose: 1: +1/-0
1108 diffstat--verbose: 1: +1/-0
1109 diffstat--verbose: 0: +0/-0
1109 diffstat--verbose: 0: +0/-0
1110 diffstat--verbose: 1: +1/-0
1110 diffstat--verbose: 1: +1/-0
1111 diffstat--verbose: 1: +4/-0
1111 diffstat--verbose: 1: +4/-0
1112 diffstat--verbose: 1: +2/-0
1112 diffstat--verbose: 1: +2/-0
1113 diffstat--verbose: 1: +1/-0
1113 diffstat--verbose: 1: +1/-0
1114 diffstat--debug: 3: +2/-1
1114 diffstat--debug: 3: +2/-1
1115 diffstat--debug: 1: +1/-0
1115 diffstat--debug: 1: +1/-0
1116 diffstat--debug: 0: +0/-0
1116 diffstat--debug: 0: +0/-0
1117 diffstat--debug: 1: +1/-0
1117 diffstat--debug: 1: +1/-0
1118 diffstat--debug: 0: +0/-0
1118 diffstat--debug: 0: +0/-0
1119 diffstat--debug: 1: +1/-0
1119 diffstat--debug: 1: +1/-0
1120 diffstat--debug: 1: +4/-0
1120 diffstat--debug: 1: +4/-0
1121 diffstat--debug: 1: +2/-0
1121 diffstat--debug: 1: +2/-0
1122 diffstat--debug: 1: +1/-0
1122 diffstat--debug: 1: +1/-0
1123 extras: branch=default
1123 extras: branch=default
1124 extras: branch=default
1124 extras: branch=default
1125 extras: branch=default
1125 extras: branch=default
1126 extras: branch=default
1126 extras: branch=default
1127 extras: branch=foo
1127 extras: branch=foo
1128 extras: branch=default
1128 extras: branch=default
1129 extras: branch=default
1129 extras: branch=default
1130 extras: branch=default
1130 extras: branch=default
1131 extras: branch=default
1131 extras: branch=default
1132 extras--verbose: branch=default
1132 extras--verbose: branch=default
1133 extras--verbose: branch=default
1133 extras--verbose: branch=default
1134 extras--verbose: branch=default
1134 extras--verbose: branch=default
1135 extras--verbose: branch=default
1135 extras--verbose: branch=default
1136 extras--verbose: branch=foo
1136 extras--verbose: branch=foo
1137 extras--verbose: branch=default
1137 extras--verbose: branch=default
1138 extras--verbose: branch=default
1138 extras--verbose: branch=default
1139 extras--verbose: branch=default
1139 extras--verbose: branch=default
1140 extras--verbose: branch=default
1140 extras--verbose: branch=default
1141 extras--debug: branch=default
1141 extras--debug: branch=default
1142 extras--debug: branch=default
1142 extras--debug: branch=default
1143 extras--debug: branch=default
1143 extras--debug: branch=default
1144 extras--debug: branch=default
1144 extras--debug: branch=default
1145 extras--debug: branch=foo
1145 extras--debug: branch=foo
1146 extras--debug: branch=default
1146 extras--debug: branch=default
1147 extras--debug: branch=default
1147 extras--debug: branch=default
1148 extras--debug: branch=default
1148 extras--debug: branch=default
1149 extras--debug: branch=default
1149 extras--debug: branch=default
1150 p1rev: 7
1150 p1rev: 7
1151 p1rev: -1
1151 p1rev: -1
1152 p1rev: 5
1152 p1rev: 5
1153 p1rev: 3
1153 p1rev: 3
1154 p1rev: 3
1154 p1rev: 3
1155 p1rev: 2
1155 p1rev: 2
1156 p1rev: 1
1156 p1rev: 1
1157 p1rev: 0
1157 p1rev: 0
1158 p1rev: -1
1158 p1rev: -1
1159 p1rev--verbose: 7
1159 p1rev--verbose: 7
1160 p1rev--verbose: -1
1160 p1rev--verbose: -1
1161 p1rev--verbose: 5
1161 p1rev--verbose: 5
1162 p1rev--verbose: 3
1162 p1rev--verbose: 3
1163 p1rev--verbose: 3
1163 p1rev--verbose: 3
1164 p1rev--verbose: 2
1164 p1rev--verbose: 2
1165 p1rev--verbose: 1
1165 p1rev--verbose: 1
1166 p1rev--verbose: 0
1166 p1rev--verbose: 0
1167 p1rev--verbose: -1
1167 p1rev--verbose: -1
1168 p1rev--debug: 7
1168 p1rev--debug: 7
1169 p1rev--debug: -1
1169 p1rev--debug: -1
1170 p1rev--debug: 5
1170 p1rev--debug: 5
1171 p1rev--debug: 3
1171 p1rev--debug: 3
1172 p1rev--debug: 3
1172 p1rev--debug: 3
1173 p1rev--debug: 2
1173 p1rev--debug: 2
1174 p1rev--debug: 1
1174 p1rev--debug: 1
1175 p1rev--debug: 0
1175 p1rev--debug: 0
1176 p1rev--debug: -1
1176 p1rev--debug: -1
1177 p2rev: -1
1177 p2rev: -1
1178 p2rev: -1
1178 p2rev: -1
1179 p2rev: 4
1179 p2rev: 4
1180 p2rev: -1
1180 p2rev: -1
1181 p2rev: -1
1181 p2rev: -1
1182 p2rev: -1
1182 p2rev: -1
1183 p2rev: -1
1183 p2rev: -1
1184 p2rev: -1
1184 p2rev: -1
1185 p2rev: -1
1185 p2rev: -1
1186 p2rev--verbose: -1
1186 p2rev--verbose: -1
1187 p2rev--verbose: -1
1187 p2rev--verbose: -1
1188 p2rev--verbose: 4
1188 p2rev--verbose: 4
1189 p2rev--verbose: -1
1189 p2rev--verbose: -1
1190 p2rev--verbose: -1
1190 p2rev--verbose: -1
1191 p2rev--verbose: -1
1191 p2rev--verbose: -1
1192 p2rev--verbose: -1
1192 p2rev--verbose: -1
1193 p2rev--verbose: -1
1193 p2rev--verbose: -1
1194 p2rev--verbose: -1
1194 p2rev--verbose: -1
1195 p2rev--debug: -1
1195 p2rev--debug: -1
1196 p2rev--debug: -1
1196 p2rev--debug: -1
1197 p2rev--debug: 4
1197 p2rev--debug: 4
1198 p2rev--debug: -1
1198 p2rev--debug: -1
1199 p2rev--debug: -1
1199 p2rev--debug: -1
1200 p2rev--debug: -1
1200 p2rev--debug: -1
1201 p2rev--debug: -1
1201 p2rev--debug: -1
1202 p2rev--debug: -1
1202 p2rev--debug: -1
1203 p2rev--debug: -1
1203 p2rev--debug: -1
1204 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1204 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1205 p1node: 0000000000000000000000000000000000000000
1205 p1node: 0000000000000000000000000000000000000000
1206 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1206 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1207 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1207 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1208 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1208 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1209 p1node: 97054abb4ab824450e9164180baf491ae0078465
1209 p1node: 97054abb4ab824450e9164180baf491ae0078465
1210 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1210 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1211 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1211 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1212 p1node: 0000000000000000000000000000000000000000
1212 p1node: 0000000000000000000000000000000000000000
1213 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1213 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1214 p1node--verbose: 0000000000000000000000000000000000000000
1214 p1node--verbose: 0000000000000000000000000000000000000000
1215 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1215 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1216 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1216 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1217 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1217 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1218 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1218 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1219 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1219 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1220 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1220 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1221 p1node--verbose: 0000000000000000000000000000000000000000
1221 p1node--verbose: 0000000000000000000000000000000000000000
1222 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1222 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1223 p1node--debug: 0000000000000000000000000000000000000000
1223 p1node--debug: 0000000000000000000000000000000000000000
1224 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1224 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1225 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1225 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1226 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1226 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1227 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1227 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1228 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1228 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1229 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1229 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1230 p1node--debug: 0000000000000000000000000000000000000000
1230 p1node--debug: 0000000000000000000000000000000000000000
1231 p2node: 0000000000000000000000000000000000000000
1231 p2node: 0000000000000000000000000000000000000000
1232 p2node: 0000000000000000000000000000000000000000
1232 p2node: 0000000000000000000000000000000000000000
1233 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1233 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1234 p2node: 0000000000000000000000000000000000000000
1234 p2node: 0000000000000000000000000000000000000000
1235 p2node: 0000000000000000000000000000000000000000
1235 p2node: 0000000000000000000000000000000000000000
1236 p2node: 0000000000000000000000000000000000000000
1236 p2node: 0000000000000000000000000000000000000000
1237 p2node: 0000000000000000000000000000000000000000
1237 p2node: 0000000000000000000000000000000000000000
1238 p2node: 0000000000000000000000000000000000000000
1238 p2node: 0000000000000000000000000000000000000000
1239 p2node: 0000000000000000000000000000000000000000
1239 p2node: 0000000000000000000000000000000000000000
1240 p2node--verbose: 0000000000000000000000000000000000000000
1240 p2node--verbose: 0000000000000000000000000000000000000000
1241 p2node--verbose: 0000000000000000000000000000000000000000
1241 p2node--verbose: 0000000000000000000000000000000000000000
1242 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1242 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1243 p2node--verbose: 0000000000000000000000000000000000000000
1243 p2node--verbose: 0000000000000000000000000000000000000000
1244 p2node--verbose: 0000000000000000000000000000000000000000
1244 p2node--verbose: 0000000000000000000000000000000000000000
1245 p2node--verbose: 0000000000000000000000000000000000000000
1245 p2node--verbose: 0000000000000000000000000000000000000000
1246 p2node--verbose: 0000000000000000000000000000000000000000
1246 p2node--verbose: 0000000000000000000000000000000000000000
1247 p2node--verbose: 0000000000000000000000000000000000000000
1247 p2node--verbose: 0000000000000000000000000000000000000000
1248 p2node--verbose: 0000000000000000000000000000000000000000
1248 p2node--verbose: 0000000000000000000000000000000000000000
1249 p2node--debug: 0000000000000000000000000000000000000000
1249 p2node--debug: 0000000000000000000000000000000000000000
1250 p2node--debug: 0000000000000000000000000000000000000000
1250 p2node--debug: 0000000000000000000000000000000000000000
1251 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1251 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1252 p2node--debug: 0000000000000000000000000000000000000000
1252 p2node--debug: 0000000000000000000000000000000000000000
1253 p2node--debug: 0000000000000000000000000000000000000000
1253 p2node--debug: 0000000000000000000000000000000000000000
1254 p2node--debug: 0000000000000000000000000000000000000000
1254 p2node--debug: 0000000000000000000000000000000000000000
1255 p2node--debug: 0000000000000000000000000000000000000000
1255 p2node--debug: 0000000000000000000000000000000000000000
1256 p2node--debug: 0000000000000000000000000000000000000000
1256 p2node--debug: 0000000000000000000000000000000000000000
1257 p2node--debug: 0000000000000000000000000000000000000000
1257 p2node--debug: 0000000000000000000000000000000000000000
1258
1258
1259 Filters work:
1259 Filters work:
1260
1260
1261 $ hg log --template '{author|domain}\n'
1261 $ hg log --template '{author|domain}\n'
1262
1262
1263 hostname
1263 hostname
1264
1264
1265
1265
1266
1266
1267
1267
1268 place
1268 place
1269 place
1269 place
1270 hostname
1270 hostname
1271
1271
1272 $ hg log --template '{author|person}\n'
1272 $ hg log --template '{author|person}\n'
1273 test
1273 test
1274 User Name
1274 User Name
1275 person
1275 person
1276 person
1276 person
1277 person
1277 person
1278 person
1278 person
1279 other
1279 other
1280 A. N. Other
1280 A. N. Other
1281 User Name
1281 User Name
1282
1282
1283 $ hg log --template '{author|user}\n'
1283 $ hg log --template '{author|user}\n'
1284 test
1284 test
1285 user
1285 user
1286 person
1286 person
1287 person
1287 person
1288 person
1288 person
1289 person
1289 person
1290 other
1290 other
1291 other
1291 other
1292 user
1292 user
1293
1293
1294 $ hg log --template '{date|date}\n'
1294 $ hg log --template '{date|date}\n'
1295 Wed Jan 01 10:01:00 2020 +0000
1295 Wed Jan 01 10:01:00 2020 +0000
1296 Mon Jan 12 13:46:40 1970 +0000
1296 Mon Jan 12 13:46:40 1970 +0000
1297 Sun Jan 18 08:40:01 1970 +0000
1297 Sun Jan 18 08:40:01 1970 +0000
1298 Sun Jan 18 08:40:00 1970 +0000
1298 Sun Jan 18 08:40:00 1970 +0000
1299 Sat Jan 17 04:53:20 1970 +0000
1299 Sat Jan 17 04:53:20 1970 +0000
1300 Fri Jan 16 01:06:40 1970 +0000
1300 Fri Jan 16 01:06:40 1970 +0000
1301 Wed Jan 14 21:20:00 1970 +0000
1301 Wed Jan 14 21:20:00 1970 +0000
1302 Tue Jan 13 17:33:20 1970 +0000
1302 Tue Jan 13 17:33:20 1970 +0000
1303 Mon Jan 12 13:46:40 1970 +0000
1303 Mon Jan 12 13:46:40 1970 +0000
1304
1304
1305 $ hg log --template '{date|isodate}\n'
1305 $ hg log --template '{date|isodate}\n'
1306 2020-01-01 10:01 +0000
1306 2020-01-01 10:01 +0000
1307 1970-01-12 13:46 +0000
1307 1970-01-12 13:46 +0000
1308 1970-01-18 08:40 +0000
1308 1970-01-18 08:40 +0000
1309 1970-01-18 08:40 +0000
1309 1970-01-18 08:40 +0000
1310 1970-01-17 04:53 +0000
1310 1970-01-17 04:53 +0000
1311 1970-01-16 01:06 +0000
1311 1970-01-16 01:06 +0000
1312 1970-01-14 21:20 +0000
1312 1970-01-14 21:20 +0000
1313 1970-01-13 17:33 +0000
1313 1970-01-13 17:33 +0000
1314 1970-01-12 13:46 +0000
1314 1970-01-12 13:46 +0000
1315
1315
1316 $ hg log --template '{date|isodatesec}\n'
1316 $ hg log --template '{date|isodatesec}\n'
1317 2020-01-01 10:01:00 +0000
1317 2020-01-01 10:01:00 +0000
1318 1970-01-12 13:46:40 +0000
1318 1970-01-12 13:46:40 +0000
1319 1970-01-18 08:40:01 +0000
1319 1970-01-18 08:40:01 +0000
1320 1970-01-18 08:40:00 +0000
1320 1970-01-18 08:40:00 +0000
1321 1970-01-17 04:53:20 +0000
1321 1970-01-17 04:53:20 +0000
1322 1970-01-16 01:06:40 +0000
1322 1970-01-16 01:06:40 +0000
1323 1970-01-14 21:20:00 +0000
1323 1970-01-14 21:20:00 +0000
1324 1970-01-13 17:33:20 +0000
1324 1970-01-13 17:33:20 +0000
1325 1970-01-12 13:46:40 +0000
1325 1970-01-12 13:46:40 +0000
1326
1326
1327 $ hg log --template '{date|rfc822date}\n'
1327 $ hg log --template '{date|rfc822date}\n'
1328 Wed, 01 Jan 2020 10:01:00 +0000
1328 Wed, 01 Jan 2020 10:01:00 +0000
1329 Mon, 12 Jan 1970 13:46:40 +0000
1329 Mon, 12 Jan 1970 13:46:40 +0000
1330 Sun, 18 Jan 1970 08:40:01 +0000
1330 Sun, 18 Jan 1970 08:40:01 +0000
1331 Sun, 18 Jan 1970 08:40:00 +0000
1331 Sun, 18 Jan 1970 08:40:00 +0000
1332 Sat, 17 Jan 1970 04:53:20 +0000
1332 Sat, 17 Jan 1970 04:53:20 +0000
1333 Fri, 16 Jan 1970 01:06:40 +0000
1333 Fri, 16 Jan 1970 01:06:40 +0000
1334 Wed, 14 Jan 1970 21:20:00 +0000
1334 Wed, 14 Jan 1970 21:20:00 +0000
1335 Tue, 13 Jan 1970 17:33:20 +0000
1335 Tue, 13 Jan 1970 17:33:20 +0000
1336 Mon, 12 Jan 1970 13:46:40 +0000
1336 Mon, 12 Jan 1970 13:46:40 +0000
1337
1337
1338 $ hg log --template '{desc|firstline}\n'
1338 $ hg log --template '{desc|firstline}\n'
1339 third
1339 third
1340 second
1340 second
1341 merge
1341 merge
1342 new head
1342 new head
1343 new branch
1343 new branch
1344 no user, no domain
1344 no user, no domain
1345 no person
1345 no person
1346 other 1
1346 other 1
1347 line 1
1347 line 1
1348
1348
1349 $ hg log --template '{node|short}\n'
1349 $ hg log --template '{node|short}\n'
1350 95c24699272e
1350 95c24699272e
1351 29114dbae42b
1351 29114dbae42b
1352 d41e714fe50d
1352 d41e714fe50d
1353 13207e5a10d9
1353 13207e5a10d9
1354 bbe44766e73d
1354 bbe44766e73d
1355 10e46f2dcbf4
1355 10e46f2dcbf4
1356 97054abb4ab8
1356 97054abb4ab8
1357 b608e9d1a3f0
1357 b608e9d1a3f0
1358 1e4e1b8f71e0
1358 1e4e1b8f71e0
1359
1359
1360 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1360 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1361 <changeset author="test"/>
1361 <changeset author="test"/>
1362 <changeset author="User Name &lt;user@hostname&gt;"/>
1362 <changeset author="User Name &lt;user@hostname&gt;"/>
1363 <changeset author="person"/>
1363 <changeset author="person"/>
1364 <changeset author="person"/>
1364 <changeset author="person"/>
1365 <changeset author="person"/>
1365 <changeset author="person"/>
1366 <changeset author="person"/>
1366 <changeset author="person"/>
1367 <changeset author="other@place"/>
1367 <changeset author="other@place"/>
1368 <changeset author="A. N. Other &lt;other@place&gt;"/>
1368 <changeset author="A. N. Other &lt;other@place&gt;"/>
1369 <changeset author="User Name &lt;user@hostname&gt;"/>
1369 <changeset author="User Name &lt;user@hostname&gt;"/>
1370
1370
1371 $ hg log --template '{rev}: {children}\n'
1371 $ hg log --template '{rev}: {children}\n'
1372 8:
1372 8:
1373 7: 8:95c24699272e
1373 7: 8:95c24699272e
1374 6:
1374 6:
1375 5: 6:d41e714fe50d
1375 5: 6:d41e714fe50d
1376 4: 6:d41e714fe50d
1376 4: 6:d41e714fe50d
1377 3: 4:bbe44766e73d 5:13207e5a10d9
1377 3: 4:bbe44766e73d 5:13207e5a10d9
1378 2: 3:10e46f2dcbf4
1378 2: 3:10e46f2dcbf4
1379 1: 2:97054abb4ab8
1379 1: 2:97054abb4ab8
1380 0: 1:b608e9d1a3f0
1380 0: 1:b608e9d1a3f0
1381
1381
1382 Formatnode filter works:
1382 Formatnode filter works:
1383
1383
1384 $ hg -q log -r 0 --template '{node|formatnode}\n'
1384 $ hg -q log -r 0 --template '{node|formatnode}\n'
1385 1e4e1b8f71e0
1385 1e4e1b8f71e0
1386
1386
1387 $ hg log -r 0 --template '{node|formatnode}\n'
1387 $ hg log -r 0 --template '{node|formatnode}\n'
1388 1e4e1b8f71e0
1388 1e4e1b8f71e0
1389
1389
1390 $ hg -v log -r 0 --template '{node|formatnode}\n'
1390 $ hg -v log -r 0 --template '{node|formatnode}\n'
1391 1e4e1b8f71e0
1391 1e4e1b8f71e0
1392
1392
1393 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1393 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1394 1e4e1b8f71e05681d422154f5421e385fec3454f
1394 1e4e1b8f71e05681d422154f5421e385fec3454f
1395
1395
1396 Age filter:
1396 Age filter:
1397
1397
1398 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1398 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1399
1399
1400 >>> from datetime import datetime, timedelta
1400 >>> from datetime import datetime, timedelta
1401 >>> fp = open('a', 'w')
1401 >>> fp = open('a', 'w')
1402 >>> n = datetime.now() + timedelta(366 * 7)
1402 >>> n = datetime.now() + timedelta(366 * 7)
1403 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1403 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1404 >>> fp.close()
1404 >>> fp.close()
1405 $ hg add a
1405 $ hg add a
1406 $ hg commit -m future -d "`cat a`"
1406 $ hg commit -m future -d "`cat a`"
1407
1407
1408 $ hg log -l1 --template '{date|age}\n'
1408 $ hg log -l1 --template '{date|age}\n'
1409 7 years from now
1409 7 years from now
1410
1410
1411 Error on syntax:
1411 Error on syntax:
1412
1412
1413 $ echo 'x = "f' >> t
1413 $ echo 'x = "f' >> t
1414 $ hg log
1414 $ hg log
1415 abort: t:3: unmatched quotes
1415 abort: t:3: unmatched quotes
1416 [255]
1416 [255]
1417
1417
1418 Behind the scenes, this will throw TypeError
1418 Behind the scenes, this will throw TypeError
1419
1419
1420 $ hg log -l 3 --template '{date|obfuscate}\n'
1420 $ hg log -l 3 --template '{date|obfuscate}\n'
1421 abort: template filter 'obfuscate' is not compatible with keyword 'date'
1421 abort: template filter 'obfuscate' is not compatible with keyword 'date'
1422 [255]
1422 [255]
1423
1423
1424 Behind the scenes, this will throw a ValueError
1424 Behind the scenes, this will throw a ValueError
1425
1425
1426 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1426 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1427 abort: template filter 'shortdate' is not compatible with keyword 'desc'
1427 abort: template filter 'shortdate' is not compatible with keyword 'desc'
1428 [255]
1428 [255]
1429
1429
1430 Behind the scenes, this will throw AttributeError
1430 Behind the scenes, this will throw AttributeError
1431
1431
1432 $ hg log -l 3 --template 'line: {date|escape}\n'
1432 $ hg log -l 3 --template 'line: {date|escape}\n'
1433 abort: template filter 'escape' is not compatible with keyword 'date'
1433 abort: template filter 'escape' is not compatible with keyword 'date'
1434 [255]
1434 [255]
1435
1435
1436 Behind the scenes, this will throw ValueError
1436 Behind the scenes, this will throw ValueError
1437
1437
1438 $ hg tip --template '{author|email|date}\n'
1438 $ hg tip --template '{author|email|date}\n'
1439 abort: template filter 'datefilter' is not compatible with keyword 'author'
1439 abort: template filter 'datefilter' is not compatible with keyword 'author'
1440 [255]
1440 [255]
1441
1441
1442 Thrown an error if a template function doesn't exist
1442 Thrown an error if a template function doesn't exist
1443
1443
1444 $ hg tip --template '{foo()}\n'
1444 $ hg tip --template '{foo()}\n'
1445 hg: parse error: unknown function 'foo'
1445 hg: parse error: unknown function 'foo'
1446 [255]
1446 [255]
1447
1447
1448 $ cd ..
1448 $ cd ..
1449
1449
1450
1450
1451 latesttag:
1451 latesttag:
1452
1452
1453 $ hg init latesttag
1453 $ hg init latesttag
1454 $ cd latesttag
1454 $ cd latesttag
1455
1455
1456 $ echo a > file
1456 $ echo a > file
1457 $ hg ci -Am a -d '0 0'
1457 $ hg ci -Am a -d '0 0'
1458 adding file
1458 adding file
1459
1459
1460 $ echo b >> file
1460 $ echo b >> file
1461 $ hg ci -m b -d '1 0'
1461 $ hg ci -m b -d '1 0'
1462
1462
1463 $ echo c >> head1
1463 $ echo c >> head1
1464 $ hg ci -Am h1c -d '2 0'
1464 $ hg ci -Am h1c -d '2 0'
1465 adding head1
1465 adding head1
1466
1466
1467 $ hg update -q 1
1467 $ hg update -q 1
1468 $ echo d >> head2
1468 $ echo d >> head2
1469 $ hg ci -Am h2d -d '3 0'
1469 $ hg ci -Am h2d -d '3 0'
1470 adding head2
1470 adding head2
1471 created new head
1471 created new head
1472
1472
1473 $ echo e >> head2
1473 $ echo e >> head2
1474 $ hg ci -m h2e -d '4 0'
1474 $ hg ci -m h2e -d '4 0'
1475
1475
1476 $ hg merge -q
1476 $ hg merge -q
1477 $ hg ci -m merge -d '5 -3600'
1477 $ hg ci -m merge -d '5 -3600'
1478
1478
1479 No tag set:
1479 No tag set:
1480
1480
1481 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1481 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1482 5: null+5
1482 5: null+5
1483 4: null+4
1483 4: null+4
1484 3: null+3
1484 3: null+3
1485 2: null+3
1485 2: null+3
1486 1: null+2
1486 1: null+2
1487 0: null+1
1487 0: null+1
1488
1488
1489 One common tag: longest path wins:
1489 One common tag: longest path wins:
1490
1490
1491 $ hg tag -r 1 -m t1 -d '6 0' t1
1491 $ hg tag -r 1 -m t1 -d '6 0' t1
1492 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1492 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1493 6: t1+4
1493 6: t1+4
1494 5: t1+3
1494 5: t1+3
1495 4: t1+2
1495 4: t1+2
1496 3: t1+1
1496 3: t1+1
1497 2: t1+1
1497 2: t1+1
1498 1: t1+0
1498 1: t1+0
1499 0: null+1
1499 0: null+1
1500
1500
1501 One ancestor tag: more recent wins:
1501 One ancestor tag: more recent wins:
1502
1502
1503 $ hg tag -r 2 -m t2 -d '7 0' t2
1503 $ hg tag -r 2 -m t2 -d '7 0' t2
1504 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1504 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1505 7: t2+3
1505 7: t2+3
1506 6: t2+2
1506 6: t2+2
1507 5: t2+1
1507 5: t2+1
1508 4: t1+2
1508 4: t1+2
1509 3: t1+1
1509 3: t1+1
1510 2: t2+0
1510 2: t2+0
1511 1: t1+0
1511 1: t1+0
1512 0: null+1
1512 0: null+1
1513
1513
1514 Two branch tags: more recent wins:
1514 Two branch tags: more recent wins:
1515
1515
1516 $ hg tag -r 3 -m t3 -d '8 0' t3
1516 $ hg tag -r 3 -m t3 -d '8 0' t3
1517 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1517 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1518 8: t3+5
1518 8: t3+5
1519 7: t3+4
1519 7: t3+4
1520 6: t3+3
1520 6: t3+3
1521 5: t3+2
1521 5: t3+2
1522 4: t3+1
1522 4: t3+1
1523 3: t3+0
1523 3: t3+0
1524 2: t2+0
1524 2: t2+0
1525 1: t1+0
1525 1: t1+0
1526 0: null+1
1526 0: null+1
1527
1527
1528 Merged tag overrides:
1528 Merged tag overrides:
1529
1529
1530 $ hg tag -r 5 -m t5 -d '9 0' t5
1530 $ hg tag -r 5 -m t5 -d '9 0' t5
1531 $ hg tag -r 3 -m at3 -d '10 0' at3
1531 $ hg tag -r 3 -m at3 -d '10 0' at3
1532 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1532 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1533 10: t5+5
1533 10: t5+5
1534 9: t5+4
1534 9: t5+4
1535 8: t5+3
1535 8: t5+3
1536 7: t5+2
1536 7: t5+2
1537 6: t5+1
1537 6: t5+1
1538 5: t5+0
1538 5: t5+0
1539 4: at3:t3+1
1539 4: at3:t3+1
1540 3: at3:t3+0
1540 3: at3:t3+0
1541 2: t2+0
1541 2: t2+0
1542 1: t1+0
1542 1: t1+0
1543 0: null+1
1543 0: null+1
1544
1544
1545 $ cd ..
1545 $ cd ..
1546
1546
1547
1547
1548 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1548 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1549 if it is a relative path
1549 if it is a relative path
1550
1550
1551 $ mkdir -p home/styles
1551 $ mkdir -p home/styles
1552
1552
1553 $ cat > home/styles/teststyle <<EOF
1553 $ cat > home/styles/teststyle <<EOF
1554 > changeset = 'test {rev}:{node|short}\n'
1554 > changeset = 'test {rev}:{node|short}\n'
1555 > EOF
1555 > EOF
1556
1556
1557 $ HOME=`pwd`/home; export HOME
1557 $ HOME=`pwd`/home; export HOME
1558
1558
1559 $ cat > latesttag/.hg/hgrc <<EOF
1559 $ cat > latesttag/.hg/hgrc <<EOF
1560 > [ui]
1560 > [ui]
1561 > style = ~/styles/teststyle
1561 > style = ~/styles/teststyle
1562 > EOF
1562 > EOF
1563
1563
1564 $ hg -R latesttag tip
1564 $ hg -R latesttag tip
1565 test 10:9b4a630e5f5f
1565 test 10:9b4a630e5f5f
1566
1566
1567 Test recursive showlist template (issue1989):
1567 Test recursive showlist template (issue1989):
1568
1568
1569 $ cat > style1989 <<EOF
1569 $ cat > style1989 <<EOF
1570 > changeset = '{file_mods}{manifest}{extras}'
1570 > changeset = '{file_mods}{manifest}{extras}'
1571 > file_mod = 'M|{author|person}\n'
1571 > file_mod = 'M|{author|person}\n'
1572 > manifest = '{rev},{author}\n'
1572 > manifest = '{rev},{author}\n'
1573 > extra = '{key}: {author}\n'
1573 > extra = '{key}: {author}\n'
1574 > EOF
1574 > EOF
1575
1575
1576 $ hg -R latesttag log -r tip --style=style1989
1576 $ hg -R latesttag log -r tip --style=style1989
1577 M|test
1577 M|test
1578 10,test
1578 10,test
1579 branch: test
1579 branch: test
1580
1580
1581 Test new-style inline templating:
1581 Test new-style inline templating:
1582
1582
1583 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1583 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1584 modified files: .hgtags
1584 modified files: .hgtags
1585
1585
1586 Test the sub function of templating for expansion:
1586 Test the sub function of templating for expansion:
1587
1587
1588 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
1588 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
1589 xx
1589 xx
1590
1590
1591 Test the strip function with chars specified:
1591 Test the strip function with chars specified:
1592
1592
1593 $ hg log -R latesttag --template '{desc}\n'
1593 $ hg log -R latesttag --template '{desc}\n'
1594 at3
1594 at3
1595 t5
1595 t5
1596 t3
1596 t3
1597 t2
1597 t2
1598 t1
1598 t1
1599 merge
1599 merge
1600 h2e
1600 h2e
1601 h2d
1601 h2d
1602 h1c
1602 h1c
1603 b
1603 b
1604 a
1604 a
1605
1605
1606 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
1606 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
1607 at3
1607 at3
1608 5
1608 5
1609 3
1609 3
1610 2
1610 2
1611 1
1611 1
1612 merg
1612 merg
1613 h2
1613 h2
1614 h2d
1614 h2d
1615 h1c
1615 h1c
1616 b
1616 b
1617 a
1617 a
1618
1618
1619 Test date format:
1619 Test date format:
1620
1620
1621 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
1621 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
1622 date: 70 01 01 10 +0000
1622 date: 70 01 01 10 +0000
1623 date: 70 01 01 09 +0000
1623 date: 70 01 01 09 +0000
1624 date: 70 01 01 08 +0000
1624 date: 70 01 01 08 +0000
1625 date: 70 01 01 07 +0000
1625 date: 70 01 01 07 +0000
1626 date: 70 01 01 06 +0000
1626 date: 70 01 01 06 +0000
1627 date: 70 01 01 05 +0100
1627 date: 70 01 01 05 +0100
1628 date: 70 01 01 04 +0000
1628 date: 70 01 01 04 +0000
1629 date: 70 01 01 03 +0000
1629 date: 70 01 01 03 +0000
1630 date: 70 01 01 02 +0000
1630 date: 70 01 01 02 +0000
1631 date: 70 01 01 01 +0000
1631 date: 70 01 01 01 +0000
1632 date: 70 01 01 00 +0000
1632 date: 70 01 01 00 +0000
1633
1633
1634 Test string escaping:
1634 Test string escaping:
1635
1635
1636 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1636 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1637 >
1637 >
1638 <>\n<[>
1638 <>\n<[>
1639 <>\n<]>
1639 <>\n<]>
1640 <>\n<
1640 <>\n<
1641
1641
1642 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
1642 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
1643
1643
1644 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
1644 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
1645 \x6e
1645 \x6e
1646 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
1646 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
1647 \x5c\x786e
1647 \x5c\x786e
1648 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
1648 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
1649 \x6e
1649 \x6e
1650 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
1650 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
1651 \x5c\x786e
1651 \x5c\x786e
1652
1652
1653 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
1653 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
1654 \x6e
1654 \x6e
1655 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
1655 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
1656 \x5c\x786e
1656 \x5c\x786e
1657 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
1657 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
1658 \x6e
1658 \x6e
1659 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
1659 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
1660 \x5c\x786e
1660 \x5c\x786e
1661
1661
1662 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
1662 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
1663 fourth
1663 fourth
1664 second
1664 second
1665 third
1665 third
1666 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
1666 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
1667 fourth\nsecond\nthird
1667 fourth\nsecond\nthird
1668
1668
1669 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
1669 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
1670 <p>
1670 <p>
1671 1st
1671 1st
1672 </p>
1672 </p>
1673 <p>
1673 <p>
1674 2nd
1674 2nd
1675 </p>
1675 </p>
1676 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
1676 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
1677 <p>
1677 <p>
1678 1st\n\n2nd
1678 1st\n\n2nd
1679 </p>
1679 </p>
1680 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
1680 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
1681 1st
1681 1st
1682
1682
1683 2nd
1683 2nd
1684
1684
1685 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
1685 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
1686 o perso
1686 o perso
1687 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
1687 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
1688 no person
1688 no person
1689 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
1689 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
1690 o perso
1690 o perso
1691 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
1691 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
1692 no perso
1692 no perso
1693
1693
1694 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
1694 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
1695 -o perso-
1695 -o perso-
1696 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
1696 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
1697 no person
1697 no person
1698 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
1698 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
1699 \x2do perso\x2d
1699 \x2do perso\x2d
1700 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
1700 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
1701 -o perso-
1701 -o perso-
1702 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
1702 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
1703 \x2do perso\x6e
1703 \x2do perso\x6e
1704
1704
1705 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
1705 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
1706 fourth
1706 fourth
1707 second
1707 second
1708 third
1708 third
1709 $ hg log -R a -r 8 --template '{files % r"{file}\n"}\n'
1709 $ hg log -R a -r 8 --template '{files % r"{file}\n"}\n'
1710 fourth\nsecond\nthird\n
1710 fourth\nsecond\nthird\n
1711
1711
1712 Test string escaping in nested expression:
1712 Test string escaping in nested expression:
1713
1713
1714 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
1714 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
1715 fourth\x6esecond\x6ethird
1715 fourth\x6esecond\x6ethird
1716 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
1716 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
1717 fourth\x6esecond\x6ethird
1717 fourth\x6esecond\x6ethird
1718
1718
1719 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
1719 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
1720 fourth\x6esecond\x6ethird
1720 fourth\x6esecond\x6ethird
1721 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
1721 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
1722 fourth\x5c\x786esecond\x5c\x786ethird
1722 fourth\x5c\x786esecond\x5c\x786ethird
1723
1723
1724 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
1724 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
1725 3:\x6eo user, \x6eo domai\x6e
1725 3:\x6eo user, \x6eo domai\x6e
1726 4:\x5c\x786eew bra\x5c\x786ech
1726 4:\x5c\x786eew bra\x5c\x786ech
1727
1727
1728 Test recursive evaluation:
1728 Test recursive evaluation:
1729
1729
1730 $ hg init r
1730 $ hg init r
1731 $ cd r
1731 $ cd r
1732 $ echo a > a
1732 $ echo a > a
1733 $ hg ci -Am '{rev}'
1733 $ hg ci -Am '{rev}'
1734 adding a
1734 adding a
1735 $ hg log -r 0 --template '{if(rev, desc)}\n'
1735 $ hg log -r 0 --template '{if(rev, desc)}\n'
1736 {rev}
1736 {rev}
1737 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
1737 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
1738 test 0
1738 test 0
1739
1739
1740 $ hg branch -q 'text.{rev}'
1740 $ hg branch -q 'text.{rev}'
1741 $ echo aa >> aa
1741 $ echo aa >> aa
1742 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
1742 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
1743
1743
1744 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
1744 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
1745 {node|short}desc to
1745 {node|short}desc to
1746 text.{rev}be wrapped
1746 text.{rev}be wrapped
1747 text.{rev}desc to be
1747 text.{rev}desc to be
1748 text.{rev}wrapped (no-eol)
1748 text.{rev}wrapped (no-eol)
1749 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
1749 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
1750 bcc7ff960b8e:desc to
1750 bcc7ff960b8e:desc to
1751 text.1:be wrapped
1751 text.1:be wrapped
1752 text.1:desc to be
1752 text.1:desc to be
1753 text.1:wrapped (no-eol)
1753 text.1:wrapped (no-eol)
1754
1754
1755 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
1755 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
1756 {node|short} (no-eol)
1756 {node|short} (no-eol)
1757 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
1757 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
1758 bcc-ff---b-e (no-eol)
1758 bcc-ff---b-e (no-eol)
1759
1759
1760 $ cat >> .hg/hgrc <<EOF
1760 $ cat >> .hg/hgrc <<EOF
1761 > [extensions]
1761 > [extensions]
1762 > color=
1762 > color=
1763 > [color]
1763 > [color]
1764 > mode=ansi
1764 > mode=ansi
1765 > text.{rev} = red
1765 > text.{rev} = red
1766 > text.1 = green
1766 > text.1 = green
1767 > EOF
1767 > EOF
1768 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
1768 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
1769 \x1b[0;31mtext\x1b[0m (esc)
1769 \x1b[0;31mtext\x1b[0m (esc)
1770 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
1770 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
1771 \x1b[0;32mtext\x1b[0m (esc)
1771 \x1b[0;32mtext\x1b[0m (esc)
1772
1772
1773 Test branches inside if statement:
1773 Test branches inside if statement:
1774
1774
1775 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
1775 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
1776 no
1776 no
1777
1777
1778 Test shortest(node) function:
1778 Test shortest(node) function:
1779
1779
1780 $ echo b > b
1780 $ echo b > b
1781 $ hg ci -qAm b
1781 $ hg ci -qAm b
1782 $ hg log --template '{shortest(node)}\n'
1782 $ hg log --template '{shortest(node)}\n'
1783 e777
1783 e777
1784 bcc7
1784 bcc7
1785 f776
1785 f776
1786 $ hg log --template '{shortest(node, 10)}\n'
1786 $ hg log --template '{shortest(node, 10)}\n'
1787 e777603221
1787 e777603221
1788 bcc7ff960b
1788 bcc7ff960b
1789 f7769ec2ab
1789 f7769ec2ab
1790
1790
1791 Test pad function
1791 Test pad function
1792
1792
1793 $ hg log --template '{pad(rev, 20)} {author|user}\n'
1793 $ hg log --template '{pad(rev, 20)} {author|user}\n'
1794 2 test
1794 2 test
1795 1 {node|short}
1795 1 {node|short}
1796 0 test
1796 0 test
1797
1797
1798 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
1798 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
1799 2 test
1799 2 test
1800 1 {node|short}
1800 1 {node|short}
1801 0 test
1801 0 test
1802
1802
1803 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
1803 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
1804 2------------------- test
1804 2------------------- test
1805 1------------------- {node|short}
1805 1------------------- {node|short}
1806 0------------------- test
1806 0------------------- test
1807
1807
1808 Test ifcontains function
1808 Test ifcontains function
1809
1809
1810 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
1810 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
1811 2 did not add a
1811 2 did not add a
1812 1 did not add a
1812 1 did not add a
1813 0 added a
1813 0 added a
1814
1814
1815 Test revset function
1815 Test revset function
1816
1816
1817 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
1817 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
1818 2 current rev
1818 2 current rev
1819 1 not current rev
1819 1 not current rev
1820 0 not current rev
1820 0 not current rev
1821
1821
1822 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
1822 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
1823 2 match rev
1823 2 match rev
1824 1 match rev
1824 1 match rev
1825 0 not match rev
1825 0 not match rev
1826
1826
1827 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
1827 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
1828 2 Parents: 1
1828 2 Parents: 1
1829 1 Parents: 0
1829 1 Parents: 0
1830 0 Parents:
1830 0 Parents:
1831
1831
1832 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
1832 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
1833 Rev: 2
1833 Rev: 2
1834 Ancestor: 0
1834 Ancestor: 0
1835 Ancestor: 1
1835 Ancestor: 1
1836 Ancestor: 2
1836 Ancestor: 2
1837
1837
1838 Rev: 1
1838 Rev: 1
1839 Ancestor: 0
1839 Ancestor: 0
1840 Ancestor: 1
1840 Ancestor: 1
1841
1841
1842 Rev: 0
1842 Rev: 0
1843 Ancestor: 0
1843 Ancestor: 0
1844
1844
1845 Test current bookmark templating
1845 Test current bookmark templating
1846
1846
1847 $ hg book foo
1847 $ hg book foo
1848 $ hg book bar
1848 $ hg book bar
1849 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}\n"
1849 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}\n"
1850 2 bar* foo
1850 2 bar* foo
1851 1
1851 1
1852 0
1852 0
1853
1853
1854 Test stringify on sub expressions
1854 Test stringify on sub expressions
1855
1855
1856 $ cd ..
1856 $ cd ..
1857 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
1857 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
1858 fourth, second, third
1858 fourth, second, third
1859 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
1859 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
1860 abc
1860 abc
1861
1861
1862 Test splitlines
1862 Test splitlines
1863
1863
1864 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
1864 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
1865 @ foo future
1865 @ foo future
1866 |
1866 |
1867 o foo third
1867 o foo third
1868 |
1868 |
1869 o foo second
1869 o foo second
1870
1870
1871 o foo merge
1871 o foo merge
1872 |\
1872 |\
1873 | o foo new head
1873 | o foo new head
1874 | |
1874 | |
1875 o | foo new branch
1875 o | foo new branch
1876 |/
1876 |/
1877 o foo no user, no domain
1877 o foo no user, no domain
1878 |
1878 |
1879 o foo no person
1879 o foo no person
1880 |
1880 |
1881 o foo other 1
1881 o foo other 1
1882 | foo other 2
1882 | foo other 2
1883 | foo
1883 | foo
1884 | foo other 3
1884 | foo other 3
1885 o foo line 1
1885 o foo line 1
1886 foo line 2
1886 foo line 2
1887
1887
1888 Test startswith
1888 Test startswith
1889 $ hg log -Gv -R a --template "{startswith(desc)}"
1889 $ hg log -Gv -R a --template "{startswith(desc)}"
1890 hg: parse error: startswith expects two arguments
1890 hg: parse error: startswith expects two arguments
1891 [255]
1891 [255]
1892
1892
1893 $ hg log -Gv -R a --template "{startswith('line', desc)}"
1893 $ hg log -Gv -R a --template "{startswith('line', desc)}"
1894 @
1894 @
1895 |
1895 |
1896 o
1896 o
1897 |
1897 |
1898 o
1898 o
1899
1899
1900 o
1900 o
1901 |\
1901 |\
1902 | o
1902 | o
1903 | |
1903 | |
1904 o |
1904 o |
1905 |/
1905 |/
1906 o
1906 o
1907 |
1907 |
1908 o
1908 o
1909 |
1909 |
1910 o
1910 o
1911 |
1911 |
1912 o line 1
1912 o line 1
1913 line 2
1913 line 2
1914
1915 Test bad template with better error message
1916
1917 $ hg log -Gv -R a --template '{desc|user()}'
1918 hg: parse error: expected a symbol, got 'func'
1919 [255]
General Comments 0
You need to be logged in to leave comments. Login now