##// END OF EJS Templates
templater: fix pad() to evaluate int argument and handle error
Yuya Nishihara -
r28345:d81437c9 default
parent child Browse files
Show More
@@ -1,997 +1,999 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 __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import os
10 import os
11 import re
11 import re
12 import types
12 import types
13
13
14 from .i18n import _
14 from .i18n import _
15 from . import (
15 from . import (
16 config,
16 config,
17 error,
17 error,
18 minirst,
18 minirst,
19 parser,
19 parser,
20 revset as revsetmod,
20 revset as revsetmod,
21 templatefilters,
21 templatefilters,
22 templatekw,
22 templatekw,
23 util,
23 util,
24 )
24 )
25
25
26 # template parsing
26 # template parsing
27
27
28 elements = {
28 elements = {
29 # token-type: binding-strength, primary, prefix, infix, suffix
29 # token-type: binding-strength, primary, prefix, infix, suffix
30 "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None),
30 "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None),
31 ",": (2, None, None, ("list", 2), None),
31 ",": (2, None, None, ("list", 2), None),
32 "|": (5, None, None, ("|", 5), None),
32 "|": (5, None, None, ("|", 5), None),
33 "%": (6, None, None, ("%", 6), None),
33 "%": (6, None, None, ("%", 6), None),
34 ")": (0, None, None, None, None),
34 ")": (0, None, None, None, None),
35 "integer": (0, "integer", None, None, None),
35 "integer": (0, "integer", None, None, None),
36 "symbol": (0, "symbol", None, None, None),
36 "symbol": (0, "symbol", None, None, None),
37 "string": (0, "string", None, None, None),
37 "string": (0, "string", None, None, None),
38 "template": (0, "template", None, None, None),
38 "template": (0, "template", None, None, None),
39 "end": (0, None, None, None, None),
39 "end": (0, None, None, None, None),
40 }
40 }
41
41
42 def tokenize(program, start, end):
42 def tokenize(program, start, end):
43 pos = start
43 pos = start
44 while pos < end:
44 while pos < end:
45 c = program[pos]
45 c = program[pos]
46 if c.isspace(): # skip inter-token whitespace
46 if c.isspace(): # skip inter-token whitespace
47 pass
47 pass
48 elif c in "(,)%|": # handle simple operators
48 elif c in "(,)%|": # handle simple operators
49 yield (c, None, pos)
49 yield (c, None, pos)
50 elif c in '"\'': # handle quoted templates
50 elif c in '"\'': # handle quoted templates
51 s = pos + 1
51 s = pos + 1
52 data, pos = _parsetemplate(program, s, end, c)
52 data, pos = _parsetemplate(program, s, end, c)
53 yield ('template', data, s)
53 yield ('template', data, s)
54 pos -= 1
54 pos -= 1
55 elif c == 'r' and program[pos:pos + 2] in ("r'", 'r"'):
55 elif c == 'r' and program[pos:pos + 2] in ("r'", 'r"'):
56 # handle quoted strings
56 # handle quoted strings
57 c = program[pos + 1]
57 c = program[pos + 1]
58 s = pos = pos + 2
58 s = pos = pos + 2
59 while pos < end: # find closing quote
59 while pos < end: # find closing quote
60 d = program[pos]
60 d = program[pos]
61 if d == '\\': # skip over escaped characters
61 if d == '\\': # skip over escaped characters
62 pos += 2
62 pos += 2
63 continue
63 continue
64 if d == c:
64 if d == c:
65 yield ('string', program[s:pos], s)
65 yield ('string', program[s:pos], s)
66 break
66 break
67 pos += 1
67 pos += 1
68 else:
68 else:
69 raise error.ParseError(_("unterminated string"), s)
69 raise error.ParseError(_("unterminated string"), s)
70 elif c.isdigit() or c == '-':
70 elif c.isdigit() or c == '-':
71 s = pos
71 s = pos
72 if c == '-': # simply take negate operator as part of integer
72 if c == '-': # simply take negate operator as part of integer
73 pos += 1
73 pos += 1
74 if pos >= end or not program[pos].isdigit():
74 if pos >= end or not program[pos].isdigit():
75 raise error.ParseError(_("integer literal without digits"), s)
75 raise error.ParseError(_("integer literal without digits"), s)
76 pos += 1
76 pos += 1
77 while pos < end:
77 while pos < end:
78 d = program[pos]
78 d = program[pos]
79 if not d.isdigit():
79 if not d.isdigit():
80 break
80 break
81 pos += 1
81 pos += 1
82 yield ('integer', program[s:pos], s)
82 yield ('integer', program[s:pos], s)
83 pos -= 1
83 pos -= 1
84 elif (c == '\\' and program[pos:pos + 2] in (r"\'", r'\"')
84 elif (c == '\\' and program[pos:pos + 2] in (r"\'", r'\"')
85 or c == 'r' and program[pos:pos + 3] in (r"r\'", r'r\"')):
85 or c == 'r' and program[pos:pos + 3] in (r"r\'", r'r\"')):
86 # handle escaped quoted strings for compatibility with 2.9.2-3.4,
86 # handle escaped quoted strings for compatibility with 2.9.2-3.4,
87 # where some of nested templates were preprocessed as strings and
87 # where some of nested templates were preprocessed as strings and
88 # then compiled. therefore, \"...\" was allowed. (issue4733)
88 # then compiled. therefore, \"...\" was allowed. (issue4733)
89 #
89 #
90 # processing flow of _evalifliteral() at 5ab28a2e9962:
90 # processing flow of _evalifliteral() at 5ab28a2e9962:
91 # outer template string -> stringify() -> compiletemplate()
91 # outer template string -> stringify() -> compiletemplate()
92 # ------------------------ ------------ ------------------
92 # ------------------------ ------------ ------------------
93 # {f("\\\\ {g(\"\\\"\")}"} \\ {g("\"")} [r'\\', {g("\"")}]
93 # {f("\\\\ {g(\"\\\"\")}"} \\ {g("\"")} [r'\\', {g("\"")}]
94 # ~~~~~~~~
94 # ~~~~~~~~
95 # escaped quoted string
95 # escaped quoted string
96 if c == 'r':
96 if c == 'r':
97 pos += 1
97 pos += 1
98 token = 'string'
98 token = 'string'
99 else:
99 else:
100 token = 'template'
100 token = 'template'
101 quote = program[pos:pos + 2]
101 quote = program[pos:pos + 2]
102 s = pos = pos + 2
102 s = pos = pos + 2
103 while pos < end: # find closing escaped quote
103 while pos < end: # find closing escaped quote
104 if program.startswith('\\\\\\', pos, end):
104 if program.startswith('\\\\\\', pos, end):
105 pos += 4 # skip over double escaped characters
105 pos += 4 # skip over double escaped characters
106 continue
106 continue
107 if program.startswith(quote, pos, end):
107 if program.startswith(quote, pos, end):
108 # interpret as if it were a part of an outer string
108 # interpret as if it were a part of an outer string
109 data = parser.unescapestr(program[s:pos])
109 data = parser.unescapestr(program[s:pos])
110 if token == 'template':
110 if token == 'template':
111 data = _parsetemplate(data, 0, len(data))[0]
111 data = _parsetemplate(data, 0, len(data))[0]
112 yield (token, data, s)
112 yield (token, data, s)
113 pos += 1
113 pos += 1
114 break
114 break
115 pos += 1
115 pos += 1
116 else:
116 else:
117 raise error.ParseError(_("unterminated string"), s)
117 raise error.ParseError(_("unterminated string"), s)
118 elif c.isalnum() or c in '_':
118 elif c.isalnum() or c in '_':
119 s = pos
119 s = pos
120 pos += 1
120 pos += 1
121 while pos < end: # find end of symbol
121 while pos < end: # find end of symbol
122 d = program[pos]
122 d = program[pos]
123 if not (d.isalnum() or d == "_"):
123 if not (d.isalnum() or d == "_"):
124 break
124 break
125 pos += 1
125 pos += 1
126 sym = program[s:pos]
126 sym = program[s:pos]
127 yield ('symbol', sym, s)
127 yield ('symbol', sym, s)
128 pos -= 1
128 pos -= 1
129 elif c == '}':
129 elif c == '}':
130 yield ('end', None, pos + 1)
130 yield ('end', None, pos + 1)
131 return
131 return
132 else:
132 else:
133 raise error.ParseError(_("syntax error"), pos)
133 raise error.ParseError(_("syntax error"), pos)
134 pos += 1
134 pos += 1
135 raise error.ParseError(_("unterminated template expansion"), start)
135 raise error.ParseError(_("unterminated template expansion"), start)
136
136
137 def _parsetemplate(tmpl, start, stop, quote=''):
137 def _parsetemplate(tmpl, start, stop, quote=''):
138 r"""
138 r"""
139 >>> _parsetemplate('foo{bar}"baz', 0, 12)
139 >>> _parsetemplate('foo{bar}"baz', 0, 12)
140 ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12)
140 ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12)
141 >>> _parsetemplate('foo{bar}"baz', 0, 12, quote='"')
141 >>> _parsetemplate('foo{bar}"baz', 0, 12, quote='"')
142 ([('string', 'foo'), ('symbol', 'bar')], 9)
142 ([('string', 'foo'), ('symbol', 'bar')], 9)
143 >>> _parsetemplate('foo"{bar}', 0, 9, quote='"')
143 >>> _parsetemplate('foo"{bar}', 0, 9, quote='"')
144 ([('string', 'foo')], 4)
144 ([('string', 'foo')], 4)
145 >>> _parsetemplate(r'foo\"bar"baz', 0, 12, quote='"')
145 >>> _parsetemplate(r'foo\"bar"baz', 0, 12, quote='"')
146 ([('string', 'foo"'), ('string', 'bar')], 9)
146 ([('string', 'foo"'), ('string', 'bar')], 9)
147 >>> _parsetemplate(r'foo\\"bar', 0, 10, quote='"')
147 >>> _parsetemplate(r'foo\\"bar', 0, 10, quote='"')
148 ([('string', 'foo\\')], 6)
148 ([('string', 'foo\\')], 6)
149 """
149 """
150 parsed = []
150 parsed = []
151 sepchars = '{' + quote
151 sepchars = '{' + quote
152 pos = start
152 pos = start
153 p = parser.parser(elements)
153 p = parser.parser(elements)
154 while pos < stop:
154 while pos < stop:
155 n = min((tmpl.find(c, pos, stop) for c in sepchars),
155 n = min((tmpl.find(c, pos, stop) for c in sepchars),
156 key=lambda n: (n < 0, n))
156 key=lambda n: (n < 0, n))
157 if n < 0:
157 if n < 0:
158 parsed.append(('string', parser.unescapestr(tmpl[pos:stop])))
158 parsed.append(('string', parser.unescapestr(tmpl[pos:stop])))
159 pos = stop
159 pos = stop
160 break
160 break
161 c = tmpl[n]
161 c = tmpl[n]
162 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
162 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
163 if bs % 2 == 1:
163 if bs % 2 == 1:
164 # escaped (e.g. '\{', '\\\{', but not '\\{')
164 # escaped (e.g. '\{', '\\\{', but not '\\{')
165 parsed.append(('string', parser.unescapestr(tmpl[pos:n - 1]) + c))
165 parsed.append(('string', parser.unescapestr(tmpl[pos:n - 1]) + c))
166 pos = n + 1
166 pos = n + 1
167 continue
167 continue
168 if n > pos:
168 if n > pos:
169 parsed.append(('string', parser.unescapestr(tmpl[pos:n])))
169 parsed.append(('string', parser.unescapestr(tmpl[pos:n])))
170 if c == quote:
170 if c == quote:
171 return parsed, n + 1
171 return parsed, n + 1
172
172
173 parseres, pos = p.parse(tokenize(tmpl, n + 1, stop))
173 parseres, pos = p.parse(tokenize(tmpl, n + 1, stop))
174 parsed.append(parseres)
174 parsed.append(parseres)
175
175
176 if quote:
176 if quote:
177 raise error.ParseError(_("unterminated string"), start)
177 raise error.ParseError(_("unterminated string"), start)
178 return parsed, pos
178 return parsed, pos
179
179
180 def compiletemplate(tmpl, context):
180 def compiletemplate(tmpl, context):
181 parsed, pos = _parsetemplate(tmpl, 0, len(tmpl))
181 parsed, pos = _parsetemplate(tmpl, 0, len(tmpl))
182 return [compileexp(e, context, methods) for e in parsed]
182 return [compileexp(e, context, methods) for e in parsed]
183
183
184 def compileexp(exp, context, curmethods):
184 def compileexp(exp, context, curmethods):
185 t = exp[0]
185 t = exp[0]
186 if t in curmethods:
186 if t in curmethods:
187 return curmethods[t](exp, context)
187 return curmethods[t](exp, context)
188 raise error.ParseError(_("unknown method '%s'") % t)
188 raise error.ParseError(_("unknown method '%s'") % t)
189
189
190 # template evaluation
190 # template evaluation
191
191
192 def getsymbol(exp):
192 def getsymbol(exp):
193 if exp[0] == 'symbol':
193 if exp[0] == 'symbol':
194 return exp[1]
194 return exp[1]
195 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
195 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
196
196
197 def getlist(x):
197 def getlist(x):
198 if not x:
198 if not x:
199 return []
199 return []
200 if x[0] == 'list':
200 if x[0] == 'list':
201 return getlist(x[1]) + [x[2]]
201 return getlist(x[1]) + [x[2]]
202 return [x]
202 return [x]
203
203
204 def gettemplate(exp, context):
204 def gettemplate(exp, context):
205 if exp[0] == 'template':
205 if exp[0] == 'template':
206 return [compileexp(e, context, methods) for e in exp[1]]
206 return [compileexp(e, context, methods) for e in exp[1]]
207 if exp[0] == 'symbol':
207 if exp[0] == 'symbol':
208 # unlike runsymbol(), here 'symbol' is always taken as template name
208 # unlike runsymbol(), here 'symbol' is always taken as template name
209 # even if it exists in mapping. this allows us to override mapping
209 # even if it exists in mapping. this allows us to override mapping
210 # by web templates, e.g. 'changelogtag' is redefined in map file.
210 # by web templates, e.g. 'changelogtag' is redefined in map file.
211 return context._load(exp[1])
211 return context._load(exp[1])
212 raise error.ParseError(_("expected template specifier"))
212 raise error.ParseError(_("expected template specifier"))
213
213
214 def evalfuncarg(context, mapping, arg):
214 def evalfuncarg(context, mapping, arg):
215 func, data = arg
215 func, data = arg
216 # func() may return string, generator of strings or arbitrary object such
216 # func() may return string, generator of strings or arbitrary object such
217 # as date tuple, but filter does not want generator.
217 # as date tuple, but filter does not want generator.
218 thing = func(context, mapping, data)
218 thing = func(context, mapping, data)
219 if isinstance(thing, types.GeneratorType):
219 if isinstance(thing, types.GeneratorType):
220 thing = stringify(thing)
220 thing = stringify(thing)
221 return thing
221 return thing
222
222
223 def evalinteger(context, mapping, arg, err):
223 def evalinteger(context, mapping, arg, err):
224 v = evalfuncarg(context, mapping, arg)
224 v = evalfuncarg(context, mapping, arg)
225 try:
225 try:
226 return int(v)
226 return int(v)
227 except (TypeError, ValueError):
227 except (TypeError, ValueError):
228 raise error.ParseError(err)
228 raise error.ParseError(err)
229
229
230 def runinteger(context, mapping, data):
230 def runinteger(context, mapping, data):
231 return int(data)
231 return int(data)
232
232
233 def runstring(context, mapping, data):
233 def runstring(context, mapping, data):
234 return data
234 return data
235
235
236 def _recursivesymbolblocker(key):
236 def _recursivesymbolblocker(key):
237 def showrecursion(**args):
237 def showrecursion(**args):
238 raise error.Abort(_("recursive reference '%s' in template") % key)
238 raise error.Abort(_("recursive reference '%s' in template") % key)
239 return showrecursion
239 return showrecursion
240
240
241 def _runrecursivesymbol(context, mapping, key):
241 def _runrecursivesymbol(context, mapping, key):
242 raise error.Abort(_("recursive reference '%s' in template") % key)
242 raise error.Abort(_("recursive reference '%s' in template") % key)
243
243
244 def runsymbol(context, mapping, key):
244 def runsymbol(context, mapping, key):
245 v = mapping.get(key)
245 v = mapping.get(key)
246 if v is None:
246 if v is None:
247 v = context._defaults.get(key)
247 v = context._defaults.get(key)
248 if v is None:
248 if v is None:
249 # put poison to cut recursion. we can't move this to parsing phase
249 # put poison to cut recursion. we can't move this to parsing phase
250 # because "x = {x}" is allowed if "x" is a keyword. (issue4758)
250 # because "x = {x}" is allowed if "x" is a keyword. (issue4758)
251 safemapping = mapping.copy()
251 safemapping = mapping.copy()
252 safemapping[key] = _recursivesymbolblocker(key)
252 safemapping[key] = _recursivesymbolblocker(key)
253 try:
253 try:
254 v = context.process(key, safemapping)
254 v = context.process(key, safemapping)
255 except TemplateNotFound:
255 except TemplateNotFound:
256 v = ''
256 v = ''
257 if callable(v):
257 if callable(v):
258 return v(**mapping)
258 return v(**mapping)
259 return v
259 return v
260
260
261 def buildtemplate(exp, context):
261 def buildtemplate(exp, context):
262 ctmpl = [compileexp(e, context, methods) for e in exp[1]]
262 ctmpl = [compileexp(e, context, methods) for e in exp[1]]
263 if len(ctmpl) == 1:
263 if len(ctmpl) == 1:
264 return ctmpl[0] # fast path for string with no template fragment
264 return ctmpl[0] # fast path for string with no template fragment
265 return (runtemplate, ctmpl)
265 return (runtemplate, ctmpl)
266
266
267 def runtemplate(context, mapping, template):
267 def runtemplate(context, mapping, template):
268 for func, data in template:
268 for func, data in template:
269 yield func(context, mapping, data)
269 yield func(context, mapping, data)
270
270
271 def buildfilter(exp, context):
271 def buildfilter(exp, context):
272 arg = compileexp(exp[1], context, methods)
272 arg = compileexp(exp[1], context, methods)
273 n = getsymbol(exp[2])
273 n = getsymbol(exp[2])
274 if n in context._filters:
274 if n in context._filters:
275 filt = context._filters[n]
275 filt = context._filters[n]
276 return (runfilter, (arg, filt))
276 return (runfilter, (arg, filt))
277 if n in funcs:
277 if n in funcs:
278 f = funcs[n]
278 f = funcs[n]
279 return (f, [arg])
279 return (f, [arg])
280 raise error.ParseError(_("unknown function '%s'") % n)
280 raise error.ParseError(_("unknown function '%s'") % n)
281
281
282 def runfilter(context, mapping, data):
282 def runfilter(context, mapping, data):
283 arg, filt = data
283 arg, filt = data
284 thing = evalfuncarg(context, mapping, arg)
284 thing = evalfuncarg(context, mapping, arg)
285 try:
285 try:
286 return filt(thing)
286 return filt(thing)
287 except (ValueError, AttributeError, TypeError):
287 except (ValueError, AttributeError, TypeError):
288 if isinstance(arg[1], tuple):
288 if isinstance(arg[1], tuple):
289 dt = arg[1][1]
289 dt = arg[1][1]
290 else:
290 else:
291 dt = arg[1]
291 dt = arg[1]
292 raise error.Abort(_("template filter '%s' is not compatible with "
292 raise error.Abort(_("template filter '%s' is not compatible with "
293 "keyword '%s'") % (filt.func_name, dt))
293 "keyword '%s'") % (filt.func_name, dt))
294
294
295 def buildmap(exp, context):
295 def buildmap(exp, context):
296 func, data = compileexp(exp[1], context, methods)
296 func, data = compileexp(exp[1], context, methods)
297 ctmpl = gettemplate(exp[2], context)
297 ctmpl = gettemplate(exp[2], context)
298 return (runmap, (func, data, ctmpl))
298 return (runmap, (func, data, ctmpl))
299
299
300 def runmap(context, mapping, data):
300 def runmap(context, mapping, data):
301 func, data, ctmpl = data
301 func, data, ctmpl = data
302 d = func(context, mapping, data)
302 d = func(context, mapping, data)
303 if util.safehasattr(d, 'itermaps'):
303 if util.safehasattr(d, 'itermaps'):
304 d = d.itermaps()
304 d = d.itermaps()
305
305
306 for i in d:
306 for i in d:
307 lm = mapping.copy()
307 lm = mapping.copy()
308 if isinstance(i, dict):
308 if isinstance(i, dict):
309 lm.update(i)
309 lm.update(i)
310 lm['originalnode'] = mapping.get('node')
310 lm['originalnode'] = mapping.get('node')
311 yield runtemplate(context, lm, ctmpl)
311 yield runtemplate(context, lm, ctmpl)
312 else:
312 else:
313 # v is not an iterable of dicts, this happen when 'key'
313 # v is not an iterable of dicts, this happen when 'key'
314 # has been fully expanded already and format is useless.
314 # has been fully expanded already and format is useless.
315 # If so, return the expanded value.
315 # If so, return the expanded value.
316 yield i
316 yield i
317
317
318 def buildfunc(exp, context):
318 def buildfunc(exp, context):
319 n = getsymbol(exp[1])
319 n = getsymbol(exp[1])
320 args = [compileexp(x, context, exprmethods) for x in getlist(exp[2])]
320 args = [compileexp(x, context, exprmethods) for x in getlist(exp[2])]
321 if n in funcs:
321 if n in funcs:
322 f = funcs[n]
322 f = funcs[n]
323 return (f, args)
323 return (f, args)
324 if n in context._filters:
324 if n in context._filters:
325 if len(args) != 1:
325 if len(args) != 1:
326 raise error.ParseError(_("filter %s expects one argument") % n)
326 raise error.ParseError(_("filter %s expects one argument") % n)
327 f = context._filters[n]
327 f = context._filters[n]
328 return (runfilter, (args[0], f))
328 return (runfilter, (args[0], f))
329 raise error.ParseError(_("unknown function '%s'") % n)
329 raise error.ParseError(_("unknown function '%s'") % n)
330
330
331 def date(context, mapping, args):
331 def date(context, mapping, args):
332 """:date(date[, fmt]): Format a date. See :hg:`help dates` for formatting
332 """:date(date[, fmt]): Format a date. See :hg:`help dates` for formatting
333 strings. The default is a Unix date format, including the timezone:
333 strings. The default is a Unix date format, including the timezone:
334 "Mon Sep 04 15:13:13 2006 0700"."""
334 "Mon Sep 04 15:13:13 2006 0700"."""
335 if not (1 <= len(args) <= 2):
335 if not (1 <= len(args) <= 2):
336 # i18n: "date" is a keyword
336 # i18n: "date" is a keyword
337 raise error.ParseError(_("date expects one or two arguments"))
337 raise error.ParseError(_("date expects one or two arguments"))
338
338
339 date = evalfuncarg(context, mapping, args[0])
339 date = evalfuncarg(context, mapping, args[0])
340 fmt = None
340 fmt = None
341 if len(args) == 2:
341 if len(args) == 2:
342 fmt = stringify(args[1][0](context, mapping, args[1][1]))
342 fmt = stringify(args[1][0](context, mapping, args[1][1]))
343 try:
343 try:
344 if fmt is None:
344 if fmt is None:
345 return util.datestr(date)
345 return util.datestr(date)
346 else:
346 else:
347 return util.datestr(date, fmt)
347 return util.datestr(date, fmt)
348 except (TypeError, ValueError):
348 except (TypeError, ValueError):
349 # i18n: "date" is a keyword
349 # i18n: "date" is a keyword
350 raise error.ParseError(_("date expects a date information"))
350 raise error.ParseError(_("date expects a date information"))
351
351
352 def diff(context, mapping, args):
352 def diff(context, mapping, args):
353 """:diff([includepattern [, excludepattern]]): Show a diff, optionally
353 """:diff([includepattern [, excludepattern]]): Show a diff, optionally
354 specifying files to include or exclude."""
354 specifying files to include or exclude."""
355 if len(args) > 2:
355 if len(args) > 2:
356 # i18n: "diff" is a keyword
356 # i18n: "diff" is a keyword
357 raise error.ParseError(_("diff expects zero, one, or two arguments"))
357 raise error.ParseError(_("diff expects zero, one, or two arguments"))
358
358
359 def getpatterns(i):
359 def getpatterns(i):
360 if i < len(args):
360 if i < len(args):
361 s = stringify(args[i][0](context, mapping, args[i][1])).strip()
361 s = stringify(args[i][0](context, mapping, args[i][1])).strip()
362 if s:
362 if s:
363 return [s]
363 return [s]
364 return []
364 return []
365
365
366 ctx = mapping['ctx']
366 ctx = mapping['ctx']
367 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
367 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
368
368
369 return ''.join(chunks)
369 return ''.join(chunks)
370
370
371 def fill(context, mapping, args):
371 def fill(context, mapping, args):
372 """:fill(text[, width[, initialident[, hangindent]]]): Fill many
372 """:fill(text[, width[, initialident[, hangindent]]]): Fill many
373 paragraphs with optional indentation. See the "fill" filter."""
373 paragraphs with optional indentation. See the "fill" filter."""
374 if not (1 <= len(args) <= 4):
374 if not (1 <= len(args) <= 4):
375 # i18n: "fill" is a keyword
375 # i18n: "fill" is a keyword
376 raise error.ParseError(_("fill expects one to four arguments"))
376 raise error.ParseError(_("fill expects one to four arguments"))
377
377
378 text = stringify(args[0][0](context, mapping, args[0][1]))
378 text = stringify(args[0][0](context, mapping, args[0][1]))
379 width = 76
379 width = 76
380 initindent = ''
380 initindent = ''
381 hangindent = ''
381 hangindent = ''
382 if 2 <= len(args) <= 4:
382 if 2 <= len(args) <= 4:
383 width = evalinteger(context, mapping, args[1],
383 width = evalinteger(context, mapping, args[1],
384 # i18n: "fill" is a keyword
384 # i18n: "fill" is a keyword
385 _("fill expects an integer width"))
385 _("fill expects an integer width"))
386 try:
386 try:
387 initindent = stringify(args[2][0](context, mapping, args[2][1]))
387 initindent = stringify(args[2][0](context, mapping, args[2][1]))
388 hangindent = stringify(args[3][0](context, mapping, args[3][1]))
388 hangindent = stringify(args[3][0](context, mapping, args[3][1]))
389 except IndexError:
389 except IndexError:
390 pass
390 pass
391
391
392 return templatefilters.fill(text, width, initindent, hangindent)
392 return templatefilters.fill(text, width, initindent, hangindent)
393
393
394 def pad(context, mapping, args):
394 def pad(context, mapping, args):
395 """:pad(text, width[, fillchar=' '[, right=False]]): Pad text with a
395 """:pad(text, width[, fillchar=' '[, right=False]]): Pad text with a
396 fill character."""
396 fill character."""
397 if not (2 <= len(args) <= 4):
397 if not (2 <= len(args) <= 4):
398 # i18n: "pad" is a keyword
398 # i18n: "pad" is a keyword
399 raise error.ParseError(_("pad() expects two to four arguments"))
399 raise error.ParseError(_("pad() expects two to four arguments"))
400
400
401 width = int(args[1][1])
401 width = evalinteger(context, mapping, args[1],
402 # i18n: "pad" is a keyword
403 _("pad() expects an integer width"))
402
404
403 text = stringify(args[0][0](context, mapping, args[0][1]))
405 text = stringify(args[0][0](context, mapping, args[0][1]))
404
406
405 right = False
407 right = False
406 fillchar = ' '
408 fillchar = ' '
407 if len(args) > 2:
409 if len(args) > 2:
408 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
410 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
409 if len(args) > 3:
411 if len(args) > 3:
410 right = util.parsebool(args[3][1])
412 right = util.parsebool(args[3][1])
411
413
412 if right:
414 if right:
413 return text.rjust(width, fillchar)
415 return text.rjust(width, fillchar)
414 else:
416 else:
415 return text.ljust(width, fillchar)
417 return text.ljust(width, fillchar)
416
418
417 def indent(context, mapping, args):
419 def indent(context, mapping, args):
418 """:indent(text, indentchars[, firstline]): Indents all non-empty lines
420 """:indent(text, indentchars[, firstline]): Indents all non-empty lines
419 with the characters given in the indentchars string. An optional
421 with the characters given in the indentchars string. An optional
420 third parameter will override the indent for the first line only
422 third parameter will override the indent for the first line only
421 if present."""
423 if present."""
422 if not (2 <= len(args) <= 3):
424 if not (2 <= len(args) <= 3):
423 # i18n: "indent" is a keyword
425 # i18n: "indent" is a keyword
424 raise error.ParseError(_("indent() expects two or three arguments"))
426 raise error.ParseError(_("indent() expects two or three arguments"))
425
427
426 text = stringify(args[0][0](context, mapping, args[0][1]))
428 text = stringify(args[0][0](context, mapping, args[0][1]))
427 indent = stringify(args[1][0](context, mapping, args[1][1]))
429 indent = stringify(args[1][0](context, mapping, args[1][1]))
428
430
429 if len(args) == 3:
431 if len(args) == 3:
430 firstline = stringify(args[2][0](context, mapping, args[2][1]))
432 firstline = stringify(args[2][0](context, mapping, args[2][1]))
431 else:
433 else:
432 firstline = indent
434 firstline = indent
433
435
434 # the indent function doesn't indent the first line, so we do it here
436 # the indent function doesn't indent the first line, so we do it here
435 return templatefilters.indent(firstline + text, indent)
437 return templatefilters.indent(firstline + text, indent)
436
438
437 def get(context, mapping, args):
439 def get(context, mapping, args):
438 """:get(dict, key): Get an attribute/key from an object. Some keywords
440 """:get(dict, key): Get an attribute/key from an object. Some keywords
439 are complex types. This function allows you to obtain the value of an
441 are complex types. This function allows you to obtain the value of an
440 attribute on these types."""
442 attribute on these types."""
441 if len(args) != 2:
443 if len(args) != 2:
442 # i18n: "get" is a keyword
444 # i18n: "get" is a keyword
443 raise error.ParseError(_("get() expects two arguments"))
445 raise error.ParseError(_("get() expects two arguments"))
444
446
445 dictarg = evalfuncarg(context, mapping, args[0])
447 dictarg = evalfuncarg(context, mapping, args[0])
446 if not util.safehasattr(dictarg, 'get'):
448 if not util.safehasattr(dictarg, 'get'):
447 # i18n: "get" is a keyword
449 # i18n: "get" is a keyword
448 raise error.ParseError(_("get() expects a dict as first argument"))
450 raise error.ParseError(_("get() expects a dict as first argument"))
449
451
450 key = evalfuncarg(context, mapping, args[1])
452 key = evalfuncarg(context, mapping, args[1])
451 return dictarg.get(key)
453 return dictarg.get(key)
452
454
453 def if_(context, mapping, args):
455 def if_(context, mapping, args):
454 """:if(expr, then[, else]): Conditionally execute based on the result of
456 """:if(expr, then[, else]): Conditionally execute based on the result of
455 an expression."""
457 an expression."""
456 if not (2 <= len(args) <= 3):
458 if not (2 <= len(args) <= 3):
457 # i18n: "if" is a keyword
459 # i18n: "if" is a keyword
458 raise error.ParseError(_("if expects two or three arguments"))
460 raise error.ParseError(_("if expects two or three arguments"))
459
461
460 test = stringify(args[0][0](context, mapping, args[0][1]))
462 test = stringify(args[0][0](context, mapping, args[0][1]))
461 if test:
463 if test:
462 yield args[1][0](context, mapping, args[1][1])
464 yield args[1][0](context, mapping, args[1][1])
463 elif len(args) == 3:
465 elif len(args) == 3:
464 yield args[2][0](context, mapping, args[2][1])
466 yield args[2][0](context, mapping, args[2][1])
465
467
466 def ifcontains(context, mapping, args):
468 def ifcontains(context, mapping, args):
467 """:ifcontains(search, thing, then[, else]): Conditionally execute based
469 """:ifcontains(search, thing, then[, else]): Conditionally execute based
468 on whether the item "search" is in "thing"."""
470 on whether the item "search" is in "thing"."""
469 if not (3 <= len(args) <= 4):
471 if not (3 <= len(args) <= 4):
470 # i18n: "ifcontains" is a keyword
472 # i18n: "ifcontains" is a keyword
471 raise error.ParseError(_("ifcontains expects three or four arguments"))
473 raise error.ParseError(_("ifcontains expects three or four arguments"))
472
474
473 item = stringify(args[0][0](context, mapping, args[0][1]))
475 item = stringify(args[0][0](context, mapping, args[0][1]))
474 items = evalfuncarg(context, mapping, args[1])
476 items = evalfuncarg(context, mapping, args[1])
475
477
476 if item in items:
478 if item in items:
477 yield args[2][0](context, mapping, args[2][1])
479 yield args[2][0](context, mapping, args[2][1])
478 elif len(args) == 4:
480 elif len(args) == 4:
479 yield args[3][0](context, mapping, args[3][1])
481 yield args[3][0](context, mapping, args[3][1])
480
482
481 def ifeq(context, mapping, args):
483 def ifeq(context, mapping, args):
482 """:ifeq(expr1, expr2, then[, else]): Conditionally execute based on
484 """:ifeq(expr1, expr2, then[, else]): Conditionally execute based on
483 whether 2 items are equivalent."""
485 whether 2 items are equivalent."""
484 if not (3 <= len(args) <= 4):
486 if not (3 <= len(args) <= 4):
485 # i18n: "ifeq" is a keyword
487 # i18n: "ifeq" is a keyword
486 raise error.ParseError(_("ifeq expects three or four arguments"))
488 raise error.ParseError(_("ifeq expects three or four arguments"))
487
489
488 test = stringify(args[0][0](context, mapping, args[0][1]))
490 test = stringify(args[0][0](context, mapping, args[0][1]))
489 match = stringify(args[1][0](context, mapping, args[1][1]))
491 match = stringify(args[1][0](context, mapping, args[1][1]))
490 if test == match:
492 if test == match:
491 yield args[2][0](context, mapping, args[2][1])
493 yield args[2][0](context, mapping, args[2][1])
492 elif len(args) == 4:
494 elif len(args) == 4:
493 yield args[3][0](context, mapping, args[3][1])
495 yield args[3][0](context, mapping, args[3][1])
494
496
495 def join(context, mapping, args):
497 def join(context, mapping, args):
496 """:join(list, sep): Join items in a list with a delimiter."""
498 """:join(list, sep): Join items in a list with a delimiter."""
497 if not (1 <= len(args) <= 2):
499 if not (1 <= len(args) <= 2):
498 # i18n: "join" is a keyword
500 # i18n: "join" is a keyword
499 raise error.ParseError(_("join expects one or two arguments"))
501 raise error.ParseError(_("join expects one or two arguments"))
500
502
501 joinset = args[0][0](context, mapping, args[0][1])
503 joinset = args[0][0](context, mapping, args[0][1])
502 if util.safehasattr(joinset, 'itermaps'):
504 if util.safehasattr(joinset, 'itermaps'):
503 jf = joinset.joinfmt
505 jf = joinset.joinfmt
504 joinset = [jf(x) for x in joinset.itermaps()]
506 joinset = [jf(x) for x in joinset.itermaps()]
505
507
506 joiner = " "
508 joiner = " "
507 if len(args) > 1:
509 if len(args) > 1:
508 joiner = stringify(args[1][0](context, mapping, args[1][1]))
510 joiner = stringify(args[1][0](context, mapping, args[1][1]))
509
511
510 first = True
512 first = True
511 for x in joinset:
513 for x in joinset:
512 if first:
514 if first:
513 first = False
515 first = False
514 else:
516 else:
515 yield joiner
517 yield joiner
516 yield x
518 yield x
517
519
518 def label(context, mapping, args):
520 def label(context, mapping, args):
519 """:label(label, expr): Apply a label to generated content. Content with
521 """:label(label, expr): Apply a label to generated content. Content with
520 a label applied can result in additional post-processing, such as
522 a label applied can result in additional post-processing, such as
521 automatic colorization."""
523 automatic colorization."""
522 if len(args) != 2:
524 if len(args) != 2:
523 # i18n: "label" is a keyword
525 # i18n: "label" is a keyword
524 raise error.ParseError(_("label expects two arguments"))
526 raise error.ParseError(_("label expects two arguments"))
525
527
526 # ignore args[0] (the label string) since this is supposed to be a a no-op
528 # ignore args[0] (the label string) since this is supposed to be a a no-op
527 yield args[1][0](context, mapping, args[1][1])
529 yield args[1][0](context, mapping, args[1][1])
528
530
529 def latesttag(context, mapping, args):
531 def latesttag(context, mapping, args):
530 """:latesttag([pattern]): The global tags matching the given pattern on the
532 """:latesttag([pattern]): The global tags matching the given pattern on the
531 most recent globally tagged ancestor of this changeset."""
533 most recent globally tagged ancestor of this changeset."""
532 if len(args) > 1:
534 if len(args) > 1:
533 # i18n: "latesttag" is a keyword
535 # i18n: "latesttag" is a keyword
534 raise error.ParseError(_("latesttag expects at most one argument"))
536 raise error.ParseError(_("latesttag expects at most one argument"))
535
537
536 pattern = None
538 pattern = None
537 if len(args) == 1:
539 if len(args) == 1:
538 pattern = stringify(args[0][0](context, mapping, args[0][1]))
540 pattern = stringify(args[0][0](context, mapping, args[0][1]))
539
541
540 return templatekw.showlatesttags(pattern, **mapping)
542 return templatekw.showlatesttags(pattern, **mapping)
541
543
542 def localdate(context, mapping, args):
544 def localdate(context, mapping, args):
543 """:localdate(date[, tz]): Converts a date to the specified timezone.
545 """:localdate(date[, tz]): Converts a date to the specified timezone.
544 The default is local date."""
546 The default is local date."""
545 if not (1 <= len(args) <= 2):
547 if not (1 <= len(args) <= 2):
546 # i18n: "localdate" is a keyword
548 # i18n: "localdate" is a keyword
547 raise error.ParseError(_("localdate expects one or two arguments"))
549 raise error.ParseError(_("localdate expects one or two arguments"))
548
550
549 date = evalfuncarg(context, mapping, args[0])
551 date = evalfuncarg(context, mapping, args[0])
550 try:
552 try:
551 date = util.parsedate(date)
553 date = util.parsedate(date)
552 except AttributeError: # not str nor date tuple
554 except AttributeError: # not str nor date tuple
553 # i18n: "localdate" is a keyword
555 # i18n: "localdate" is a keyword
554 raise error.ParseError(_("localdate expects a date information"))
556 raise error.ParseError(_("localdate expects a date information"))
555 if len(args) >= 2:
557 if len(args) >= 2:
556 tzoffset = None
558 tzoffset = None
557 tz = evalfuncarg(context, mapping, args[1])
559 tz = evalfuncarg(context, mapping, args[1])
558 if isinstance(tz, str):
560 if isinstance(tz, str):
559 tzoffset = util.parsetimezone(tz)
561 tzoffset = util.parsetimezone(tz)
560 if tzoffset is None:
562 if tzoffset is None:
561 try:
563 try:
562 tzoffset = int(tz)
564 tzoffset = int(tz)
563 except (TypeError, ValueError):
565 except (TypeError, ValueError):
564 # i18n: "localdate" is a keyword
566 # i18n: "localdate" is a keyword
565 raise error.ParseError(_("localdate expects a timezone"))
567 raise error.ParseError(_("localdate expects a timezone"))
566 else:
568 else:
567 tzoffset = util.makedate()[1]
569 tzoffset = util.makedate()[1]
568 return (date[0], tzoffset)
570 return (date[0], tzoffset)
569
571
570 def revset(context, mapping, args):
572 def revset(context, mapping, args):
571 """:revset(query[, formatargs...]): Execute a revision set query. See
573 """:revset(query[, formatargs...]): Execute a revision set query. See
572 :hg:`help revset`."""
574 :hg:`help revset`."""
573 if not len(args) > 0:
575 if not len(args) > 0:
574 # i18n: "revset" is a keyword
576 # i18n: "revset" is a keyword
575 raise error.ParseError(_("revset expects one or more arguments"))
577 raise error.ParseError(_("revset expects one or more arguments"))
576
578
577 raw = stringify(args[0][0](context, mapping, args[0][1]))
579 raw = stringify(args[0][0](context, mapping, args[0][1]))
578 ctx = mapping['ctx']
580 ctx = mapping['ctx']
579 repo = ctx.repo()
581 repo = ctx.repo()
580
582
581 def query(expr):
583 def query(expr):
582 m = revsetmod.match(repo.ui, expr)
584 m = revsetmod.match(repo.ui, expr)
583 return m(repo)
585 return m(repo)
584
586
585 if len(args) > 1:
587 if len(args) > 1:
586 formatargs = [evalfuncarg(context, mapping, a) for a in args[1:]]
588 formatargs = [evalfuncarg(context, mapping, a) for a in args[1:]]
587 revs = query(revsetmod.formatspec(raw, *formatargs))
589 revs = query(revsetmod.formatspec(raw, *formatargs))
588 revs = list(revs)
590 revs = list(revs)
589 else:
591 else:
590 revsetcache = mapping['cache'].setdefault("revsetcache", {})
592 revsetcache = mapping['cache'].setdefault("revsetcache", {})
591 if raw in revsetcache:
593 if raw in revsetcache:
592 revs = revsetcache[raw]
594 revs = revsetcache[raw]
593 else:
595 else:
594 revs = query(raw)
596 revs = query(raw)
595 revs = list(revs)
597 revs = list(revs)
596 revsetcache[raw] = revs
598 revsetcache[raw] = revs
597
599
598 return templatekw.showrevslist("revision", revs, **mapping)
600 return templatekw.showrevslist("revision", revs, **mapping)
599
601
600 def rstdoc(context, mapping, args):
602 def rstdoc(context, mapping, args):
601 """:rstdoc(text, style): Format ReStructuredText."""
603 """:rstdoc(text, style): Format ReStructuredText."""
602 if len(args) != 2:
604 if len(args) != 2:
603 # i18n: "rstdoc" is a keyword
605 # i18n: "rstdoc" is a keyword
604 raise error.ParseError(_("rstdoc expects two arguments"))
606 raise error.ParseError(_("rstdoc expects two arguments"))
605
607
606 text = stringify(args[0][0](context, mapping, args[0][1]))
608 text = stringify(args[0][0](context, mapping, args[0][1]))
607 style = stringify(args[1][0](context, mapping, args[1][1]))
609 style = stringify(args[1][0](context, mapping, args[1][1]))
608
610
609 return minirst.format(text, style=style, keep=['verbose'])
611 return minirst.format(text, style=style, keep=['verbose'])
610
612
611 def shortest(context, mapping, args):
613 def shortest(context, mapping, args):
612 """:shortest(node, minlength=4): Obtain the shortest representation of
614 """:shortest(node, minlength=4): Obtain the shortest representation of
613 a node."""
615 a node."""
614 if not (1 <= len(args) <= 2):
616 if not (1 <= len(args) <= 2):
615 # i18n: "shortest" is a keyword
617 # i18n: "shortest" is a keyword
616 raise error.ParseError(_("shortest() expects one or two arguments"))
618 raise error.ParseError(_("shortest() expects one or two arguments"))
617
619
618 node = stringify(args[0][0](context, mapping, args[0][1]))
620 node = stringify(args[0][0](context, mapping, args[0][1]))
619
621
620 minlength = 4
622 minlength = 4
621 if len(args) > 1:
623 if len(args) > 1:
622 minlength = int(args[1][1])
624 minlength = int(args[1][1])
623
625
624 cl = mapping['ctx']._repo.changelog
626 cl = mapping['ctx']._repo.changelog
625 def isvalid(test):
627 def isvalid(test):
626 try:
628 try:
627 try:
629 try:
628 cl.index.partialmatch(test)
630 cl.index.partialmatch(test)
629 except AttributeError:
631 except AttributeError:
630 # Pure mercurial doesn't support partialmatch on the index.
632 # Pure mercurial doesn't support partialmatch on the index.
631 # Fallback to the slow way.
633 # Fallback to the slow way.
632 if cl._partialmatch(test) is None:
634 if cl._partialmatch(test) is None:
633 return False
635 return False
634
636
635 try:
637 try:
636 i = int(test)
638 i = int(test)
637 # if we are a pure int, then starting with zero will not be
639 # if we are a pure int, then starting with zero will not be
638 # confused as a rev; or, obviously, if the int is larger than
640 # confused as a rev; or, obviously, if the int is larger than
639 # the value of the tip rev
641 # the value of the tip rev
640 if test[0] == '0' or i > len(cl):
642 if test[0] == '0' or i > len(cl):
641 return True
643 return True
642 return False
644 return False
643 except ValueError:
645 except ValueError:
644 return True
646 return True
645 except error.RevlogError:
647 except error.RevlogError:
646 return False
648 return False
647
649
648 shortest = node
650 shortest = node
649 startlength = max(6, minlength)
651 startlength = max(6, minlength)
650 length = startlength
652 length = startlength
651 while True:
653 while True:
652 test = node[:length]
654 test = node[:length]
653 if isvalid(test):
655 if isvalid(test):
654 shortest = test
656 shortest = test
655 if length == minlength or length > startlength:
657 if length == minlength or length > startlength:
656 return shortest
658 return shortest
657 length -= 1
659 length -= 1
658 else:
660 else:
659 length += 1
661 length += 1
660 if len(shortest) <= length:
662 if len(shortest) <= length:
661 return shortest
663 return shortest
662
664
663 def strip(context, mapping, args):
665 def strip(context, mapping, args):
664 """:strip(text[, chars]): Strip characters from a string. By default,
666 """:strip(text[, chars]): Strip characters from a string. By default,
665 strips all leading and trailing whitespace."""
667 strips all leading and trailing whitespace."""
666 if not (1 <= len(args) <= 2):
668 if not (1 <= len(args) <= 2):
667 # i18n: "strip" is a keyword
669 # i18n: "strip" is a keyword
668 raise error.ParseError(_("strip expects one or two arguments"))
670 raise error.ParseError(_("strip expects one or two arguments"))
669
671
670 text = stringify(args[0][0](context, mapping, args[0][1]))
672 text = stringify(args[0][0](context, mapping, args[0][1]))
671 if len(args) == 2:
673 if len(args) == 2:
672 chars = stringify(args[1][0](context, mapping, args[1][1]))
674 chars = stringify(args[1][0](context, mapping, args[1][1]))
673 return text.strip(chars)
675 return text.strip(chars)
674 return text.strip()
676 return text.strip()
675
677
676 def sub(context, mapping, args):
678 def sub(context, mapping, args):
677 """:sub(pattern, replacement, expression): Perform text substitution
679 """:sub(pattern, replacement, expression): Perform text substitution
678 using regular expressions."""
680 using regular expressions."""
679 if len(args) != 3:
681 if len(args) != 3:
680 # i18n: "sub" is a keyword
682 # i18n: "sub" is a keyword
681 raise error.ParseError(_("sub expects three arguments"))
683 raise error.ParseError(_("sub expects three arguments"))
682
684
683 pat = stringify(args[0][0](context, mapping, args[0][1]))
685 pat = stringify(args[0][0](context, mapping, args[0][1]))
684 rpl = stringify(args[1][0](context, mapping, args[1][1]))
686 rpl = stringify(args[1][0](context, mapping, args[1][1]))
685 src = stringify(args[2][0](context, mapping, args[2][1]))
687 src = stringify(args[2][0](context, mapping, args[2][1]))
686 try:
688 try:
687 patre = re.compile(pat)
689 patre = re.compile(pat)
688 except re.error:
690 except re.error:
689 # i18n: "sub" is a keyword
691 # i18n: "sub" is a keyword
690 raise error.ParseError(_("sub got an invalid pattern: %s") % pat)
692 raise error.ParseError(_("sub got an invalid pattern: %s") % pat)
691 try:
693 try:
692 yield patre.sub(rpl, src)
694 yield patre.sub(rpl, src)
693 except re.error:
695 except re.error:
694 # i18n: "sub" is a keyword
696 # i18n: "sub" is a keyword
695 raise error.ParseError(_("sub got an invalid replacement: %s") % rpl)
697 raise error.ParseError(_("sub got an invalid replacement: %s") % rpl)
696
698
697 def startswith(context, mapping, args):
699 def startswith(context, mapping, args):
698 """:startswith(pattern, text): Returns the value from the "text" argument
700 """:startswith(pattern, text): Returns the value from the "text" argument
699 if it begins with the content from the "pattern" argument."""
701 if it begins with the content from the "pattern" argument."""
700 if len(args) != 2:
702 if len(args) != 2:
701 # i18n: "startswith" is a keyword
703 # i18n: "startswith" is a keyword
702 raise error.ParseError(_("startswith expects two arguments"))
704 raise error.ParseError(_("startswith expects two arguments"))
703
705
704 patn = stringify(args[0][0](context, mapping, args[0][1]))
706 patn = stringify(args[0][0](context, mapping, args[0][1]))
705 text = stringify(args[1][0](context, mapping, args[1][1]))
707 text = stringify(args[1][0](context, mapping, args[1][1]))
706 if text.startswith(patn):
708 if text.startswith(patn):
707 return text
709 return text
708 return ''
710 return ''
709
711
710
712
711 def word(context, mapping, args):
713 def word(context, mapping, args):
712 """:word(number, text[, separator]): Return the nth word from a string."""
714 """:word(number, text[, separator]): Return the nth word from a string."""
713 if not (2 <= len(args) <= 3):
715 if not (2 <= len(args) <= 3):
714 # i18n: "word" is a keyword
716 # i18n: "word" is a keyword
715 raise error.ParseError(_("word expects two or three arguments, got %d")
717 raise error.ParseError(_("word expects two or three arguments, got %d")
716 % len(args))
718 % len(args))
717
719
718 num = evalinteger(context, mapping, args[0],
720 num = evalinteger(context, mapping, args[0],
719 # i18n: "word" is a keyword
721 # i18n: "word" is a keyword
720 _("word expects an integer index"))
722 _("word expects an integer index"))
721 text = stringify(args[1][0](context, mapping, args[1][1]))
723 text = stringify(args[1][0](context, mapping, args[1][1]))
722 if len(args) == 3:
724 if len(args) == 3:
723 splitter = stringify(args[2][0](context, mapping, args[2][1]))
725 splitter = stringify(args[2][0](context, mapping, args[2][1]))
724 else:
726 else:
725 splitter = None
727 splitter = None
726
728
727 tokens = text.split(splitter)
729 tokens = text.split(splitter)
728 if num >= len(tokens) or num < -len(tokens):
730 if num >= len(tokens) or num < -len(tokens):
729 return ''
731 return ''
730 else:
732 else:
731 return tokens[num]
733 return tokens[num]
732
734
733 # methods to interpret function arguments or inner expressions (e.g. {_(x)})
735 # methods to interpret function arguments or inner expressions (e.g. {_(x)})
734 exprmethods = {
736 exprmethods = {
735 "integer": lambda e, c: (runinteger, e[1]),
737 "integer": lambda e, c: (runinteger, e[1]),
736 "string": lambda e, c: (runstring, e[1]),
738 "string": lambda e, c: (runstring, e[1]),
737 "symbol": lambda e, c: (runsymbol, e[1]),
739 "symbol": lambda e, c: (runsymbol, e[1]),
738 "template": buildtemplate,
740 "template": buildtemplate,
739 "group": lambda e, c: compileexp(e[1], c, exprmethods),
741 "group": lambda e, c: compileexp(e[1], c, exprmethods),
740 # ".": buildmember,
742 # ".": buildmember,
741 "|": buildfilter,
743 "|": buildfilter,
742 "%": buildmap,
744 "%": buildmap,
743 "func": buildfunc,
745 "func": buildfunc,
744 }
746 }
745
747
746 # methods to interpret top-level template (e.g. {x}, {x|_}, {x % "y"})
748 # methods to interpret top-level template (e.g. {x}, {x|_}, {x % "y"})
747 methods = exprmethods.copy()
749 methods = exprmethods.copy()
748 methods["integer"] = exprmethods["symbol"] # '{1}' as variable
750 methods["integer"] = exprmethods["symbol"] # '{1}' as variable
749
751
750 funcs = {
752 funcs = {
751 "date": date,
753 "date": date,
752 "diff": diff,
754 "diff": diff,
753 "fill": fill,
755 "fill": fill,
754 "get": get,
756 "get": get,
755 "if": if_,
757 "if": if_,
756 "ifcontains": ifcontains,
758 "ifcontains": ifcontains,
757 "ifeq": ifeq,
759 "ifeq": ifeq,
758 "indent": indent,
760 "indent": indent,
759 "join": join,
761 "join": join,
760 "label": label,
762 "label": label,
761 "latesttag": latesttag,
763 "latesttag": latesttag,
762 "localdate": localdate,
764 "localdate": localdate,
763 "pad": pad,
765 "pad": pad,
764 "revset": revset,
766 "revset": revset,
765 "rstdoc": rstdoc,
767 "rstdoc": rstdoc,
766 "shortest": shortest,
768 "shortest": shortest,
767 "startswith": startswith,
769 "startswith": startswith,
768 "strip": strip,
770 "strip": strip,
769 "sub": sub,
771 "sub": sub,
770 "word": word,
772 "word": word,
771 }
773 }
772
774
773 # template engine
775 # template engine
774
776
775 stringify = templatefilters.stringify
777 stringify = templatefilters.stringify
776
778
777 def _flatten(thing):
779 def _flatten(thing):
778 '''yield a single stream from a possibly nested set of iterators'''
780 '''yield a single stream from a possibly nested set of iterators'''
779 if isinstance(thing, str):
781 if isinstance(thing, str):
780 yield thing
782 yield thing
781 elif not util.safehasattr(thing, '__iter__'):
783 elif not util.safehasattr(thing, '__iter__'):
782 if thing is not None:
784 if thing is not None:
783 yield str(thing)
785 yield str(thing)
784 else:
786 else:
785 for i in thing:
787 for i in thing:
786 if isinstance(i, str):
788 if isinstance(i, str):
787 yield i
789 yield i
788 elif not util.safehasattr(i, '__iter__'):
790 elif not util.safehasattr(i, '__iter__'):
789 if i is not None:
791 if i is not None:
790 yield str(i)
792 yield str(i)
791 elif i is not None:
793 elif i is not None:
792 for j in _flatten(i):
794 for j in _flatten(i):
793 yield j
795 yield j
794
796
795 def unquotestring(s):
797 def unquotestring(s):
796 '''unwrap quotes'''
798 '''unwrap quotes'''
797 if len(s) < 2 or s[0] != s[-1]:
799 if len(s) < 2 or s[0] != s[-1]:
798 raise SyntaxError(_('unmatched quotes'))
800 raise SyntaxError(_('unmatched quotes'))
799 return s[1:-1]
801 return s[1:-1]
800
802
801 class engine(object):
803 class engine(object):
802 '''template expansion engine.
804 '''template expansion engine.
803
805
804 template expansion works like this. a map file contains key=value
806 template expansion works like this. a map file contains key=value
805 pairs. if value is quoted, it is treated as string. otherwise, it
807 pairs. if value is quoted, it is treated as string. otherwise, it
806 is treated as name of template file.
808 is treated as name of template file.
807
809
808 templater is asked to expand a key in map. it looks up key, and
810 templater is asked to expand a key in map. it looks up key, and
809 looks for strings like this: {foo}. it expands {foo} by looking up
811 looks for strings like this: {foo}. it expands {foo} by looking up
810 foo in map, and substituting it. expansion is recursive: it stops
812 foo in map, and substituting it. expansion is recursive: it stops
811 when there is no more {foo} to replace.
813 when there is no more {foo} to replace.
812
814
813 expansion also allows formatting and filtering.
815 expansion also allows formatting and filtering.
814
816
815 format uses key to expand each item in list. syntax is
817 format uses key to expand each item in list. syntax is
816 {key%format}.
818 {key%format}.
817
819
818 filter uses function to transform value. syntax is
820 filter uses function to transform value. syntax is
819 {key|filter1|filter2|...}.'''
821 {key|filter1|filter2|...}.'''
820
822
821 def __init__(self, loader, filters=None, defaults=None):
823 def __init__(self, loader, filters=None, defaults=None):
822 self._loader = loader
824 self._loader = loader
823 if filters is None:
825 if filters is None:
824 filters = {}
826 filters = {}
825 self._filters = filters
827 self._filters = filters
826 if defaults is None:
828 if defaults is None:
827 defaults = {}
829 defaults = {}
828 self._defaults = defaults
830 self._defaults = defaults
829 self._cache = {}
831 self._cache = {}
830
832
831 def _load(self, t):
833 def _load(self, t):
832 '''load, parse, and cache a template'''
834 '''load, parse, and cache a template'''
833 if t not in self._cache:
835 if t not in self._cache:
834 # put poison to cut recursion while compiling 't'
836 # put poison to cut recursion while compiling 't'
835 self._cache[t] = [(_runrecursivesymbol, t)]
837 self._cache[t] = [(_runrecursivesymbol, t)]
836 try:
838 try:
837 self._cache[t] = compiletemplate(self._loader(t), self)
839 self._cache[t] = compiletemplate(self._loader(t), self)
838 except: # re-raises
840 except: # re-raises
839 del self._cache[t]
841 del self._cache[t]
840 raise
842 raise
841 return self._cache[t]
843 return self._cache[t]
842
844
843 def process(self, t, mapping):
845 def process(self, t, mapping):
844 '''Perform expansion. t is name of map element to expand.
846 '''Perform expansion. t is name of map element to expand.
845 mapping contains added elements for use during expansion. Is a
847 mapping contains added elements for use during expansion. Is a
846 generator.'''
848 generator.'''
847 return _flatten(runtemplate(self, mapping, self._load(t)))
849 return _flatten(runtemplate(self, mapping, self._load(t)))
848
850
849 engines = {'default': engine}
851 engines = {'default': engine}
850
852
851 def stylelist():
853 def stylelist():
852 paths = templatepaths()
854 paths = templatepaths()
853 if not paths:
855 if not paths:
854 return _('no templates found, try `hg debuginstall` for more info')
856 return _('no templates found, try `hg debuginstall` for more info')
855 dirlist = os.listdir(paths[0])
857 dirlist = os.listdir(paths[0])
856 stylelist = []
858 stylelist = []
857 for file in dirlist:
859 for file in dirlist:
858 split = file.split(".")
860 split = file.split(".")
859 if split[0] == "map-cmdline":
861 if split[0] == "map-cmdline":
860 stylelist.append(split[1])
862 stylelist.append(split[1])
861 return ", ".join(sorted(stylelist))
863 return ", ".join(sorted(stylelist))
862
864
863 class TemplateNotFound(error.Abort):
865 class TemplateNotFound(error.Abort):
864 pass
866 pass
865
867
866 class templater(object):
868 class templater(object):
867
869
868 def __init__(self, mapfile, filters=None, defaults=None, cache=None,
870 def __init__(self, mapfile, filters=None, defaults=None, cache=None,
869 minchunk=1024, maxchunk=65536):
871 minchunk=1024, maxchunk=65536):
870 '''set up template engine.
872 '''set up template engine.
871 mapfile is name of file to read map definitions from.
873 mapfile is name of file to read map definitions from.
872 filters is dict of functions. each transforms a value into another.
874 filters is dict of functions. each transforms a value into another.
873 defaults is dict of default map definitions.'''
875 defaults is dict of default map definitions.'''
874 if filters is None:
876 if filters is None:
875 filters = {}
877 filters = {}
876 if defaults is None:
878 if defaults is None:
877 defaults = {}
879 defaults = {}
878 if cache is None:
880 if cache is None:
879 cache = {}
881 cache = {}
880 self.mapfile = mapfile or 'template'
882 self.mapfile = mapfile or 'template'
881 self.cache = cache.copy()
883 self.cache = cache.copy()
882 self.map = {}
884 self.map = {}
883 if mapfile:
885 if mapfile:
884 self.base = os.path.dirname(mapfile)
886 self.base = os.path.dirname(mapfile)
885 else:
887 else:
886 self.base = ''
888 self.base = ''
887 self.filters = templatefilters.filters.copy()
889 self.filters = templatefilters.filters.copy()
888 self.filters.update(filters)
890 self.filters.update(filters)
889 self.defaults = defaults
891 self.defaults = defaults
890 self.minchunk, self.maxchunk = minchunk, maxchunk
892 self.minchunk, self.maxchunk = minchunk, maxchunk
891 self.ecache = {}
893 self.ecache = {}
892
894
893 if not mapfile:
895 if not mapfile:
894 return
896 return
895 if not os.path.exists(mapfile):
897 if not os.path.exists(mapfile):
896 raise error.Abort(_("style '%s' not found") % mapfile,
898 raise error.Abort(_("style '%s' not found") % mapfile,
897 hint=_("available styles: %s") % stylelist())
899 hint=_("available styles: %s") % stylelist())
898
900
899 conf = config.config(includepaths=templatepaths())
901 conf = config.config(includepaths=templatepaths())
900 conf.read(mapfile)
902 conf.read(mapfile)
901
903
902 for key, val in conf[''].items():
904 for key, val in conf[''].items():
903 if not val:
905 if not val:
904 raise SyntaxError(_('%s: missing value') % conf.source('', key))
906 raise SyntaxError(_('%s: missing value') % conf.source('', key))
905 if val[0] in "'\"":
907 if val[0] in "'\"":
906 try:
908 try:
907 self.cache[key] = unquotestring(val)
909 self.cache[key] = unquotestring(val)
908 except SyntaxError as inst:
910 except SyntaxError as inst:
909 raise SyntaxError('%s: %s' %
911 raise SyntaxError('%s: %s' %
910 (conf.source('', key), inst.args[0]))
912 (conf.source('', key), inst.args[0]))
911 else:
913 else:
912 val = 'default', val
914 val = 'default', val
913 if ':' in val[1]:
915 if ':' in val[1]:
914 val = val[1].split(':', 1)
916 val = val[1].split(':', 1)
915 self.map[key] = val[0], os.path.join(self.base, val[1])
917 self.map[key] = val[0], os.path.join(self.base, val[1])
916
918
917 def __contains__(self, key):
919 def __contains__(self, key):
918 return key in self.cache or key in self.map
920 return key in self.cache or key in self.map
919
921
920 def load(self, t):
922 def load(self, t):
921 '''Get the template for the given template name. Use a local cache.'''
923 '''Get the template for the given template name. Use a local cache.'''
922 if t not in self.cache:
924 if t not in self.cache:
923 try:
925 try:
924 self.cache[t] = util.readfile(self.map[t][1])
926 self.cache[t] = util.readfile(self.map[t][1])
925 except KeyError as inst:
927 except KeyError as inst:
926 raise TemplateNotFound(_('"%s" not in template map') %
928 raise TemplateNotFound(_('"%s" not in template map') %
927 inst.args[0])
929 inst.args[0])
928 except IOError as inst:
930 except IOError as inst:
929 raise IOError(inst.args[0], _('template file %s: %s') %
931 raise IOError(inst.args[0], _('template file %s: %s') %
930 (self.map[t][1], inst.args[1]))
932 (self.map[t][1], inst.args[1]))
931 return self.cache[t]
933 return self.cache[t]
932
934
933 def __call__(self, t, **mapping):
935 def __call__(self, t, **mapping):
934 ttype = t in self.map and self.map[t][0] or 'default'
936 ttype = t in self.map and self.map[t][0] or 'default'
935 if ttype not in self.ecache:
937 if ttype not in self.ecache:
936 self.ecache[ttype] = engines[ttype](self.load,
938 self.ecache[ttype] = engines[ttype](self.load,
937 self.filters, self.defaults)
939 self.filters, self.defaults)
938 proc = self.ecache[ttype]
940 proc = self.ecache[ttype]
939
941
940 stream = proc.process(t, mapping)
942 stream = proc.process(t, mapping)
941 if self.minchunk:
943 if self.minchunk:
942 stream = util.increasingchunks(stream, min=self.minchunk,
944 stream = util.increasingchunks(stream, min=self.minchunk,
943 max=self.maxchunk)
945 max=self.maxchunk)
944 return stream
946 return stream
945
947
946 def templatepaths():
948 def templatepaths():
947 '''return locations used for template files.'''
949 '''return locations used for template files.'''
948 pathsrel = ['templates']
950 pathsrel = ['templates']
949 paths = [os.path.normpath(os.path.join(util.datapath, f))
951 paths = [os.path.normpath(os.path.join(util.datapath, f))
950 for f in pathsrel]
952 for f in pathsrel]
951 return [p for p in paths if os.path.isdir(p)]
953 return [p for p in paths if os.path.isdir(p)]
952
954
953 def templatepath(name):
955 def templatepath(name):
954 '''return location of template file. returns None if not found.'''
956 '''return location of template file. returns None if not found.'''
955 for p in templatepaths():
957 for p in templatepaths():
956 f = os.path.join(p, name)
958 f = os.path.join(p, name)
957 if os.path.exists(f):
959 if os.path.exists(f):
958 return f
960 return f
959 return None
961 return None
960
962
961 def stylemap(styles, paths=None):
963 def stylemap(styles, paths=None):
962 """Return path to mapfile for a given style.
964 """Return path to mapfile for a given style.
963
965
964 Searches mapfile in the following locations:
966 Searches mapfile in the following locations:
965 1. templatepath/style/map
967 1. templatepath/style/map
966 2. templatepath/map-style
968 2. templatepath/map-style
967 3. templatepath/map
969 3. templatepath/map
968 """
970 """
969
971
970 if paths is None:
972 if paths is None:
971 paths = templatepaths()
973 paths = templatepaths()
972 elif isinstance(paths, str):
974 elif isinstance(paths, str):
973 paths = [paths]
975 paths = [paths]
974
976
975 if isinstance(styles, str):
977 if isinstance(styles, str):
976 styles = [styles]
978 styles = [styles]
977
979
978 for style in styles:
980 for style in styles:
979 # only plain name is allowed to honor template paths
981 # only plain name is allowed to honor template paths
980 if (not style
982 if (not style
981 or style in (os.curdir, os.pardir)
983 or style in (os.curdir, os.pardir)
982 or os.sep in style
984 or os.sep in style
983 or os.altsep and os.altsep in style):
985 or os.altsep and os.altsep in style):
984 continue
986 continue
985 locations = [os.path.join(style, 'map'), 'map-' + style]
987 locations = [os.path.join(style, 'map'), 'map-' + style]
986 locations.append('map')
988 locations.append('map')
987
989
988 for path in paths:
990 for path in paths:
989 for location in locations:
991 for location in locations:
990 mapfile = os.path.join(path, location)
992 mapfile = os.path.join(path, location)
991 if os.path.isfile(mapfile):
993 if os.path.isfile(mapfile):
992 return style, mapfile
994 return style, mapfile
993
995
994 raise RuntimeError("No hgweb templates found in %r" % paths)
996 raise RuntimeError("No hgweb templates found in %r" % paths)
995
997
996 # tell hggettext to extract docstrings from these functions:
998 # tell hggettext to extract docstrings from these functions:
997 i18nfunctions = funcs.values()
999 i18nfunctions = funcs.values()
@@ -1,3619 +1,3627 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo a > a
3 $ echo a > a
4 $ hg add a
4 $ hg add a
5 $ echo line 1 > b
5 $ echo line 1 > b
6 $ echo line 2 >> b
6 $ echo line 2 >> b
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
8
8
9 $ hg add b
9 $ hg add b
10 $ echo other 1 > c
10 $ echo other 1 > c
11 $ echo other 2 >> c
11 $ echo other 2 >> c
12 $ echo >> c
12 $ echo >> c
13 $ echo other 3 >> c
13 $ echo other 3 >> c
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
15
15
16 $ hg add c
16 $ hg add c
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
18 $ echo c >> c
18 $ echo c >> c
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
20
20
21 $ echo foo > .hg/branch
21 $ echo foo > .hg/branch
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
23
23
24 $ hg co -q 3
24 $ hg co -q 3
25 $ echo other 4 >> d
25 $ echo other 4 >> d
26 $ hg add d
26 $ hg add d
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
28
28
29 $ hg merge -q foo
29 $ hg merge -q foo
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
31
31
32 Second branch starting at nullrev:
32 Second branch starting at nullrev:
33
33
34 $ hg update null
34 $ hg update null
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
36 $ echo second > second
36 $ echo second > second
37 $ hg add second
37 $ hg add second
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
39 created new head
39 created new head
40
40
41 $ echo third > third
41 $ echo third > third
42 $ hg add third
42 $ hg add third
43 $ hg mv second fourth
43 $ hg mv second fourth
44 $ hg commit -m third -d "2020-01-01 10:01"
44 $ hg commit -m third -d "2020-01-01 10:01"
45
45
46 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
46 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
47 fourth (second)
47 fourth (second)
48 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
48 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
49 second -> fourth
49 second -> fourth
50 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
50 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
51 8 t
51 8 t
52 7 f
52 7 f
53
53
54 Working-directory revision has special identifiers, though they are still
54 Working-directory revision has special identifiers, though they are still
55 experimental:
55 experimental:
56
56
57 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
57 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
58 2147483647:ffffffffffffffffffffffffffffffffffffffff
58 2147483647:ffffffffffffffffffffffffffffffffffffffff
59
59
60 Some keywords are invalid for working-directory revision, but they should
60 Some keywords are invalid for working-directory revision, but they should
61 never cause crash:
61 never cause crash:
62
62
63 $ hg log -r 'wdir()' -T '{manifest}\n'
63 $ hg log -r 'wdir()' -T '{manifest}\n'
64
64
65
65
66 Quoting for ui.logtemplate
66 Quoting for ui.logtemplate
67
67
68 $ hg tip --config "ui.logtemplate={rev}\n"
68 $ hg tip --config "ui.logtemplate={rev}\n"
69 8
69 8
70 $ hg tip --config "ui.logtemplate='{rev}\n'"
70 $ hg tip --config "ui.logtemplate='{rev}\n'"
71 8
71 8
72 $ hg tip --config 'ui.logtemplate="{rev}\n"'
72 $ hg tip --config 'ui.logtemplate="{rev}\n"'
73 8
73 8
74
74
75 Make sure user/global hgrc does not affect tests
75 Make sure user/global hgrc does not affect tests
76
76
77 $ echo '[ui]' > .hg/hgrc
77 $ echo '[ui]' > .hg/hgrc
78 $ echo 'logtemplate =' >> .hg/hgrc
78 $ echo 'logtemplate =' >> .hg/hgrc
79 $ echo 'style =' >> .hg/hgrc
79 $ echo 'style =' >> .hg/hgrc
80
80
81 Add some simple styles to settings
81 Add some simple styles to settings
82
82
83 $ echo '[templates]' >> .hg/hgrc
83 $ echo '[templates]' >> .hg/hgrc
84 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
84 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
85 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
85 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
86
86
87 $ hg log -l1 -Tsimple
87 $ hg log -l1 -Tsimple
88 8
88 8
89 $ hg log -l1 -Tsimple2
89 $ hg log -l1 -Tsimple2
90 8
90 8
91
91
92 Test templates and style maps in files:
92 Test templates and style maps in files:
93
93
94 $ echo "{rev}" > tmpl
94 $ echo "{rev}" > tmpl
95 $ hg log -l1 -T./tmpl
95 $ hg log -l1 -T./tmpl
96 8
96 8
97 $ hg log -l1 -Tblah/blah
97 $ hg log -l1 -Tblah/blah
98 blah/blah (no-eol)
98 blah/blah (no-eol)
99
99
100 $ printf 'changeset = "{rev}\\n"\n' > map-simple
100 $ printf 'changeset = "{rev}\\n"\n' > map-simple
101 $ hg log -l1 -T./map-simple
101 $ hg log -l1 -T./map-simple
102 8
102 8
103
103
104 Template should precede style option
104 Template should precede style option
105
105
106 $ hg log -l1 --style default -T '{rev}\n'
106 $ hg log -l1 --style default -T '{rev}\n'
107 8
107 8
108
108
109 Add a commit with empty description, to ensure that the templates
109 Add a commit with empty description, to ensure that the templates
110 below will omit the description line.
110 below will omit the description line.
111
111
112 $ echo c >> c
112 $ echo c >> c
113 $ hg add c
113 $ hg add c
114 $ hg commit -qm ' '
114 $ hg commit -qm ' '
115
115
116 Default style is like normal output. Phases style should be the same
116 Default style is like normal output. Phases style should be the same
117 as default style, except for extra phase lines.
117 as default style, except for extra phase lines.
118
118
119 $ hg log > log.out
119 $ hg log > log.out
120 $ hg log --style default > style.out
120 $ hg log --style default > style.out
121 $ cmp log.out style.out || diff -u log.out style.out
121 $ cmp log.out style.out || diff -u log.out style.out
122 $ hg log -T phases > phases.out
122 $ hg log -T phases > phases.out
123 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
123 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
124 +phase: draft
124 +phase: draft
125 +phase: draft
125 +phase: draft
126 +phase: draft
126 +phase: draft
127 +phase: draft
127 +phase: draft
128 +phase: draft
128 +phase: draft
129 +phase: draft
129 +phase: draft
130 +phase: draft
130 +phase: draft
131 +phase: draft
131 +phase: draft
132 +phase: draft
132 +phase: draft
133 +phase: draft
133 +phase: draft
134
134
135 $ hg log -v > log.out
135 $ hg log -v > log.out
136 $ hg log -v --style default > style.out
136 $ hg log -v --style default > style.out
137 $ cmp log.out style.out || diff -u log.out style.out
137 $ cmp log.out style.out || diff -u log.out style.out
138 $ hg log -v -T phases > phases.out
138 $ hg log -v -T phases > phases.out
139 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
139 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
140 +phase: draft
140 +phase: draft
141 +phase: draft
141 +phase: draft
142 +phase: draft
142 +phase: draft
143 +phase: draft
143 +phase: draft
144 +phase: draft
144 +phase: draft
145 +phase: draft
145 +phase: draft
146 +phase: draft
146 +phase: draft
147 +phase: draft
147 +phase: draft
148 +phase: draft
148 +phase: draft
149 +phase: draft
149 +phase: draft
150
150
151 $ hg log -q > log.out
151 $ hg log -q > log.out
152 $ hg log -q --style default > style.out
152 $ hg log -q --style default > style.out
153 $ cmp log.out style.out || diff -u log.out style.out
153 $ cmp log.out style.out || diff -u log.out style.out
154 $ hg log -q -T phases > phases.out
154 $ hg log -q -T phases > phases.out
155 $ cmp log.out phases.out || diff -u log.out phases.out
155 $ cmp log.out phases.out || diff -u log.out phases.out
156
156
157 $ hg log --debug > log.out
157 $ hg log --debug > log.out
158 $ hg log --debug --style default > style.out
158 $ hg log --debug --style default > style.out
159 $ cmp log.out style.out || diff -u log.out style.out
159 $ cmp log.out style.out || diff -u log.out style.out
160 $ hg log --debug -T phases > phases.out
160 $ hg log --debug -T phases > phases.out
161 $ cmp log.out phases.out || diff -u log.out phases.out
161 $ cmp log.out phases.out || diff -u log.out phases.out
162
162
163 Default style of working-directory revision should also be the same (but
163 Default style of working-directory revision should also be the same (but
164 date may change while running tests):
164 date may change while running tests):
165
165
166 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
166 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
167 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
167 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
168 $ cmp log.out style.out || diff -u log.out style.out
168 $ cmp log.out style.out || diff -u log.out style.out
169
169
170 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
170 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
171 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
171 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
172 $ cmp log.out style.out || diff -u log.out style.out
172 $ cmp log.out style.out || diff -u log.out style.out
173
173
174 $ hg log -r 'wdir()' -q > log.out
174 $ hg log -r 'wdir()' -q > log.out
175 $ hg log -r 'wdir()' -q --style default > style.out
175 $ hg log -r 'wdir()' -q --style default > style.out
176 $ cmp log.out style.out || diff -u log.out style.out
176 $ cmp log.out style.out || diff -u log.out style.out
177
177
178 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
178 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
179 $ hg log -r 'wdir()' --debug --style default \
179 $ hg log -r 'wdir()' --debug --style default \
180 > | sed 's|^date:.*|date:|' > style.out
180 > | sed 's|^date:.*|date:|' > style.out
181 $ cmp log.out style.out || diff -u log.out style.out
181 $ cmp log.out style.out || diff -u log.out style.out
182
182
183 Default style should also preserve color information (issue2866):
183 Default style should also preserve color information (issue2866):
184
184
185 $ cp $HGRCPATH $HGRCPATH-bak
185 $ cp $HGRCPATH $HGRCPATH-bak
186 $ cat <<EOF >> $HGRCPATH
186 $ cat <<EOF >> $HGRCPATH
187 > [extensions]
187 > [extensions]
188 > color=
188 > color=
189 > EOF
189 > EOF
190
190
191 $ hg --color=debug log > log.out
191 $ hg --color=debug log > log.out
192 $ hg --color=debug log --style default > style.out
192 $ hg --color=debug log --style default > style.out
193 $ cmp log.out style.out || diff -u log.out style.out
193 $ cmp log.out style.out || diff -u log.out style.out
194 $ hg --color=debug log -T phases > phases.out
194 $ hg --color=debug log -T phases > phases.out
195 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
195 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
196 +[log.phase|phase: draft]
196 +[log.phase|phase: draft]
197 +[log.phase|phase: draft]
197 +[log.phase|phase: draft]
198 +[log.phase|phase: draft]
198 +[log.phase|phase: draft]
199 +[log.phase|phase: draft]
199 +[log.phase|phase: draft]
200 +[log.phase|phase: draft]
200 +[log.phase|phase: draft]
201 +[log.phase|phase: draft]
201 +[log.phase|phase: draft]
202 +[log.phase|phase: draft]
202 +[log.phase|phase: draft]
203 +[log.phase|phase: draft]
203 +[log.phase|phase: draft]
204 +[log.phase|phase: draft]
204 +[log.phase|phase: draft]
205 +[log.phase|phase: draft]
205 +[log.phase|phase: draft]
206
206
207 $ hg --color=debug -v log > log.out
207 $ hg --color=debug -v log > log.out
208 $ hg --color=debug -v log --style default > style.out
208 $ hg --color=debug -v log --style default > style.out
209 $ cmp log.out style.out || diff -u log.out style.out
209 $ cmp log.out style.out || diff -u log.out style.out
210 $ hg --color=debug -v log -T phases > phases.out
210 $ hg --color=debug -v log -T phases > phases.out
211 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
211 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
212 +[log.phase|phase: draft]
212 +[log.phase|phase: draft]
213 +[log.phase|phase: draft]
213 +[log.phase|phase: draft]
214 +[log.phase|phase: draft]
214 +[log.phase|phase: draft]
215 +[log.phase|phase: draft]
215 +[log.phase|phase: draft]
216 +[log.phase|phase: draft]
216 +[log.phase|phase: draft]
217 +[log.phase|phase: draft]
217 +[log.phase|phase: draft]
218 +[log.phase|phase: draft]
218 +[log.phase|phase: draft]
219 +[log.phase|phase: draft]
219 +[log.phase|phase: draft]
220 +[log.phase|phase: draft]
220 +[log.phase|phase: draft]
221 +[log.phase|phase: draft]
221 +[log.phase|phase: draft]
222
222
223 $ hg --color=debug -q log > log.out
223 $ hg --color=debug -q log > log.out
224 $ hg --color=debug -q log --style default > style.out
224 $ hg --color=debug -q log --style default > style.out
225 $ cmp log.out style.out || diff -u log.out style.out
225 $ cmp log.out style.out || diff -u log.out style.out
226 $ hg --color=debug -q log -T phases > phases.out
226 $ hg --color=debug -q log -T phases > phases.out
227 $ cmp log.out phases.out || diff -u log.out phases.out
227 $ cmp log.out phases.out || diff -u log.out phases.out
228
228
229 $ hg --color=debug --debug log > log.out
229 $ hg --color=debug --debug log > log.out
230 $ hg --color=debug --debug log --style default > style.out
230 $ hg --color=debug --debug log --style default > style.out
231 $ cmp log.out style.out || diff -u log.out style.out
231 $ cmp log.out style.out || diff -u log.out style.out
232 $ hg --color=debug --debug log -T phases > phases.out
232 $ hg --color=debug --debug log -T phases > phases.out
233 $ cmp log.out phases.out || diff -u log.out phases.out
233 $ cmp log.out phases.out || diff -u log.out phases.out
234
234
235 $ mv $HGRCPATH-bak $HGRCPATH
235 $ mv $HGRCPATH-bak $HGRCPATH
236
236
237 Remove commit with empty commit message, so as to not pollute further
237 Remove commit with empty commit message, so as to not pollute further
238 tests.
238 tests.
239
239
240 $ hg --config extensions.strip= strip -q .
240 $ hg --config extensions.strip= strip -q .
241
241
242 Revision with no copies (used to print a traceback):
242 Revision with no copies (used to print a traceback):
243
243
244 $ hg tip -v --template '\n'
244 $ hg tip -v --template '\n'
245
245
246
246
247 Compact style works:
247 Compact style works:
248
248
249 $ hg log -Tcompact
249 $ hg log -Tcompact
250 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
250 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
251 third
251 third
252
252
253 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
253 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
254 second
254 second
255
255
256 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
256 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
257 merge
257 merge
258
258
259 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
259 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
260 new head
260 new head
261
261
262 4 bbe44766e73d 1970-01-17 04:53 +0000 person
262 4 bbe44766e73d 1970-01-17 04:53 +0000 person
263 new branch
263 new branch
264
264
265 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
265 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
266 no user, no domain
266 no user, no domain
267
267
268 2 97054abb4ab8 1970-01-14 21:20 +0000 other
268 2 97054abb4ab8 1970-01-14 21:20 +0000 other
269 no person
269 no person
270
270
271 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
271 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
272 other 1
272 other 1
273
273
274 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
274 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
275 line 1
275 line 1
276
276
277
277
278 $ hg log -v --style compact
278 $ hg log -v --style compact
279 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
279 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
280 third
280 third
281
281
282 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
282 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
283 second
283 second
284
284
285 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
285 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
286 merge
286 merge
287
287
288 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
288 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
289 new head
289 new head
290
290
291 4 bbe44766e73d 1970-01-17 04:53 +0000 person
291 4 bbe44766e73d 1970-01-17 04:53 +0000 person
292 new branch
292 new branch
293
293
294 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
294 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
295 no user, no domain
295 no user, no domain
296
296
297 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
297 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
298 no person
298 no person
299
299
300 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
300 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
301 other 1
301 other 1
302 other 2
302 other 2
303
303
304 other 3
304 other 3
305
305
306 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
306 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
307 line 1
307 line 1
308 line 2
308 line 2
309
309
310
310
311 $ hg log --debug --style compact
311 $ hg log --debug --style compact
312 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
312 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
313 third
313 third
314
314
315 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
315 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
316 second
316 second
317
317
318 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
318 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
319 merge
319 merge
320
320
321 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
321 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
322 new head
322 new head
323
323
324 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
324 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
325 new branch
325 new branch
326
326
327 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
327 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
328 no user, no domain
328 no user, no domain
329
329
330 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
330 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
331 no person
331 no person
332
332
333 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
333 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
334 other 1
334 other 1
335 other 2
335 other 2
336
336
337 other 3
337 other 3
338
338
339 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
339 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
340 line 1
340 line 1
341 line 2
341 line 2
342
342
343
343
344 Test xml styles:
344 Test xml styles:
345
345
346 $ hg log --style xml -r 'not all()'
346 $ hg log --style xml -r 'not all()'
347 <?xml version="1.0"?>
347 <?xml version="1.0"?>
348 <log>
348 <log>
349 </log>
349 </log>
350
350
351 $ hg log --style xml
351 $ hg log --style xml
352 <?xml version="1.0"?>
352 <?xml version="1.0"?>
353 <log>
353 <log>
354 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
354 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
355 <tag>tip</tag>
355 <tag>tip</tag>
356 <author email="test">test</author>
356 <author email="test">test</author>
357 <date>2020-01-01T10:01:00+00:00</date>
357 <date>2020-01-01T10:01:00+00:00</date>
358 <msg xml:space="preserve">third</msg>
358 <msg xml:space="preserve">third</msg>
359 </logentry>
359 </logentry>
360 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
360 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
361 <parent revision="-1" node="0000000000000000000000000000000000000000" />
361 <parent revision="-1" node="0000000000000000000000000000000000000000" />
362 <author email="user@hostname">User Name</author>
362 <author email="user@hostname">User Name</author>
363 <date>1970-01-12T13:46:40+00:00</date>
363 <date>1970-01-12T13:46:40+00:00</date>
364 <msg xml:space="preserve">second</msg>
364 <msg xml:space="preserve">second</msg>
365 </logentry>
365 </logentry>
366 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
366 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
367 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
367 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
368 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
368 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
369 <author email="person">person</author>
369 <author email="person">person</author>
370 <date>1970-01-18T08:40:01+00:00</date>
370 <date>1970-01-18T08:40:01+00:00</date>
371 <msg xml:space="preserve">merge</msg>
371 <msg xml:space="preserve">merge</msg>
372 </logentry>
372 </logentry>
373 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
373 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
374 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
374 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
375 <author email="person">person</author>
375 <author email="person">person</author>
376 <date>1970-01-18T08:40:00+00:00</date>
376 <date>1970-01-18T08:40:00+00:00</date>
377 <msg xml:space="preserve">new head</msg>
377 <msg xml:space="preserve">new head</msg>
378 </logentry>
378 </logentry>
379 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
379 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
380 <branch>foo</branch>
380 <branch>foo</branch>
381 <author email="person">person</author>
381 <author email="person">person</author>
382 <date>1970-01-17T04:53:20+00:00</date>
382 <date>1970-01-17T04:53:20+00:00</date>
383 <msg xml:space="preserve">new branch</msg>
383 <msg xml:space="preserve">new branch</msg>
384 </logentry>
384 </logentry>
385 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
385 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
386 <author email="person">person</author>
386 <author email="person">person</author>
387 <date>1970-01-16T01:06:40+00:00</date>
387 <date>1970-01-16T01:06:40+00:00</date>
388 <msg xml:space="preserve">no user, no domain</msg>
388 <msg xml:space="preserve">no user, no domain</msg>
389 </logentry>
389 </logentry>
390 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
390 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
391 <author email="other@place">other</author>
391 <author email="other@place">other</author>
392 <date>1970-01-14T21:20:00+00:00</date>
392 <date>1970-01-14T21:20:00+00:00</date>
393 <msg xml:space="preserve">no person</msg>
393 <msg xml:space="preserve">no person</msg>
394 </logentry>
394 </logentry>
395 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
395 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
396 <author email="other@place">A. N. Other</author>
396 <author email="other@place">A. N. Other</author>
397 <date>1970-01-13T17:33:20+00:00</date>
397 <date>1970-01-13T17:33:20+00:00</date>
398 <msg xml:space="preserve">other 1
398 <msg xml:space="preserve">other 1
399 other 2
399 other 2
400
400
401 other 3</msg>
401 other 3</msg>
402 </logentry>
402 </logentry>
403 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
403 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
404 <author email="user@hostname">User Name</author>
404 <author email="user@hostname">User Name</author>
405 <date>1970-01-12T13:46:40+00:00</date>
405 <date>1970-01-12T13:46:40+00:00</date>
406 <msg xml:space="preserve">line 1
406 <msg xml:space="preserve">line 1
407 line 2</msg>
407 line 2</msg>
408 </logentry>
408 </logentry>
409 </log>
409 </log>
410
410
411 $ hg log -v --style xml
411 $ hg log -v --style xml
412 <?xml version="1.0"?>
412 <?xml version="1.0"?>
413 <log>
413 <log>
414 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
414 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
415 <tag>tip</tag>
415 <tag>tip</tag>
416 <author email="test">test</author>
416 <author email="test">test</author>
417 <date>2020-01-01T10:01:00+00:00</date>
417 <date>2020-01-01T10:01:00+00:00</date>
418 <msg xml:space="preserve">third</msg>
418 <msg xml:space="preserve">third</msg>
419 <paths>
419 <paths>
420 <path action="A">fourth</path>
420 <path action="A">fourth</path>
421 <path action="A">third</path>
421 <path action="A">third</path>
422 <path action="R">second</path>
422 <path action="R">second</path>
423 </paths>
423 </paths>
424 <copies>
424 <copies>
425 <copy source="second">fourth</copy>
425 <copy source="second">fourth</copy>
426 </copies>
426 </copies>
427 </logentry>
427 </logentry>
428 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
428 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
429 <parent revision="-1" node="0000000000000000000000000000000000000000" />
429 <parent revision="-1" node="0000000000000000000000000000000000000000" />
430 <author email="user@hostname">User Name</author>
430 <author email="user@hostname">User Name</author>
431 <date>1970-01-12T13:46:40+00:00</date>
431 <date>1970-01-12T13:46:40+00:00</date>
432 <msg xml:space="preserve">second</msg>
432 <msg xml:space="preserve">second</msg>
433 <paths>
433 <paths>
434 <path action="A">second</path>
434 <path action="A">second</path>
435 </paths>
435 </paths>
436 </logentry>
436 </logentry>
437 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
437 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
438 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
438 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
439 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
439 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
440 <author email="person">person</author>
440 <author email="person">person</author>
441 <date>1970-01-18T08:40:01+00:00</date>
441 <date>1970-01-18T08:40:01+00:00</date>
442 <msg xml:space="preserve">merge</msg>
442 <msg xml:space="preserve">merge</msg>
443 <paths>
443 <paths>
444 </paths>
444 </paths>
445 </logentry>
445 </logentry>
446 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
446 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
447 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
447 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
448 <author email="person">person</author>
448 <author email="person">person</author>
449 <date>1970-01-18T08:40:00+00:00</date>
449 <date>1970-01-18T08:40:00+00:00</date>
450 <msg xml:space="preserve">new head</msg>
450 <msg xml:space="preserve">new head</msg>
451 <paths>
451 <paths>
452 <path action="A">d</path>
452 <path action="A">d</path>
453 </paths>
453 </paths>
454 </logentry>
454 </logentry>
455 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
455 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
456 <branch>foo</branch>
456 <branch>foo</branch>
457 <author email="person">person</author>
457 <author email="person">person</author>
458 <date>1970-01-17T04:53:20+00:00</date>
458 <date>1970-01-17T04:53:20+00:00</date>
459 <msg xml:space="preserve">new branch</msg>
459 <msg xml:space="preserve">new branch</msg>
460 <paths>
460 <paths>
461 </paths>
461 </paths>
462 </logentry>
462 </logentry>
463 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
463 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
464 <author email="person">person</author>
464 <author email="person">person</author>
465 <date>1970-01-16T01:06:40+00:00</date>
465 <date>1970-01-16T01:06:40+00:00</date>
466 <msg xml:space="preserve">no user, no domain</msg>
466 <msg xml:space="preserve">no user, no domain</msg>
467 <paths>
467 <paths>
468 <path action="M">c</path>
468 <path action="M">c</path>
469 </paths>
469 </paths>
470 </logentry>
470 </logentry>
471 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
471 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
472 <author email="other@place">other</author>
472 <author email="other@place">other</author>
473 <date>1970-01-14T21:20:00+00:00</date>
473 <date>1970-01-14T21:20:00+00:00</date>
474 <msg xml:space="preserve">no person</msg>
474 <msg xml:space="preserve">no person</msg>
475 <paths>
475 <paths>
476 <path action="A">c</path>
476 <path action="A">c</path>
477 </paths>
477 </paths>
478 </logentry>
478 </logentry>
479 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
479 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
480 <author email="other@place">A. N. Other</author>
480 <author email="other@place">A. N. Other</author>
481 <date>1970-01-13T17:33:20+00:00</date>
481 <date>1970-01-13T17:33:20+00:00</date>
482 <msg xml:space="preserve">other 1
482 <msg xml:space="preserve">other 1
483 other 2
483 other 2
484
484
485 other 3</msg>
485 other 3</msg>
486 <paths>
486 <paths>
487 <path action="A">b</path>
487 <path action="A">b</path>
488 </paths>
488 </paths>
489 </logentry>
489 </logentry>
490 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
490 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
491 <author email="user@hostname">User Name</author>
491 <author email="user@hostname">User Name</author>
492 <date>1970-01-12T13:46:40+00:00</date>
492 <date>1970-01-12T13:46:40+00:00</date>
493 <msg xml:space="preserve">line 1
493 <msg xml:space="preserve">line 1
494 line 2</msg>
494 line 2</msg>
495 <paths>
495 <paths>
496 <path action="A">a</path>
496 <path action="A">a</path>
497 </paths>
497 </paths>
498 </logentry>
498 </logentry>
499 </log>
499 </log>
500
500
501 $ hg log --debug --style xml
501 $ hg log --debug --style xml
502 <?xml version="1.0"?>
502 <?xml version="1.0"?>
503 <log>
503 <log>
504 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
504 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
505 <tag>tip</tag>
505 <tag>tip</tag>
506 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
506 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
507 <parent revision="-1" node="0000000000000000000000000000000000000000" />
507 <parent revision="-1" node="0000000000000000000000000000000000000000" />
508 <author email="test">test</author>
508 <author email="test">test</author>
509 <date>2020-01-01T10:01:00+00:00</date>
509 <date>2020-01-01T10:01:00+00:00</date>
510 <msg xml:space="preserve">third</msg>
510 <msg xml:space="preserve">third</msg>
511 <paths>
511 <paths>
512 <path action="A">fourth</path>
512 <path action="A">fourth</path>
513 <path action="A">third</path>
513 <path action="A">third</path>
514 <path action="R">second</path>
514 <path action="R">second</path>
515 </paths>
515 </paths>
516 <copies>
516 <copies>
517 <copy source="second">fourth</copy>
517 <copy source="second">fourth</copy>
518 </copies>
518 </copies>
519 <extra key="branch">default</extra>
519 <extra key="branch">default</extra>
520 </logentry>
520 </logentry>
521 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
521 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
522 <parent revision="-1" node="0000000000000000000000000000000000000000" />
522 <parent revision="-1" node="0000000000000000000000000000000000000000" />
523 <parent revision="-1" node="0000000000000000000000000000000000000000" />
523 <parent revision="-1" node="0000000000000000000000000000000000000000" />
524 <author email="user@hostname">User Name</author>
524 <author email="user@hostname">User Name</author>
525 <date>1970-01-12T13:46:40+00:00</date>
525 <date>1970-01-12T13:46:40+00:00</date>
526 <msg xml:space="preserve">second</msg>
526 <msg xml:space="preserve">second</msg>
527 <paths>
527 <paths>
528 <path action="A">second</path>
528 <path action="A">second</path>
529 </paths>
529 </paths>
530 <extra key="branch">default</extra>
530 <extra key="branch">default</extra>
531 </logentry>
531 </logentry>
532 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
532 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
533 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
533 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
534 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
534 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
535 <author email="person">person</author>
535 <author email="person">person</author>
536 <date>1970-01-18T08:40:01+00:00</date>
536 <date>1970-01-18T08:40:01+00:00</date>
537 <msg xml:space="preserve">merge</msg>
537 <msg xml:space="preserve">merge</msg>
538 <paths>
538 <paths>
539 </paths>
539 </paths>
540 <extra key="branch">default</extra>
540 <extra key="branch">default</extra>
541 </logentry>
541 </logentry>
542 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
542 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
543 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
543 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
544 <parent revision="-1" node="0000000000000000000000000000000000000000" />
544 <parent revision="-1" node="0000000000000000000000000000000000000000" />
545 <author email="person">person</author>
545 <author email="person">person</author>
546 <date>1970-01-18T08:40:00+00:00</date>
546 <date>1970-01-18T08:40:00+00:00</date>
547 <msg xml:space="preserve">new head</msg>
547 <msg xml:space="preserve">new head</msg>
548 <paths>
548 <paths>
549 <path action="A">d</path>
549 <path action="A">d</path>
550 </paths>
550 </paths>
551 <extra key="branch">default</extra>
551 <extra key="branch">default</extra>
552 </logentry>
552 </logentry>
553 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
553 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
554 <branch>foo</branch>
554 <branch>foo</branch>
555 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
555 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
556 <parent revision="-1" node="0000000000000000000000000000000000000000" />
556 <parent revision="-1" node="0000000000000000000000000000000000000000" />
557 <author email="person">person</author>
557 <author email="person">person</author>
558 <date>1970-01-17T04:53:20+00:00</date>
558 <date>1970-01-17T04:53:20+00:00</date>
559 <msg xml:space="preserve">new branch</msg>
559 <msg xml:space="preserve">new branch</msg>
560 <paths>
560 <paths>
561 </paths>
561 </paths>
562 <extra key="branch">foo</extra>
562 <extra key="branch">foo</extra>
563 </logentry>
563 </logentry>
564 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
564 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
565 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
565 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
566 <parent revision="-1" node="0000000000000000000000000000000000000000" />
566 <parent revision="-1" node="0000000000000000000000000000000000000000" />
567 <author email="person">person</author>
567 <author email="person">person</author>
568 <date>1970-01-16T01:06:40+00:00</date>
568 <date>1970-01-16T01:06:40+00:00</date>
569 <msg xml:space="preserve">no user, no domain</msg>
569 <msg xml:space="preserve">no user, no domain</msg>
570 <paths>
570 <paths>
571 <path action="M">c</path>
571 <path action="M">c</path>
572 </paths>
572 </paths>
573 <extra key="branch">default</extra>
573 <extra key="branch">default</extra>
574 </logentry>
574 </logentry>
575 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
575 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
576 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
576 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
577 <parent revision="-1" node="0000000000000000000000000000000000000000" />
577 <parent revision="-1" node="0000000000000000000000000000000000000000" />
578 <author email="other@place">other</author>
578 <author email="other@place">other</author>
579 <date>1970-01-14T21:20:00+00:00</date>
579 <date>1970-01-14T21:20:00+00:00</date>
580 <msg xml:space="preserve">no person</msg>
580 <msg xml:space="preserve">no person</msg>
581 <paths>
581 <paths>
582 <path action="A">c</path>
582 <path action="A">c</path>
583 </paths>
583 </paths>
584 <extra key="branch">default</extra>
584 <extra key="branch">default</extra>
585 </logentry>
585 </logentry>
586 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
586 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
587 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
587 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
588 <parent revision="-1" node="0000000000000000000000000000000000000000" />
588 <parent revision="-1" node="0000000000000000000000000000000000000000" />
589 <author email="other@place">A. N. Other</author>
589 <author email="other@place">A. N. Other</author>
590 <date>1970-01-13T17:33:20+00:00</date>
590 <date>1970-01-13T17:33:20+00:00</date>
591 <msg xml:space="preserve">other 1
591 <msg xml:space="preserve">other 1
592 other 2
592 other 2
593
593
594 other 3</msg>
594 other 3</msg>
595 <paths>
595 <paths>
596 <path action="A">b</path>
596 <path action="A">b</path>
597 </paths>
597 </paths>
598 <extra key="branch">default</extra>
598 <extra key="branch">default</extra>
599 </logentry>
599 </logentry>
600 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
600 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
601 <parent revision="-1" node="0000000000000000000000000000000000000000" />
601 <parent revision="-1" node="0000000000000000000000000000000000000000" />
602 <parent revision="-1" node="0000000000000000000000000000000000000000" />
602 <parent revision="-1" node="0000000000000000000000000000000000000000" />
603 <author email="user@hostname">User Name</author>
603 <author email="user@hostname">User Name</author>
604 <date>1970-01-12T13:46:40+00:00</date>
604 <date>1970-01-12T13:46:40+00:00</date>
605 <msg xml:space="preserve">line 1
605 <msg xml:space="preserve">line 1
606 line 2</msg>
606 line 2</msg>
607 <paths>
607 <paths>
608 <path action="A">a</path>
608 <path action="A">a</path>
609 </paths>
609 </paths>
610 <extra key="branch">default</extra>
610 <extra key="branch">default</extra>
611 </logentry>
611 </logentry>
612 </log>
612 </log>
613
613
614
614
615 Test JSON style:
615 Test JSON style:
616
616
617 $ hg log -k nosuch -Tjson
617 $ hg log -k nosuch -Tjson
618 []
618 []
619
619
620 $ hg log -qr . -Tjson
620 $ hg log -qr . -Tjson
621 [
621 [
622 {
622 {
623 "rev": 8,
623 "rev": 8,
624 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
624 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
625 }
625 }
626 ]
626 ]
627
627
628 $ hg log -vpr . -Tjson --stat
628 $ hg log -vpr . -Tjson --stat
629 [
629 [
630 {
630 {
631 "rev": 8,
631 "rev": 8,
632 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
632 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
633 "branch": "default",
633 "branch": "default",
634 "phase": "draft",
634 "phase": "draft",
635 "user": "test",
635 "user": "test",
636 "date": [1577872860, 0],
636 "date": [1577872860, 0],
637 "desc": "third",
637 "desc": "third",
638 "bookmarks": [],
638 "bookmarks": [],
639 "tags": ["tip"],
639 "tags": ["tip"],
640 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
640 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
641 "files": ["fourth", "second", "third"],
641 "files": ["fourth", "second", "third"],
642 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
642 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
643 "diff": "diff -r 29114dbae42b -r 95c24699272e fourth\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/fourth\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+second\ndiff -r 29114dbae42b -r 95c24699272e second\n--- a/second\tMon Jan 12 13:46:40 1970 +0000\n+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,1 +0,0 @@\n-second\ndiff -r 29114dbae42b -r 95c24699272e third\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/third\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+third\n"
643 "diff": "diff -r 29114dbae42b -r 95c24699272e fourth\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/fourth\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+second\ndiff -r 29114dbae42b -r 95c24699272e second\n--- a/second\tMon Jan 12 13:46:40 1970 +0000\n+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,1 +0,0 @@\n-second\ndiff -r 29114dbae42b -r 95c24699272e third\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/third\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+third\n"
644 }
644 }
645 ]
645 ]
646
646
647 honor --git but not format-breaking diffopts
647 honor --git but not format-breaking diffopts
648 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
648 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
649 [
649 [
650 {
650 {
651 "rev": 8,
651 "rev": 8,
652 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
652 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
653 "branch": "default",
653 "branch": "default",
654 "phase": "draft",
654 "phase": "draft",
655 "user": "test",
655 "user": "test",
656 "date": [1577872860, 0],
656 "date": [1577872860, 0],
657 "desc": "third",
657 "desc": "third",
658 "bookmarks": [],
658 "bookmarks": [],
659 "tags": ["tip"],
659 "tags": ["tip"],
660 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
660 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
661 "files": ["fourth", "second", "third"],
661 "files": ["fourth", "second", "third"],
662 "diff": "diff --git a/second b/fourth\nrename from second\nrename to fourth\ndiff --git a/third b/third\nnew file mode 100644\n--- /dev/null\n+++ b/third\n@@ -0,0 +1,1 @@\n+third\n"
662 "diff": "diff --git a/second b/fourth\nrename from second\nrename to fourth\ndiff --git a/third b/third\nnew file mode 100644\n--- /dev/null\n+++ b/third\n@@ -0,0 +1,1 @@\n+third\n"
663 }
663 }
664 ]
664 ]
665
665
666 $ hg log -T json
666 $ hg log -T json
667 [
667 [
668 {
668 {
669 "rev": 8,
669 "rev": 8,
670 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
670 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
671 "branch": "default",
671 "branch": "default",
672 "phase": "draft",
672 "phase": "draft",
673 "user": "test",
673 "user": "test",
674 "date": [1577872860, 0],
674 "date": [1577872860, 0],
675 "desc": "third",
675 "desc": "third",
676 "bookmarks": [],
676 "bookmarks": [],
677 "tags": ["tip"],
677 "tags": ["tip"],
678 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
678 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
679 },
679 },
680 {
680 {
681 "rev": 7,
681 "rev": 7,
682 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
682 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
683 "branch": "default",
683 "branch": "default",
684 "phase": "draft",
684 "phase": "draft",
685 "user": "User Name <user@hostname>",
685 "user": "User Name <user@hostname>",
686 "date": [1000000, 0],
686 "date": [1000000, 0],
687 "desc": "second",
687 "desc": "second",
688 "bookmarks": [],
688 "bookmarks": [],
689 "tags": [],
689 "tags": [],
690 "parents": ["0000000000000000000000000000000000000000"]
690 "parents": ["0000000000000000000000000000000000000000"]
691 },
691 },
692 {
692 {
693 "rev": 6,
693 "rev": 6,
694 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
694 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
695 "branch": "default",
695 "branch": "default",
696 "phase": "draft",
696 "phase": "draft",
697 "user": "person",
697 "user": "person",
698 "date": [1500001, 0],
698 "date": [1500001, 0],
699 "desc": "merge",
699 "desc": "merge",
700 "bookmarks": [],
700 "bookmarks": [],
701 "tags": [],
701 "tags": [],
702 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
702 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
703 },
703 },
704 {
704 {
705 "rev": 5,
705 "rev": 5,
706 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
706 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
707 "branch": "default",
707 "branch": "default",
708 "phase": "draft",
708 "phase": "draft",
709 "user": "person",
709 "user": "person",
710 "date": [1500000, 0],
710 "date": [1500000, 0],
711 "desc": "new head",
711 "desc": "new head",
712 "bookmarks": [],
712 "bookmarks": [],
713 "tags": [],
713 "tags": [],
714 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
714 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
715 },
715 },
716 {
716 {
717 "rev": 4,
717 "rev": 4,
718 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
718 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
719 "branch": "foo",
719 "branch": "foo",
720 "phase": "draft",
720 "phase": "draft",
721 "user": "person",
721 "user": "person",
722 "date": [1400000, 0],
722 "date": [1400000, 0],
723 "desc": "new branch",
723 "desc": "new branch",
724 "bookmarks": [],
724 "bookmarks": [],
725 "tags": [],
725 "tags": [],
726 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
726 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
727 },
727 },
728 {
728 {
729 "rev": 3,
729 "rev": 3,
730 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
730 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
731 "branch": "default",
731 "branch": "default",
732 "phase": "draft",
732 "phase": "draft",
733 "user": "person",
733 "user": "person",
734 "date": [1300000, 0],
734 "date": [1300000, 0],
735 "desc": "no user, no domain",
735 "desc": "no user, no domain",
736 "bookmarks": [],
736 "bookmarks": [],
737 "tags": [],
737 "tags": [],
738 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
738 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
739 },
739 },
740 {
740 {
741 "rev": 2,
741 "rev": 2,
742 "node": "97054abb4ab824450e9164180baf491ae0078465",
742 "node": "97054abb4ab824450e9164180baf491ae0078465",
743 "branch": "default",
743 "branch": "default",
744 "phase": "draft",
744 "phase": "draft",
745 "user": "other@place",
745 "user": "other@place",
746 "date": [1200000, 0],
746 "date": [1200000, 0],
747 "desc": "no person",
747 "desc": "no person",
748 "bookmarks": [],
748 "bookmarks": [],
749 "tags": [],
749 "tags": [],
750 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
750 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
751 },
751 },
752 {
752 {
753 "rev": 1,
753 "rev": 1,
754 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
754 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
755 "branch": "default",
755 "branch": "default",
756 "phase": "draft",
756 "phase": "draft",
757 "user": "A. N. Other <other@place>",
757 "user": "A. N. Other <other@place>",
758 "date": [1100000, 0],
758 "date": [1100000, 0],
759 "desc": "other 1\nother 2\n\nother 3",
759 "desc": "other 1\nother 2\n\nother 3",
760 "bookmarks": [],
760 "bookmarks": [],
761 "tags": [],
761 "tags": [],
762 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
762 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
763 },
763 },
764 {
764 {
765 "rev": 0,
765 "rev": 0,
766 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
766 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
767 "branch": "default",
767 "branch": "default",
768 "phase": "draft",
768 "phase": "draft",
769 "user": "User Name <user@hostname>",
769 "user": "User Name <user@hostname>",
770 "date": [1000000, 0],
770 "date": [1000000, 0],
771 "desc": "line 1\nline 2",
771 "desc": "line 1\nline 2",
772 "bookmarks": [],
772 "bookmarks": [],
773 "tags": [],
773 "tags": [],
774 "parents": ["0000000000000000000000000000000000000000"]
774 "parents": ["0000000000000000000000000000000000000000"]
775 }
775 }
776 ]
776 ]
777
777
778 $ hg heads -v -Tjson
778 $ hg heads -v -Tjson
779 [
779 [
780 {
780 {
781 "rev": 8,
781 "rev": 8,
782 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
782 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
783 "branch": "default",
783 "branch": "default",
784 "phase": "draft",
784 "phase": "draft",
785 "user": "test",
785 "user": "test",
786 "date": [1577872860, 0],
786 "date": [1577872860, 0],
787 "desc": "third",
787 "desc": "third",
788 "bookmarks": [],
788 "bookmarks": [],
789 "tags": ["tip"],
789 "tags": ["tip"],
790 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
790 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
791 "files": ["fourth", "second", "third"]
791 "files": ["fourth", "second", "third"]
792 },
792 },
793 {
793 {
794 "rev": 6,
794 "rev": 6,
795 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
795 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
796 "branch": "default",
796 "branch": "default",
797 "phase": "draft",
797 "phase": "draft",
798 "user": "person",
798 "user": "person",
799 "date": [1500001, 0],
799 "date": [1500001, 0],
800 "desc": "merge",
800 "desc": "merge",
801 "bookmarks": [],
801 "bookmarks": [],
802 "tags": [],
802 "tags": [],
803 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
803 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
804 "files": []
804 "files": []
805 },
805 },
806 {
806 {
807 "rev": 4,
807 "rev": 4,
808 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
808 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
809 "branch": "foo",
809 "branch": "foo",
810 "phase": "draft",
810 "phase": "draft",
811 "user": "person",
811 "user": "person",
812 "date": [1400000, 0],
812 "date": [1400000, 0],
813 "desc": "new branch",
813 "desc": "new branch",
814 "bookmarks": [],
814 "bookmarks": [],
815 "tags": [],
815 "tags": [],
816 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
816 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
817 "files": []
817 "files": []
818 }
818 }
819 ]
819 ]
820
820
821 $ hg log --debug -Tjson
821 $ hg log --debug -Tjson
822 [
822 [
823 {
823 {
824 "rev": 8,
824 "rev": 8,
825 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
825 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
826 "branch": "default",
826 "branch": "default",
827 "phase": "draft",
827 "phase": "draft",
828 "user": "test",
828 "user": "test",
829 "date": [1577872860, 0],
829 "date": [1577872860, 0],
830 "desc": "third",
830 "desc": "third",
831 "bookmarks": [],
831 "bookmarks": [],
832 "tags": ["tip"],
832 "tags": ["tip"],
833 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
833 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
834 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
834 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
835 "extra": {"branch": "default"},
835 "extra": {"branch": "default"},
836 "modified": [],
836 "modified": [],
837 "added": ["fourth", "third"],
837 "added": ["fourth", "third"],
838 "removed": ["second"]
838 "removed": ["second"]
839 },
839 },
840 {
840 {
841 "rev": 7,
841 "rev": 7,
842 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
842 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
843 "branch": "default",
843 "branch": "default",
844 "phase": "draft",
844 "phase": "draft",
845 "user": "User Name <user@hostname>",
845 "user": "User Name <user@hostname>",
846 "date": [1000000, 0],
846 "date": [1000000, 0],
847 "desc": "second",
847 "desc": "second",
848 "bookmarks": [],
848 "bookmarks": [],
849 "tags": [],
849 "tags": [],
850 "parents": ["0000000000000000000000000000000000000000"],
850 "parents": ["0000000000000000000000000000000000000000"],
851 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
851 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
852 "extra": {"branch": "default"},
852 "extra": {"branch": "default"},
853 "modified": [],
853 "modified": [],
854 "added": ["second"],
854 "added": ["second"],
855 "removed": []
855 "removed": []
856 },
856 },
857 {
857 {
858 "rev": 6,
858 "rev": 6,
859 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
859 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
860 "branch": "default",
860 "branch": "default",
861 "phase": "draft",
861 "phase": "draft",
862 "user": "person",
862 "user": "person",
863 "date": [1500001, 0],
863 "date": [1500001, 0],
864 "desc": "merge",
864 "desc": "merge",
865 "bookmarks": [],
865 "bookmarks": [],
866 "tags": [],
866 "tags": [],
867 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
867 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
868 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
868 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
869 "extra": {"branch": "default"},
869 "extra": {"branch": "default"},
870 "modified": [],
870 "modified": [],
871 "added": [],
871 "added": [],
872 "removed": []
872 "removed": []
873 },
873 },
874 {
874 {
875 "rev": 5,
875 "rev": 5,
876 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
876 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
877 "branch": "default",
877 "branch": "default",
878 "phase": "draft",
878 "phase": "draft",
879 "user": "person",
879 "user": "person",
880 "date": [1500000, 0],
880 "date": [1500000, 0],
881 "desc": "new head",
881 "desc": "new head",
882 "bookmarks": [],
882 "bookmarks": [],
883 "tags": [],
883 "tags": [],
884 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
884 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
885 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
885 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
886 "extra": {"branch": "default"},
886 "extra": {"branch": "default"},
887 "modified": [],
887 "modified": [],
888 "added": ["d"],
888 "added": ["d"],
889 "removed": []
889 "removed": []
890 },
890 },
891 {
891 {
892 "rev": 4,
892 "rev": 4,
893 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
893 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
894 "branch": "foo",
894 "branch": "foo",
895 "phase": "draft",
895 "phase": "draft",
896 "user": "person",
896 "user": "person",
897 "date": [1400000, 0],
897 "date": [1400000, 0],
898 "desc": "new branch",
898 "desc": "new branch",
899 "bookmarks": [],
899 "bookmarks": [],
900 "tags": [],
900 "tags": [],
901 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
901 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
902 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
902 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
903 "extra": {"branch": "foo"},
903 "extra": {"branch": "foo"},
904 "modified": [],
904 "modified": [],
905 "added": [],
905 "added": [],
906 "removed": []
906 "removed": []
907 },
907 },
908 {
908 {
909 "rev": 3,
909 "rev": 3,
910 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
910 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
911 "branch": "default",
911 "branch": "default",
912 "phase": "draft",
912 "phase": "draft",
913 "user": "person",
913 "user": "person",
914 "date": [1300000, 0],
914 "date": [1300000, 0],
915 "desc": "no user, no domain",
915 "desc": "no user, no domain",
916 "bookmarks": [],
916 "bookmarks": [],
917 "tags": [],
917 "tags": [],
918 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
918 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
919 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
919 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
920 "extra": {"branch": "default"},
920 "extra": {"branch": "default"},
921 "modified": ["c"],
921 "modified": ["c"],
922 "added": [],
922 "added": [],
923 "removed": []
923 "removed": []
924 },
924 },
925 {
925 {
926 "rev": 2,
926 "rev": 2,
927 "node": "97054abb4ab824450e9164180baf491ae0078465",
927 "node": "97054abb4ab824450e9164180baf491ae0078465",
928 "branch": "default",
928 "branch": "default",
929 "phase": "draft",
929 "phase": "draft",
930 "user": "other@place",
930 "user": "other@place",
931 "date": [1200000, 0],
931 "date": [1200000, 0],
932 "desc": "no person",
932 "desc": "no person",
933 "bookmarks": [],
933 "bookmarks": [],
934 "tags": [],
934 "tags": [],
935 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
935 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
936 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
936 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
937 "extra": {"branch": "default"},
937 "extra": {"branch": "default"},
938 "modified": [],
938 "modified": [],
939 "added": ["c"],
939 "added": ["c"],
940 "removed": []
940 "removed": []
941 },
941 },
942 {
942 {
943 "rev": 1,
943 "rev": 1,
944 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
944 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
945 "branch": "default",
945 "branch": "default",
946 "phase": "draft",
946 "phase": "draft",
947 "user": "A. N. Other <other@place>",
947 "user": "A. N. Other <other@place>",
948 "date": [1100000, 0],
948 "date": [1100000, 0],
949 "desc": "other 1\nother 2\n\nother 3",
949 "desc": "other 1\nother 2\n\nother 3",
950 "bookmarks": [],
950 "bookmarks": [],
951 "tags": [],
951 "tags": [],
952 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
952 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
953 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
953 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
954 "extra": {"branch": "default"},
954 "extra": {"branch": "default"},
955 "modified": [],
955 "modified": [],
956 "added": ["b"],
956 "added": ["b"],
957 "removed": []
957 "removed": []
958 },
958 },
959 {
959 {
960 "rev": 0,
960 "rev": 0,
961 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
961 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
962 "branch": "default",
962 "branch": "default",
963 "phase": "draft",
963 "phase": "draft",
964 "user": "User Name <user@hostname>",
964 "user": "User Name <user@hostname>",
965 "date": [1000000, 0],
965 "date": [1000000, 0],
966 "desc": "line 1\nline 2",
966 "desc": "line 1\nline 2",
967 "bookmarks": [],
967 "bookmarks": [],
968 "tags": [],
968 "tags": [],
969 "parents": ["0000000000000000000000000000000000000000"],
969 "parents": ["0000000000000000000000000000000000000000"],
970 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
970 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
971 "extra": {"branch": "default"},
971 "extra": {"branch": "default"},
972 "modified": [],
972 "modified": [],
973 "added": ["a"],
973 "added": ["a"],
974 "removed": []
974 "removed": []
975 }
975 }
976 ]
976 ]
977
977
978 Error if style not readable:
978 Error if style not readable:
979
979
980 #if unix-permissions no-root
980 #if unix-permissions no-root
981 $ touch q
981 $ touch q
982 $ chmod 0 q
982 $ chmod 0 q
983 $ hg log --style ./q
983 $ hg log --style ./q
984 abort: Permission denied: ./q
984 abort: Permission denied: ./q
985 [255]
985 [255]
986 #endif
986 #endif
987
987
988 Error if no style:
988 Error if no style:
989
989
990 $ hg log --style notexist
990 $ hg log --style notexist
991 abort: style 'notexist' not found
991 abort: style 'notexist' not found
992 (available styles: bisect, changelog, compact, default, phases, status, xml)
992 (available styles: bisect, changelog, compact, default, phases, status, xml)
993 [255]
993 [255]
994
994
995 $ hg log -T list
995 $ hg log -T list
996 available styles: bisect, changelog, compact, default, phases, status, xml
996 available styles: bisect, changelog, compact, default, phases, status, xml
997 abort: specify a template
997 abort: specify a template
998 [255]
998 [255]
999
999
1000 Error if style missing key:
1000 Error if style missing key:
1001
1001
1002 $ echo 'q = q' > t
1002 $ echo 'q = q' > t
1003 $ hg log --style ./t
1003 $ hg log --style ./t
1004 abort: "changeset" not in template map
1004 abort: "changeset" not in template map
1005 [255]
1005 [255]
1006
1006
1007 Error if style missing value:
1007 Error if style missing value:
1008
1008
1009 $ echo 'changeset =' > t
1009 $ echo 'changeset =' > t
1010 $ hg log --style t
1010 $ hg log --style t
1011 abort: t:1: missing value
1011 abort: t:1: missing value
1012 [255]
1012 [255]
1013
1013
1014 Error if include fails:
1014 Error if include fails:
1015
1015
1016 $ echo 'changeset = q' >> t
1016 $ echo 'changeset = q' >> t
1017 #if unix-permissions no-root
1017 #if unix-permissions no-root
1018 $ hg log --style ./t
1018 $ hg log --style ./t
1019 abort: template file ./q: Permission denied
1019 abort: template file ./q: Permission denied
1020 [255]
1020 [255]
1021 $ rm -f q
1021 $ rm -f q
1022 #endif
1022 #endif
1023
1023
1024 Include works:
1024 Include works:
1025
1025
1026 $ echo '{rev}' > q
1026 $ echo '{rev}' > q
1027 $ hg log --style ./t
1027 $ hg log --style ./t
1028 8
1028 8
1029 7
1029 7
1030 6
1030 6
1031 5
1031 5
1032 4
1032 4
1033 3
1033 3
1034 2
1034 2
1035 1
1035 1
1036 0
1036 0
1037
1037
1038 Check that recursive reference does not fall into RuntimeError (issue4758):
1038 Check that recursive reference does not fall into RuntimeError (issue4758):
1039
1039
1040 common mistake:
1040 common mistake:
1041
1041
1042 $ hg log -T '{changeset}\n'
1042 $ hg log -T '{changeset}\n'
1043 abort: recursive reference 'changeset' in template
1043 abort: recursive reference 'changeset' in template
1044 [255]
1044 [255]
1045
1045
1046 circular reference:
1046 circular reference:
1047
1047
1048 $ cat << EOF > issue4758
1048 $ cat << EOF > issue4758
1049 > changeset = '{foo}'
1049 > changeset = '{foo}'
1050 > foo = '{changeset}'
1050 > foo = '{changeset}'
1051 > EOF
1051 > EOF
1052 $ hg log --style ./issue4758
1052 $ hg log --style ./issue4758
1053 abort: recursive reference 'foo' in template
1053 abort: recursive reference 'foo' in template
1054 [255]
1054 [255]
1055
1055
1056 buildmap() -> gettemplate(), where no thunk was made:
1056 buildmap() -> gettemplate(), where no thunk was made:
1057
1057
1058 $ hg log -T '{files % changeset}\n'
1058 $ hg log -T '{files % changeset}\n'
1059 abort: recursive reference 'changeset' in template
1059 abort: recursive reference 'changeset' in template
1060 [255]
1060 [255]
1061
1061
1062 not a recursion if a keyword of the same name exists:
1062 not a recursion if a keyword of the same name exists:
1063
1063
1064 $ cat << EOF > issue4758
1064 $ cat << EOF > issue4758
1065 > changeset = '{tags % rev}'
1065 > changeset = '{tags % rev}'
1066 > rev = '{rev} {tag}\n'
1066 > rev = '{rev} {tag}\n'
1067 > EOF
1067 > EOF
1068 $ hg log --style ./issue4758 -r tip
1068 $ hg log --style ./issue4758 -r tip
1069 8 tip
1069 8 tip
1070
1070
1071 Check that {phase} works correctly on parents:
1071 Check that {phase} works correctly on parents:
1072
1072
1073 $ cat << EOF > parentphase
1073 $ cat << EOF > parentphase
1074 > changeset_debug = '{rev} ({phase}):{parents}\n'
1074 > changeset_debug = '{rev} ({phase}):{parents}\n'
1075 > parent = ' {rev} ({phase})'
1075 > parent = ' {rev} ({phase})'
1076 > EOF
1076 > EOF
1077 $ hg phase -r 5 --public
1077 $ hg phase -r 5 --public
1078 $ hg phase -r 7 --secret --force
1078 $ hg phase -r 7 --secret --force
1079 $ hg log --debug -G --style ./parentphase
1079 $ hg log --debug -G --style ./parentphase
1080 @ 8 (secret): 7 (secret) -1 (public)
1080 @ 8 (secret): 7 (secret) -1 (public)
1081 |
1081 |
1082 o 7 (secret): -1 (public) -1 (public)
1082 o 7 (secret): -1 (public) -1 (public)
1083
1083
1084 o 6 (draft): 5 (public) 4 (draft)
1084 o 6 (draft): 5 (public) 4 (draft)
1085 |\
1085 |\
1086 | o 5 (public): 3 (public) -1 (public)
1086 | o 5 (public): 3 (public) -1 (public)
1087 | |
1087 | |
1088 o | 4 (draft): 3 (public) -1 (public)
1088 o | 4 (draft): 3 (public) -1 (public)
1089 |/
1089 |/
1090 o 3 (public): 2 (public) -1 (public)
1090 o 3 (public): 2 (public) -1 (public)
1091 |
1091 |
1092 o 2 (public): 1 (public) -1 (public)
1092 o 2 (public): 1 (public) -1 (public)
1093 |
1093 |
1094 o 1 (public): 0 (public) -1 (public)
1094 o 1 (public): 0 (public) -1 (public)
1095 |
1095 |
1096 o 0 (public): -1 (public) -1 (public)
1096 o 0 (public): -1 (public) -1 (public)
1097
1097
1098
1098
1099 Missing non-standard names give no error (backward compatibility):
1099 Missing non-standard names give no error (backward compatibility):
1100
1100
1101 $ echo "changeset = '{c}'" > t
1101 $ echo "changeset = '{c}'" > t
1102 $ hg log --style ./t
1102 $ hg log --style ./t
1103
1103
1104 Defining non-standard name works:
1104 Defining non-standard name works:
1105
1105
1106 $ cat <<EOF > t
1106 $ cat <<EOF > t
1107 > changeset = '{c}'
1107 > changeset = '{c}'
1108 > c = q
1108 > c = q
1109 > EOF
1109 > EOF
1110 $ hg log --style ./t
1110 $ hg log --style ./t
1111 8
1111 8
1112 7
1112 7
1113 6
1113 6
1114 5
1114 5
1115 4
1115 4
1116 3
1116 3
1117 2
1117 2
1118 1
1118 1
1119 0
1119 0
1120
1120
1121 ui.style works:
1121 ui.style works:
1122
1122
1123 $ echo '[ui]' > .hg/hgrc
1123 $ echo '[ui]' > .hg/hgrc
1124 $ echo 'style = t' >> .hg/hgrc
1124 $ echo 'style = t' >> .hg/hgrc
1125 $ hg log
1125 $ hg log
1126 8
1126 8
1127 7
1127 7
1128 6
1128 6
1129 5
1129 5
1130 4
1130 4
1131 3
1131 3
1132 2
1132 2
1133 1
1133 1
1134 0
1134 0
1135
1135
1136
1136
1137 Issue338:
1137 Issue338:
1138
1138
1139 $ hg log --style=changelog > changelog
1139 $ hg log --style=changelog > changelog
1140
1140
1141 $ cat changelog
1141 $ cat changelog
1142 2020-01-01 test <test>
1142 2020-01-01 test <test>
1143
1143
1144 * fourth, second, third:
1144 * fourth, second, third:
1145 third
1145 third
1146 [95c24699272e] [tip]
1146 [95c24699272e] [tip]
1147
1147
1148 1970-01-12 User Name <user@hostname>
1148 1970-01-12 User Name <user@hostname>
1149
1149
1150 * second:
1150 * second:
1151 second
1151 second
1152 [29114dbae42b]
1152 [29114dbae42b]
1153
1153
1154 1970-01-18 person <person>
1154 1970-01-18 person <person>
1155
1155
1156 * merge
1156 * merge
1157 [d41e714fe50d]
1157 [d41e714fe50d]
1158
1158
1159 * d:
1159 * d:
1160 new head
1160 new head
1161 [13207e5a10d9]
1161 [13207e5a10d9]
1162
1162
1163 1970-01-17 person <person>
1163 1970-01-17 person <person>
1164
1164
1165 * new branch
1165 * new branch
1166 [bbe44766e73d] <foo>
1166 [bbe44766e73d] <foo>
1167
1167
1168 1970-01-16 person <person>
1168 1970-01-16 person <person>
1169
1169
1170 * c:
1170 * c:
1171 no user, no domain
1171 no user, no domain
1172 [10e46f2dcbf4]
1172 [10e46f2dcbf4]
1173
1173
1174 1970-01-14 other <other@place>
1174 1970-01-14 other <other@place>
1175
1175
1176 * c:
1176 * c:
1177 no person
1177 no person
1178 [97054abb4ab8]
1178 [97054abb4ab8]
1179
1179
1180 1970-01-13 A. N. Other <other@place>
1180 1970-01-13 A. N. Other <other@place>
1181
1181
1182 * b:
1182 * b:
1183 other 1 other 2
1183 other 1 other 2
1184
1184
1185 other 3
1185 other 3
1186 [b608e9d1a3f0]
1186 [b608e9d1a3f0]
1187
1187
1188 1970-01-12 User Name <user@hostname>
1188 1970-01-12 User Name <user@hostname>
1189
1189
1190 * a:
1190 * a:
1191 line 1 line 2
1191 line 1 line 2
1192 [1e4e1b8f71e0]
1192 [1e4e1b8f71e0]
1193
1193
1194
1194
1195 Issue2130: xml output for 'hg heads' is malformed
1195 Issue2130: xml output for 'hg heads' is malformed
1196
1196
1197 $ hg heads --style changelog
1197 $ hg heads --style changelog
1198 2020-01-01 test <test>
1198 2020-01-01 test <test>
1199
1199
1200 * fourth, second, third:
1200 * fourth, second, third:
1201 third
1201 third
1202 [95c24699272e] [tip]
1202 [95c24699272e] [tip]
1203
1203
1204 1970-01-18 person <person>
1204 1970-01-18 person <person>
1205
1205
1206 * merge
1206 * merge
1207 [d41e714fe50d]
1207 [d41e714fe50d]
1208
1208
1209 1970-01-17 person <person>
1209 1970-01-17 person <person>
1210
1210
1211 * new branch
1211 * new branch
1212 [bbe44766e73d] <foo>
1212 [bbe44766e73d] <foo>
1213
1213
1214
1214
1215 Keys work:
1215 Keys work:
1216
1216
1217 $ for key in author branch branches date desc file_adds file_dels file_mods \
1217 $ for key in author branch branches date desc file_adds file_dels file_mods \
1218 > file_copies file_copies_switch files \
1218 > file_copies file_copies_switch files \
1219 > manifest node parents rev tags diffstat extras \
1219 > manifest node parents rev tags diffstat extras \
1220 > p1rev p2rev p1node p2node; do
1220 > p1rev p2rev p1node p2node; do
1221 > for mode in '' --verbose --debug; do
1221 > for mode in '' --verbose --debug; do
1222 > hg log $mode --template "$key$mode: {$key}\n"
1222 > hg log $mode --template "$key$mode: {$key}\n"
1223 > done
1223 > done
1224 > done
1224 > done
1225 author: test
1225 author: test
1226 author: User Name <user@hostname>
1226 author: User Name <user@hostname>
1227 author: person
1227 author: person
1228 author: person
1228 author: person
1229 author: person
1229 author: person
1230 author: person
1230 author: person
1231 author: other@place
1231 author: other@place
1232 author: A. N. Other <other@place>
1232 author: A. N. Other <other@place>
1233 author: User Name <user@hostname>
1233 author: User Name <user@hostname>
1234 author--verbose: test
1234 author--verbose: test
1235 author--verbose: User Name <user@hostname>
1235 author--verbose: User Name <user@hostname>
1236 author--verbose: person
1236 author--verbose: person
1237 author--verbose: person
1237 author--verbose: person
1238 author--verbose: person
1238 author--verbose: person
1239 author--verbose: person
1239 author--verbose: person
1240 author--verbose: other@place
1240 author--verbose: other@place
1241 author--verbose: A. N. Other <other@place>
1241 author--verbose: A. N. Other <other@place>
1242 author--verbose: User Name <user@hostname>
1242 author--verbose: User Name <user@hostname>
1243 author--debug: test
1243 author--debug: test
1244 author--debug: User Name <user@hostname>
1244 author--debug: User Name <user@hostname>
1245 author--debug: person
1245 author--debug: person
1246 author--debug: person
1246 author--debug: person
1247 author--debug: person
1247 author--debug: person
1248 author--debug: person
1248 author--debug: person
1249 author--debug: other@place
1249 author--debug: other@place
1250 author--debug: A. N. Other <other@place>
1250 author--debug: A. N. Other <other@place>
1251 author--debug: User Name <user@hostname>
1251 author--debug: User Name <user@hostname>
1252 branch: default
1252 branch: default
1253 branch: default
1253 branch: default
1254 branch: default
1254 branch: default
1255 branch: default
1255 branch: default
1256 branch: foo
1256 branch: foo
1257 branch: default
1257 branch: default
1258 branch: default
1258 branch: default
1259 branch: default
1259 branch: default
1260 branch: default
1260 branch: default
1261 branch--verbose: default
1261 branch--verbose: default
1262 branch--verbose: default
1262 branch--verbose: default
1263 branch--verbose: default
1263 branch--verbose: default
1264 branch--verbose: default
1264 branch--verbose: default
1265 branch--verbose: foo
1265 branch--verbose: foo
1266 branch--verbose: default
1266 branch--verbose: default
1267 branch--verbose: default
1267 branch--verbose: default
1268 branch--verbose: default
1268 branch--verbose: default
1269 branch--verbose: default
1269 branch--verbose: default
1270 branch--debug: default
1270 branch--debug: default
1271 branch--debug: default
1271 branch--debug: default
1272 branch--debug: default
1272 branch--debug: default
1273 branch--debug: default
1273 branch--debug: default
1274 branch--debug: foo
1274 branch--debug: foo
1275 branch--debug: default
1275 branch--debug: default
1276 branch--debug: default
1276 branch--debug: default
1277 branch--debug: default
1277 branch--debug: default
1278 branch--debug: default
1278 branch--debug: default
1279 branches:
1279 branches:
1280 branches:
1280 branches:
1281 branches:
1281 branches:
1282 branches:
1282 branches:
1283 branches: foo
1283 branches: foo
1284 branches:
1284 branches:
1285 branches:
1285 branches:
1286 branches:
1286 branches:
1287 branches:
1287 branches:
1288 branches--verbose:
1288 branches--verbose:
1289 branches--verbose:
1289 branches--verbose:
1290 branches--verbose:
1290 branches--verbose:
1291 branches--verbose:
1291 branches--verbose:
1292 branches--verbose: foo
1292 branches--verbose: foo
1293 branches--verbose:
1293 branches--verbose:
1294 branches--verbose:
1294 branches--verbose:
1295 branches--verbose:
1295 branches--verbose:
1296 branches--verbose:
1296 branches--verbose:
1297 branches--debug:
1297 branches--debug:
1298 branches--debug:
1298 branches--debug:
1299 branches--debug:
1299 branches--debug:
1300 branches--debug:
1300 branches--debug:
1301 branches--debug: foo
1301 branches--debug: foo
1302 branches--debug:
1302 branches--debug:
1303 branches--debug:
1303 branches--debug:
1304 branches--debug:
1304 branches--debug:
1305 branches--debug:
1305 branches--debug:
1306 date: 1577872860.00
1306 date: 1577872860.00
1307 date: 1000000.00
1307 date: 1000000.00
1308 date: 1500001.00
1308 date: 1500001.00
1309 date: 1500000.00
1309 date: 1500000.00
1310 date: 1400000.00
1310 date: 1400000.00
1311 date: 1300000.00
1311 date: 1300000.00
1312 date: 1200000.00
1312 date: 1200000.00
1313 date: 1100000.00
1313 date: 1100000.00
1314 date: 1000000.00
1314 date: 1000000.00
1315 date--verbose: 1577872860.00
1315 date--verbose: 1577872860.00
1316 date--verbose: 1000000.00
1316 date--verbose: 1000000.00
1317 date--verbose: 1500001.00
1317 date--verbose: 1500001.00
1318 date--verbose: 1500000.00
1318 date--verbose: 1500000.00
1319 date--verbose: 1400000.00
1319 date--verbose: 1400000.00
1320 date--verbose: 1300000.00
1320 date--verbose: 1300000.00
1321 date--verbose: 1200000.00
1321 date--verbose: 1200000.00
1322 date--verbose: 1100000.00
1322 date--verbose: 1100000.00
1323 date--verbose: 1000000.00
1323 date--verbose: 1000000.00
1324 date--debug: 1577872860.00
1324 date--debug: 1577872860.00
1325 date--debug: 1000000.00
1325 date--debug: 1000000.00
1326 date--debug: 1500001.00
1326 date--debug: 1500001.00
1327 date--debug: 1500000.00
1327 date--debug: 1500000.00
1328 date--debug: 1400000.00
1328 date--debug: 1400000.00
1329 date--debug: 1300000.00
1329 date--debug: 1300000.00
1330 date--debug: 1200000.00
1330 date--debug: 1200000.00
1331 date--debug: 1100000.00
1331 date--debug: 1100000.00
1332 date--debug: 1000000.00
1332 date--debug: 1000000.00
1333 desc: third
1333 desc: third
1334 desc: second
1334 desc: second
1335 desc: merge
1335 desc: merge
1336 desc: new head
1336 desc: new head
1337 desc: new branch
1337 desc: new branch
1338 desc: no user, no domain
1338 desc: no user, no domain
1339 desc: no person
1339 desc: no person
1340 desc: other 1
1340 desc: other 1
1341 other 2
1341 other 2
1342
1342
1343 other 3
1343 other 3
1344 desc: line 1
1344 desc: line 1
1345 line 2
1345 line 2
1346 desc--verbose: third
1346 desc--verbose: third
1347 desc--verbose: second
1347 desc--verbose: second
1348 desc--verbose: merge
1348 desc--verbose: merge
1349 desc--verbose: new head
1349 desc--verbose: new head
1350 desc--verbose: new branch
1350 desc--verbose: new branch
1351 desc--verbose: no user, no domain
1351 desc--verbose: no user, no domain
1352 desc--verbose: no person
1352 desc--verbose: no person
1353 desc--verbose: other 1
1353 desc--verbose: other 1
1354 other 2
1354 other 2
1355
1355
1356 other 3
1356 other 3
1357 desc--verbose: line 1
1357 desc--verbose: line 1
1358 line 2
1358 line 2
1359 desc--debug: third
1359 desc--debug: third
1360 desc--debug: second
1360 desc--debug: second
1361 desc--debug: merge
1361 desc--debug: merge
1362 desc--debug: new head
1362 desc--debug: new head
1363 desc--debug: new branch
1363 desc--debug: new branch
1364 desc--debug: no user, no domain
1364 desc--debug: no user, no domain
1365 desc--debug: no person
1365 desc--debug: no person
1366 desc--debug: other 1
1366 desc--debug: other 1
1367 other 2
1367 other 2
1368
1368
1369 other 3
1369 other 3
1370 desc--debug: line 1
1370 desc--debug: line 1
1371 line 2
1371 line 2
1372 file_adds: fourth third
1372 file_adds: fourth third
1373 file_adds: second
1373 file_adds: second
1374 file_adds:
1374 file_adds:
1375 file_adds: d
1375 file_adds: d
1376 file_adds:
1376 file_adds:
1377 file_adds:
1377 file_adds:
1378 file_adds: c
1378 file_adds: c
1379 file_adds: b
1379 file_adds: b
1380 file_adds: a
1380 file_adds: a
1381 file_adds--verbose: fourth third
1381 file_adds--verbose: fourth third
1382 file_adds--verbose: second
1382 file_adds--verbose: second
1383 file_adds--verbose:
1383 file_adds--verbose:
1384 file_adds--verbose: d
1384 file_adds--verbose: d
1385 file_adds--verbose:
1385 file_adds--verbose:
1386 file_adds--verbose:
1386 file_adds--verbose:
1387 file_adds--verbose: c
1387 file_adds--verbose: c
1388 file_adds--verbose: b
1388 file_adds--verbose: b
1389 file_adds--verbose: a
1389 file_adds--verbose: a
1390 file_adds--debug: fourth third
1390 file_adds--debug: fourth third
1391 file_adds--debug: second
1391 file_adds--debug: second
1392 file_adds--debug:
1392 file_adds--debug:
1393 file_adds--debug: d
1393 file_adds--debug: d
1394 file_adds--debug:
1394 file_adds--debug:
1395 file_adds--debug:
1395 file_adds--debug:
1396 file_adds--debug: c
1396 file_adds--debug: c
1397 file_adds--debug: b
1397 file_adds--debug: b
1398 file_adds--debug: a
1398 file_adds--debug: a
1399 file_dels: second
1399 file_dels: second
1400 file_dels:
1400 file_dels:
1401 file_dels:
1401 file_dels:
1402 file_dels:
1402 file_dels:
1403 file_dels:
1403 file_dels:
1404 file_dels:
1404 file_dels:
1405 file_dels:
1405 file_dels:
1406 file_dels:
1406 file_dels:
1407 file_dels:
1407 file_dels:
1408 file_dels--verbose: second
1408 file_dels--verbose: second
1409 file_dels--verbose:
1409 file_dels--verbose:
1410 file_dels--verbose:
1410 file_dels--verbose:
1411 file_dels--verbose:
1411 file_dels--verbose:
1412 file_dels--verbose:
1412 file_dels--verbose:
1413 file_dels--verbose:
1413 file_dels--verbose:
1414 file_dels--verbose:
1414 file_dels--verbose:
1415 file_dels--verbose:
1415 file_dels--verbose:
1416 file_dels--verbose:
1416 file_dels--verbose:
1417 file_dels--debug: second
1417 file_dels--debug: second
1418 file_dels--debug:
1418 file_dels--debug:
1419 file_dels--debug:
1419 file_dels--debug:
1420 file_dels--debug:
1420 file_dels--debug:
1421 file_dels--debug:
1421 file_dels--debug:
1422 file_dels--debug:
1422 file_dels--debug:
1423 file_dels--debug:
1423 file_dels--debug:
1424 file_dels--debug:
1424 file_dels--debug:
1425 file_dels--debug:
1425 file_dels--debug:
1426 file_mods:
1426 file_mods:
1427 file_mods:
1427 file_mods:
1428 file_mods:
1428 file_mods:
1429 file_mods:
1429 file_mods:
1430 file_mods:
1430 file_mods:
1431 file_mods: c
1431 file_mods: c
1432 file_mods:
1432 file_mods:
1433 file_mods:
1433 file_mods:
1434 file_mods:
1434 file_mods:
1435 file_mods--verbose:
1435 file_mods--verbose:
1436 file_mods--verbose:
1436 file_mods--verbose:
1437 file_mods--verbose:
1437 file_mods--verbose:
1438 file_mods--verbose:
1438 file_mods--verbose:
1439 file_mods--verbose:
1439 file_mods--verbose:
1440 file_mods--verbose: c
1440 file_mods--verbose: c
1441 file_mods--verbose:
1441 file_mods--verbose:
1442 file_mods--verbose:
1442 file_mods--verbose:
1443 file_mods--verbose:
1443 file_mods--verbose:
1444 file_mods--debug:
1444 file_mods--debug:
1445 file_mods--debug:
1445 file_mods--debug:
1446 file_mods--debug:
1446 file_mods--debug:
1447 file_mods--debug:
1447 file_mods--debug:
1448 file_mods--debug:
1448 file_mods--debug:
1449 file_mods--debug: c
1449 file_mods--debug: c
1450 file_mods--debug:
1450 file_mods--debug:
1451 file_mods--debug:
1451 file_mods--debug:
1452 file_mods--debug:
1452 file_mods--debug:
1453 file_copies: fourth (second)
1453 file_copies: fourth (second)
1454 file_copies:
1454 file_copies:
1455 file_copies:
1455 file_copies:
1456 file_copies:
1456 file_copies:
1457 file_copies:
1457 file_copies:
1458 file_copies:
1458 file_copies:
1459 file_copies:
1459 file_copies:
1460 file_copies:
1460 file_copies:
1461 file_copies:
1461 file_copies:
1462 file_copies--verbose: fourth (second)
1462 file_copies--verbose: fourth (second)
1463 file_copies--verbose:
1463 file_copies--verbose:
1464 file_copies--verbose:
1464 file_copies--verbose:
1465 file_copies--verbose:
1465 file_copies--verbose:
1466 file_copies--verbose:
1466 file_copies--verbose:
1467 file_copies--verbose:
1467 file_copies--verbose:
1468 file_copies--verbose:
1468 file_copies--verbose:
1469 file_copies--verbose:
1469 file_copies--verbose:
1470 file_copies--verbose:
1470 file_copies--verbose:
1471 file_copies--debug: fourth (second)
1471 file_copies--debug: fourth (second)
1472 file_copies--debug:
1472 file_copies--debug:
1473 file_copies--debug:
1473 file_copies--debug:
1474 file_copies--debug:
1474 file_copies--debug:
1475 file_copies--debug:
1475 file_copies--debug:
1476 file_copies--debug:
1476 file_copies--debug:
1477 file_copies--debug:
1477 file_copies--debug:
1478 file_copies--debug:
1478 file_copies--debug:
1479 file_copies--debug:
1479 file_copies--debug:
1480 file_copies_switch:
1480 file_copies_switch:
1481 file_copies_switch:
1481 file_copies_switch:
1482 file_copies_switch:
1482 file_copies_switch:
1483 file_copies_switch:
1483 file_copies_switch:
1484 file_copies_switch:
1484 file_copies_switch:
1485 file_copies_switch:
1485 file_copies_switch:
1486 file_copies_switch:
1486 file_copies_switch:
1487 file_copies_switch:
1487 file_copies_switch:
1488 file_copies_switch:
1488 file_copies_switch:
1489 file_copies_switch--verbose:
1489 file_copies_switch--verbose:
1490 file_copies_switch--verbose:
1490 file_copies_switch--verbose:
1491 file_copies_switch--verbose:
1491 file_copies_switch--verbose:
1492 file_copies_switch--verbose:
1492 file_copies_switch--verbose:
1493 file_copies_switch--verbose:
1493 file_copies_switch--verbose:
1494 file_copies_switch--verbose:
1494 file_copies_switch--verbose:
1495 file_copies_switch--verbose:
1495 file_copies_switch--verbose:
1496 file_copies_switch--verbose:
1496 file_copies_switch--verbose:
1497 file_copies_switch--verbose:
1497 file_copies_switch--verbose:
1498 file_copies_switch--debug:
1498 file_copies_switch--debug:
1499 file_copies_switch--debug:
1499 file_copies_switch--debug:
1500 file_copies_switch--debug:
1500 file_copies_switch--debug:
1501 file_copies_switch--debug:
1501 file_copies_switch--debug:
1502 file_copies_switch--debug:
1502 file_copies_switch--debug:
1503 file_copies_switch--debug:
1503 file_copies_switch--debug:
1504 file_copies_switch--debug:
1504 file_copies_switch--debug:
1505 file_copies_switch--debug:
1505 file_copies_switch--debug:
1506 file_copies_switch--debug:
1506 file_copies_switch--debug:
1507 files: fourth second third
1507 files: fourth second third
1508 files: second
1508 files: second
1509 files:
1509 files:
1510 files: d
1510 files: d
1511 files:
1511 files:
1512 files: c
1512 files: c
1513 files: c
1513 files: c
1514 files: b
1514 files: b
1515 files: a
1515 files: a
1516 files--verbose: fourth second third
1516 files--verbose: fourth second third
1517 files--verbose: second
1517 files--verbose: second
1518 files--verbose:
1518 files--verbose:
1519 files--verbose: d
1519 files--verbose: d
1520 files--verbose:
1520 files--verbose:
1521 files--verbose: c
1521 files--verbose: c
1522 files--verbose: c
1522 files--verbose: c
1523 files--verbose: b
1523 files--verbose: b
1524 files--verbose: a
1524 files--verbose: a
1525 files--debug: fourth second third
1525 files--debug: fourth second third
1526 files--debug: second
1526 files--debug: second
1527 files--debug:
1527 files--debug:
1528 files--debug: d
1528 files--debug: d
1529 files--debug:
1529 files--debug:
1530 files--debug: c
1530 files--debug: c
1531 files--debug: c
1531 files--debug: c
1532 files--debug: b
1532 files--debug: b
1533 files--debug: a
1533 files--debug: a
1534 manifest: 6:94961b75a2da
1534 manifest: 6:94961b75a2da
1535 manifest: 5:f2dbc354b94e
1535 manifest: 5:f2dbc354b94e
1536 manifest: 4:4dc3def4f9b4
1536 manifest: 4:4dc3def4f9b4
1537 manifest: 4:4dc3def4f9b4
1537 manifest: 4:4dc3def4f9b4
1538 manifest: 3:cb5a1327723b
1538 manifest: 3:cb5a1327723b
1539 manifest: 3:cb5a1327723b
1539 manifest: 3:cb5a1327723b
1540 manifest: 2:6e0e82995c35
1540 manifest: 2:6e0e82995c35
1541 manifest: 1:4e8d705b1e53
1541 manifest: 1:4e8d705b1e53
1542 manifest: 0:a0c8bcbbb45c
1542 manifest: 0:a0c8bcbbb45c
1543 manifest--verbose: 6:94961b75a2da
1543 manifest--verbose: 6:94961b75a2da
1544 manifest--verbose: 5:f2dbc354b94e
1544 manifest--verbose: 5:f2dbc354b94e
1545 manifest--verbose: 4:4dc3def4f9b4
1545 manifest--verbose: 4:4dc3def4f9b4
1546 manifest--verbose: 4:4dc3def4f9b4
1546 manifest--verbose: 4:4dc3def4f9b4
1547 manifest--verbose: 3:cb5a1327723b
1547 manifest--verbose: 3:cb5a1327723b
1548 manifest--verbose: 3:cb5a1327723b
1548 manifest--verbose: 3:cb5a1327723b
1549 manifest--verbose: 2:6e0e82995c35
1549 manifest--verbose: 2:6e0e82995c35
1550 manifest--verbose: 1:4e8d705b1e53
1550 manifest--verbose: 1:4e8d705b1e53
1551 manifest--verbose: 0:a0c8bcbbb45c
1551 manifest--verbose: 0:a0c8bcbbb45c
1552 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1552 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1553 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1553 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1554 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1554 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1555 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1555 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1556 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1556 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1557 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1557 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1558 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1558 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1559 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1559 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1560 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1560 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1561 node: 95c24699272ef57d062b8bccc32c878bf841784a
1561 node: 95c24699272ef57d062b8bccc32c878bf841784a
1562 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1562 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1563 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1563 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1564 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1564 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1565 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1565 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1566 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1566 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1567 node: 97054abb4ab824450e9164180baf491ae0078465
1567 node: 97054abb4ab824450e9164180baf491ae0078465
1568 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1568 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1569 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1569 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1570 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1570 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1571 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1571 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1572 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1572 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1573 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1573 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1574 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1574 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1575 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1575 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1576 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1576 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1577 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1577 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1578 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1578 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1579 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1579 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1580 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1580 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1581 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1581 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1582 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1582 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1583 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1583 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1584 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1584 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1585 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1585 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1586 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1586 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1587 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1587 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1588 parents:
1588 parents:
1589 parents: -1:000000000000
1589 parents: -1:000000000000
1590 parents: 5:13207e5a10d9 4:bbe44766e73d
1590 parents: 5:13207e5a10d9 4:bbe44766e73d
1591 parents: 3:10e46f2dcbf4
1591 parents: 3:10e46f2dcbf4
1592 parents:
1592 parents:
1593 parents:
1593 parents:
1594 parents:
1594 parents:
1595 parents:
1595 parents:
1596 parents:
1596 parents:
1597 parents--verbose:
1597 parents--verbose:
1598 parents--verbose: -1:000000000000
1598 parents--verbose: -1:000000000000
1599 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1599 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1600 parents--verbose: 3:10e46f2dcbf4
1600 parents--verbose: 3:10e46f2dcbf4
1601 parents--verbose:
1601 parents--verbose:
1602 parents--verbose:
1602 parents--verbose:
1603 parents--verbose:
1603 parents--verbose:
1604 parents--verbose:
1604 parents--verbose:
1605 parents--verbose:
1605 parents--verbose:
1606 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1606 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1607 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1607 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1608 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1608 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1609 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1609 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1610 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1610 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1611 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1611 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1612 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1612 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1613 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1613 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1614 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1614 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1615 rev: 8
1615 rev: 8
1616 rev: 7
1616 rev: 7
1617 rev: 6
1617 rev: 6
1618 rev: 5
1618 rev: 5
1619 rev: 4
1619 rev: 4
1620 rev: 3
1620 rev: 3
1621 rev: 2
1621 rev: 2
1622 rev: 1
1622 rev: 1
1623 rev: 0
1623 rev: 0
1624 rev--verbose: 8
1624 rev--verbose: 8
1625 rev--verbose: 7
1625 rev--verbose: 7
1626 rev--verbose: 6
1626 rev--verbose: 6
1627 rev--verbose: 5
1627 rev--verbose: 5
1628 rev--verbose: 4
1628 rev--verbose: 4
1629 rev--verbose: 3
1629 rev--verbose: 3
1630 rev--verbose: 2
1630 rev--verbose: 2
1631 rev--verbose: 1
1631 rev--verbose: 1
1632 rev--verbose: 0
1632 rev--verbose: 0
1633 rev--debug: 8
1633 rev--debug: 8
1634 rev--debug: 7
1634 rev--debug: 7
1635 rev--debug: 6
1635 rev--debug: 6
1636 rev--debug: 5
1636 rev--debug: 5
1637 rev--debug: 4
1637 rev--debug: 4
1638 rev--debug: 3
1638 rev--debug: 3
1639 rev--debug: 2
1639 rev--debug: 2
1640 rev--debug: 1
1640 rev--debug: 1
1641 rev--debug: 0
1641 rev--debug: 0
1642 tags: tip
1642 tags: tip
1643 tags:
1643 tags:
1644 tags:
1644 tags:
1645 tags:
1645 tags:
1646 tags:
1646 tags:
1647 tags:
1647 tags:
1648 tags:
1648 tags:
1649 tags:
1649 tags:
1650 tags:
1650 tags:
1651 tags--verbose: tip
1651 tags--verbose: tip
1652 tags--verbose:
1652 tags--verbose:
1653 tags--verbose:
1653 tags--verbose:
1654 tags--verbose:
1654 tags--verbose:
1655 tags--verbose:
1655 tags--verbose:
1656 tags--verbose:
1656 tags--verbose:
1657 tags--verbose:
1657 tags--verbose:
1658 tags--verbose:
1658 tags--verbose:
1659 tags--verbose:
1659 tags--verbose:
1660 tags--debug: tip
1660 tags--debug: tip
1661 tags--debug:
1661 tags--debug:
1662 tags--debug:
1662 tags--debug:
1663 tags--debug:
1663 tags--debug:
1664 tags--debug:
1664 tags--debug:
1665 tags--debug:
1665 tags--debug:
1666 tags--debug:
1666 tags--debug:
1667 tags--debug:
1667 tags--debug:
1668 tags--debug:
1668 tags--debug:
1669 diffstat: 3: +2/-1
1669 diffstat: 3: +2/-1
1670 diffstat: 1: +1/-0
1670 diffstat: 1: +1/-0
1671 diffstat: 0: +0/-0
1671 diffstat: 0: +0/-0
1672 diffstat: 1: +1/-0
1672 diffstat: 1: +1/-0
1673 diffstat: 0: +0/-0
1673 diffstat: 0: +0/-0
1674 diffstat: 1: +1/-0
1674 diffstat: 1: +1/-0
1675 diffstat: 1: +4/-0
1675 diffstat: 1: +4/-0
1676 diffstat: 1: +2/-0
1676 diffstat: 1: +2/-0
1677 diffstat: 1: +1/-0
1677 diffstat: 1: +1/-0
1678 diffstat--verbose: 3: +2/-1
1678 diffstat--verbose: 3: +2/-1
1679 diffstat--verbose: 1: +1/-0
1679 diffstat--verbose: 1: +1/-0
1680 diffstat--verbose: 0: +0/-0
1680 diffstat--verbose: 0: +0/-0
1681 diffstat--verbose: 1: +1/-0
1681 diffstat--verbose: 1: +1/-0
1682 diffstat--verbose: 0: +0/-0
1682 diffstat--verbose: 0: +0/-0
1683 diffstat--verbose: 1: +1/-0
1683 diffstat--verbose: 1: +1/-0
1684 diffstat--verbose: 1: +4/-0
1684 diffstat--verbose: 1: +4/-0
1685 diffstat--verbose: 1: +2/-0
1685 diffstat--verbose: 1: +2/-0
1686 diffstat--verbose: 1: +1/-0
1686 diffstat--verbose: 1: +1/-0
1687 diffstat--debug: 3: +2/-1
1687 diffstat--debug: 3: +2/-1
1688 diffstat--debug: 1: +1/-0
1688 diffstat--debug: 1: +1/-0
1689 diffstat--debug: 0: +0/-0
1689 diffstat--debug: 0: +0/-0
1690 diffstat--debug: 1: +1/-0
1690 diffstat--debug: 1: +1/-0
1691 diffstat--debug: 0: +0/-0
1691 diffstat--debug: 0: +0/-0
1692 diffstat--debug: 1: +1/-0
1692 diffstat--debug: 1: +1/-0
1693 diffstat--debug: 1: +4/-0
1693 diffstat--debug: 1: +4/-0
1694 diffstat--debug: 1: +2/-0
1694 diffstat--debug: 1: +2/-0
1695 diffstat--debug: 1: +1/-0
1695 diffstat--debug: 1: +1/-0
1696 extras: branch=default
1696 extras: branch=default
1697 extras: branch=default
1697 extras: branch=default
1698 extras: branch=default
1698 extras: branch=default
1699 extras: branch=default
1699 extras: branch=default
1700 extras: branch=foo
1700 extras: branch=foo
1701 extras: branch=default
1701 extras: branch=default
1702 extras: branch=default
1702 extras: branch=default
1703 extras: branch=default
1703 extras: branch=default
1704 extras: branch=default
1704 extras: branch=default
1705 extras--verbose: branch=default
1705 extras--verbose: branch=default
1706 extras--verbose: branch=default
1706 extras--verbose: branch=default
1707 extras--verbose: branch=default
1707 extras--verbose: branch=default
1708 extras--verbose: branch=default
1708 extras--verbose: branch=default
1709 extras--verbose: branch=foo
1709 extras--verbose: branch=foo
1710 extras--verbose: branch=default
1710 extras--verbose: branch=default
1711 extras--verbose: branch=default
1711 extras--verbose: branch=default
1712 extras--verbose: branch=default
1712 extras--verbose: branch=default
1713 extras--verbose: branch=default
1713 extras--verbose: branch=default
1714 extras--debug: branch=default
1714 extras--debug: branch=default
1715 extras--debug: branch=default
1715 extras--debug: branch=default
1716 extras--debug: branch=default
1716 extras--debug: branch=default
1717 extras--debug: branch=default
1717 extras--debug: branch=default
1718 extras--debug: branch=foo
1718 extras--debug: branch=foo
1719 extras--debug: branch=default
1719 extras--debug: branch=default
1720 extras--debug: branch=default
1720 extras--debug: branch=default
1721 extras--debug: branch=default
1721 extras--debug: branch=default
1722 extras--debug: branch=default
1722 extras--debug: branch=default
1723 p1rev: 7
1723 p1rev: 7
1724 p1rev: -1
1724 p1rev: -1
1725 p1rev: 5
1725 p1rev: 5
1726 p1rev: 3
1726 p1rev: 3
1727 p1rev: 3
1727 p1rev: 3
1728 p1rev: 2
1728 p1rev: 2
1729 p1rev: 1
1729 p1rev: 1
1730 p1rev: 0
1730 p1rev: 0
1731 p1rev: -1
1731 p1rev: -1
1732 p1rev--verbose: 7
1732 p1rev--verbose: 7
1733 p1rev--verbose: -1
1733 p1rev--verbose: -1
1734 p1rev--verbose: 5
1734 p1rev--verbose: 5
1735 p1rev--verbose: 3
1735 p1rev--verbose: 3
1736 p1rev--verbose: 3
1736 p1rev--verbose: 3
1737 p1rev--verbose: 2
1737 p1rev--verbose: 2
1738 p1rev--verbose: 1
1738 p1rev--verbose: 1
1739 p1rev--verbose: 0
1739 p1rev--verbose: 0
1740 p1rev--verbose: -1
1740 p1rev--verbose: -1
1741 p1rev--debug: 7
1741 p1rev--debug: 7
1742 p1rev--debug: -1
1742 p1rev--debug: -1
1743 p1rev--debug: 5
1743 p1rev--debug: 5
1744 p1rev--debug: 3
1744 p1rev--debug: 3
1745 p1rev--debug: 3
1745 p1rev--debug: 3
1746 p1rev--debug: 2
1746 p1rev--debug: 2
1747 p1rev--debug: 1
1747 p1rev--debug: 1
1748 p1rev--debug: 0
1748 p1rev--debug: 0
1749 p1rev--debug: -1
1749 p1rev--debug: -1
1750 p2rev: -1
1750 p2rev: -1
1751 p2rev: -1
1751 p2rev: -1
1752 p2rev: 4
1752 p2rev: 4
1753 p2rev: -1
1753 p2rev: -1
1754 p2rev: -1
1754 p2rev: -1
1755 p2rev: -1
1755 p2rev: -1
1756 p2rev: -1
1756 p2rev: -1
1757 p2rev: -1
1757 p2rev: -1
1758 p2rev: -1
1758 p2rev: -1
1759 p2rev--verbose: -1
1759 p2rev--verbose: -1
1760 p2rev--verbose: -1
1760 p2rev--verbose: -1
1761 p2rev--verbose: 4
1761 p2rev--verbose: 4
1762 p2rev--verbose: -1
1762 p2rev--verbose: -1
1763 p2rev--verbose: -1
1763 p2rev--verbose: -1
1764 p2rev--verbose: -1
1764 p2rev--verbose: -1
1765 p2rev--verbose: -1
1765 p2rev--verbose: -1
1766 p2rev--verbose: -1
1766 p2rev--verbose: -1
1767 p2rev--verbose: -1
1767 p2rev--verbose: -1
1768 p2rev--debug: -1
1768 p2rev--debug: -1
1769 p2rev--debug: -1
1769 p2rev--debug: -1
1770 p2rev--debug: 4
1770 p2rev--debug: 4
1771 p2rev--debug: -1
1771 p2rev--debug: -1
1772 p2rev--debug: -1
1772 p2rev--debug: -1
1773 p2rev--debug: -1
1773 p2rev--debug: -1
1774 p2rev--debug: -1
1774 p2rev--debug: -1
1775 p2rev--debug: -1
1775 p2rev--debug: -1
1776 p2rev--debug: -1
1776 p2rev--debug: -1
1777 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1777 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1778 p1node: 0000000000000000000000000000000000000000
1778 p1node: 0000000000000000000000000000000000000000
1779 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1779 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1780 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1780 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1781 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1781 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1782 p1node: 97054abb4ab824450e9164180baf491ae0078465
1782 p1node: 97054abb4ab824450e9164180baf491ae0078465
1783 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1783 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1784 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1784 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1785 p1node: 0000000000000000000000000000000000000000
1785 p1node: 0000000000000000000000000000000000000000
1786 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1786 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1787 p1node--verbose: 0000000000000000000000000000000000000000
1787 p1node--verbose: 0000000000000000000000000000000000000000
1788 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1788 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1789 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1789 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1790 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1790 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1791 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1791 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1792 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1792 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1793 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1793 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1794 p1node--verbose: 0000000000000000000000000000000000000000
1794 p1node--verbose: 0000000000000000000000000000000000000000
1795 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1795 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1796 p1node--debug: 0000000000000000000000000000000000000000
1796 p1node--debug: 0000000000000000000000000000000000000000
1797 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1797 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1798 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1798 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1799 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1799 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1800 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1800 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1801 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1801 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1802 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1802 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1803 p1node--debug: 0000000000000000000000000000000000000000
1803 p1node--debug: 0000000000000000000000000000000000000000
1804 p2node: 0000000000000000000000000000000000000000
1804 p2node: 0000000000000000000000000000000000000000
1805 p2node: 0000000000000000000000000000000000000000
1805 p2node: 0000000000000000000000000000000000000000
1806 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1806 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1807 p2node: 0000000000000000000000000000000000000000
1807 p2node: 0000000000000000000000000000000000000000
1808 p2node: 0000000000000000000000000000000000000000
1808 p2node: 0000000000000000000000000000000000000000
1809 p2node: 0000000000000000000000000000000000000000
1809 p2node: 0000000000000000000000000000000000000000
1810 p2node: 0000000000000000000000000000000000000000
1810 p2node: 0000000000000000000000000000000000000000
1811 p2node: 0000000000000000000000000000000000000000
1811 p2node: 0000000000000000000000000000000000000000
1812 p2node: 0000000000000000000000000000000000000000
1812 p2node: 0000000000000000000000000000000000000000
1813 p2node--verbose: 0000000000000000000000000000000000000000
1813 p2node--verbose: 0000000000000000000000000000000000000000
1814 p2node--verbose: 0000000000000000000000000000000000000000
1814 p2node--verbose: 0000000000000000000000000000000000000000
1815 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1815 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1816 p2node--verbose: 0000000000000000000000000000000000000000
1816 p2node--verbose: 0000000000000000000000000000000000000000
1817 p2node--verbose: 0000000000000000000000000000000000000000
1817 p2node--verbose: 0000000000000000000000000000000000000000
1818 p2node--verbose: 0000000000000000000000000000000000000000
1818 p2node--verbose: 0000000000000000000000000000000000000000
1819 p2node--verbose: 0000000000000000000000000000000000000000
1819 p2node--verbose: 0000000000000000000000000000000000000000
1820 p2node--verbose: 0000000000000000000000000000000000000000
1820 p2node--verbose: 0000000000000000000000000000000000000000
1821 p2node--verbose: 0000000000000000000000000000000000000000
1821 p2node--verbose: 0000000000000000000000000000000000000000
1822 p2node--debug: 0000000000000000000000000000000000000000
1822 p2node--debug: 0000000000000000000000000000000000000000
1823 p2node--debug: 0000000000000000000000000000000000000000
1823 p2node--debug: 0000000000000000000000000000000000000000
1824 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1824 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1825 p2node--debug: 0000000000000000000000000000000000000000
1825 p2node--debug: 0000000000000000000000000000000000000000
1826 p2node--debug: 0000000000000000000000000000000000000000
1826 p2node--debug: 0000000000000000000000000000000000000000
1827 p2node--debug: 0000000000000000000000000000000000000000
1827 p2node--debug: 0000000000000000000000000000000000000000
1828 p2node--debug: 0000000000000000000000000000000000000000
1828 p2node--debug: 0000000000000000000000000000000000000000
1829 p2node--debug: 0000000000000000000000000000000000000000
1829 p2node--debug: 0000000000000000000000000000000000000000
1830 p2node--debug: 0000000000000000000000000000000000000000
1830 p2node--debug: 0000000000000000000000000000000000000000
1831
1831
1832 Filters work:
1832 Filters work:
1833
1833
1834 $ hg log --template '{author|domain}\n'
1834 $ hg log --template '{author|domain}\n'
1835
1835
1836 hostname
1836 hostname
1837
1837
1838
1838
1839
1839
1840
1840
1841 place
1841 place
1842 place
1842 place
1843 hostname
1843 hostname
1844
1844
1845 $ hg log --template '{author|person}\n'
1845 $ hg log --template '{author|person}\n'
1846 test
1846 test
1847 User Name
1847 User Name
1848 person
1848 person
1849 person
1849 person
1850 person
1850 person
1851 person
1851 person
1852 other
1852 other
1853 A. N. Other
1853 A. N. Other
1854 User Name
1854 User Name
1855
1855
1856 $ hg log --template '{author|user}\n'
1856 $ hg log --template '{author|user}\n'
1857 test
1857 test
1858 user
1858 user
1859 person
1859 person
1860 person
1860 person
1861 person
1861 person
1862 person
1862 person
1863 other
1863 other
1864 other
1864 other
1865 user
1865 user
1866
1866
1867 $ hg log --template '{date|date}\n'
1867 $ hg log --template '{date|date}\n'
1868 Wed Jan 01 10:01:00 2020 +0000
1868 Wed Jan 01 10:01:00 2020 +0000
1869 Mon Jan 12 13:46:40 1970 +0000
1869 Mon Jan 12 13:46:40 1970 +0000
1870 Sun Jan 18 08:40:01 1970 +0000
1870 Sun Jan 18 08:40:01 1970 +0000
1871 Sun Jan 18 08:40:00 1970 +0000
1871 Sun Jan 18 08:40:00 1970 +0000
1872 Sat Jan 17 04:53:20 1970 +0000
1872 Sat Jan 17 04:53:20 1970 +0000
1873 Fri Jan 16 01:06:40 1970 +0000
1873 Fri Jan 16 01:06:40 1970 +0000
1874 Wed Jan 14 21:20:00 1970 +0000
1874 Wed Jan 14 21:20:00 1970 +0000
1875 Tue Jan 13 17:33:20 1970 +0000
1875 Tue Jan 13 17:33:20 1970 +0000
1876 Mon Jan 12 13:46:40 1970 +0000
1876 Mon Jan 12 13:46:40 1970 +0000
1877
1877
1878 $ hg log --template '{date|isodate}\n'
1878 $ hg log --template '{date|isodate}\n'
1879 2020-01-01 10:01 +0000
1879 2020-01-01 10:01 +0000
1880 1970-01-12 13:46 +0000
1880 1970-01-12 13:46 +0000
1881 1970-01-18 08:40 +0000
1881 1970-01-18 08:40 +0000
1882 1970-01-18 08:40 +0000
1882 1970-01-18 08:40 +0000
1883 1970-01-17 04:53 +0000
1883 1970-01-17 04:53 +0000
1884 1970-01-16 01:06 +0000
1884 1970-01-16 01:06 +0000
1885 1970-01-14 21:20 +0000
1885 1970-01-14 21:20 +0000
1886 1970-01-13 17:33 +0000
1886 1970-01-13 17:33 +0000
1887 1970-01-12 13:46 +0000
1887 1970-01-12 13:46 +0000
1888
1888
1889 $ hg log --template '{date|isodatesec}\n'
1889 $ hg log --template '{date|isodatesec}\n'
1890 2020-01-01 10:01:00 +0000
1890 2020-01-01 10:01:00 +0000
1891 1970-01-12 13:46:40 +0000
1891 1970-01-12 13:46:40 +0000
1892 1970-01-18 08:40:01 +0000
1892 1970-01-18 08:40:01 +0000
1893 1970-01-18 08:40:00 +0000
1893 1970-01-18 08:40:00 +0000
1894 1970-01-17 04:53:20 +0000
1894 1970-01-17 04:53:20 +0000
1895 1970-01-16 01:06:40 +0000
1895 1970-01-16 01:06:40 +0000
1896 1970-01-14 21:20:00 +0000
1896 1970-01-14 21:20:00 +0000
1897 1970-01-13 17:33:20 +0000
1897 1970-01-13 17:33:20 +0000
1898 1970-01-12 13:46:40 +0000
1898 1970-01-12 13:46:40 +0000
1899
1899
1900 $ hg log --template '{date|rfc822date}\n'
1900 $ hg log --template '{date|rfc822date}\n'
1901 Wed, 01 Jan 2020 10:01:00 +0000
1901 Wed, 01 Jan 2020 10:01:00 +0000
1902 Mon, 12 Jan 1970 13:46:40 +0000
1902 Mon, 12 Jan 1970 13:46:40 +0000
1903 Sun, 18 Jan 1970 08:40:01 +0000
1903 Sun, 18 Jan 1970 08:40:01 +0000
1904 Sun, 18 Jan 1970 08:40:00 +0000
1904 Sun, 18 Jan 1970 08:40:00 +0000
1905 Sat, 17 Jan 1970 04:53:20 +0000
1905 Sat, 17 Jan 1970 04:53:20 +0000
1906 Fri, 16 Jan 1970 01:06:40 +0000
1906 Fri, 16 Jan 1970 01:06:40 +0000
1907 Wed, 14 Jan 1970 21:20:00 +0000
1907 Wed, 14 Jan 1970 21:20:00 +0000
1908 Tue, 13 Jan 1970 17:33:20 +0000
1908 Tue, 13 Jan 1970 17:33:20 +0000
1909 Mon, 12 Jan 1970 13:46:40 +0000
1909 Mon, 12 Jan 1970 13:46:40 +0000
1910
1910
1911 $ hg log --template '{desc|firstline}\n'
1911 $ hg log --template '{desc|firstline}\n'
1912 third
1912 third
1913 second
1913 second
1914 merge
1914 merge
1915 new head
1915 new head
1916 new branch
1916 new branch
1917 no user, no domain
1917 no user, no domain
1918 no person
1918 no person
1919 other 1
1919 other 1
1920 line 1
1920 line 1
1921
1921
1922 $ hg log --template '{node|short}\n'
1922 $ hg log --template '{node|short}\n'
1923 95c24699272e
1923 95c24699272e
1924 29114dbae42b
1924 29114dbae42b
1925 d41e714fe50d
1925 d41e714fe50d
1926 13207e5a10d9
1926 13207e5a10d9
1927 bbe44766e73d
1927 bbe44766e73d
1928 10e46f2dcbf4
1928 10e46f2dcbf4
1929 97054abb4ab8
1929 97054abb4ab8
1930 b608e9d1a3f0
1930 b608e9d1a3f0
1931 1e4e1b8f71e0
1931 1e4e1b8f71e0
1932
1932
1933 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1933 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1934 <changeset author="test"/>
1934 <changeset author="test"/>
1935 <changeset author="User Name &lt;user@hostname&gt;"/>
1935 <changeset author="User Name &lt;user@hostname&gt;"/>
1936 <changeset author="person"/>
1936 <changeset author="person"/>
1937 <changeset author="person"/>
1937 <changeset author="person"/>
1938 <changeset author="person"/>
1938 <changeset author="person"/>
1939 <changeset author="person"/>
1939 <changeset author="person"/>
1940 <changeset author="other@place"/>
1940 <changeset author="other@place"/>
1941 <changeset author="A. N. Other &lt;other@place&gt;"/>
1941 <changeset author="A. N. Other &lt;other@place&gt;"/>
1942 <changeset author="User Name &lt;user@hostname&gt;"/>
1942 <changeset author="User Name &lt;user@hostname&gt;"/>
1943
1943
1944 $ hg log --template '{rev}: {children}\n'
1944 $ hg log --template '{rev}: {children}\n'
1945 8:
1945 8:
1946 7: 8:95c24699272e
1946 7: 8:95c24699272e
1947 6:
1947 6:
1948 5: 6:d41e714fe50d
1948 5: 6:d41e714fe50d
1949 4: 6:d41e714fe50d
1949 4: 6:d41e714fe50d
1950 3: 4:bbe44766e73d 5:13207e5a10d9
1950 3: 4:bbe44766e73d 5:13207e5a10d9
1951 2: 3:10e46f2dcbf4
1951 2: 3:10e46f2dcbf4
1952 1: 2:97054abb4ab8
1952 1: 2:97054abb4ab8
1953 0: 1:b608e9d1a3f0
1953 0: 1:b608e9d1a3f0
1954
1954
1955 Formatnode filter works:
1955 Formatnode filter works:
1956
1956
1957 $ hg -q log -r 0 --template '{node|formatnode}\n'
1957 $ hg -q log -r 0 --template '{node|formatnode}\n'
1958 1e4e1b8f71e0
1958 1e4e1b8f71e0
1959
1959
1960 $ hg log -r 0 --template '{node|formatnode}\n'
1960 $ hg log -r 0 --template '{node|formatnode}\n'
1961 1e4e1b8f71e0
1961 1e4e1b8f71e0
1962
1962
1963 $ hg -v log -r 0 --template '{node|formatnode}\n'
1963 $ hg -v log -r 0 --template '{node|formatnode}\n'
1964 1e4e1b8f71e0
1964 1e4e1b8f71e0
1965
1965
1966 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1966 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1967 1e4e1b8f71e05681d422154f5421e385fec3454f
1967 1e4e1b8f71e05681d422154f5421e385fec3454f
1968
1968
1969 Age filter:
1969 Age filter:
1970
1970
1971 $ hg init unstable-hash
1971 $ hg init unstable-hash
1972 $ cd unstable-hash
1972 $ cd unstable-hash
1973 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1973 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1974
1974
1975 >>> from datetime import datetime, timedelta
1975 >>> from datetime import datetime, timedelta
1976 >>> fp = open('a', 'w')
1976 >>> fp = open('a', 'w')
1977 >>> n = datetime.now() + timedelta(366 * 7)
1977 >>> n = datetime.now() + timedelta(366 * 7)
1978 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1978 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1979 >>> fp.close()
1979 >>> fp.close()
1980 $ hg add a
1980 $ hg add a
1981 $ hg commit -m future -d "`cat a`"
1981 $ hg commit -m future -d "`cat a`"
1982
1982
1983 $ hg log -l1 --template '{date|age}\n'
1983 $ hg log -l1 --template '{date|age}\n'
1984 7 years from now
1984 7 years from now
1985
1985
1986 $ cd ..
1986 $ cd ..
1987 $ rm -rf unstable-hash
1987 $ rm -rf unstable-hash
1988
1988
1989 Add a dummy commit to make up for the instability of the above:
1989 Add a dummy commit to make up for the instability of the above:
1990
1990
1991 $ echo a > a
1991 $ echo a > a
1992 $ hg add a
1992 $ hg add a
1993 $ hg ci -m future
1993 $ hg ci -m future
1994
1994
1995 Count filter:
1995 Count filter:
1996
1996
1997 $ hg log -l1 --template '{node|count} {node|short|count}\n'
1997 $ hg log -l1 --template '{node|count} {node|short|count}\n'
1998 40 12
1998 40 12
1999
1999
2000 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
2000 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
2001 0 1 4
2001 0 1 4
2002
2002
2003 $ hg log -G --template '{rev}: children: {children|count}, \
2003 $ hg log -G --template '{rev}: children: {children|count}, \
2004 > tags: {tags|count}, file_adds: {file_adds|count}, \
2004 > tags: {tags|count}, file_adds: {file_adds|count}, \
2005 > ancestors: {revset("ancestors(%s)", rev)|count}'
2005 > ancestors: {revset("ancestors(%s)", rev)|count}'
2006 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
2006 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
2007 |
2007 |
2008 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
2008 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
2009 |
2009 |
2010 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
2010 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
2011
2011
2012 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
2012 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
2013 |\
2013 |\
2014 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
2014 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
2015 | |
2015 | |
2016 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
2016 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
2017 |/
2017 |/
2018 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
2018 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
2019 |
2019 |
2020 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
2020 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
2021 |
2021 |
2022 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
2022 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
2023 |
2023 |
2024 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
2024 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
2025
2025
2026
2026
2027 Upper/lower filters:
2027 Upper/lower filters:
2028
2028
2029 $ hg log -r0 --template '{branch|upper}\n'
2029 $ hg log -r0 --template '{branch|upper}\n'
2030 DEFAULT
2030 DEFAULT
2031 $ hg log -r0 --template '{author|lower}\n'
2031 $ hg log -r0 --template '{author|lower}\n'
2032 user name <user@hostname>
2032 user name <user@hostname>
2033 $ hg log -r0 --template '{date|upper}\n'
2033 $ hg log -r0 --template '{date|upper}\n'
2034 abort: template filter 'upper' is not compatible with keyword 'date'
2034 abort: template filter 'upper' is not compatible with keyword 'date'
2035 [255]
2035 [255]
2036
2036
2037 Add a commit that does all possible modifications at once
2037 Add a commit that does all possible modifications at once
2038
2038
2039 $ echo modify >> third
2039 $ echo modify >> third
2040 $ touch b
2040 $ touch b
2041 $ hg add b
2041 $ hg add b
2042 $ hg mv fourth fifth
2042 $ hg mv fourth fifth
2043 $ hg rm a
2043 $ hg rm a
2044 $ hg ci -m "Modify, add, remove, rename"
2044 $ hg ci -m "Modify, add, remove, rename"
2045
2045
2046 Check the status template
2046 Check the status template
2047
2047
2048 $ cat <<EOF >> $HGRCPATH
2048 $ cat <<EOF >> $HGRCPATH
2049 > [extensions]
2049 > [extensions]
2050 > color=
2050 > color=
2051 > EOF
2051 > EOF
2052
2052
2053 $ hg log -T status -r 10
2053 $ hg log -T status -r 10
2054 changeset: 10:0f9759ec227a
2054 changeset: 10:0f9759ec227a
2055 tag: tip
2055 tag: tip
2056 user: test
2056 user: test
2057 date: Thu Jan 01 00:00:00 1970 +0000
2057 date: Thu Jan 01 00:00:00 1970 +0000
2058 summary: Modify, add, remove, rename
2058 summary: Modify, add, remove, rename
2059 files:
2059 files:
2060 M third
2060 M third
2061 A b
2061 A b
2062 A fifth
2062 A fifth
2063 R a
2063 R a
2064 R fourth
2064 R fourth
2065
2065
2066 $ hg log -T status -C -r 10
2066 $ hg log -T status -C -r 10
2067 changeset: 10:0f9759ec227a
2067 changeset: 10:0f9759ec227a
2068 tag: tip
2068 tag: tip
2069 user: test
2069 user: test
2070 date: Thu Jan 01 00:00:00 1970 +0000
2070 date: Thu Jan 01 00:00:00 1970 +0000
2071 summary: Modify, add, remove, rename
2071 summary: Modify, add, remove, rename
2072 files:
2072 files:
2073 M third
2073 M third
2074 A b
2074 A b
2075 A fifth
2075 A fifth
2076 fourth
2076 fourth
2077 R a
2077 R a
2078 R fourth
2078 R fourth
2079
2079
2080 $ hg log -T status -C -r 10 -v
2080 $ hg log -T status -C -r 10 -v
2081 changeset: 10:0f9759ec227a
2081 changeset: 10:0f9759ec227a
2082 tag: tip
2082 tag: tip
2083 user: test
2083 user: test
2084 date: Thu Jan 01 00:00:00 1970 +0000
2084 date: Thu Jan 01 00:00:00 1970 +0000
2085 description:
2085 description:
2086 Modify, add, remove, rename
2086 Modify, add, remove, rename
2087
2087
2088 files:
2088 files:
2089 M third
2089 M third
2090 A b
2090 A b
2091 A fifth
2091 A fifth
2092 fourth
2092 fourth
2093 R a
2093 R a
2094 R fourth
2094 R fourth
2095
2095
2096 $ hg log -T status -C -r 10 --debug
2096 $ hg log -T status -C -r 10 --debug
2097 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2097 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2098 tag: tip
2098 tag: tip
2099 phase: secret
2099 phase: secret
2100 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2100 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2101 parent: -1:0000000000000000000000000000000000000000
2101 parent: -1:0000000000000000000000000000000000000000
2102 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2102 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2103 user: test
2103 user: test
2104 date: Thu Jan 01 00:00:00 1970 +0000
2104 date: Thu Jan 01 00:00:00 1970 +0000
2105 extra: branch=default
2105 extra: branch=default
2106 description:
2106 description:
2107 Modify, add, remove, rename
2107 Modify, add, remove, rename
2108
2108
2109 files:
2109 files:
2110 M third
2110 M third
2111 A b
2111 A b
2112 A fifth
2112 A fifth
2113 fourth
2113 fourth
2114 R a
2114 R a
2115 R fourth
2115 R fourth
2116
2116
2117 $ hg log -T status -C -r 10 --quiet
2117 $ hg log -T status -C -r 10 --quiet
2118 10:0f9759ec227a
2118 10:0f9759ec227a
2119 $ hg --color=debug log -T status -r 10
2119 $ hg --color=debug log -T status -r 10
2120 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2120 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2121 [log.tag|tag: tip]
2121 [log.tag|tag: tip]
2122 [log.user|user: test]
2122 [log.user|user: test]
2123 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2123 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2124 [log.summary|summary: Modify, add, remove, rename]
2124 [log.summary|summary: Modify, add, remove, rename]
2125 [ui.note log.files|files:]
2125 [ui.note log.files|files:]
2126 [status.modified|M third]
2126 [status.modified|M third]
2127 [status.added|A b]
2127 [status.added|A b]
2128 [status.added|A fifth]
2128 [status.added|A fifth]
2129 [status.removed|R a]
2129 [status.removed|R a]
2130 [status.removed|R fourth]
2130 [status.removed|R fourth]
2131
2131
2132 $ hg --color=debug log -T status -C -r 10
2132 $ hg --color=debug log -T status -C -r 10
2133 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2133 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2134 [log.tag|tag: tip]
2134 [log.tag|tag: tip]
2135 [log.user|user: test]
2135 [log.user|user: test]
2136 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2136 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2137 [log.summary|summary: Modify, add, remove, rename]
2137 [log.summary|summary: Modify, add, remove, rename]
2138 [ui.note log.files|files:]
2138 [ui.note log.files|files:]
2139 [status.modified|M third]
2139 [status.modified|M third]
2140 [status.added|A b]
2140 [status.added|A b]
2141 [status.added|A fifth]
2141 [status.added|A fifth]
2142 [status.copied| fourth]
2142 [status.copied| fourth]
2143 [status.removed|R a]
2143 [status.removed|R a]
2144 [status.removed|R fourth]
2144 [status.removed|R fourth]
2145
2145
2146 $ hg --color=debug log -T status -C -r 10 -v
2146 $ hg --color=debug log -T status -C -r 10 -v
2147 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2147 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2148 [log.tag|tag: tip]
2148 [log.tag|tag: tip]
2149 [log.user|user: test]
2149 [log.user|user: test]
2150 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2150 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2151 [ui.note log.description|description:]
2151 [ui.note log.description|description:]
2152 [ui.note log.description|Modify, add, remove, rename]
2152 [ui.note log.description|Modify, add, remove, rename]
2153
2153
2154 [ui.note log.files|files:]
2154 [ui.note log.files|files:]
2155 [status.modified|M third]
2155 [status.modified|M third]
2156 [status.added|A b]
2156 [status.added|A b]
2157 [status.added|A fifth]
2157 [status.added|A fifth]
2158 [status.copied| fourth]
2158 [status.copied| fourth]
2159 [status.removed|R a]
2159 [status.removed|R a]
2160 [status.removed|R fourth]
2160 [status.removed|R fourth]
2161
2161
2162 $ hg --color=debug log -T status -C -r 10 --debug
2162 $ hg --color=debug log -T status -C -r 10 --debug
2163 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2163 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2164 [log.tag|tag: tip]
2164 [log.tag|tag: tip]
2165 [log.phase|phase: secret]
2165 [log.phase|phase: secret]
2166 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2166 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2167 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2167 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2168 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2168 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2169 [log.user|user: test]
2169 [log.user|user: test]
2170 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2170 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2171 [ui.debug log.extra|extra: branch=default]
2171 [ui.debug log.extra|extra: branch=default]
2172 [ui.note log.description|description:]
2172 [ui.note log.description|description:]
2173 [ui.note log.description|Modify, add, remove, rename]
2173 [ui.note log.description|Modify, add, remove, rename]
2174
2174
2175 [ui.note log.files|files:]
2175 [ui.note log.files|files:]
2176 [status.modified|M third]
2176 [status.modified|M third]
2177 [status.added|A b]
2177 [status.added|A b]
2178 [status.added|A fifth]
2178 [status.added|A fifth]
2179 [status.copied| fourth]
2179 [status.copied| fourth]
2180 [status.removed|R a]
2180 [status.removed|R a]
2181 [status.removed|R fourth]
2181 [status.removed|R fourth]
2182
2182
2183 $ hg --color=debug log -T status -C -r 10 --quiet
2183 $ hg --color=debug log -T status -C -r 10 --quiet
2184 [log.node|10:0f9759ec227a]
2184 [log.node|10:0f9759ec227a]
2185
2185
2186 Check the bisect template
2186 Check the bisect template
2187
2187
2188 $ hg bisect -g 1
2188 $ hg bisect -g 1
2189 $ hg bisect -b 3 --noupdate
2189 $ hg bisect -b 3 --noupdate
2190 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2190 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2191 $ hg log -T bisect -r 0:4
2191 $ hg log -T bisect -r 0:4
2192 changeset: 0:1e4e1b8f71e0
2192 changeset: 0:1e4e1b8f71e0
2193 bisect: good (implicit)
2193 bisect: good (implicit)
2194 user: User Name <user@hostname>
2194 user: User Name <user@hostname>
2195 date: Mon Jan 12 13:46:40 1970 +0000
2195 date: Mon Jan 12 13:46:40 1970 +0000
2196 summary: line 1
2196 summary: line 1
2197
2197
2198 changeset: 1:b608e9d1a3f0
2198 changeset: 1:b608e9d1a3f0
2199 bisect: good
2199 bisect: good
2200 user: A. N. Other <other@place>
2200 user: A. N. Other <other@place>
2201 date: Tue Jan 13 17:33:20 1970 +0000
2201 date: Tue Jan 13 17:33:20 1970 +0000
2202 summary: other 1
2202 summary: other 1
2203
2203
2204 changeset: 2:97054abb4ab8
2204 changeset: 2:97054abb4ab8
2205 bisect: untested
2205 bisect: untested
2206 user: other@place
2206 user: other@place
2207 date: Wed Jan 14 21:20:00 1970 +0000
2207 date: Wed Jan 14 21:20:00 1970 +0000
2208 summary: no person
2208 summary: no person
2209
2209
2210 changeset: 3:10e46f2dcbf4
2210 changeset: 3:10e46f2dcbf4
2211 bisect: bad
2211 bisect: bad
2212 user: person
2212 user: person
2213 date: Fri Jan 16 01:06:40 1970 +0000
2213 date: Fri Jan 16 01:06:40 1970 +0000
2214 summary: no user, no domain
2214 summary: no user, no domain
2215
2215
2216 changeset: 4:bbe44766e73d
2216 changeset: 4:bbe44766e73d
2217 bisect: bad (implicit)
2217 bisect: bad (implicit)
2218 branch: foo
2218 branch: foo
2219 user: person
2219 user: person
2220 date: Sat Jan 17 04:53:20 1970 +0000
2220 date: Sat Jan 17 04:53:20 1970 +0000
2221 summary: new branch
2221 summary: new branch
2222
2222
2223 $ hg log --debug -T bisect -r 0:4
2223 $ hg log --debug -T bisect -r 0:4
2224 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2224 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2225 bisect: good (implicit)
2225 bisect: good (implicit)
2226 phase: public
2226 phase: public
2227 parent: -1:0000000000000000000000000000000000000000
2227 parent: -1:0000000000000000000000000000000000000000
2228 parent: -1:0000000000000000000000000000000000000000
2228 parent: -1:0000000000000000000000000000000000000000
2229 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2229 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2230 user: User Name <user@hostname>
2230 user: User Name <user@hostname>
2231 date: Mon Jan 12 13:46:40 1970 +0000
2231 date: Mon Jan 12 13:46:40 1970 +0000
2232 files+: a
2232 files+: a
2233 extra: branch=default
2233 extra: branch=default
2234 description:
2234 description:
2235 line 1
2235 line 1
2236 line 2
2236 line 2
2237
2237
2238
2238
2239 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2239 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2240 bisect: good
2240 bisect: good
2241 phase: public
2241 phase: public
2242 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2242 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2243 parent: -1:0000000000000000000000000000000000000000
2243 parent: -1:0000000000000000000000000000000000000000
2244 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2244 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2245 user: A. N. Other <other@place>
2245 user: A. N. Other <other@place>
2246 date: Tue Jan 13 17:33:20 1970 +0000
2246 date: Tue Jan 13 17:33:20 1970 +0000
2247 files+: b
2247 files+: b
2248 extra: branch=default
2248 extra: branch=default
2249 description:
2249 description:
2250 other 1
2250 other 1
2251 other 2
2251 other 2
2252
2252
2253 other 3
2253 other 3
2254
2254
2255
2255
2256 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2256 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2257 bisect: untested
2257 bisect: untested
2258 phase: public
2258 phase: public
2259 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2259 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2260 parent: -1:0000000000000000000000000000000000000000
2260 parent: -1:0000000000000000000000000000000000000000
2261 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2261 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2262 user: other@place
2262 user: other@place
2263 date: Wed Jan 14 21:20:00 1970 +0000
2263 date: Wed Jan 14 21:20:00 1970 +0000
2264 files+: c
2264 files+: c
2265 extra: branch=default
2265 extra: branch=default
2266 description:
2266 description:
2267 no person
2267 no person
2268
2268
2269
2269
2270 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2270 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2271 bisect: bad
2271 bisect: bad
2272 phase: public
2272 phase: public
2273 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2273 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2274 parent: -1:0000000000000000000000000000000000000000
2274 parent: -1:0000000000000000000000000000000000000000
2275 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2275 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2276 user: person
2276 user: person
2277 date: Fri Jan 16 01:06:40 1970 +0000
2277 date: Fri Jan 16 01:06:40 1970 +0000
2278 files: c
2278 files: c
2279 extra: branch=default
2279 extra: branch=default
2280 description:
2280 description:
2281 no user, no domain
2281 no user, no domain
2282
2282
2283
2283
2284 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2284 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2285 bisect: bad (implicit)
2285 bisect: bad (implicit)
2286 branch: foo
2286 branch: foo
2287 phase: draft
2287 phase: draft
2288 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2288 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2289 parent: -1:0000000000000000000000000000000000000000
2289 parent: -1:0000000000000000000000000000000000000000
2290 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2290 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2291 user: person
2291 user: person
2292 date: Sat Jan 17 04:53:20 1970 +0000
2292 date: Sat Jan 17 04:53:20 1970 +0000
2293 extra: branch=foo
2293 extra: branch=foo
2294 description:
2294 description:
2295 new branch
2295 new branch
2296
2296
2297
2297
2298 $ hg log -v -T bisect -r 0:4
2298 $ hg log -v -T bisect -r 0:4
2299 changeset: 0:1e4e1b8f71e0
2299 changeset: 0:1e4e1b8f71e0
2300 bisect: good (implicit)
2300 bisect: good (implicit)
2301 user: User Name <user@hostname>
2301 user: User Name <user@hostname>
2302 date: Mon Jan 12 13:46:40 1970 +0000
2302 date: Mon Jan 12 13:46:40 1970 +0000
2303 files: a
2303 files: a
2304 description:
2304 description:
2305 line 1
2305 line 1
2306 line 2
2306 line 2
2307
2307
2308
2308
2309 changeset: 1:b608e9d1a3f0
2309 changeset: 1:b608e9d1a3f0
2310 bisect: good
2310 bisect: good
2311 user: A. N. Other <other@place>
2311 user: A. N. Other <other@place>
2312 date: Tue Jan 13 17:33:20 1970 +0000
2312 date: Tue Jan 13 17:33:20 1970 +0000
2313 files: b
2313 files: b
2314 description:
2314 description:
2315 other 1
2315 other 1
2316 other 2
2316 other 2
2317
2317
2318 other 3
2318 other 3
2319
2319
2320
2320
2321 changeset: 2:97054abb4ab8
2321 changeset: 2:97054abb4ab8
2322 bisect: untested
2322 bisect: untested
2323 user: other@place
2323 user: other@place
2324 date: Wed Jan 14 21:20:00 1970 +0000
2324 date: Wed Jan 14 21:20:00 1970 +0000
2325 files: c
2325 files: c
2326 description:
2326 description:
2327 no person
2327 no person
2328
2328
2329
2329
2330 changeset: 3:10e46f2dcbf4
2330 changeset: 3:10e46f2dcbf4
2331 bisect: bad
2331 bisect: bad
2332 user: person
2332 user: person
2333 date: Fri Jan 16 01:06:40 1970 +0000
2333 date: Fri Jan 16 01:06:40 1970 +0000
2334 files: c
2334 files: c
2335 description:
2335 description:
2336 no user, no domain
2336 no user, no domain
2337
2337
2338
2338
2339 changeset: 4:bbe44766e73d
2339 changeset: 4:bbe44766e73d
2340 bisect: bad (implicit)
2340 bisect: bad (implicit)
2341 branch: foo
2341 branch: foo
2342 user: person
2342 user: person
2343 date: Sat Jan 17 04:53:20 1970 +0000
2343 date: Sat Jan 17 04:53:20 1970 +0000
2344 description:
2344 description:
2345 new branch
2345 new branch
2346
2346
2347
2347
2348 $ hg --color=debug log -T bisect -r 0:4
2348 $ hg --color=debug log -T bisect -r 0:4
2349 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2349 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2350 [log.bisect bisect.good|bisect: good (implicit)]
2350 [log.bisect bisect.good|bisect: good (implicit)]
2351 [log.user|user: User Name <user@hostname>]
2351 [log.user|user: User Name <user@hostname>]
2352 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2352 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2353 [log.summary|summary: line 1]
2353 [log.summary|summary: line 1]
2354
2354
2355 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2355 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2356 [log.bisect bisect.good|bisect: good]
2356 [log.bisect bisect.good|bisect: good]
2357 [log.user|user: A. N. Other <other@place>]
2357 [log.user|user: A. N. Other <other@place>]
2358 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2358 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2359 [log.summary|summary: other 1]
2359 [log.summary|summary: other 1]
2360
2360
2361 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2361 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2362 [log.bisect bisect.untested|bisect: untested]
2362 [log.bisect bisect.untested|bisect: untested]
2363 [log.user|user: other@place]
2363 [log.user|user: other@place]
2364 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2364 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2365 [log.summary|summary: no person]
2365 [log.summary|summary: no person]
2366
2366
2367 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2367 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2368 [log.bisect bisect.bad|bisect: bad]
2368 [log.bisect bisect.bad|bisect: bad]
2369 [log.user|user: person]
2369 [log.user|user: person]
2370 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2370 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2371 [log.summary|summary: no user, no domain]
2371 [log.summary|summary: no user, no domain]
2372
2372
2373 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2373 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2374 [log.bisect bisect.bad|bisect: bad (implicit)]
2374 [log.bisect bisect.bad|bisect: bad (implicit)]
2375 [log.branch|branch: foo]
2375 [log.branch|branch: foo]
2376 [log.user|user: person]
2376 [log.user|user: person]
2377 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2377 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2378 [log.summary|summary: new branch]
2378 [log.summary|summary: new branch]
2379
2379
2380 $ hg --color=debug log --debug -T bisect -r 0:4
2380 $ hg --color=debug log --debug -T bisect -r 0:4
2381 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2381 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2382 [log.bisect bisect.good|bisect: good (implicit)]
2382 [log.bisect bisect.good|bisect: good (implicit)]
2383 [log.phase|phase: public]
2383 [log.phase|phase: public]
2384 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2384 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2385 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2385 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2386 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2386 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2387 [log.user|user: User Name <user@hostname>]
2387 [log.user|user: User Name <user@hostname>]
2388 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2388 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2389 [ui.debug log.files|files+: a]
2389 [ui.debug log.files|files+: a]
2390 [ui.debug log.extra|extra: branch=default]
2390 [ui.debug log.extra|extra: branch=default]
2391 [ui.note log.description|description:]
2391 [ui.note log.description|description:]
2392 [ui.note log.description|line 1
2392 [ui.note log.description|line 1
2393 line 2]
2393 line 2]
2394
2394
2395
2395
2396 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2396 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2397 [log.bisect bisect.good|bisect: good]
2397 [log.bisect bisect.good|bisect: good]
2398 [log.phase|phase: public]
2398 [log.phase|phase: public]
2399 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2399 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2400 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2400 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2401 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2401 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2402 [log.user|user: A. N. Other <other@place>]
2402 [log.user|user: A. N. Other <other@place>]
2403 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2403 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2404 [ui.debug log.files|files+: b]
2404 [ui.debug log.files|files+: b]
2405 [ui.debug log.extra|extra: branch=default]
2405 [ui.debug log.extra|extra: branch=default]
2406 [ui.note log.description|description:]
2406 [ui.note log.description|description:]
2407 [ui.note log.description|other 1
2407 [ui.note log.description|other 1
2408 other 2
2408 other 2
2409
2409
2410 other 3]
2410 other 3]
2411
2411
2412
2412
2413 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2413 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2414 [log.bisect bisect.untested|bisect: untested]
2414 [log.bisect bisect.untested|bisect: untested]
2415 [log.phase|phase: public]
2415 [log.phase|phase: public]
2416 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2416 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2417 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2417 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2418 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2418 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2419 [log.user|user: other@place]
2419 [log.user|user: other@place]
2420 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2420 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2421 [ui.debug log.files|files+: c]
2421 [ui.debug log.files|files+: c]
2422 [ui.debug log.extra|extra: branch=default]
2422 [ui.debug log.extra|extra: branch=default]
2423 [ui.note log.description|description:]
2423 [ui.note log.description|description:]
2424 [ui.note log.description|no person]
2424 [ui.note log.description|no person]
2425
2425
2426
2426
2427 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2427 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2428 [log.bisect bisect.bad|bisect: bad]
2428 [log.bisect bisect.bad|bisect: bad]
2429 [log.phase|phase: public]
2429 [log.phase|phase: public]
2430 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2430 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2431 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2431 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2432 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2432 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2433 [log.user|user: person]
2433 [log.user|user: person]
2434 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2434 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2435 [ui.debug log.files|files: c]
2435 [ui.debug log.files|files: c]
2436 [ui.debug log.extra|extra: branch=default]
2436 [ui.debug log.extra|extra: branch=default]
2437 [ui.note log.description|description:]
2437 [ui.note log.description|description:]
2438 [ui.note log.description|no user, no domain]
2438 [ui.note log.description|no user, no domain]
2439
2439
2440
2440
2441 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2441 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2442 [log.bisect bisect.bad|bisect: bad (implicit)]
2442 [log.bisect bisect.bad|bisect: bad (implicit)]
2443 [log.branch|branch: foo]
2443 [log.branch|branch: foo]
2444 [log.phase|phase: draft]
2444 [log.phase|phase: draft]
2445 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2445 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2446 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2446 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2447 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2447 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2448 [log.user|user: person]
2448 [log.user|user: person]
2449 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2449 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2450 [ui.debug log.extra|extra: branch=foo]
2450 [ui.debug log.extra|extra: branch=foo]
2451 [ui.note log.description|description:]
2451 [ui.note log.description|description:]
2452 [ui.note log.description|new branch]
2452 [ui.note log.description|new branch]
2453
2453
2454
2454
2455 $ hg --color=debug log -v -T bisect -r 0:4
2455 $ hg --color=debug log -v -T bisect -r 0:4
2456 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2456 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2457 [log.bisect bisect.good|bisect: good (implicit)]
2457 [log.bisect bisect.good|bisect: good (implicit)]
2458 [log.user|user: User Name <user@hostname>]
2458 [log.user|user: User Name <user@hostname>]
2459 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2459 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2460 [ui.note log.files|files: a]
2460 [ui.note log.files|files: a]
2461 [ui.note log.description|description:]
2461 [ui.note log.description|description:]
2462 [ui.note log.description|line 1
2462 [ui.note log.description|line 1
2463 line 2]
2463 line 2]
2464
2464
2465
2465
2466 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2466 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2467 [log.bisect bisect.good|bisect: good]
2467 [log.bisect bisect.good|bisect: good]
2468 [log.user|user: A. N. Other <other@place>]
2468 [log.user|user: A. N. Other <other@place>]
2469 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2469 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2470 [ui.note log.files|files: b]
2470 [ui.note log.files|files: b]
2471 [ui.note log.description|description:]
2471 [ui.note log.description|description:]
2472 [ui.note log.description|other 1
2472 [ui.note log.description|other 1
2473 other 2
2473 other 2
2474
2474
2475 other 3]
2475 other 3]
2476
2476
2477
2477
2478 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2478 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2479 [log.bisect bisect.untested|bisect: untested]
2479 [log.bisect bisect.untested|bisect: untested]
2480 [log.user|user: other@place]
2480 [log.user|user: other@place]
2481 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2481 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2482 [ui.note log.files|files: c]
2482 [ui.note log.files|files: c]
2483 [ui.note log.description|description:]
2483 [ui.note log.description|description:]
2484 [ui.note log.description|no person]
2484 [ui.note log.description|no person]
2485
2485
2486
2486
2487 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2487 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2488 [log.bisect bisect.bad|bisect: bad]
2488 [log.bisect bisect.bad|bisect: bad]
2489 [log.user|user: person]
2489 [log.user|user: person]
2490 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2490 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2491 [ui.note log.files|files: c]
2491 [ui.note log.files|files: c]
2492 [ui.note log.description|description:]
2492 [ui.note log.description|description:]
2493 [ui.note log.description|no user, no domain]
2493 [ui.note log.description|no user, no domain]
2494
2494
2495
2495
2496 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2496 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2497 [log.bisect bisect.bad|bisect: bad (implicit)]
2497 [log.bisect bisect.bad|bisect: bad (implicit)]
2498 [log.branch|branch: foo]
2498 [log.branch|branch: foo]
2499 [log.user|user: person]
2499 [log.user|user: person]
2500 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2500 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2501 [ui.note log.description|description:]
2501 [ui.note log.description|description:]
2502 [ui.note log.description|new branch]
2502 [ui.note log.description|new branch]
2503
2503
2504
2504
2505 $ hg bisect --reset
2505 $ hg bisect --reset
2506
2506
2507 Error on syntax:
2507 Error on syntax:
2508
2508
2509 $ echo 'x = "f' >> t
2509 $ echo 'x = "f' >> t
2510 $ hg log
2510 $ hg log
2511 abort: t:3: unmatched quotes
2511 abort: t:3: unmatched quotes
2512 [255]
2512 [255]
2513
2513
2514 $ hg log -T '{date'
2514 $ hg log -T '{date'
2515 hg: parse error at 1: unterminated template expansion
2515 hg: parse error at 1: unterminated template expansion
2516 [255]
2516 [255]
2517
2517
2518 Behind the scenes, this will throw TypeError
2518 Behind the scenes, this will throw TypeError
2519
2519
2520 $ hg log -l 3 --template '{date|obfuscate}\n'
2520 $ hg log -l 3 --template '{date|obfuscate}\n'
2521 abort: template filter 'obfuscate' is not compatible with keyword 'date'
2521 abort: template filter 'obfuscate' is not compatible with keyword 'date'
2522 [255]
2522 [255]
2523
2523
2524 Behind the scenes, this will throw a ValueError
2524 Behind the scenes, this will throw a ValueError
2525
2525
2526 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2526 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2527 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2527 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2528 [255]
2528 [255]
2529
2529
2530 Behind the scenes, this will throw AttributeError
2530 Behind the scenes, this will throw AttributeError
2531
2531
2532 $ hg log -l 3 --template 'line: {date|escape}\n'
2532 $ hg log -l 3 --template 'line: {date|escape}\n'
2533 abort: template filter 'escape' is not compatible with keyword 'date'
2533 abort: template filter 'escape' is not compatible with keyword 'date'
2534 [255]
2534 [255]
2535
2535
2536 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2536 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2537 hg: parse error: localdate expects a date information
2537 hg: parse error: localdate expects a date information
2538 [255]
2538 [255]
2539
2539
2540 Behind the scenes, this will throw ValueError
2540 Behind the scenes, this will throw ValueError
2541
2541
2542 $ hg tip --template '{author|email|date}\n'
2542 $ hg tip --template '{author|email|date}\n'
2543 hg: parse error: date expects a date information
2543 hg: parse error: date expects a date information
2544 [255]
2544 [255]
2545
2545
2546 Error in nested template:
2546 Error in nested template:
2547
2547
2548 $ hg log -T '{"date'
2548 $ hg log -T '{"date'
2549 hg: parse error at 2: unterminated string
2549 hg: parse error at 2: unterminated string
2550 [255]
2550 [255]
2551
2551
2552 $ hg log -T '{"foo{date|=}"}'
2552 $ hg log -T '{"foo{date|=}"}'
2553 hg: parse error at 11: syntax error
2553 hg: parse error at 11: syntax error
2554 [255]
2554 [255]
2555
2555
2556 Thrown an error if a template function doesn't exist
2556 Thrown an error if a template function doesn't exist
2557
2557
2558 $ hg tip --template '{foo()}\n'
2558 $ hg tip --template '{foo()}\n'
2559 hg: parse error: unknown function 'foo'
2559 hg: parse error: unknown function 'foo'
2560 [255]
2560 [255]
2561
2561
2562 Pass generator object created by template function to filter
2562 Pass generator object created by template function to filter
2563
2563
2564 $ hg log -l 1 --template '{if(author, author)|user}\n'
2564 $ hg log -l 1 --template '{if(author, author)|user}\n'
2565 test
2565 test
2566
2566
2567 Test diff function:
2567 Test diff function:
2568
2568
2569 $ hg diff -c 8
2569 $ hg diff -c 8
2570 diff -r 29114dbae42b -r 95c24699272e fourth
2570 diff -r 29114dbae42b -r 95c24699272e fourth
2571 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2571 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2572 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2572 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2573 @@ -0,0 +1,1 @@
2573 @@ -0,0 +1,1 @@
2574 +second
2574 +second
2575 diff -r 29114dbae42b -r 95c24699272e second
2575 diff -r 29114dbae42b -r 95c24699272e second
2576 --- a/second Mon Jan 12 13:46:40 1970 +0000
2576 --- a/second Mon Jan 12 13:46:40 1970 +0000
2577 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2577 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2578 @@ -1,1 +0,0 @@
2578 @@ -1,1 +0,0 @@
2579 -second
2579 -second
2580 diff -r 29114dbae42b -r 95c24699272e third
2580 diff -r 29114dbae42b -r 95c24699272e third
2581 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2581 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2582 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2582 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2583 @@ -0,0 +1,1 @@
2583 @@ -0,0 +1,1 @@
2584 +third
2584 +third
2585
2585
2586 $ hg log -r 8 -T "{diff()}"
2586 $ hg log -r 8 -T "{diff()}"
2587 diff -r 29114dbae42b -r 95c24699272e fourth
2587 diff -r 29114dbae42b -r 95c24699272e fourth
2588 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2588 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2589 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2589 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2590 @@ -0,0 +1,1 @@
2590 @@ -0,0 +1,1 @@
2591 +second
2591 +second
2592 diff -r 29114dbae42b -r 95c24699272e second
2592 diff -r 29114dbae42b -r 95c24699272e second
2593 --- a/second Mon Jan 12 13:46:40 1970 +0000
2593 --- a/second Mon Jan 12 13:46:40 1970 +0000
2594 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2594 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2595 @@ -1,1 +0,0 @@
2595 @@ -1,1 +0,0 @@
2596 -second
2596 -second
2597 diff -r 29114dbae42b -r 95c24699272e third
2597 diff -r 29114dbae42b -r 95c24699272e third
2598 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2598 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2599 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2599 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2600 @@ -0,0 +1,1 @@
2600 @@ -0,0 +1,1 @@
2601 +third
2601 +third
2602
2602
2603 $ hg log -r 8 -T "{diff('glob:f*')}"
2603 $ hg log -r 8 -T "{diff('glob:f*')}"
2604 diff -r 29114dbae42b -r 95c24699272e fourth
2604 diff -r 29114dbae42b -r 95c24699272e fourth
2605 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2605 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2606 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2606 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2607 @@ -0,0 +1,1 @@
2607 @@ -0,0 +1,1 @@
2608 +second
2608 +second
2609
2609
2610 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2610 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2611 diff -r 29114dbae42b -r 95c24699272e second
2611 diff -r 29114dbae42b -r 95c24699272e second
2612 --- a/second Mon Jan 12 13:46:40 1970 +0000
2612 --- a/second Mon Jan 12 13:46:40 1970 +0000
2613 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2613 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2614 @@ -1,1 +0,0 @@
2614 @@ -1,1 +0,0 @@
2615 -second
2615 -second
2616 diff -r 29114dbae42b -r 95c24699272e third
2616 diff -r 29114dbae42b -r 95c24699272e third
2617 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2617 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2618 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2618 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2619 @@ -0,0 +1,1 @@
2619 @@ -0,0 +1,1 @@
2620 +third
2620 +third
2621
2621
2622 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2622 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2623 diff -r 29114dbae42b -r 95c24699272e fourth
2623 diff -r 29114dbae42b -r 95c24699272e fourth
2624 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2624 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2625 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2625 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2626 @@ -0,0 +1,1 @@
2626 @@ -0,0 +1,1 @@
2627 +second
2627 +second
2628
2628
2629 $ cd ..
2629 $ cd ..
2630
2630
2631
2631
2632 latesttag:
2632 latesttag:
2633
2633
2634 $ hg init latesttag
2634 $ hg init latesttag
2635 $ cd latesttag
2635 $ cd latesttag
2636
2636
2637 $ echo a > file
2637 $ echo a > file
2638 $ hg ci -Am a -d '0 0'
2638 $ hg ci -Am a -d '0 0'
2639 adding file
2639 adding file
2640
2640
2641 $ echo b >> file
2641 $ echo b >> file
2642 $ hg ci -m b -d '1 0'
2642 $ hg ci -m b -d '1 0'
2643
2643
2644 $ echo c >> head1
2644 $ echo c >> head1
2645 $ hg ci -Am h1c -d '2 0'
2645 $ hg ci -Am h1c -d '2 0'
2646 adding head1
2646 adding head1
2647
2647
2648 $ hg update -q 1
2648 $ hg update -q 1
2649 $ echo d >> head2
2649 $ echo d >> head2
2650 $ hg ci -Am h2d -d '3 0'
2650 $ hg ci -Am h2d -d '3 0'
2651 adding head2
2651 adding head2
2652 created new head
2652 created new head
2653
2653
2654 $ echo e >> head2
2654 $ echo e >> head2
2655 $ hg ci -m h2e -d '4 0'
2655 $ hg ci -m h2e -d '4 0'
2656
2656
2657 $ hg merge -q
2657 $ hg merge -q
2658 $ hg ci -m merge -d '5 -3600'
2658 $ hg ci -m merge -d '5 -3600'
2659
2659
2660 No tag set:
2660 No tag set:
2661
2661
2662 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2662 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2663 5: null+5
2663 5: null+5
2664 4: null+4
2664 4: null+4
2665 3: null+3
2665 3: null+3
2666 2: null+3
2666 2: null+3
2667 1: null+2
2667 1: null+2
2668 0: null+1
2668 0: null+1
2669
2669
2670 One common tag: longest path wins:
2670 One common tag: longest path wins:
2671
2671
2672 $ hg tag -r 1 -m t1 -d '6 0' t1
2672 $ hg tag -r 1 -m t1 -d '6 0' t1
2673 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2673 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2674 6: t1+4
2674 6: t1+4
2675 5: t1+3
2675 5: t1+3
2676 4: t1+2
2676 4: t1+2
2677 3: t1+1
2677 3: t1+1
2678 2: t1+1
2678 2: t1+1
2679 1: t1+0
2679 1: t1+0
2680 0: null+1
2680 0: null+1
2681
2681
2682 One ancestor tag: more recent wins:
2682 One ancestor tag: more recent wins:
2683
2683
2684 $ hg tag -r 2 -m t2 -d '7 0' t2
2684 $ hg tag -r 2 -m t2 -d '7 0' t2
2685 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2685 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2686 7: t2+3
2686 7: t2+3
2687 6: t2+2
2687 6: t2+2
2688 5: t2+1
2688 5: t2+1
2689 4: t1+2
2689 4: t1+2
2690 3: t1+1
2690 3: t1+1
2691 2: t2+0
2691 2: t2+0
2692 1: t1+0
2692 1: t1+0
2693 0: null+1
2693 0: null+1
2694
2694
2695 Two branch tags: more recent wins:
2695 Two branch tags: more recent wins:
2696
2696
2697 $ hg tag -r 3 -m t3 -d '8 0' t3
2697 $ hg tag -r 3 -m t3 -d '8 0' t3
2698 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2698 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2699 8: t3+5
2699 8: t3+5
2700 7: t3+4
2700 7: t3+4
2701 6: t3+3
2701 6: t3+3
2702 5: t3+2
2702 5: t3+2
2703 4: t3+1
2703 4: t3+1
2704 3: t3+0
2704 3: t3+0
2705 2: t2+0
2705 2: t2+0
2706 1: t1+0
2706 1: t1+0
2707 0: null+1
2707 0: null+1
2708
2708
2709 Merged tag overrides:
2709 Merged tag overrides:
2710
2710
2711 $ hg tag -r 5 -m t5 -d '9 0' t5
2711 $ hg tag -r 5 -m t5 -d '9 0' t5
2712 $ hg tag -r 3 -m at3 -d '10 0' at3
2712 $ hg tag -r 3 -m at3 -d '10 0' at3
2713 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2713 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2714 10: t5+5
2714 10: t5+5
2715 9: t5+4
2715 9: t5+4
2716 8: t5+3
2716 8: t5+3
2717 7: t5+2
2717 7: t5+2
2718 6: t5+1
2718 6: t5+1
2719 5: t5+0
2719 5: t5+0
2720 4: at3:t3+1
2720 4: at3:t3+1
2721 3: at3:t3+0
2721 3: at3:t3+0
2722 2: t2+0
2722 2: t2+0
2723 1: t1+0
2723 1: t1+0
2724 0: null+1
2724 0: null+1
2725
2725
2726 $ hg log --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
2726 $ hg log --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
2727 10: t5+5,5
2727 10: t5+5,5
2728 9: t5+4,4
2728 9: t5+4,4
2729 8: t5+3,3
2729 8: t5+3,3
2730 7: t5+2,2
2730 7: t5+2,2
2731 6: t5+1,1
2731 6: t5+1,1
2732 5: t5+0,0
2732 5: t5+0,0
2733 4: at3+1,1 t3+1,1
2733 4: at3+1,1 t3+1,1
2734 3: at3+0,0 t3+0,0
2734 3: at3+0,0 t3+0,0
2735 2: t2+0,0
2735 2: t2+0,0
2736 1: t1+0,0
2736 1: t1+0,0
2737 0: null+1,1
2737 0: null+1,1
2738
2738
2739 $ hg log --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
2739 $ hg log --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
2740 10: t3, C: 8, D: 7
2740 10: t3, C: 8, D: 7
2741 9: t3, C: 7, D: 6
2741 9: t3, C: 7, D: 6
2742 8: t3, C: 6, D: 5
2742 8: t3, C: 6, D: 5
2743 7: t3, C: 5, D: 4
2743 7: t3, C: 5, D: 4
2744 6: t3, C: 4, D: 3
2744 6: t3, C: 4, D: 3
2745 5: t3, C: 3, D: 2
2745 5: t3, C: 3, D: 2
2746 4: t3, C: 1, D: 1
2746 4: t3, C: 1, D: 1
2747 3: t3, C: 0, D: 0
2747 3: t3, C: 0, D: 0
2748 2: t1, C: 1, D: 1
2748 2: t1, C: 1, D: 1
2749 1: t1, C: 0, D: 0
2749 1: t1, C: 0, D: 0
2750 0: null, C: 1, D: 1
2750 0: null, C: 1, D: 1
2751
2751
2752 $ cd ..
2752 $ cd ..
2753
2753
2754
2754
2755 Style path expansion: issue1948 - ui.style option doesn't work on OSX
2755 Style path expansion: issue1948 - ui.style option doesn't work on OSX
2756 if it is a relative path
2756 if it is a relative path
2757
2757
2758 $ mkdir -p home/styles
2758 $ mkdir -p home/styles
2759
2759
2760 $ cat > home/styles/teststyle <<EOF
2760 $ cat > home/styles/teststyle <<EOF
2761 > changeset = 'test {rev}:{node|short}\n'
2761 > changeset = 'test {rev}:{node|short}\n'
2762 > EOF
2762 > EOF
2763
2763
2764 $ HOME=`pwd`/home; export HOME
2764 $ HOME=`pwd`/home; export HOME
2765
2765
2766 $ cat > latesttag/.hg/hgrc <<EOF
2766 $ cat > latesttag/.hg/hgrc <<EOF
2767 > [ui]
2767 > [ui]
2768 > style = ~/styles/teststyle
2768 > style = ~/styles/teststyle
2769 > EOF
2769 > EOF
2770
2770
2771 $ hg -R latesttag tip
2771 $ hg -R latesttag tip
2772 test 10:9b4a630e5f5f
2772 test 10:9b4a630e5f5f
2773
2773
2774 Test recursive showlist template (issue1989):
2774 Test recursive showlist template (issue1989):
2775
2775
2776 $ cat > style1989 <<EOF
2776 $ cat > style1989 <<EOF
2777 > changeset = '{file_mods}{manifest}{extras}'
2777 > changeset = '{file_mods}{manifest}{extras}'
2778 > file_mod = 'M|{author|person}\n'
2778 > file_mod = 'M|{author|person}\n'
2779 > manifest = '{rev},{author}\n'
2779 > manifest = '{rev},{author}\n'
2780 > extra = '{key}: {author}\n'
2780 > extra = '{key}: {author}\n'
2781 > EOF
2781 > EOF
2782
2782
2783 $ hg -R latesttag log -r tip --style=style1989
2783 $ hg -R latesttag log -r tip --style=style1989
2784 M|test
2784 M|test
2785 10,test
2785 10,test
2786 branch: test
2786 branch: test
2787
2787
2788 Test new-style inline templating:
2788 Test new-style inline templating:
2789
2789
2790 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
2790 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
2791 modified files: .hgtags
2791 modified files: .hgtags
2792
2792
2793 Test the sub function of templating for expansion:
2793 Test the sub function of templating for expansion:
2794
2794
2795 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
2795 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
2796 xx
2796 xx
2797
2797
2798 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
2798 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
2799 hg: parse error: sub got an invalid pattern: [
2799 hg: parse error: sub got an invalid pattern: [
2800 [255]
2800 [255]
2801 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
2801 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
2802 hg: parse error: sub got an invalid replacement: \1
2802 hg: parse error: sub got an invalid replacement: \1
2803 [255]
2803 [255]
2804
2804
2805 Test the strip function with chars specified:
2805 Test the strip function with chars specified:
2806
2806
2807 $ hg log -R latesttag --template '{desc}\n'
2807 $ hg log -R latesttag --template '{desc}\n'
2808 at3
2808 at3
2809 t5
2809 t5
2810 t3
2810 t3
2811 t2
2811 t2
2812 t1
2812 t1
2813 merge
2813 merge
2814 h2e
2814 h2e
2815 h2d
2815 h2d
2816 h1c
2816 h1c
2817 b
2817 b
2818 a
2818 a
2819
2819
2820 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2820 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2821 at3
2821 at3
2822 5
2822 5
2823 3
2823 3
2824 2
2824 2
2825 1
2825 1
2826 merg
2826 merg
2827 h2
2827 h2
2828 h2d
2828 h2d
2829 h1c
2829 h1c
2830 b
2830 b
2831 a
2831 a
2832
2832
2833 Test date format:
2833 Test date format:
2834
2834
2835 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2835 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2836 date: 70 01 01 10 +0000
2836 date: 70 01 01 10 +0000
2837 date: 70 01 01 09 +0000
2837 date: 70 01 01 09 +0000
2838 date: 70 01 01 08 +0000
2838 date: 70 01 01 08 +0000
2839 date: 70 01 01 07 +0000
2839 date: 70 01 01 07 +0000
2840 date: 70 01 01 06 +0000
2840 date: 70 01 01 06 +0000
2841 date: 70 01 01 05 +0100
2841 date: 70 01 01 05 +0100
2842 date: 70 01 01 04 +0000
2842 date: 70 01 01 04 +0000
2843 date: 70 01 01 03 +0000
2843 date: 70 01 01 03 +0000
2844 date: 70 01 01 02 +0000
2844 date: 70 01 01 02 +0000
2845 date: 70 01 01 01 +0000
2845 date: 70 01 01 01 +0000
2846 date: 70 01 01 00 +0000
2846 date: 70 01 01 00 +0000
2847
2847
2848 Test invalid date:
2848 Test invalid date:
2849
2849
2850 $ hg log -R latesttag -T '{date(rev)}\n'
2850 $ hg log -R latesttag -T '{date(rev)}\n'
2851 hg: parse error: date expects a date information
2851 hg: parse error: date expects a date information
2852 [255]
2852 [255]
2853
2853
2854 Test integer literal:
2854 Test integer literal:
2855
2855
2856 $ hg log -Ra -r0 -T '{(0)}\n'
2856 $ hg log -Ra -r0 -T '{(0)}\n'
2857 0
2857 0
2858 $ hg log -Ra -r0 -T '{(123)}\n'
2858 $ hg log -Ra -r0 -T '{(123)}\n'
2859 123
2859 123
2860 $ hg log -Ra -r0 -T '{(-4)}\n'
2860 $ hg log -Ra -r0 -T '{(-4)}\n'
2861 -4
2861 -4
2862 $ hg log -Ra -r0 -T '{(-)}\n'
2862 $ hg log -Ra -r0 -T '{(-)}\n'
2863 hg: parse error at 2: integer literal without digits
2863 hg: parse error at 2: integer literal without digits
2864 [255]
2864 [255]
2865 $ hg log -Ra -r0 -T '{(-a)}\n'
2865 $ hg log -Ra -r0 -T '{(-a)}\n'
2866 hg: parse error at 2: integer literal without digits
2866 hg: parse error at 2: integer literal without digits
2867 [255]
2867 [255]
2868
2868
2869 top-level integer literal is interpreted as symbol (i.e. variable name):
2869 top-level integer literal is interpreted as symbol (i.e. variable name):
2870
2870
2871 $ hg log -Ra -r0 -T '{1}\n'
2871 $ hg log -Ra -r0 -T '{1}\n'
2872
2872
2873 $ hg log -Ra -r0 -T '{if("t", "{1}")}\n'
2873 $ hg log -Ra -r0 -T '{if("t", "{1}")}\n'
2874
2874
2875 $ hg log -Ra -r0 -T '{1|stringify}\n'
2875 $ hg log -Ra -r0 -T '{1|stringify}\n'
2876
2876
2877
2877
2878 unless explicit symbol is expected:
2878 unless explicit symbol is expected:
2879
2879
2880 $ hg log -Ra -r0 -T '{desc|1}\n'
2880 $ hg log -Ra -r0 -T '{desc|1}\n'
2881 hg: parse error: expected a symbol, got 'integer'
2881 hg: parse error: expected a symbol, got 'integer'
2882 [255]
2882 [255]
2883 $ hg log -Ra -r0 -T '{1()}\n'
2883 $ hg log -Ra -r0 -T '{1()}\n'
2884 hg: parse error: expected a symbol, got 'integer'
2884 hg: parse error: expected a symbol, got 'integer'
2885 [255]
2885 [255]
2886
2886
2887 Test string literal:
2887 Test string literal:
2888
2888
2889 $ hg log -Ra -r0 -T '{"string with no template fragment"}\n'
2889 $ hg log -Ra -r0 -T '{"string with no template fragment"}\n'
2890 string with no template fragment
2890 string with no template fragment
2891 $ hg log -Ra -r0 -T '{"template: {rev}"}\n'
2891 $ hg log -Ra -r0 -T '{"template: {rev}"}\n'
2892 template: 0
2892 template: 0
2893 $ hg log -Ra -r0 -T '{r"rawstring: {rev}"}\n'
2893 $ hg log -Ra -r0 -T '{r"rawstring: {rev}"}\n'
2894 rawstring: {rev}
2894 rawstring: {rev}
2895
2895
2896 because map operation requires template, raw string can't be used
2896 because map operation requires template, raw string can't be used
2897
2897
2898 $ hg log -Ra -r0 -T '{files % r"rawstring"}\n'
2898 $ hg log -Ra -r0 -T '{files % r"rawstring"}\n'
2899 hg: parse error: expected template specifier
2899 hg: parse error: expected template specifier
2900 [255]
2900 [255]
2901
2901
2902 Test string escaping:
2902 Test string escaping:
2903
2903
2904 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2904 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2905 >
2905 >
2906 <>\n<[>
2906 <>\n<[>
2907 <>\n<]>
2907 <>\n<]>
2908 <>\n<
2908 <>\n<
2909
2909
2910 $ hg log -R latesttag -r 0 \
2910 $ hg log -R latesttag -r 0 \
2911 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2911 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2912 >
2912 >
2913 <>\n<[>
2913 <>\n<[>
2914 <>\n<]>
2914 <>\n<]>
2915 <>\n<
2915 <>\n<
2916
2916
2917 $ hg log -R latesttag -r 0 -T esc \
2917 $ hg log -R latesttag -r 0 -T esc \
2918 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2918 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2919 >
2919 >
2920 <>\n<[>
2920 <>\n<[>
2921 <>\n<]>
2921 <>\n<]>
2922 <>\n<
2922 <>\n<
2923
2923
2924 $ cat <<'EOF' > esctmpl
2924 $ cat <<'EOF' > esctmpl
2925 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2925 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2926 > EOF
2926 > EOF
2927 $ hg log -R latesttag -r 0 --style ./esctmpl
2927 $ hg log -R latesttag -r 0 --style ./esctmpl
2928 >
2928 >
2929 <>\n<[>
2929 <>\n<[>
2930 <>\n<]>
2930 <>\n<]>
2931 <>\n<
2931 <>\n<
2932
2932
2933 Test string escaping of quotes:
2933 Test string escaping of quotes:
2934
2934
2935 $ hg log -Ra -r0 -T '{"\""}\n'
2935 $ hg log -Ra -r0 -T '{"\""}\n'
2936 "
2936 "
2937 $ hg log -Ra -r0 -T '{"\\\""}\n'
2937 $ hg log -Ra -r0 -T '{"\\\""}\n'
2938 \"
2938 \"
2939 $ hg log -Ra -r0 -T '{r"\""}\n'
2939 $ hg log -Ra -r0 -T '{r"\""}\n'
2940 \"
2940 \"
2941 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2941 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2942 \\\"
2942 \\\"
2943
2943
2944
2944
2945 $ hg log -Ra -r0 -T '{"\""}\n'
2945 $ hg log -Ra -r0 -T '{"\""}\n'
2946 "
2946 "
2947 $ hg log -Ra -r0 -T '{"\\\""}\n'
2947 $ hg log -Ra -r0 -T '{"\\\""}\n'
2948 \"
2948 \"
2949 $ hg log -Ra -r0 -T '{r"\""}\n'
2949 $ hg log -Ra -r0 -T '{r"\""}\n'
2950 \"
2950 \"
2951 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2951 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2952 \\\"
2952 \\\"
2953
2953
2954 Test exception in quoted template. single backslash before quotation mark is
2954 Test exception in quoted template. single backslash before quotation mark is
2955 stripped before parsing:
2955 stripped before parsing:
2956
2956
2957 $ cat <<'EOF' > escquotetmpl
2957 $ cat <<'EOF' > escquotetmpl
2958 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
2958 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
2959 > EOF
2959 > EOF
2960 $ cd latesttag
2960 $ cd latesttag
2961 $ hg log -r 2 --style ../escquotetmpl
2961 $ hg log -r 2 --style ../escquotetmpl
2962 " \" \" \\" head1
2962 " \" \" \\" head1
2963
2963
2964 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
2964 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
2965 valid
2965 valid
2966 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
2966 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
2967 valid
2967 valid
2968
2968
2969 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
2969 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
2970 _evalifliteral() templates (issue4733):
2970 _evalifliteral() templates (issue4733):
2971
2971
2972 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
2972 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
2973 "2
2973 "2
2974 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
2974 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
2975 "2
2975 "2
2976 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
2976 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
2977 "2
2977 "2
2978
2978
2979 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
2979 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
2980 \"
2980 \"
2981 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
2981 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
2982 \"
2982 \"
2983 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2983 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2984 \"
2984 \"
2985
2985
2986 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
2986 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
2987 \\\"
2987 \\\"
2988 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
2988 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
2989 \\\"
2989 \\\"
2990 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2990 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2991 \\\"
2991 \\\"
2992
2992
2993 escaped single quotes and errors:
2993 escaped single quotes and errors:
2994
2994
2995 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
2995 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
2996 foo
2996 foo
2997 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
2997 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
2998 foo
2998 foo
2999 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
2999 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3000 hg: parse error at 21: unterminated string
3000 hg: parse error at 21: unterminated string
3001 [255]
3001 [255]
3002 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3002 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3003 hg: parse error: trailing \ in string
3003 hg: parse error: trailing \ in string
3004 [255]
3004 [255]
3005 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3005 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3006 hg: parse error: trailing \ in string
3006 hg: parse error: trailing \ in string
3007 [255]
3007 [255]
3008
3008
3009 $ cd ..
3009 $ cd ..
3010
3010
3011 Test leading backslashes:
3011 Test leading backslashes:
3012
3012
3013 $ cd latesttag
3013 $ cd latesttag
3014 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3014 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3015 {rev} {file}
3015 {rev} {file}
3016 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3016 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3017 \2 \head1
3017 \2 \head1
3018 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3018 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3019 \{rev} \{file}
3019 \{rev} \{file}
3020 $ cd ..
3020 $ cd ..
3021
3021
3022 Test leading backslashes in "if" expression (issue4714):
3022 Test leading backslashes in "if" expression (issue4714):
3023
3023
3024 $ cd latesttag
3024 $ cd latesttag
3025 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3025 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3026 {rev} \{rev}
3026 {rev} \{rev}
3027 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3027 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3028 \2 \\{rev}
3028 \2 \\{rev}
3029 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3029 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3030 \{rev} \\\{rev}
3030 \{rev} \\\{rev}
3031 $ cd ..
3031 $ cd ..
3032
3032
3033 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3033 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3034
3034
3035 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3035 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3036 \x6e
3036 \x6e
3037 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3037 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3038 \x5c\x786e
3038 \x5c\x786e
3039 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3039 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3040 \x6e
3040 \x6e
3041 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3041 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3042 \x5c\x786e
3042 \x5c\x786e
3043
3043
3044 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3044 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3045 \x6e
3045 \x6e
3046 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3046 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3047 \x5c\x786e
3047 \x5c\x786e
3048 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3048 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3049 \x6e
3049 \x6e
3050 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3050 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3051 \x5c\x786e
3051 \x5c\x786e
3052
3052
3053 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3053 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3054 fourth
3054 fourth
3055 second
3055 second
3056 third
3056 third
3057 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3057 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3058 fourth\nsecond\nthird
3058 fourth\nsecond\nthird
3059
3059
3060 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3060 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3061 <p>
3061 <p>
3062 1st
3062 1st
3063 </p>
3063 </p>
3064 <p>
3064 <p>
3065 2nd
3065 2nd
3066 </p>
3066 </p>
3067 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3067 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3068 <p>
3068 <p>
3069 1st\n\n2nd
3069 1st\n\n2nd
3070 </p>
3070 </p>
3071 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3071 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3072 1st
3072 1st
3073
3073
3074 2nd
3074 2nd
3075
3075
3076 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3076 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3077 o perso
3077 o perso
3078 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3078 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3079 no person
3079 no person
3080 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3080 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3081 o perso
3081 o perso
3082 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3082 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3083 no perso
3083 no perso
3084
3084
3085 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3085 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3086 -o perso-
3086 -o perso-
3087 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3087 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3088 no person
3088 no person
3089 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3089 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3090 \x2do perso\x2d
3090 \x2do perso\x2d
3091 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3091 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3092 -o perso-
3092 -o perso-
3093 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3093 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3094 \x2do perso\x6e
3094 \x2do perso\x6e
3095
3095
3096 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3096 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3097 fourth
3097 fourth
3098 second
3098 second
3099 third
3099 third
3100
3100
3101 Test string escaping in nested expression:
3101 Test string escaping in nested expression:
3102
3102
3103 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3103 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3104 fourth\x6esecond\x6ethird
3104 fourth\x6esecond\x6ethird
3105 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3105 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3106 fourth\x6esecond\x6ethird
3106 fourth\x6esecond\x6ethird
3107
3107
3108 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3108 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3109 fourth\x6esecond\x6ethird
3109 fourth\x6esecond\x6ethird
3110 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3110 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3111 fourth\x5c\x786esecond\x5c\x786ethird
3111 fourth\x5c\x786esecond\x5c\x786ethird
3112
3112
3113 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3113 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3114 3:\x6eo user, \x6eo domai\x6e
3114 3:\x6eo user, \x6eo domai\x6e
3115 4:\x5c\x786eew bra\x5c\x786ech
3115 4:\x5c\x786eew bra\x5c\x786ech
3116
3116
3117 Test quotes in nested expression are evaluated just like a $(command)
3117 Test quotes in nested expression are evaluated just like a $(command)
3118 substitution in POSIX shells:
3118 substitution in POSIX shells:
3119
3119
3120 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3120 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3121 8:95c24699272e
3121 8:95c24699272e
3122 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3122 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3123 {8} "95c24699272e"
3123 {8} "95c24699272e"
3124
3124
3125 Test recursive evaluation:
3125 Test recursive evaluation:
3126
3126
3127 $ hg init r
3127 $ hg init r
3128 $ cd r
3128 $ cd r
3129 $ echo a > a
3129 $ echo a > a
3130 $ hg ci -Am '{rev}'
3130 $ hg ci -Am '{rev}'
3131 adding a
3131 adding a
3132 $ hg log -r 0 --template '{if(rev, desc)}\n'
3132 $ hg log -r 0 --template '{if(rev, desc)}\n'
3133 {rev}
3133 {rev}
3134 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3134 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3135 test 0
3135 test 0
3136
3136
3137 $ hg branch -q 'text.{rev}'
3137 $ hg branch -q 'text.{rev}'
3138 $ echo aa >> aa
3138 $ echo aa >> aa
3139 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3139 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3140
3140
3141 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3141 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3142 {node|short}desc to
3142 {node|short}desc to
3143 text.{rev}be wrapped
3143 text.{rev}be wrapped
3144 text.{rev}desc to be
3144 text.{rev}desc to be
3145 text.{rev}wrapped (no-eol)
3145 text.{rev}wrapped (no-eol)
3146 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3146 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3147 bcc7ff960b8e:desc to
3147 bcc7ff960b8e:desc to
3148 text.1:be wrapped
3148 text.1:be wrapped
3149 text.1:desc to be
3149 text.1:desc to be
3150 text.1:wrapped (no-eol)
3150 text.1:wrapped (no-eol)
3151 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3151 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3152 hg: parse error: fill expects an integer width
3152 hg: parse error: fill expects an integer width
3153 [255]
3153 [255]
3154
3154
3155 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3155 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3156 {node|short} (no-eol)
3156 {node|short} (no-eol)
3157 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3157 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3158 bcc-ff---b-e (no-eol)
3158 bcc-ff---b-e (no-eol)
3159
3159
3160 $ cat >> .hg/hgrc <<EOF
3160 $ cat >> .hg/hgrc <<EOF
3161 > [extensions]
3161 > [extensions]
3162 > color=
3162 > color=
3163 > [color]
3163 > [color]
3164 > mode=ansi
3164 > mode=ansi
3165 > text.{rev} = red
3165 > text.{rev} = red
3166 > text.1 = green
3166 > text.1 = green
3167 > EOF
3167 > EOF
3168 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3168 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3169 \x1b[0;31mtext\x1b[0m (esc)
3169 \x1b[0;31mtext\x1b[0m (esc)
3170 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3170 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3171 \x1b[0;32mtext\x1b[0m (esc)
3171 \x1b[0;32mtext\x1b[0m (esc)
3172
3172
3173 Test branches inside if statement:
3173 Test branches inside if statement:
3174
3174
3175 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3175 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3176 no
3176 no
3177
3177
3178 Test get function:
3178 Test get function:
3179
3179
3180 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3180 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3181 default
3181 default
3182 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3182 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3183 default
3183 default
3184 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3184 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3185 hg: parse error: get() expects a dict as first argument
3185 hg: parse error: get() expects a dict as first argument
3186 [255]
3186 [255]
3187
3187
3188 Test localdate(date, tz) function:
3188 Test localdate(date, tz) function:
3189
3189
3190 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3190 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3191 1970-01-01 09:00 +0900
3191 1970-01-01 09:00 +0900
3192 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3192 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3193 1970-01-01 00:00 +0000
3193 1970-01-01 00:00 +0000
3194 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3194 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3195 1970-01-01 02:00 +0200
3195 1970-01-01 02:00 +0200
3196 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3196 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3197 1970-01-01 00:00 +0000
3197 1970-01-01 00:00 +0000
3198 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3198 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3199 1970-01-01 00:00 +0000
3199 1970-01-01 00:00 +0000
3200 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3200 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3201 hg: parse error: localdate expects a timezone
3201 hg: parse error: localdate expects a timezone
3202 [255]
3202 [255]
3203 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3203 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3204 hg: parse error: localdate expects a timezone
3204 hg: parse error: localdate expects a timezone
3205 [255]
3205 [255]
3206
3206
3207 Test shortest(node) function:
3207 Test shortest(node) function:
3208
3208
3209 $ echo b > b
3209 $ echo b > b
3210 $ hg ci -qAm b
3210 $ hg ci -qAm b
3211 $ hg log --template '{shortest(node)}\n'
3211 $ hg log --template '{shortest(node)}\n'
3212 e777
3212 e777
3213 bcc7
3213 bcc7
3214 f776
3214 f776
3215 $ hg log --template '{shortest(node, 10)}\n'
3215 $ hg log --template '{shortest(node, 10)}\n'
3216 e777603221
3216 e777603221
3217 bcc7ff960b
3217 bcc7ff960b
3218 f7769ec2ab
3218 f7769ec2ab
3219 $ hg log --template '{node|shortest}\n' -l1
3219 $ hg log --template '{node|shortest}\n' -l1
3220 e777
3220 e777
3221
3221
3222 Test pad function
3222 Test pad function
3223
3223
3224 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3224 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3225 2 test
3225 2 test
3226 1 {node|short}
3226 1 {node|short}
3227 0 test
3227 0 test
3228
3228
3229 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3229 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3230 2 test
3230 2 test
3231 1 {node|short}
3231 1 {node|short}
3232 0 test
3232 0 test
3233
3233
3234 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3234 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3235 2------------------- test
3235 2------------------- test
3236 1------------------- {node|short}
3236 1------------------- {node|short}
3237 0------------------- test
3237 0------------------- test
3238
3238
3239 Test template string in pad function
3239 Test template string in pad function
3240
3240
3241 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3241 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3242 {0} test
3242 {0} test
3243
3243
3244 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3244 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3245 \{rev} test
3245 \{rev} test
3246
3246
3247 Test width argument passed to pad function
3248
3249 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
3250 0 test
3251 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
3252 hg: parse error: pad() expects an integer width
3253 [255]
3254
3247 Test ifcontains function
3255 Test ifcontains function
3248
3256
3249 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
3257 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
3250 2 is in the string
3258 2 is in the string
3251 1 is not
3259 1 is not
3252 0 is in the string
3260 0 is in the string
3253
3261
3254 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
3262 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
3255 2 is in the string
3263 2 is in the string
3256 1 is not
3264 1 is not
3257 0 is in the string
3265 0 is in the string
3258
3266
3259 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
3267 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
3260 2 did not add a
3268 2 did not add a
3261 1 did not add a
3269 1 did not add a
3262 0 added a
3270 0 added a
3263
3271
3264 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
3272 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
3265 2 is parent of 1
3273 2 is parent of 1
3266 1
3274 1
3267 0
3275 0
3268
3276
3269 Test revset function
3277 Test revset function
3270
3278
3271 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
3279 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
3272 2 current rev
3280 2 current rev
3273 1 not current rev
3281 1 not current rev
3274 0 not current rev
3282 0 not current rev
3275
3283
3276 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
3284 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
3277 2 match rev
3285 2 match rev
3278 1 match rev
3286 1 match rev
3279 0 not match rev
3287 0 not match rev
3280
3288
3281 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
3289 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
3282 2 Parents: 1
3290 2 Parents: 1
3283 1 Parents: 0
3291 1 Parents: 0
3284 0 Parents:
3292 0 Parents:
3285
3293
3286 $ cat >> .hg/hgrc <<EOF
3294 $ cat >> .hg/hgrc <<EOF
3287 > [revsetalias]
3295 > [revsetalias]
3288 > myparents(\$1) = parents(\$1)
3296 > myparents(\$1) = parents(\$1)
3289 > EOF
3297 > EOF
3290 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
3298 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
3291 2 Parents: 1
3299 2 Parents: 1
3292 1 Parents: 0
3300 1 Parents: 0
3293 0 Parents:
3301 0 Parents:
3294
3302
3295 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
3303 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
3296 Rev: 2
3304 Rev: 2
3297 Ancestor: 0
3305 Ancestor: 0
3298 Ancestor: 1
3306 Ancestor: 1
3299 Ancestor: 2
3307 Ancestor: 2
3300
3308
3301 Rev: 1
3309 Rev: 1
3302 Ancestor: 0
3310 Ancestor: 0
3303 Ancestor: 1
3311 Ancestor: 1
3304
3312
3305 Rev: 0
3313 Rev: 0
3306 Ancestor: 0
3314 Ancestor: 0
3307
3315
3308 $ hg log --template '{revset("TIP"|lower)}\n' -l1
3316 $ hg log --template '{revset("TIP"|lower)}\n' -l1
3309 2
3317 2
3310
3318
3311 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
3319 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
3312 2
3320 2
3313
3321
3314 a list template is evaluated for each item of revset/parents
3322 a list template is evaluated for each item of revset/parents
3315
3323
3316 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
3324 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
3317 2 p: 1:bcc7ff960b8e
3325 2 p: 1:bcc7ff960b8e
3318 1 p: 0:f7769ec2ab97
3326 1 p: 0:f7769ec2ab97
3319 0 p:
3327 0 p:
3320
3328
3321 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
3329 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
3322 2 p: 1:bcc7ff960b8e -1:000000000000
3330 2 p: 1:bcc7ff960b8e -1:000000000000
3323 1 p: 0:f7769ec2ab97 -1:000000000000
3331 1 p: 0:f7769ec2ab97 -1:000000000000
3324 0 p: -1:000000000000 -1:000000000000
3332 0 p: -1:000000000000 -1:000000000000
3325
3333
3326 therefore, 'revcache' should be recreated for each rev
3334 therefore, 'revcache' should be recreated for each rev
3327
3335
3328 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
3336 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
3329 2 aa b
3337 2 aa b
3330 p
3338 p
3331 1
3339 1
3332 p a
3340 p a
3333 0 a
3341 0 a
3334 p
3342 p
3335
3343
3336 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
3344 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
3337 2 aa b
3345 2 aa b
3338 p
3346 p
3339 1
3347 1
3340 p a
3348 p a
3341 0 a
3349 0 a
3342 p
3350 p
3343
3351
3344 a revset item must be evaluated as an integer revision, not an offset from tip
3352 a revset item must be evaluated as an integer revision, not an offset from tip
3345
3353
3346 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
3354 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
3347 -1:000000000000
3355 -1:000000000000
3348 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
3356 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
3349 -1:000000000000
3357 -1:000000000000
3350
3358
3351 Test active bookmark templating
3359 Test active bookmark templating
3352
3360
3353 $ hg book foo
3361 $ hg book foo
3354 $ hg book bar
3362 $ hg book bar
3355 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
3363 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
3356 2 bar* foo
3364 2 bar* foo
3357 1
3365 1
3358 0
3366 0
3359 $ hg log --template "{rev} {activebookmark}\n"
3367 $ hg log --template "{rev} {activebookmark}\n"
3360 2 bar
3368 2 bar
3361 1
3369 1
3362 0
3370 0
3363 $ hg bookmarks --inactive bar
3371 $ hg bookmarks --inactive bar
3364 $ hg log --template "{rev} {activebookmark}\n"
3372 $ hg log --template "{rev} {activebookmark}\n"
3365 2
3373 2
3366 1
3374 1
3367 0
3375 0
3368 $ hg book -r1 baz
3376 $ hg book -r1 baz
3369 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
3377 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
3370 2 bar foo
3378 2 bar foo
3371 1 baz
3379 1 baz
3372 0
3380 0
3373 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
3381 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
3374 2 t
3382 2 t
3375 1 f
3383 1 f
3376 0 f
3384 0 f
3377
3385
3378 Test namespaces dict
3386 Test namespaces dict
3379
3387
3380 $ hg log -T '{rev}{namespaces % " {namespace}={join(names, ",")}"}\n'
3388 $ hg log -T '{rev}{namespaces % " {namespace}={join(names, ",")}"}\n'
3381 2 bookmarks=bar,foo tags=tip branches=text.{rev}
3389 2 bookmarks=bar,foo tags=tip branches=text.{rev}
3382 1 bookmarks=baz tags= branches=text.{rev}
3390 1 bookmarks=baz tags= branches=text.{rev}
3383 0 bookmarks= tags= branches=default
3391 0 bookmarks= tags= branches=default
3384 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
3392 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
3385 bookmarks: bar foo
3393 bookmarks: bar foo
3386 tags: tip
3394 tags: tip
3387 branches: text.{rev}
3395 branches: text.{rev}
3388 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
3396 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
3389 bookmarks:
3397 bookmarks:
3390 bar
3398 bar
3391 foo
3399 foo
3392 tags:
3400 tags:
3393 tip
3401 tip
3394 branches:
3402 branches:
3395 text.{rev}
3403 text.{rev}
3396 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
3404 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
3397 bar
3405 bar
3398 foo
3406 foo
3399
3407
3400 Test stringify on sub expressions
3408 Test stringify on sub expressions
3401
3409
3402 $ cd ..
3410 $ cd ..
3403 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
3411 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
3404 fourth, second, third
3412 fourth, second, third
3405 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
3413 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
3406 abc
3414 abc
3407
3415
3408 Test splitlines
3416 Test splitlines
3409
3417
3410 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
3418 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
3411 @ foo Modify, add, remove, rename
3419 @ foo Modify, add, remove, rename
3412 |
3420 |
3413 o foo future
3421 o foo future
3414 |
3422 |
3415 o foo third
3423 o foo third
3416 |
3424 |
3417 o foo second
3425 o foo second
3418
3426
3419 o foo merge
3427 o foo merge
3420 |\
3428 |\
3421 | o foo new head
3429 | o foo new head
3422 | |
3430 | |
3423 o | foo new branch
3431 o | foo new branch
3424 |/
3432 |/
3425 o foo no user, no domain
3433 o foo no user, no domain
3426 |
3434 |
3427 o foo no person
3435 o foo no person
3428 |
3436 |
3429 o foo other 1
3437 o foo other 1
3430 | foo other 2
3438 | foo other 2
3431 | foo
3439 | foo
3432 | foo other 3
3440 | foo other 3
3433 o foo line 1
3441 o foo line 1
3434 foo line 2
3442 foo line 2
3435
3443
3436 Test startswith
3444 Test startswith
3437 $ hg log -Gv -R a --template "{startswith(desc)}"
3445 $ hg log -Gv -R a --template "{startswith(desc)}"
3438 hg: parse error: startswith expects two arguments
3446 hg: parse error: startswith expects two arguments
3439 [255]
3447 [255]
3440
3448
3441 $ hg log -Gv -R a --template "{startswith('line', desc)}"
3449 $ hg log -Gv -R a --template "{startswith('line', desc)}"
3442 @
3450 @
3443 |
3451 |
3444 o
3452 o
3445 |
3453 |
3446 o
3454 o
3447 |
3455 |
3448 o
3456 o
3449
3457
3450 o
3458 o
3451 |\
3459 |\
3452 | o
3460 | o
3453 | |
3461 | |
3454 o |
3462 o |
3455 |/
3463 |/
3456 o
3464 o
3457 |
3465 |
3458 o
3466 o
3459 |
3467 |
3460 o
3468 o
3461 |
3469 |
3462 o line 1
3470 o line 1
3463 line 2
3471 line 2
3464
3472
3465 Test bad template with better error message
3473 Test bad template with better error message
3466
3474
3467 $ hg log -Gv -R a --template '{desc|user()}'
3475 $ hg log -Gv -R a --template '{desc|user()}'
3468 hg: parse error: expected a symbol, got 'func'
3476 hg: parse error: expected a symbol, got 'func'
3469 [255]
3477 [255]
3470
3478
3471 Test word function (including index out of bounds graceful failure)
3479 Test word function (including index out of bounds graceful failure)
3472
3480
3473 $ hg log -Gv -R a --template "{word('1', desc)}"
3481 $ hg log -Gv -R a --template "{word('1', desc)}"
3474 @ add,
3482 @ add,
3475 |
3483 |
3476 o
3484 o
3477 |
3485 |
3478 o
3486 o
3479 |
3487 |
3480 o
3488 o
3481
3489
3482 o
3490 o
3483 |\
3491 |\
3484 | o head
3492 | o head
3485 | |
3493 | |
3486 o | branch
3494 o | branch
3487 |/
3495 |/
3488 o user,
3496 o user,
3489 |
3497 |
3490 o person
3498 o person
3491 |
3499 |
3492 o 1
3500 o 1
3493 |
3501 |
3494 o 1
3502 o 1
3495
3503
3496
3504
3497 Test word third parameter used as splitter
3505 Test word third parameter used as splitter
3498
3506
3499 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
3507 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
3500 @ M
3508 @ M
3501 |
3509 |
3502 o future
3510 o future
3503 |
3511 |
3504 o third
3512 o third
3505 |
3513 |
3506 o sec
3514 o sec
3507
3515
3508 o merge
3516 o merge
3509 |\
3517 |\
3510 | o new head
3518 | o new head
3511 | |
3519 | |
3512 o | new branch
3520 o | new branch
3513 |/
3521 |/
3514 o n
3522 o n
3515 |
3523 |
3516 o n
3524 o n
3517 |
3525 |
3518 o
3526 o
3519 |
3527 |
3520 o line 1
3528 o line 1
3521 line 2
3529 line 2
3522
3530
3523 Test word error messages for not enough and too many arguments
3531 Test word error messages for not enough and too many arguments
3524
3532
3525 $ hg log -Gv -R a --template "{word('0')}"
3533 $ hg log -Gv -R a --template "{word('0')}"
3526 hg: parse error: word expects two or three arguments, got 1
3534 hg: parse error: word expects two or three arguments, got 1
3527 [255]
3535 [255]
3528
3536
3529 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
3537 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
3530 hg: parse error: word expects two or three arguments, got 7
3538 hg: parse error: word expects two or three arguments, got 7
3531 [255]
3539 [255]
3532
3540
3533 Test word for integer literal
3541 Test word for integer literal
3534
3542
3535 $ hg log -R a --template "{word(2, desc)}\n" -r0
3543 $ hg log -R a --template "{word(2, desc)}\n" -r0
3536 line
3544 line
3537
3545
3538 Test word for invalid numbers
3546 Test word for invalid numbers
3539
3547
3540 $ hg log -Gv -R a --template "{word('a', desc)}"
3548 $ hg log -Gv -R a --template "{word('a', desc)}"
3541 hg: parse error: word expects an integer index
3549 hg: parse error: word expects an integer index
3542 [255]
3550 [255]
3543
3551
3544 Test word for out of range
3552 Test word for out of range
3545
3553
3546 $ hg log -R a --template "{word(10000, desc)}"
3554 $ hg log -R a --template "{word(10000, desc)}"
3547 $ hg log -R a --template "{word(-10000, desc)}"
3555 $ hg log -R a --template "{word(-10000, desc)}"
3548
3556
3549 Test indent and not adding to empty lines
3557 Test indent and not adding to empty lines
3550
3558
3551 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
3559 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
3552 -----
3560 -----
3553 > line 1
3561 > line 1
3554 >> line 2
3562 >> line 2
3555 -----
3563 -----
3556 > other 1
3564 > other 1
3557 >> other 2
3565 >> other 2
3558
3566
3559 >> other 3
3567 >> other 3
3560
3568
3561 Test with non-strings like dates
3569 Test with non-strings like dates
3562
3570
3563 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3571 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3564 1200000.00
3572 1200000.00
3565 1300000.00
3573 1300000.00
3566
3574
3567 Test broken string escapes:
3575 Test broken string escapes:
3568
3576
3569 $ hg log -T "bogus\\" -R a
3577 $ hg log -T "bogus\\" -R a
3570 hg: parse error: trailing \ in string
3578 hg: parse error: trailing \ in string
3571 [255]
3579 [255]
3572 $ hg log -T "\\xy" -R a
3580 $ hg log -T "\\xy" -R a
3573 hg: parse error: invalid \x escape
3581 hg: parse error: invalid \x escape
3574 [255]
3582 [255]
3575
3583
3576 json filter should escape HTML tags so that the output can be embedded in hgweb:
3584 json filter should escape HTML tags so that the output can be embedded in hgweb:
3577
3585
3578 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
3586 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
3579 "\u003cfoo@example.org\u003e"
3587 "\u003cfoo@example.org\u003e"
3580
3588
3581 Set up repository for non-ascii encoding tests:
3589 Set up repository for non-ascii encoding tests:
3582
3590
3583 $ hg init nonascii
3591 $ hg init nonascii
3584 $ cd nonascii
3592 $ cd nonascii
3585 $ python <<EOF
3593 $ python <<EOF
3586 > open('latin1', 'w').write('\xe9')
3594 > open('latin1', 'w').write('\xe9')
3587 > open('utf-8', 'w').write('\xc3\xa9')
3595 > open('utf-8', 'w').write('\xc3\xa9')
3588 > EOF
3596 > EOF
3589 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
3597 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
3590 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
3598 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
3591
3599
3592 json filter should try round-trip conversion to utf-8:
3600 json filter should try round-trip conversion to utf-8:
3593
3601
3594 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
3602 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
3595 "\u00e9"
3603 "\u00e9"
3596 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
3604 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
3597 "non-ascii branch: \u00e9"
3605 "non-ascii branch: \u00e9"
3598
3606
3599 json filter takes input as utf-8b:
3607 json filter takes input as utf-8b:
3600
3608
3601 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
3609 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
3602 "\u00e9"
3610 "\u00e9"
3603 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
3611 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
3604 "\udce9"
3612 "\udce9"
3605
3613
3606 utf8 filter:
3614 utf8 filter:
3607
3615
3608 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
3616 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
3609 round-trip: c3a9
3617 round-trip: c3a9
3610 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
3618 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
3611 decoded: c3a9
3619 decoded: c3a9
3612 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
3620 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
3613 abort: decoding near * (glob)
3621 abort: decoding near * (glob)
3614 [255]
3622 [255]
3615 $ hg log -T "invalid type: {rev|utf8}\n" -r0
3623 $ hg log -T "invalid type: {rev|utf8}\n" -r0
3616 abort: template filter 'utf8' is not compatible with keyword 'rev'
3624 abort: template filter 'utf8' is not compatible with keyword 'rev'
3617 [255]
3625 [255]
3618
3626
3619 $ cd ..
3627 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now