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