##// END OF EJS Templates
shortest: make {shortest("fffffffff")} work again...
Martin von Zweigbergk -
r37876:66dc9db6 default
parent child Browse files
Show More
@@ -1,690 +1,693
1 # templatefuncs.py - common template functions
1 # templatefuncs.py - common template functions
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 re
10 import re
11
11
12 from .i18n import _
12 from .i18n import _
13 from .node import (
13 from .node import (
14 bin,
14 bin,
15 wdirid,
15 )
16 )
16 from . import (
17 from . import (
17 color,
18 color,
18 encoding,
19 encoding,
19 error,
20 error,
20 minirst,
21 minirst,
21 obsutil,
22 obsutil,
22 pycompat,
23 pycompat,
23 registrar,
24 registrar,
24 revset as revsetmod,
25 revset as revsetmod,
25 revsetlang,
26 revsetlang,
26 scmutil,
27 scmutil,
27 templatefilters,
28 templatefilters,
28 templatekw,
29 templatekw,
29 templateutil,
30 templateutil,
30 util,
31 util,
31 )
32 )
32 from .utils import (
33 from .utils import (
33 dateutil,
34 dateutil,
34 stringutil,
35 stringutil,
35 )
36 )
36
37
37 evalrawexp = templateutil.evalrawexp
38 evalrawexp = templateutil.evalrawexp
38 evalfuncarg = templateutil.evalfuncarg
39 evalfuncarg = templateutil.evalfuncarg
39 evalboolean = templateutil.evalboolean
40 evalboolean = templateutil.evalboolean
40 evaldate = templateutil.evaldate
41 evaldate = templateutil.evaldate
41 evalinteger = templateutil.evalinteger
42 evalinteger = templateutil.evalinteger
42 evalstring = templateutil.evalstring
43 evalstring = templateutil.evalstring
43 evalstringliteral = templateutil.evalstringliteral
44 evalstringliteral = templateutil.evalstringliteral
44
45
45 # dict of template built-in functions
46 # dict of template built-in functions
46 funcs = {}
47 funcs = {}
47 templatefunc = registrar.templatefunc(funcs)
48 templatefunc = registrar.templatefunc(funcs)
48
49
49 @templatefunc('date(date[, fmt])')
50 @templatefunc('date(date[, fmt])')
50 def date(context, mapping, args):
51 def date(context, mapping, args):
51 """Format a date. See :hg:`help dates` for formatting
52 """Format a date. See :hg:`help dates` for formatting
52 strings. The default is a Unix date format, including the timezone:
53 strings. The default is a Unix date format, including the timezone:
53 "Mon Sep 04 15:13:13 2006 0700"."""
54 "Mon Sep 04 15:13:13 2006 0700"."""
54 if not (1 <= len(args) <= 2):
55 if not (1 <= len(args) <= 2):
55 # i18n: "date" is a keyword
56 # i18n: "date" is a keyword
56 raise error.ParseError(_("date expects one or two arguments"))
57 raise error.ParseError(_("date expects one or two arguments"))
57
58
58 date = evaldate(context, mapping, args[0],
59 date = evaldate(context, mapping, args[0],
59 # i18n: "date" is a keyword
60 # i18n: "date" is a keyword
60 _("date expects a date information"))
61 _("date expects a date information"))
61 fmt = None
62 fmt = None
62 if len(args) == 2:
63 if len(args) == 2:
63 fmt = evalstring(context, mapping, args[1])
64 fmt = evalstring(context, mapping, args[1])
64 if fmt is None:
65 if fmt is None:
65 return dateutil.datestr(date)
66 return dateutil.datestr(date)
66 else:
67 else:
67 return dateutil.datestr(date, fmt)
68 return dateutil.datestr(date, fmt)
68
69
69 @templatefunc('dict([[key=]value...])', argspec='*args **kwargs')
70 @templatefunc('dict([[key=]value...])', argspec='*args **kwargs')
70 def dict_(context, mapping, args):
71 def dict_(context, mapping, args):
71 """Construct a dict from key-value pairs. A key may be omitted if
72 """Construct a dict from key-value pairs. A key may be omitted if
72 a value expression can provide an unambiguous name."""
73 a value expression can provide an unambiguous name."""
73 data = util.sortdict()
74 data = util.sortdict()
74
75
75 for v in args['args']:
76 for v in args['args']:
76 k = templateutil.findsymbolicname(v)
77 k = templateutil.findsymbolicname(v)
77 if not k:
78 if not k:
78 raise error.ParseError(_('dict key cannot be inferred'))
79 raise error.ParseError(_('dict key cannot be inferred'))
79 if k in data or k in args['kwargs']:
80 if k in data or k in args['kwargs']:
80 raise error.ParseError(_("duplicated dict key '%s' inferred") % k)
81 raise error.ParseError(_("duplicated dict key '%s' inferred") % k)
81 data[k] = evalfuncarg(context, mapping, v)
82 data[k] = evalfuncarg(context, mapping, v)
82
83
83 data.update((k, evalfuncarg(context, mapping, v))
84 data.update((k, evalfuncarg(context, mapping, v))
84 for k, v in args['kwargs'].iteritems())
85 for k, v in args['kwargs'].iteritems())
85 return templateutil.hybriddict(data)
86 return templateutil.hybriddict(data)
86
87
87 @templatefunc('diff([includepattern [, excludepattern]])')
88 @templatefunc('diff([includepattern [, excludepattern]])')
88 def diff(context, mapping, args):
89 def diff(context, mapping, args):
89 """Show a diff, optionally
90 """Show a diff, optionally
90 specifying files to include or exclude."""
91 specifying files to include or exclude."""
91 if len(args) > 2:
92 if len(args) > 2:
92 # i18n: "diff" is a keyword
93 # i18n: "diff" is a keyword
93 raise error.ParseError(_("diff expects zero, one, or two arguments"))
94 raise error.ParseError(_("diff expects zero, one, or two arguments"))
94
95
95 def getpatterns(i):
96 def getpatterns(i):
96 if i < len(args):
97 if i < len(args):
97 s = evalstring(context, mapping, args[i]).strip()
98 s = evalstring(context, mapping, args[i]).strip()
98 if s:
99 if s:
99 return [s]
100 return [s]
100 return []
101 return []
101
102
102 ctx = context.resource(mapping, 'ctx')
103 ctx = context.resource(mapping, 'ctx')
103 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
104 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
104
105
105 return ''.join(chunks)
106 return ''.join(chunks)
106
107
107 @templatefunc('extdata(source)', argspec='source')
108 @templatefunc('extdata(source)', argspec='source')
108 def extdata(context, mapping, args):
109 def extdata(context, mapping, args):
109 """Show a text read from the specified extdata source. (EXPERIMENTAL)"""
110 """Show a text read from the specified extdata source. (EXPERIMENTAL)"""
110 if 'source' not in args:
111 if 'source' not in args:
111 # i18n: "extdata" is a keyword
112 # i18n: "extdata" is a keyword
112 raise error.ParseError(_('extdata expects one argument'))
113 raise error.ParseError(_('extdata expects one argument'))
113
114
114 source = evalstring(context, mapping, args['source'])
115 source = evalstring(context, mapping, args['source'])
115 cache = context.resource(mapping, 'cache').setdefault('extdata', {})
116 cache = context.resource(mapping, 'cache').setdefault('extdata', {})
116 ctx = context.resource(mapping, 'ctx')
117 ctx = context.resource(mapping, 'ctx')
117 if source in cache:
118 if source in cache:
118 data = cache[source]
119 data = cache[source]
119 else:
120 else:
120 data = cache[source] = scmutil.extdatasource(ctx.repo(), source)
121 data = cache[source] = scmutil.extdatasource(ctx.repo(), source)
121 return data.get(ctx.rev(), '')
122 return data.get(ctx.rev(), '')
122
123
123 @templatefunc('files(pattern)')
124 @templatefunc('files(pattern)')
124 def files(context, mapping, args):
125 def files(context, mapping, args):
125 """All files of the current changeset matching the pattern. See
126 """All files of the current changeset matching the pattern. See
126 :hg:`help patterns`."""
127 :hg:`help patterns`."""
127 if not len(args) == 1:
128 if not len(args) == 1:
128 # i18n: "files" is a keyword
129 # i18n: "files" is a keyword
129 raise error.ParseError(_("files expects one argument"))
130 raise error.ParseError(_("files expects one argument"))
130
131
131 raw = evalstring(context, mapping, args[0])
132 raw = evalstring(context, mapping, args[0])
132 ctx = context.resource(mapping, 'ctx')
133 ctx = context.resource(mapping, 'ctx')
133 m = ctx.match([raw])
134 m = ctx.match([raw])
134 files = list(ctx.matches(m))
135 files = list(ctx.matches(m))
135 return templateutil.compatlist(context, mapping, "file", files)
136 return templateutil.compatlist(context, mapping, "file", files)
136
137
137 @templatefunc('fill(text[, width[, initialident[, hangindent]]])')
138 @templatefunc('fill(text[, width[, initialident[, hangindent]]])')
138 def fill(context, mapping, args):
139 def fill(context, mapping, args):
139 """Fill many
140 """Fill many
140 paragraphs with optional indentation. See the "fill" filter."""
141 paragraphs with optional indentation. See the "fill" filter."""
141 if not (1 <= len(args) <= 4):
142 if not (1 <= len(args) <= 4):
142 # i18n: "fill" is a keyword
143 # i18n: "fill" is a keyword
143 raise error.ParseError(_("fill expects one to four arguments"))
144 raise error.ParseError(_("fill expects one to four arguments"))
144
145
145 text = evalstring(context, mapping, args[0])
146 text = evalstring(context, mapping, args[0])
146 width = 76
147 width = 76
147 initindent = ''
148 initindent = ''
148 hangindent = ''
149 hangindent = ''
149 if 2 <= len(args) <= 4:
150 if 2 <= len(args) <= 4:
150 width = evalinteger(context, mapping, args[1],
151 width = evalinteger(context, mapping, args[1],
151 # i18n: "fill" is a keyword
152 # i18n: "fill" is a keyword
152 _("fill expects an integer width"))
153 _("fill expects an integer width"))
153 try:
154 try:
154 initindent = evalstring(context, mapping, args[2])
155 initindent = evalstring(context, mapping, args[2])
155 hangindent = evalstring(context, mapping, args[3])
156 hangindent = evalstring(context, mapping, args[3])
156 except IndexError:
157 except IndexError:
157 pass
158 pass
158
159
159 return templatefilters.fill(text, width, initindent, hangindent)
160 return templatefilters.fill(text, width, initindent, hangindent)
160
161
161 @templatefunc('formatnode(node)')
162 @templatefunc('formatnode(node)')
162 def formatnode(context, mapping, args):
163 def formatnode(context, mapping, args):
163 """Obtain the preferred form of a changeset hash. (DEPRECATED)"""
164 """Obtain the preferred form of a changeset hash. (DEPRECATED)"""
164 if len(args) != 1:
165 if len(args) != 1:
165 # i18n: "formatnode" is a keyword
166 # i18n: "formatnode" is a keyword
166 raise error.ParseError(_("formatnode expects one argument"))
167 raise error.ParseError(_("formatnode expects one argument"))
167
168
168 ui = context.resource(mapping, 'ui')
169 ui = context.resource(mapping, 'ui')
169 node = evalstring(context, mapping, args[0])
170 node = evalstring(context, mapping, args[0])
170 if ui.debugflag:
171 if ui.debugflag:
171 return node
172 return node
172 return templatefilters.short(node)
173 return templatefilters.short(node)
173
174
174 @templatefunc('mailmap(author)')
175 @templatefunc('mailmap(author)')
175 def mailmap(context, mapping, args):
176 def mailmap(context, mapping, args):
176 """Return the author, updated according to the value
177 """Return the author, updated according to the value
177 set in the .mailmap file"""
178 set in the .mailmap file"""
178 if len(args) != 1:
179 if len(args) != 1:
179 raise error.ParseError(_("mailmap expects one argument"))
180 raise error.ParseError(_("mailmap expects one argument"))
180
181
181 author = evalstring(context, mapping, args[0])
182 author = evalstring(context, mapping, args[0])
182
183
183 cache = context.resource(mapping, 'cache')
184 cache = context.resource(mapping, 'cache')
184 repo = context.resource(mapping, 'repo')
185 repo = context.resource(mapping, 'repo')
185
186
186 if 'mailmap' not in cache:
187 if 'mailmap' not in cache:
187 data = repo.wvfs.tryread('.mailmap')
188 data = repo.wvfs.tryread('.mailmap')
188 cache['mailmap'] = stringutil.parsemailmap(data)
189 cache['mailmap'] = stringutil.parsemailmap(data)
189
190
190 return stringutil.mapname(cache['mailmap'], author)
191 return stringutil.mapname(cache['mailmap'], author)
191
192
192 @templatefunc('pad(text, width[, fillchar=\' \'[, left=False]])',
193 @templatefunc('pad(text, width[, fillchar=\' \'[, left=False]])',
193 argspec='text width fillchar left')
194 argspec='text width fillchar left')
194 def pad(context, mapping, args):
195 def pad(context, mapping, args):
195 """Pad text with a
196 """Pad text with a
196 fill character."""
197 fill character."""
197 if 'text' not in args or 'width' not in args:
198 if 'text' not in args or 'width' not in args:
198 # i18n: "pad" is a keyword
199 # i18n: "pad" is a keyword
199 raise error.ParseError(_("pad() expects two to four arguments"))
200 raise error.ParseError(_("pad() expects two to four arguments"))
200
201
201 width = evalinteger(context, mapping, args['width'],
202 width = evalinteger(context, mapping, args['width'],
202 # i18n: "pad" is a keyword
203 # i18n: "pad" is a keyword
203 _("pad() expects an integer width"))
204 _("pad() expects an integer width"))
204
205
205 text = evalstring(context, mapping, args['text'])
206 text = evalstring(context, mapping, args['text'])
206
207
207 left = False
208 left = False
208 fillchar = ' '
209 fillchar = ' '
209 if 'fillchar' in args:
210 if 'fillchar' in args:
210 fillchar = evalstring(context, mapping, args['fillchar'])
211 fillchar = evalstring(context, mapping, args['fillchar'])
211 if len(color.stripeffects(fillchar)) != 1:
212 if len(color.stripeffects(fillchar)) != 1:
212 # i18n: "pad" is a keyword
213 # i18n: "pad" is a keyword
213 raise error.ParseError(_("pad() expects a single fill character"))
214 raise error.ParseError(_("pad() expects a single fill character"))
214 if 'left' in args:
215 if 'left' in args:
215 left = evalboolean(context, mapping, args['left'])
216 left = evalboolean(context, mapping, args['left'])
216
217
217 fillwidth = width - encoding.colwidth(color.stripeffects(text))
218 fillwidth = width - encoding.colwidth(color.stripeffects(text))
218 if fillwidth <= 0:
219 if fillwidth <= 0:
219 return text
220 return text
220 if left:
221 if left:
221 return fillchar * fillwidth + text
222 return fillchar * fillwidth + text
222 else:
223 else:
223 return text + fillchar * fillwidth
224 return text + fillchar * fillwidth
224
225
225 @templatefunc('indent(text, indentchars[, firstline])')
226 @templatefunc('indent(text, indentchars[, firstline])')
226 def indent(context, mapping, args):
227 def indent(context, mapping, args):
227 """Indents all non-empty lines
228 """Indents all non-empty lines
228 with the characters given in the indentchars string. An optional
229 with the characters given in the indentchars string. An optional
229 third parameter will override the indent for the first line only
230 third parameter will override the indent for the first line only
230 if present."""
231 if present."""
231 if not (2 <= len(args) <= 3):
232 if not (2 <= len(args) <= 3):
232 # i18n: "indent" is a keyword
233 # i18n: "indent" is a keyword
233 raise error.ParseError(_("indent() expects two or three arguments"))
234 raise error.ParseError(_("indent() expects two or three arguments"))
234
235
235 text = evalstring(context, mapping, args[0])
236 text = evalstring(context, mapping, args[0])
236 indent = evalstring(context, mapping, args[1])
237 indent = evalstring(context, mapping, args[1])
237
238
238 if len(args) == 3:
239 if len(args) == 3:
239 firstline = evalstring(context, mapping, args[2])
240 firstline = evalstring(context, mapping, args[2])
240 else:
241 else:
241 firstline = indent
242 firstline = indent
242
243
243 # the indent function doesn't indent the first line, so we do it here
244 # the indent function doesn't indent the first line, so we do it here
244 return templatefilters.indent(firstline + text, indent)
245 return templatefilters.indent(firstline + text, indent)
245
246
246 @templatefunc('get(dict, key)')
247 @templatefunc('get(dict, key)')
247 def get(context, mapping, args):
248 def get(context, mapping, args):
248 """Get an attribute/key from an object. Some keywords
249 """Get an attribute/key from an object. Some keywords
249 are complex types. This function allows you to obtain the value of an
250 are complex types. This function allows you to obtain the value of an
250 attribute on these types."""
251 attribute on these types."""
251 if len(args) != 2:
252 if len(args) != 2:
252 # i18n: "get" is a keyword
253 # i18n: "get" is a keyword
253 raise error.ParseError(_("get() expects two arguments"))
254 raise error.ParseError(_("get() expects two arguments"))
254
255
255 dictarg = evalfuncarg(context, mapping, args[0])
256 dictarg = evalfuncarg(context, mapping, args[0])
256 if not util.safehasattr(dictarg, 'get'):
257 if not util.safehasattr(dictarg, 'get'):
257 # i18n: "get" is a keyword
258 # i18n: "get" is a keyword
258 raise error.ParseError(_("get() expects a dict as first argument"))
259 raise error.ParseError(_("get() expects a dict as first argument"))
259
260
260 key = evalfuncarg(context, mapping, args[1])
261 key = evalfuncarg(context, mapping, args[1])
261 return templateutil.getdictitem(dictarg, key)
262 return templateutil.getdictitem(dictarg, key)
262
263
263 @templatefunc('if(expr, then[, else])')
264 @templatefunc('if(expr, then[, else])')
264 def if_(context, mapping, args):
265 def if_(context, mapping, args):
265 """Conditionally execute based on the result of
266 """Conditionally execute based on the result of
266 an expression."""
267 an expression."""
267 if not (2 <= len(args) <= 3):
268 if not (2 <= len(args) <= 3):
268 # i18n: "if" is a keyword
269 # i18n: "if" is a keyword
269 raise error.ParseError(_("if expects two or three arguments"))
270 raise error.ParseError(_("if expects two or three arguments"))
270
271
271 test = evalboolean(context, mapping, args[0])
272 test = evalboolean(context, mapping, args[0])
272 if test:
273 if test:
273 return evalrawexp(context, mapping, args[1])
274 return evalrawexp(context, mapping, args[1])
274 elif len(args) == 3:
275 elif len(args) == 3:
275 return evalrawexp(context, mapping, args[2])
276 return evalrawexp(context, mapping, args[2])
276
277
277 @templatefunc('ifcontains(needle, haystack, then[, else])')
278 @templatefunc('ifcontains(needle, haystack, then[, else])')
278 def ifcontains(context, mapping, args):
279 def ifcontains(context, mapping, args):
279 """Conditionally execute based
280 """Conditionally execute based
280 on whether the item "needle" is in "haystack"."""
281 on whether the item "needle" is in "haystack"."""
281 if not (3 <= len(args) <= 4):
282 if not (3 <= len(args) <= 4):
282 # i18n: "ifcontains" is a keyword
283 # i18n: "ifcontains" is a keyword
283 raise error.ParseError(_("ifcontains expects three or four arguments"))
284 raise error.ParseError(_("ifcontains expects three or four arguments"))
284
285
285 haystack = evalfuncarg(context, mapping, args[1])
286 haystack = evalfuncarg(context, mapping, args[1])
286 keytype = getattr(haystack, 'keytype', None)
287 keytype = getattr(haystack, 'keytype', None)
287 try:
288 try:
288 needle = evalrawexp(context, mapping, args[0])
289 needle = evalrawexp(context, mapping, args[0])
289 needle = templateutil.unwrapastype(context, mapping, needle,
290 needle = templateutil.unwrapastype(context, mapping, needle,
290 keytype or bytes)
291 keytype or bytes)
291 found = (needle in haystack)
292 found = (needle in haystack)
292 except error.ParseError:
293 except error.ParseError:
293 found = False
294 found = False
294
295
295 if found:
296 if found:
296 return evalrawexp(context, mapping, args[2])
297 return evalrawexp(context, mapping, args[2])
297 elif len(args) == 4:
298 elif len(args) == 4:
298 return evalrawexp(context, mapping, args[3])
299 return evalrawexp(context, mapping, args[3])
299
300
300 @templatefunc('ifeq(expr1, expr2, then[, else])')
301 @templatefunc('ifeq(expr1, expr2, then[, else])')
301 def ifeq(context, mapping, args):
302 def ifeq(context, mapping, args):
302 """Conditionally execute based on
303 """Conditionally execute based on
303 whether 2 items are equivalent."""
304 whether 2 items are equivalent."""
304 if not (3 <= len(args) <= 4):
305 if not (3 <= len(args) <= 4):
305 # i18n: "ifeq" is a keyword
306 # i18n: "ifeq" is a keyword
306 raise error.ParseError(_("ifeq expects three or four arguments"))
307 raise error.ParseError(_("ifeq expects three or four arguments"))
307
308
308 test = evalstring(context, mapping, args[0])
309 test = evalstring(context, mapping, args[0])
309 match = evalstring(context, mapping, args[1])
310 match = evalstring(context, mapping, args[1])
310 if test == match:
311 if test == match:
311 return evalrawexp(context, mapping, args[2])
312 return evalrawexp(context, mapping, args[2])
312 elif len(args) == 4:
313 elif len(args) == 4:
313 return evalrawexp(context, mapping, args[3])
314 return evalrawexp(context, mapping, args[3])
314
315
315 @templatefunc('join(list, sep)')
316 @templatefunc('join(list, sep)')
316 def join(context, mapping, args):
317 def join(context, mapping, args):
317 """Join items in a list with a delimiter."""
318 """Join items in a list with a delimiter."""
318 if not (1 <= len(args) <= 2):
319 if not (1 <= len(args) <= 2):
319 # i18n: "join" is a keyword
320 # i18n: "join" is a keyword
320 raise error.ParseError(_("join expects one or two arguments"))
321 raise error.ParseError(_("join expects one or two arguments"))
321
322
322 joinset = evalrawexp(context, mapping, args[0])
323 joinset = evalrawexp(context, mapping, args[0])
323 joiner = " "
324 joiner = " "
324 if len(args) > 1:
325 if len(args) > 1:
325 joiner = evalstring(context, mapping, args[1])
326 joiner = evalstring(context, mapping, args[1])
326 if isinstance(joinset, templateutil.wrapped):
327 if isinstance(joinset, templateutil.wrapped):
327 return joinset.join(context, mapping, joiner)
328 return joinset.join(context, mapping, joiner)
328 # TODO: perhaps a generator should be stringify()-ed here, but we can't
329 # TODO: perhaps a generator should be stringify()-ed here, but we can't
329 # because hgweb abuses it as a keyword that returns a list of dicts.
330 # because hgweb abuses it as a keyword that returns a list of dicts.
330 joinset = templateutil.unwrapvalue(context, mapping, joinset)
331 joinset = templateutil.unwrapvalue(context, mapping, joinset)
331 return templateutil.joinitems(pycompat.maybebytestr(joinset), joiner)
332 return templateutil.joinitems(pycompat.maybebytestr(joinset), joiner)
332
333
333 @templatefunc('label(label, expr)')
334 @templatefunc('label(label, expr)')
334 def label(context, mapping, args):
335 def label(context, mapping, args):
335 """Apply a label to generated content. Content with
336 """Apply a label to generated content. Content with
336 a label applied can result in additional post-processing, such as
337 a label applied can result in additional post-processing, such as
337 automatic colorization."""
338 automatic colorization."""
338 if len(args) != 2:
339 if len(args) != 2:
339 # i18n: "label" is a keyword
340 # i18n: "label" is a keyword
340 raise error.ParseError(_("label expects two arguments"))
341 raise error.ParseError(_("label expects two arguments"))
341
342
342 ui = context.resource(mapping, 'ui')
343 ui = context.resource(mapping, 'ui')
343 thing = evalstring(context, mapping, args[1])
344 thing = evalstring(context, mapping, args[1])
344 # preserve unknown symbol as literal so effects like 'red', 'bold',
345 # preserve unknown symbol as literal so effects like 'red', 'bold',
345 # etc. don't need to be quoted
346 # etc. don't need to be quoted
346 label = evalstringliteral(context, mapping, args[0])
347 label = evalstringliteral(context, mapping, args[0])
347
348
348 return ui.label(thing, label)
349 return ui.label(thing, label)
349
350
350 @templatefunc('latesttag([pattern])')
351 @templatefunc('latesttag([pattern])')
351 def latesttag(context, mapping, args):
352 def latesttag(context, mapping, args):
352 """The global tags matching the given pattern on the
353 """The global tags matching the given pattern on the
353 most recent globally tagged ancestor of this changeset.
354 most recent globally tagged ancestor of this changeset.
354 If no such tags exist, the "{tag}" template resolves to
355 If no such tags exist, the "{tag}" template resolves to
355 the string "null"."""
356 the string "null"."""
356 if len(args) > 1:
357 if len(args) > 1:
357 # i18n: "latesttag" is a keyword
358 # i18n: "latesttag" is a keyword
358 raise error.ParseError(_("latesttag expects at most one argument"))
359 raise error.ParseError(_("latesttag expects at most one argument"))
359
360
360 pattern = None
361 pattern = None
361 if len(args) == 1:
362 if len(args) == 1:
362 pattern = evalstring(context, mapping, args[0])
363 pattern = evalstring(context, mapping, args[0])
363 return templatekw.showlatesttags(context, mapping, pattern)
364 return templatekw.showlatesttags(context, mapping, pattern)
364
365
365 @templatefunc('localdate(date[, tz])')
366 @templatefunc('localdate(date[, tz])')
366 def localdate(context, mapping, args):
367 def localdate(context, mapping, args):
367 """Converts a date to the specified timezone.
368 """Converts a date to the specified timezone.
368 The default is local date."""
369 The default is local date."""
369 if not (1 <= len(args) <= 2):
370 if not (1 <= len(args) <= 2):
370 # i18n: "localdate" is a keyword
371 # i18n: "localdate" is a keyword
371 raise error.ParseError(_("localdate expects one or two arguments"))
372 raise error.ParseError(_("localdate expects one or two arguments"))
372
373
373 date = evaldate(context, mapping, args[0],
374 date = evaldate(context, mapping, args[0],
374 # i18n: "localdate" is a keyword
375 # i18n: "localdate" is a keyword
375 _("localdate expects a date information"))
376 _("localdate expects a date information"))
376 if len(args) >= 2:
377 if len(args) >= 2:
377 tzoffset = None
378 tzoffset = None
378 tz = evalfuncarg(context, mapping, args[1])
379 tz = evalfuncarg(context, mapping, args[1])
379 if isinstance(tz, bytes):
380 if isinstance(tz, bytes):
380 tzoffset, remainder = dateutil.parsetimezone(tz)
381 tzoffset, remainder = dateutil.parsetimezone(tz)
381 if remainder:
382 if remainder:
382 tzoffset = None
383 tzoffset = None
383 if tzoffset is None:
384 if tzoffset is None:
384 try:
385 try:
385 tzoffset = int(tz)
386 tzoffset = int(tz)
386 except (TypeError, ValueError):
387 except (TypeError, ValueError):
387 # i18n: "localdate" is a keyword
388 # i18n: "localdate" is a keyword
388 raise error.ParseError(_("localdate expects a timezone"))
389 raise error.ParseError(_("localdate expects a timezone"))
389 else:
390 else:
390 tzoffset = dateutil.makedate()[1]
391 tzoffset = dateutil.makedate()[1]
391 return (date[0], tzoffset)
392 return (date[0], tzoffset)
392
393
393 @templatefunc('max(iterable)')
394 @templatefunc('max(iterable)')
394 def max_(context, mapping, args, **kwargs):
395 def max_(context, mapping, args, **kwargs):
395 """Return the max of an iterable"""
396 """Return the max of an iterable"""
396 if len(args) != 1:
397 if len(args) != 1:
397 # i18n: "max" is a keyword
398 # i18n: "max" is a keyword
398 raise error.ParseError(_("max expects one argument"))
399 raise error.ParseError(_("max expects one argument"))
399
400
400 iterable = evalfuncarg(context, mapping, args[0])
401 iterable = evalfuncarg(context, mapping, args[0])
401 try:
402 try:
402 x = max(pycompat.maybebytestr(iterable))
403 x = max(pycompat.maybebytestr(iterable))
403 except (TypeError, ValueError):
404 except (TypeError, ValueError):
404 # i18n: "max" is a keyword
405 # i18n: "max" is a keyword
405 raise error.ParseError(_("max first argument should be an iterable"))
406 raise error.ParseError(_("max first argument should be an iterable"))
406 return templateutil.wraphybridvalue(iterable, x, x)
407 return templateutil.wraphybridvalue(iterable, x, x)
407
408
408 @templatefunc('min(iterable)')
409 @templatefunc('min(iterable)')
409 def min_(context, mapping, args, **kwargs):
410 def min_(context, mapping, args, **kwargs):
410 """Return the min of an iterable"""
411 """Return the min of an iterable"""
411 if len(args) != 1:
412 if len(args) != 1:
412 # i18n: "min" is a keyword
413 # i18n: "min" is a keyword
413 raise error.ParseError(_("min expects one argument"))
414 raise error.ParseError(_("min expects one argument"))
414
415
415 iterable = evalfuncarg(context, mapping, args[0])
416 iterable = evalfuncarg(context, mapping, args[0])
416 try:
417 try:
417 x = min(pycompat.maybebytestr(iterable))
418 x = min(pycompat.maybebytestr(iterable))
418 except (TypeError, ValueError):
419 except (TypeError, ValueError):
419 # i18n: "min" is a keyword
420 # i18n: "min" is a keyword
420 raise error.ParseError(_("min first argument should be an iterable"))
421 raise error.ParseError(_("min first argument should be an iterable"))
421 return templateutil.wraphybridvalue(iterable, x, x)
422 return templateutil.wraphybridvalue(iterable, x, x)
422
423
423 @templatefunc('mod(a, b)')
424 @templatefunc('mod(a, b)')
424 def mod(context, mapping, args):
425 def mod(context, mapping, args):
425 """Calculate a mod b such that a / b + a mod b == a"""
426 """Calculate a mod b such that a / b + a mod b == a"""
426 if not len(args) == 2:
427 if not len(args) == 2:
427 # i18n: "mod" is a keyword
428 # i18n: "mod" is a keyword
428 raise error.ParseError(_("mod expects two arguments"))
429 raise error.ParseError(_("mod expects two arguments"))
429
430
430 func = lambda a, b: a % b
431 func = lambda a, b: a % b
431 return templateutil.runarithmetic(context, mapping,
432 return templateutil.runarithmetic(context, mapping,
432 (func, args[0], args[1]))
433 (func, args[0], args[1]))
433
434
434 @templatefunc('obsfateoperations(markers)')
435 @templatefunc('obsfateoperations(markers)')
435 def obsfateoperations(context, mapping, args):
436 def obsfateoperations(context, mapping, args):
436 """Compute obsfate related information based on markers (EXPERIMENTAL)"""
437 """Compute obsfate related information based on markers (EXPERIMENTAL)"""
437 if len(args) != 1:
438 if len(args) != 1:
438 # i18n: "obsfateoperations" is a keyword
439 # i18n: "obsfateoperations" is a keyword
439 raise error.ParseError(_("obsfateoperations expects one argument"))
440 raise error.ParseError(_("obsfateoperations expects one argument"))
440
441
441 markers = evalfuncarg(context, mapping, args[0])
442 markers = evalfuncarg(context, mapping, args[0])
442
443
443 try:
444 try:
444 data = obsutil.markersoperations(markers)
445 data = obsutil.markersoperations(markers)
445 return templateutil.hybridlist(data, name='operation')
446 return templateutil.hybridlist(data, name='operation')
446 except (TypeError, KeyError):
447 except (TypeError, KeyError):
447 # i18n: "obsfateoperations" is a keyword
448 # i18n: "obsfateoperations" is a keyword
448 errmsg = _("obsfateoperations first argument should be an iterable")
449 errmsg = _("obsfateoperations first argument should be an iterable")
449 raise error.ParseError(errmsg)
450 raise error.ParseError(errmsg)
450
451
451 @templatefunc('obsfatedate(markers)')
452 @templatefunc('obsfatedate(markers)')
452 def obsfatedate(context, mapping, args):
453 def obsfatedate(context, mapping, args):
453 """Compute obsfate related information based on markers (EXPERIMENTAL)"""
454 """Compute obsfate related information based on markers (EXPERIMENTAL)"""
454 if len(args) != 1:
455 if len(args) != 1:
455 # i18n: "obsfatedate" is a keyword
456 # i18n: "obsfatedate" is a keyword
456 raise error.ParseError(_("obsfatedate expects one argument"))
457 raise error.ParseError(_("obsfatedate expects one argument"))
457
458
458 markers = evalfuncarg(context, mapping, args[0])
459 markers = evalfuncarg(context, mapping, args[0])
459
460
460 try:
461 try:
461 data = obsutil.markersdates(markers)
462 data = obsutil.markersdates(markers)
462 return templateutil.hybridlist(data, name='date', fmt='%d %d')
463 return templateutil.hybridlist(data, name='date', fmt='%d %d')
463 except (TypeError, KeyError):
464 except (TypeError, KeyError):
464 # i18n: "obsfatedate" is a keyword
465 # i18n: "obsfatedate" is a keyword
465 errmsg = _("obsfatedate first argument should be an iterable")
466 errmsg = _("obsfatedate first argument should be an iterable")
466 raise error.ParseError(errmsg)
467 raise error.ParseError(errmsg)
467
468
468 @templatefunc('obsfateusers(markers)')
469 @templatefunc('obsfateusers(markers)')
469 def obsfateusers(context, mapping, args):
470 def obsfateusers(context, mapping, args):
470 """Compute obsfate related information based on markers (EXPERIMENTAL)"""
471 """Compute obsfate related information based on markers (EXPERIMENTAL)"""
471 if len(args) != 1:
472 if len(args) != 1:
472 # i18n: "obsfateusers" is a keyword
473 # i18n: "obsfateusers" is a keyword
473 raise error.ParseError(_("obsfateusers expects one argument"))
474 raise error.ParseError(_("obsfateusers expects one argument"))
474
475
475 markers = evalfuncarg(context, mapping, args[0])
476 markers = evalfuncarg(context, mapping, args[0])
476
477
477 try:
478 try:
478 data = obsutil.markersusers(markers)
479 data = obsutil.markersusers(markers)
479 return templateutil.hybridlist(data, name='user')
480 return templateutil.hybridlist(data, name='user')
480 except (TypeError, KeyError, ValueError):
481 except (TypeError, KeyError, ValueError):
481 # i18n: "obsfateusers" is a keyword
482 # i18n: "obsfateusers" is a keyword
482 msg = _("obsfateusers first argument should be an iterable of "
483 msg = _("obsfateusers first argument should be an iterable of "
483 "obsmakers")
484 "obsmakers")
484 raise error.ParseError(msg)
485 raise error.ParseError(msg)
485
486
486 @templatefunc('obsfateverb(successors, markers)')
487 @templatefunc('obsfateverb(successors, markers)')
487 def obsfateverb(context, mapping, args):
488 def obsfateverb(context, mapping, args):
488 """Compute obsfate related information based on successors (EXPERIMENTAL)"""
489 """Compute obsfate related information based on successors (EXPERIMENTAL)"""
489 if len(args) != 2:
490 if len(args) != 2:
490 # i18n: "obsfateverb" is a keyword
491 # i18n: "obsfateverb" is a keyword
491 raise error.ParseError(_("obsfateverb expects two arguments"))
492 raise error.ParseError(_("obsfateverb expects two arguments"))
492
493
493 successors = evalfuncarg(context, mapping, args[0])
494 successors = evalfuncarg(context, mapping, args[0])
494 markers = evalfuncarg(context, mapping, args[1])
495 markers = evalfuncarg(context, mapping, args[1])
495
496
496 try:
497 try:
497 return obsutil.obsfateverb(successors, markers)
498 return obsutil.obsfateverb(successors, markers)
498 except TypeError:
499 except TypeError:
499 # i18n: "obsfateverb" is a keyword
500 # i18n: "obsfateverb" is a keyword
500 errmsg = _("obsfateverb first argument should be countable")
501 errmsg = _("obsfateverb first argument should be countable")
501 raise error.ParseError(errmsg)
502 raise error.ParseError(errmsg)
502
503
503 @templatefunc('relpath(path)')
504 @templatefunc('relpath(path)')
504 def relpath(context, mapping, args):
505 def relpath(context, mapping, args):
505 """Convert a repository-absolute path into a filesystem path relative to
506 """Convert a repository-absolute path into a filesystem path relative to
506 the current working directory."""
507 the current working directory."""
507 if len(args) != 1:
508 if len(args) != 1:
508 # i18n: "relpath" is a keyword
509 # i18n: "relpath" is a keyword
509 raise error.ParseError(_("relpath expects one argument"))
510 raise error.ParseError(_("relpath expects one argument"))
510
511
511 repo = context.resource(mapping, 'ctx').repo()
512 repo = context.resource(mapping, 'ctx').repo()
512 path = evalstring(context, mapping, args[0])
513 path = evalstring(context, mapping, args[0])
513 return repo.pathto(path)
514 return repo.pathto(path)
514
515
515 @templatefunc('revset(query[, formatargs...])')
516 @templatefunc('revset(query[, formatargs...])')
516 def revset(context, mapping, args):
517 def revset(context, mapping, args):
517 """Execute a revision set query. See
518 """Execute a revision set query. See
518 :hg:`help revset`."""
519 :hg:`help revset`."""
519 if not len(args) > 0:
520 if not len(args) > 0:
520 # i18n: "revset" is a keyword
521 # i18n: "revset" is a keyword
521 raise error.ParseError(_("revset expects one or more arguments"))
522 raise error.ParseError(_("revset expects one or more arguments"))
522
523
523 raw = evalstring(context, mapping, args[0])
524 raw = evalstring(context, mapping, args[0])
524 ctx = context.resource(mapping, 'ctx')
525 ctx = context.resource(mapping, 'ctx')
525 repo = ctx.repo()
526 repo = ctx.repo()
526
527
527 def query(expr):
528 def query(expr):
528 m = revsetmod.match(repo.ui, expr, lookup=revsetmod.lookupfn(repo))
529 m = revsetmod.match(repo.ui, expr, lookup=revsetmod.lookupfn(repo))
529 return m(repo)
530 return m(repo)
530
531
531 if len(args) > 1:
532 if len(args) > 1:
532 formatargs = [evalfuncarg(context, mapping, a) for a in args[1:]]
533 formatargs = [evalfuncarg(context, mapping, a) for a in args[1:]]
533 revs = query(revsetlang.formatspec(raw, *formatargs))
534 revs = query(revsetlang.formatspec(raw, *formatargs))
534 revs = list(revs)
535 revs = list(revs)
535 else:
536 else:
536 cache = context.resource(mapping, 'cache')
537 cache = context.resource(mapping, 'cache')
537 revsetcache = cache.setdefault("revsetcache", {})
538 revsetcache = cache.setdefault("revsetcache", {})
538 if raw in revsetcache:
539 if raw in revsetcache:
539 revs = revsetcache[raw]
540 revs = revsetcache[raw]
540 else:
541 else:
541 revs = query(raw)
542 revs = query(raw)
542 revs = list(revs)
543 revs = list(revs)
543 revsetcache[raw] = revs
544 revsetcache[raw] = revs
544 return templatekw.showrevslist(context, mapping, "revision", revs)
545 return templatekw.showrevslist(context, mapping, "revision", revs)
545
546
546 @templatefunc('rstdoc(text, style)')
547 @templatefunc('rstdoc(text, style)')
547 def rstdoc(context, mapping, args):
548 def rstdoc(context, mapping, args):
548 """Format reStructuredText."""
549 """Format reStructuredText."""
549 if len(args) != 2:
550 if len(args) != 2:
550 # i18n: "rstdoc" is a keyword
551 # i18n: "rstdoc" is a keyword
551 raise error.ParseError(_("rstdoc expects two arguments"))
552 raise error.ParseError(_("rstdoc expects two arguments"))
552
553
553 text = evalstring(context, mapping, args[0])
554 text = evalstring(context, mapping, args[0])
554 style = evalstring(context, mapping, args[1])
555 style = evalstring(context, mapping, args[1])
555
556
556 return minirst.format(text, style=style, keep=['verbose'])
557 return minirst.format(text, style=style, keep=['verbose'])
557
558
558 @templatefunc('separate(sep, args)', argspec='sep *args')
559 @templatefunc('separate(sep, args)', argspec='sep *args')
559 def separate(context, mapping, args):
560 def separate(context, mapping, args):
560 """Add a separator between non-empty arguments."""
561 """Add a separator between non-empty arguments."""
561 if 'sep' not in args:
562 if 'sep' not in args:
562 # i18n: "separate" is a keyword
563 # i18n: "separate" is a keyword
563 raise error.ParseError(_("separate expects at least one argument"))
564 raise error.ParseError(_("separate expects at least one argument"))
564
565
565 sep = evalstring(context, mapping, args['sep'])
566 sep = evalstring(context, mapping, args['sep'])
566 first = True
567 first = True
567 for arg in args['args']:
568 for arg in args['args']:
568 argstr = evalstring(context, mapping, arg)
569 argstr = evalstring(context, mapping, arg)
569 if not argstr:
570 if not argstr:
570 continue
571 continue
571 if first:
572 if first:
572 first = False
573 first = False
573 else:
574 else:
574 yield sep
575 yield sep
575 yield argstr
576 yield argstr
576
577
577 @templatefunc('shortest(node, minlength=4)')
578 @templatefunc('shortest(node, minlength=4)')
578 def shortest(context, mapping, args):
579 def shortest(context, mapping, args):
579 """Obtain the shortest representation of
580 """Obtain the shortest representation of
580 a node."""
581 a node."""
581 if not (1 <= len(args) <= 2):
582 if not (1 <= len(args) <= 2):
582 # i18n: "shortest" is a keyword
583 # i18n: "shortest" is a keyword
583 raise error.ParseError(_("shortest() expects one or two arguments"))
584 raise error.ParseError(_("shortest() expects one or two arguments"))
584
585
585 hexnode = evalstring(context, mapping, args[0])
586 hexnode = evalstring(context, mapping, args[0])
586
587
587 minlength = 4
588 minlength = 4
588 if len(args) > 1:
589 if len(args) > 1:
589 minlength = evalinteger(context, mapping, args[1],
590 minlength = evalinteger(context, mapping, args[1],
590 # i18n: "shortest" is a keyword
591 # i18n: "shortest" is a keyword
591 _("shortest() expects an integer minlength"))
592 _("shortest() expects an integer minlength"))
592
593
593 repo = context.resource(mapping, 'ctx')._repo
594 repo = context.resource(mapping, 'ctx')._repo
594 if len(hexnode) > 40:
595 if len(hexnode) > 40:
595 return hexnode
596 return hexnode
596 elif len(hexnode) == 40:
597 elif len(hexnode) == 40:
597 try:
598 try:
598 node = bin(hexnode)
599 node = bin(hexnode)
599 except TypeError:
600 except TypeError:
600 return hexnode
601 return hexnode
601 else:
602 else:
602 try:
603 try:
603 node = scmutil.resolvehexnodeidprefix(repo, hexnode)
604 node = scmutil.resolvehexnodeidprefix(repo, hexnode)
604 except (error.LookupError, error.WdirUnsupported):
605 except error.WdirUnsupported:
606 node = wdirid
607 except error.LookupError:
605 return hexnode
608 return hexnode
606 if not node:
609 if not node:
607 return hexnode
610 return hexnode
608 return scmutil.shortesthexnodeidprefix(repo, node, minlength)
611 return scmutil.shortesthexnodeidprefix(repo, node, minlength)
609
612
610 @templatefunc('strip(text[, chars])')
613 @templatefunc('strip(text[, chars])')
611 def strip(context, mapping, args):
614 def strip(context, mapping, args):
612 """Strip characters from a string. By default,
615 """Strip characters from a string. By default,
613 strips all leading and trailing whitespace."""
616 strips all leading and trailing whitespace."""
614 if not (1 <= len(args) <= 2):
617 if not (1 <= len(args) <= 2):
615 # i18n: "strip" is a keyword
618 # i18n: "strip" is a keyword
616 raise error.ParseError(_("strip expects one or two arguments"))
619 raise error.ParseError(_("strip expects one or two arguments"))
617
620
618 text = evalstring(context, mapping, args[0])
621 text = evalstring(context, mapping, args[0])
619 if len(args) == 2:
622 if len(args) == 2:
620 chars = evalstring(context, mapping, args[1])
623 chars = evalstring(context, mapping, args[1])
621 return text.strip(chars)
624 return text.strip(chars)
622 return text.strip()
625 return text.strip()
623
626
624 @templatefunc('sub(pattern, replacement, expression)')
627 @templatefunc('sub(pattern, replacement, expression)')
625 def sub(context, mapping, args):
628 def sub(context, mapping, args):
626 """Perform text substitution
629 """Perform text substitution
627 using regular expressions."""
630 using regular expressions."""
628 if len(args) != 3:
631 if len(args) != 3:
629 # i18n: "sub" is a keyword
632 # i18n: "sub" is a keyword
630 raise error.ParseError(_("sub expects three arguments"))
633 raise error.ParseError(_("sub expects three arguments"))
631
634
632 pat = evalstring(context, mapping, args[0])
635 pat = evalstring(context, mapping, args[0])
633 rpl = evalstring(context, mapping, args[1])
636 rpl = evalstring(context, mapping, args[1])
634 src = evalstring(context, mapping, args[2])
637 src = evalstring(context, mapping, args[2])
635 try:
638 try:
636 patre = re.compile(pat)
639 patre = re.compile(pat)
637 except re.error:
640 except re.error:
638 # i18n: "sub" is a keyword
641 # i18n: "sub" is a keyword
639 raise error.ParseError(_("sub got an invalid pattern: %s") % pat)
642 raise error.ParseError(_("sub got an invalid pattern: %s") % pat)
640 try:
643 try:
641 yield patre.sub(rpl, src)
644 yield patre.sub(rpl, src)
642 except re.error:
645 except re.error:
643 # i18n: "sub" is a keyword
646 # i18n: "sub" is a keyword
644 raise error.ParseError(_("sub got an invalid replacement: %s") % rpl)
647 raise error.ParseError(_("sub got an invalid replacement: %s") % rpl)
645
648
646 @templatefunc('startswith(pattern, text)')
649 @templatefunc('startswith(pattern, text)')
647 def startswith(context, mapping, args):
650 def startswith(context, mapping, args):
648 """Returns the value from the "text" argument
651 """Returns the value from the "text" argument
649 if it begins with the content from the "pattern" argument."""
652 if it begins with the content from the "pattern" argument."""
650 if len(args) != 2:
653 if len(args) != 2:
651 # i18n: "startswith" is a keyword
654 # i18n: "startswith" is a keyword
652 raise error.ParseError(_("startswith expects two arguments"))
655 raise error.ParseError(_("startswith expects two arguments"))
653
656
654 patn = evalstring(context, mapping, args[0])
657 patn = evalstring(context, mapping, args[0])
655 text = evalstring(context, mapping, args[1])
658 text = evalstring(context, mapping, args[1])
656 if text.startswith(patn):
659 if text.startswith(patn):
657 return text
660 return text
658 return ''
661 return ''
659
662
660 @templatefunc('word(number, text[, separator])')
663 @templatefunc('word(number, text[, separator])')
661 def word(context, mapping, args):
664 def word(context, mapping, args):
662 """Return the nth word from a string."""
665 """Return the nth word from a string."""
663 if not (2 <= len(args) <= 3):
666 if not (2 <= len(args) <= 3):
664 # i18n: "word" is a keyword
667 # i18n: "word" is a keyword
665 raise error.ParseError(_("word expects two or three arguments, got %d")
668 raise error.ParseError(_("word expects two or three arguments, got %d")
666 % len(args))
669 % len(args))
667
670
668 num = evalinteger(context, mapping, args[0],
671 num = evalinteger(context, mapping, args[0],
669 # i18n: "word" is a keyword
672 # i18n: "word" is a keyword
670 _("word expects an integer index"))
673 _("word expects an integer index"))
671 text = evalstring(context, mapping, args[1])
674 text = evalstring(context, mapping, args[1])
672 if len(args) == 3:
675 if len(args) == 3:
673 splitter = evalstring(context, mapping, args[2])
676 splitter = evalstring(context, mapping, args[2])
674 else:
677 else:
675 splitter = None
678 splitter = None
676
679
677 tokens = text.split(splitter)
680 tokens = text.split(splitter)
678 if num >= len(tokens) or num < -len(tokens):
681 if num >= len(tokens) or num < -len(tokens):
679 return ''
682 return ''
680 else:
683 else:
681 return tokens[num]
684 return tokens[num]
682
685
683 def loadfunction(ui, extname, registrarobj):
686 def loadfunction(ui, extname, registrarobj):
684 """Load template function from specified registrarobj
687 """Load template function from specified registrarobj
685 """
688 """
686 for name, func in registrarobj._table.iteritems():
689 for name, func in registrarobj._table.iteritems():
687 funcs[name] = func
690 funcs[name] = func
688
691
689 # tell hggettext to extract docstrings from these functions:
692 # tell hggettext to extract docstrings from these functions:
690 i18nfunctions = funcs.values()
693 i18nfunctions = funcs.values()
@@ -1,4884 +1,4893
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 Test arithmetic operators have the right precedence:
32 Test arithmetic operators have the right precedence:
33
33
34 $ hg log -l 1 -T '{date(date, "%Y") + 5 * 10} {date(date, "%Y") - 2 * 3}\n'
34 $ hg log -l 1 -T '{date(date, "%Y") + 5 * 10} {date(date, "%Y") - 2 * 3}\n'
35 2020 1964
35 2020 1964
36 $ hg log -l 1 -T '{date(date, "%Y") * 5 + 10} {date(date, "%Y") * 3 - 2}\n'
36 $ hg log -l 1 -T '{date(date, "%Y") * 5 + 10} {date(date, "%Y") * 3 - 2}\n'
37 9860 5908
37 9860 5908
38
38
39 Test division:
39 Test division:
40
40
41 $ hg debugtemplate -r0 -v '{5 / 2} {mod(5, 2)}\n'
41 $ hg debugtemplate -r0 -v '{5 / 2} {mod(5, 2)}\n'
42 (template
42 (template
43 (/
43 (/
44 (integer '5')
44 (integer '5')
45 (integer '2'))
45 (integer '2'))
46 (string ' ')
46 (string ' ')
47 (func
47 (func
48 (symbol 'mod')
48 (symbol 'mod')
49 (list
49 (list
50 (integer '5')
50 (integer '5')
51 (integer '2')))
51 (integer '2')))
52 (string '\n'))
52 (string '\n'))
53 2 1
53 2 1
54 $ hg debugtemplate -r0 -v '{5 / -2} {mod(5, -2)}\n'
54 $ hg debugtemplate -r0 -v '{5 / -2} {mod(5, -2)}\n'
55 (template
55 (template
56 (/
56 (/
57 (integer '5')
57 (integer '5')
58 (negate
58 (negate
59 (integer '2')))
59 (integer '2')))
60 (string ' ')
60 (string ' ')
61 (func
61 (func
62 (symbol 'mod')
62 (symbol 'mod')
63 (list
63 (list
64 (integer '5')
64 (integer '5')
65 (negate
65 (negate
66 (integer '2'))))
66 (integer '2'))))
67 (string '\n'))
67 (string '\n'))
68 -3 -1
68 -3 -1
69 $ hg debugtemplate -r0 -v '{-5 / 2} {mod(-5, 2)}\n'
69 $ hg debugtemplate -r0 -v '{-5 / 2} {mod(-5, 2)}\n'
70 (template
70 (template
71 (/
71 (/
72 (negate
72 (negate
73 (integer '5'))
73 (integer '5'))
74 (integer '2'))
74 (integer '2'))
75 (string ' ')
75 (string ' ')
76 (func
76 (func
77 (symbol 'mod')
77 (symbol 'mod')
78 (list
78 (list
79 (negate
79 (negate
80 (integer '5'))
80 (integer '5'))
81 (integer '2')))
81 (integer '2')))
82 (string '\n'))
82 (string '\n'))
83 -3 1
83 -3 1
84 $ hg debugtemplate -r0 -v '{-5 / -2} {mod(-5, -2)}\n'
84 $ hg debugtemplate -r0 -v '{-5 / -2} {mod(-5, -2)}\n'
85 (template
85 (template
86 (/
86 (/
87 (negate
87 (negate
88 (integer '5'))
88 (integer '5'))
89 (negate
89 (negate
90 (integer '2')))
90 (integer '2')))
91 (string ' ')
91 (string ' ')
92 (func
92 (func
93 (symbol 'mod')
93 (symbol 'mod')
94 (list
94 (list
95 (negate
95 (negate
96 (integer '5'))
96 (integer '5'))
97 (negate
97 (negate
98 (integer '2'))))
98 (integer '2'))))
99 (string '\n'))
99 (string '\n'))
100 2 -1
100 2 -1
101
101
102 Filters bind closer than arithmetic:
102 Filters bind closer than arithmetic:
103
103
104 $ hg debugtemplate -r0 -v '{revset(".")|count - 1}\n'
104 $ hg debugtemplate -r0 -v '{revset(".")|count - 1}\n'
105 (template
105 (template
106 (-
106 (-
107 (|
107 (|
108 (func
108 (func
109 (symbol 'revset')
109 (symbol 'revset')
110 (string '.'))
110 (string '.'))
111 (symbol 'count'))
111 (symbol 'count'))
112 (integer '1'))
112 (integer '1'))
113 (string '\n'))
113 (string '\n'))
114 0
114 0
115
115
116 But negate binds closer still:
116 But negate binds closer still:
117
117
118 $ hg debugtemplate -r0 -v '{1-3|stringify}\n'
118 $ hg debugtemplate -r0 -v '{1-3|stringify}\n'
119 (template
119 (template
120 (-
120 (-
121 (integer '1')
121 (integer '1')
122 (|
122 (|
123 (integer '3')
123 (integer '3')
124 (symbol 'stringify')))
124 (symbol 'stringify')))
125 (string '\n'))
125 (string '\n'))
126 hg: parse error: arithmetic only defined on integers
126 hg: parse error: arithmetic only defined on integers
127 [255]
127 [255]
128 $ hg debugtemplate -r0 -v '{-3|stringify}\n'
128 $ hg debugtemplate -r0 -v '{-3|stringify}\n'
129 (template
129 (template
130 (|
130 (|
131 (negate
131 (negate
132 (integer '3'))
132 (integer '3'))
133 (symbol 'stringify'))
133 (symbol 'stringify'))
134 (string '\n'))
134 (string '\n'))
135 -3
135 -3
136
136
137 Filters bind as close as map operator:
137 Filters bind as close as map operator:
138
138
139 $ hg debugtemplate -r0 -v '{desc|splitlines % "{line}\n"}'
139 $ hg debugtemplate -r0 -v '{desc|splitlines % "{line}\n"}'
140 (template
140 (template
141 (%
141 (%
142 (|
142 (|
143 (symbol 'desc')
143 (symbol 'desc')
144 (symbol 'splitlines'))
144 (symbol 'splitlines'))
145 (template
145 (template
146 (symbol 'line')
146 (symbol 'line')
147 (string '\n'))))
147 (string '\n'))))
148 line 1
148 line 1
149 line 2
149 line 2
150
150
151 Keyword arguments:
151 Keyword arguments:
152
152
153 $ hg debugtemplate -r0 -v '{foo=bar|baz}'
153 $ hg debugtemplate -r0 -v '{foo=bar|baz}'
154 (template
154 (template
155 (keyvalue
155 (keyvalue
156 (symbol 'foo')
156 (symbol 'foo')
157 (|
157 (|
158 (symbol 'bar')
158 (symbol 'bar')
159 (symbol 'baz'))))
159 (symbol 'baz'))))
160 hg: parse error: can't use a key-value pair in this context
160 hg: parse error: can't use a key-value pair in this context
161 [255]
161 [255]
162
162
163 $ hg debugtemplate '{pad("foo", width=10, left=true)}\n'
163 $ hg debugtemplate '{pad("foo", width=10, left=true)}\n'
164 foo
164 foo
165
165
166 Call function which takes named arguments by filter syntax:
166 Call function which takes named arguments by filter syntax:
167
167
168 $ hg debugtemplate '{" "|separate}'
168 $ hg debugtemplate '{" "|separate}'
169 $ hg debugtemplate '{("not", "an", "argument", "list")|separate}'
169 $ hg debugtemplate '{("not", "an", "argument", "list")|separate}'
170 hg: parse error: unknown method 'list'
170 hg: parse error: unknown method 'list'
171 [255]
171 [255]
172
172
173 Second branch starting at nullrev:
173 Second branch starting at nullrev:
174
174
175 $ hg update null
175 $ hg update null
176 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
176 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
177 $ echo second > second
177 $ echo second > second
178 $ hg add second
178 $ hg add second
179 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
179 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
180 created new head
180 created new head
181
181
182 $ echo third > third
182 $ echo third > third
183 $ hg add third
183 $ hg add third
184 $ hg mv second fourth
184 $ hg mv second fourth
185 $ hg commit -m third -d "2020-01-01 10:01"
185 $ hg commit -m third -d "2020-01-01 10:01"
186
186
187 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
187 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
188 fourth (second)
188 fourth (second)
189 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
189 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
190 second -> fourth
190 second -> fourth
191 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
191 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
192 8 t
192 8 t
193 7 f
193 7 f
194
194
195 Working-directory revision has special identifiers, though they are still
195 Working-directory revision has special identifiers, though they are still
196 experimental:
196 experimental:
197
197
198 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
198 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
199 2147483647:ffffffffffffffffffffffffffffffffffffffff
199 2147483647:ffffffffffffffffffffffffffffffffffffffff
200
200
201 Some keywords are invalid for working-directory revision, but they should
201 Some keywords are invalid for working-directory revision, but they should
202 never cause crash:
202 never cause crash:
203
203
204 $ hg log -r 'wdir()' -T '{manifest}\n'
204 $ hg log -r 'wdir()' -T '{manifest}\n'
205
205
206
206
207 Internal resources shouldn't be exposed (issue5699):
207 Internal resources shouldn't be exposed (issue5699):
208
208
209 $ hg log -r. -T '{cache}{ctx}{repo}{revcache}{templ}{ui}'
209 $ hg log -r. -T '{cache}{ctx}{repo}{revcache}{templ}{ui}'
210
210
211 Never crash on internal resource not available:
211 Never crash on internal resource not available:
212
212
213 $ hg --cwd .. debugtemplate '{"c0bebeef"|shortest}\n'
213 $ hg --cwd .. debugtemplate '{"c0bebeef"|shortest}\n'
214 abort: template resource not available: ctx
214 abort: template resource not available: ctx
215 [255]
215 [255]
216
216
217 $ hg config -T '{author}'
217 $ hg config -T '{author}'
218
218
219 Quoting for ui.logtemplate
219 Quoting for ui.logtemplate
220
220
221 $ hg tip --config "ui.logtemplate={rev}\n"
221 $ hg tip --config "ui.logtemplate={rev}\n"
222 8
222 8
223 $ hg tip --config "ui.logtemplate='{rev}\n'"
223 $ hg tip --config "ui.logtemplate='{rev}\n'"
224 8
224 8
225 $ hg tip --config 'ui.logtemplate="{rev}\n"'
225 $ hg tip --config 'ui.logtemplate="{rev}\n"'
226 8
226 8
227 $ hg tip --config 'ui.logtemplate=n{rev}\n'
227 $ hg tip --config 'ui.logtemplate=n{rev}\n'
228 n8
228 n8
229
229
230 Make sure user/global hgrc does not affect tests
230 Make sure user/global hgrc does not affect tests
231
231
232 $ echo '[ui]' > .hg/hgrc
232 $ echo '[ui]' > .hg/hgrc
233 $ echo 'logtemplate =' >> .hg/hgrc
233 $ echo 'logtemplate =' >> .hg/hgrc
234 $ echo 'style =' >> .hg/hgrc
234 $ echo 'style =' >> .hg/hgrc
235
235
236 Add some simple styles to settings
236 Add some simple styles to settings
237
237
238 $ cat <<'EOF' >> .hg/hgrc
238 $ cat <<'EOF' >> .hg/hgrc
239 > [templates]
239 > [templates]
240 > simple = "{rev}\n"
240 > simple = "{rev}\n"
241 > simple2 = {rev}\n
241 > simple2 = {rev}\n
242 > rev = "should not precede {rev} keyword\n"
242 > rev = "should not precede {rev} keyword\n"
243 > EOF
243 > EOF
244
244
245 $ hg log -l1 -Tsimple
245 $ hg log -l1 -Tsimple
246 8
246 8
247 $ hg log -l1 -Tsimple2
247 $ hg log -l1 -Tsimple2
248 8
248 8
249 $ hg log -l1 -Trev
249 $ hg log -l1 -Trev
250 should not precede 8 keyword
250 should not precede 8 keyword
251 $ hg log -l1 -T '{simple}'
251 $ hg log -l1 -T '{simple}'
252 8
252 8
253
253
254 Map file shouldn't see user templates:
254 Map file shouldn't see user templates:
255
255
256 $ cat <<EOF > tmpl
256 $ cat <<EOF > tmpl
257 > changeset = 'nothing expanded:{simple}\n'
257 > changeset = 'nothing expanded:{simple}\n'
258 > EOF
258 > EOF
259 $ hg log -l1 --style ./tmpl
259 $ hg log -l1 --style ./tmpl
260 nothing expanded:
260 nothing expanded:
261
261
262 Test templates and style maps in files:
262 Test templates and style maps in files:
263
263
264 $ echo "{rev}" > tmpl
264 $ echo "{rev}" > tmpl
265 $ hg log -l1 -T./tmpl
265 $ hg log -l1 -T./tmpl
266 8
266 8
267 $ hg log -l1 -Tblah/blah
267 $ hg log -l1 -Tblah/blah
268 blah/blah (no-eol)
268 blah/blah (no-eol)
269
269
270 $ printf 'changeset = "{rev}\\n"\n' > map-simple
270 $ printf 'changeset = "{rev}\\n"\n' > map-simple
271 $ hg log -l1 -T./map-simple
271 $ hg log -l1 -T./map-simple
272 8
272 8
273
273
274 a map file may have [templates] and [templatealias] sections:
274 a map file may have [templates] and [templatealias] sections:
275
275
276 $ cat <<'EOF' > map-simple
276 $ cat <<'EOF' > map-simple
277 > [templates]
277 > [templates]
278 > changeset = "{a}\n"
278 > changeset = "{a}\n"
279 > [templatealias]
279 > [templatealias]
280 > a = rev
280 > a = rev
281 > EOF
281 > EOF
282 $ hg log -l1 -T./map-simple
282 $ hg log -l1 -T./map-simple
283 8
283 8
284
284
285 so it can be included in hgrc
285 so it can be included in hgrc
286
286
287 $ cat <<EOF > myhgrc
287 $ cat <<EOF > myhgrc
288 > %include $HGRCPATH
288 > %include $HGRCPATH
289 > %include map-simple
289 > %include map-simple
290 > [templates]
290 > [templates]
291 > foo = "{changeset}"
291 > foo = "{changeset}"
292 > EOF
292 > EOF
293 $ HGRCPATH=./myhgrc hg log -l1 -Tfoo
293 $ HGRCPATH=./myhgrc hg log -l1 -Tfoo
294 8
294 8
295 $ HGRCPATH=./myhgrc hg log -l1 -T'{a}\n'
295 $ HGRCPATH=./myhgrc hg log -l1 -T'{a}\n'
296 8
296 8
297
297
298 Test template map inheritance
298 Test template map inheritance
299
299
300 $ echo "__base__ = map-cmdline.default" > map-simple
300 $ echo "__base__ = map-cmdline.default" > map-simple
301 $ printf 'cset = "changeset: ***{rev}***\\n"\n' >> map-simple
301 $ printf 'cset = "changeset: ***{rev}***\\n"\n' >> map-simple
302 $ hg log -l1 -T./map-simple
302 $ hg log -l1 -T./map-simple
303 changeset: ***8***
303 changeset: ***8***
304 tag: tip
304 tag: tip
305 user: test
305 user: test
306 date: Wed Jan 01 10:01:00 2020 +0000
306 date: Wed Jan 01 10:01:00 2020 +0000
307 summary: third
307 summary: third
308
308
309
309
310 Test docheader, docfooter and separator in template map
310 Test docheader, docfooter and separator in template map
311
311
312 $ cat <<'EOF' > map-myjson
312 $ cat <<'EOF' > map-myjson
313 > docheader = '\{\n'
313 > docheader = '\{\n'
314 > docfooter = '\n}\n'
314 > docfooter = '\n}\n'
315 > separator = ',\n'
315 > separator = ',\n'
316 > changeset = ' {dict(rev, node|short)|json}'
316 > changeset = ' {dict(rev, node|short)|json}'
317 > EOF
317 > EOF
318 $ hg log -l2 -T./map-myjson
318 $ hg log -l2 -T./map-myjson
319 {
319 {
320 {"node": "95c24699272e", "rev": 8},
320 {"node": "95c24699272e", "rev": 8},
321 {"node": "29114dbae42b", "rev": 7}
321 {"node": "29114dbae42b", "rev": 7}
322 }
322 }
323
323
324 Test docheader, docfooter and separator in [templates] section
324 Test docheader, docfooter and separator in [templates] section
325
325
326 $ cat <<'EOF' >> .hg/hgrc
326 $ cat <<'EOF' >> .hg/hgrc
327 > [templates]
327 > [templates]
328 > myjson = ' {dict(rev, node|short)|json}'
328 > myjson = ' {dict(rev, node|short)|json}'
329 > myjson:docheader = '\{\n'
329 > myjson:docheader = '\{\n'
330 > myjson:docfooter = '\n}\n'
330 > myjson:docfooter = '\n}\n'
331 > myjson:separator = ',\n'
331 > myjson:separator = ',\n'
332 > :docheader = 'should not be selected as a docheader for literal templates\n'
332 > :docheader = 'should not be selected as a docheader for literal templates\n'
333 > EOF
333 > EOF
334 $ hg log -l2 -Tmyjson
334 $ hg log -l2 -Tmyjson
335 {
335 {
336 {"node": "95c24699272e", "rev": 8},
336 {"node": "95c24699272e", "rev": 8},
337 {"node": "29114dbae42b", "rev": 7}
337 {"node": "29114dbae42b", "rev": 7}
338 }
338 }
339 $ hg log -l1 -T'{rev}\n'
339 $ hg log -l1 -T'{rev}\n'
340 8
340 8
341
341
342 Template should precede style option
342 Template should precede style option
343
343
344 $ hg log -l1 --style default -T '{rev}\n'
344 $ hg log -l1 --style default -T '{rev}\n'
345 8
345 8
346
346
347 Add a commit with empty description, to ensure that the templates
347 Add a commit with empty description, to ensure that the templates
348 below will omit the description line.
348 below will omit the description line.
349
349
350 $ echo c >> c
350 $ echo c >> c
351 $ hg add c
351 $ hg add c
352 $ hg commit -qm ' '
352 $ hg commit -qm ' '
353
353
354 Default style is like normal output. Phases style should be the same
354 Default style is like normal output. Phases style should be the same
355 as default style, except for extra phase lines.
355 as default style, except for extra phase lines.
356
356
357 $ hg log > log.out
357 $ hg log > log.out
358 $ hg log --style default > style.out
358 $ hg log --style default > style.out
359 $ cmp log.out style.out || diff -u log.out style.out
359 $ cmp log.out style.out || diff -u log.out style.out
360 $ hg log -T phases > phases.out
360 $ hg log -T phases > phases.out
361 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
361 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
362 +phase: draft
362 +phase: draft
363 +phase: draft
363 +phase: draft
364 +phase: draft
364 +phase: draft
365 +phase: draft
365 +phase: draft
366 +phase: draft
366 +phase: draft
367 +phase: draft
367 +phase: draft
368 +phase: draft
368 +phase: draft
369 +phase: draft
369 +phase: draft
370 +phase: draft
370 +phase: draft
371 +phase: draft
371 +phase: draft
372
372
373 $ hg log -v > log.out
373 $ hg log -v > log.out
374 $ hg log -v --style default > style.out
374 $ hg log -v --style default > style.out
375 $ cmp log.out style.out || diff -u log.out style.out
375 $ cmp log.out style.out || diff -u log.out style.out
376 $ hg log -v -T phases > phases.out
376 $ hg log -v -T phases > phases.out
377 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
377 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
378 +phase: draft
378 +phase: draft
379 +phase: draft
379 +phase: draft
380 +phase: draft
380 +phase: draft
381 +phase: draft
381 +phase: draft
382 +phase: draft
382 +phase: draft
383 +phase: draft
383 +phase: draft
384 +phase: draft
384 +phase: draft
385 +phase: draft
385 +phase: draft
386 +phase: draft
386 +phase: draft
387 +phase: draft
387 +phase: draft
388
388
389 $ hg log -q > log.out
389 $ hg log -q > log.out
390 $ hg log -q --style default > style.out
390 $ hg log -q --style default > style.out
391 $ cmp log.out style.out || diff -u log.out style.out
391 $ cmp log.out style.out || diff -u log.out style.out
392 $ hg log -q -T phases > phases.out
392 $ hg log -q -T phases > phases.out
393 $ cmp log.out phases.out || diff -u log.out phases.out
393 $ cmp log.out phases.out || diff -u log.out phases.out
394
394
395 $ hg log --debug > log.out
395 $ hg log --debug > log.out
396 $ hg log --debug --style default > style.out
396 $ hg log --debug --style default > style.out
397 $ cmp log.out style.out || diff -u log.out style.out
397 $ cmp log.out style.out || diff -u log.out style.out
398 $ hg log --debug -T phases > phases.out
398 $ hg log --debug -T phases > phases.out
399 $ cmp log.out phases.out || diff -u log.out phases.out
399 $ cmp log.out phases.out || diff -u log.out phases.out
400
400
401 Default style of working-directory revision should also be the same (but
401 Default style of working-directory revision should also be the same (but
402 date may change while running tests):
402 date may change while running tests):
403
403
404 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
404 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
405 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
405 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
406 $ cmp log.out style.out || diff -u log.out style.out
406 $ cmp log.out style.out || diff -u log.out style.out
407
407
408 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
408 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
409 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
409 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
410 $ cmp log.out style.out || diff -u log.out style.out
410 $ cmp log.out style.out || diff -u log.out style.out
411
411
412 $ hg log -r 'wdir()' -q > log.out
412 $ hg log -r 'wdir()' -q > log.out
413 $ hg log -r 'wdir()' -q --style default > style.out
413 $ hg log -r 'wdir()' -q --style default > style.out
414 $ cmp log.out style.out || diff -u log.out style.out
414 $ cmp log.out style.out || diff -u log.out style.out
415
415
416 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
416 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
417 $ hg log -r 'wdir()' --debug --style default \
417 $ hg log -r 'wdir()' --debug --style default \
418 > | sed 's|^date:.*|date:|' > style.out
418 > | sed 's|^date:.*|date:|' > style.out
419 $ cmp log.out style.out || diff -u log.out style.out
419 $ cmp log.out style.out || diff -u log.out style.out
420
420
421 Default style should also preserve color information (issue2866):
421 Default style should also preserve color information (issue2866):
422
422
423 $ cp $HGRCPATH $HGRCPATH-bak
423 $ cp $HGRCPATH $HGRCPATH-bak
424 $ cat <<EOF >> $HGRCPATH
424 $ cat <<EOF >> $HGRCPATH
425 > [extensions]
425 > [extensions]
426 > color=
426 > color=
427 > EOF
427 > EOF
428
428
429 $ hg --color=debug log > log.out
429 $ hg --color=debug log > log.out
430 $ hg --color=debug log --style default > style.out
430 $ hg --color=debug log --style default > style.out
431 $ cmp log.out style.out || diff -u log.out style.out
431 $ cmp log.out style.out || diff -u log.out style.out
432 $ hg --color=debug log -T phases > phases.out
432 $ hg --color=debug log -T phases > phases.out
433 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
433 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
434 +[log.phase|phase: draft]
434 +[log.phase|phase: draft]
435 +[log.phase|phase: draft]
435 +[log.phase|phase: draft]
436 +[log.phase|phase: draft]
436 +[log.phase|phase: draft]
437 +[log.phase|phase: draft]
437 +[log.phase|phase: draft]
438 +[log.phase|phase: draft]
438 +[log.phase|phase: draft]
439 +[log.phase|phase: draft]
439 +[log.phase|phase: draft]
440 +[log.phase|phase: draft]
440 +[log.phase|phase: draft]
441 +[log.phase|phase: draft]
441 +[log.phase|phase: draft]
442 +[log.phase|phase: draft]
442 +[log.phase|phase: draft]
443 +[log.phase|phase: draft]
443 +[log.phase|phase: draft]
444
444
445 $ hg --color=debug -v log > log.out
445 $ hg --color=debug -v log > log.out
446 $ hg --color=debug -v log --style default > style.out
446 $ hg --color=debug -v log --style default > style.out
447 $ cmp log.out style.out || diff -u log.out style.out
447 $ cmp log.out style.out || diff -u log.out style.out
448 $ hg --color=debug -v log -T phases > phases.out
448 $ hg --color=debug -v log -T phases > phases.out
449 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
449 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
450 +[log.phase|phase: draft]
450 +[log.phase|phase: draft]
451 +[log.phase|phase: draft]
451 +[log.phase|phase: draft]
452 +[log.phase|phase: draft]
452 +[log.phase|phase: draft]
453 +[log.phase|phase: draft]
453 +[log.phase|phase: draft]
454 +[log.phase|phase: draft]
454 +[log.phase|phase: draft]
455 +[log.phase|phase: draft]
455 +[log.phase|phase: draft]
456 +[log.phase|phase: draft]
456 +[log.phase|phase: draft]
457 +[log.phase|phase: draft]
457 +[log.phase|phase: draft]
458 +[log.phase|phase: draft]
458 +[log.phase|phase: draft]
459 +[log.phase|phase: draft]
459 +[log.phase|phase: draft]
460
460
461 $ hg --color=debug -q log > log.out
461 $ hg --color=debug -q log > log.out
462 $ hg --color=debug -q log --style default > style.out
462 $ hg --color=debug -q log --style default > style.out
463 $ cmp log.out style.out || diff -u log.out style.out
463 $ cmp log.out style.out || diff -u log.out style.out
464 $ hg --color=debug -q log -T phases > phases.out
464 $ hg --color=debug -q log -T phases > phases.out
465 $ cmp log.out phases.out || diff -u log.out phases.out
465 $ cmp log.out phases.out || diff -u log.out phases.out
466
466
467 $ hg --color=debug --debug log > log.out
467 $ hg --color=debug --debug log > log.out
468 $ hg --color=debug --debug log --style default > style.out
468 $ hg --color=debug --debug log --style default > style.out
469 $ cmp log.out style.out || diff -u log.out style.out
469 $ cmp log.out style.out || diff -u log.out style.out
470 $ hg --color=debug --debug log -T phases > phases.out
470 $ hg --color=debug --debug log -T phases > phases.out
471 $ cmp log.out phases.out || diff -u log.out phases.out
471 $ cmp log.out phases.out || diff -u log.out phases.out
472
472
473 $ mv $HGRCPATH-bak $HGRCPATH
473 $ mv $HGRCPATH-bak $HGRCPATH
474
474
475 Remove commit with empty commit message, so as to not pollute further
475 Remove commit with empty commit message, so as to not pollute further
476 tests.
476 tests.
477
477
478 $ hg --config extensions.strip= strip -q .
478 $ hg --config extensions.strip= strip -q .
479
479
480 Revision with no copies (used to print a traceback):
480 Revision with no copies (used to print a traceback):
481
481
482 $ hg tip -v --template '\n'
482 $ hg tip -v --template '\n'
483
483
484
484
485 Compact style works:
485 Compact style works:
486
486
487 $ hg log -Tcompact
487 $ hg log -Tcompact
488 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
488 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
489 third
489 third
490
490
491 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
491 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
492 second
492 second
493
493
494 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
494 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
495 merge
495 merge
496
496
497 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
497 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
498 new head
498 new head
499
499
500 4 bbe44766e73d 1970-01-17 04:53 +0000 person
500 4 bbe44766e73d 1970-01-17 04:53 +0000 person
501 new branch
501 new branch
502
502
503 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
503 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
504 no user, no domain
504 no user, no domain
505
505
506 2 97054abb4ab8 1970-01-14 21:20 +0000 other
506 2 97054abb4ab8 1970-01-14 21:20 +0000 other
507 no person
507 no person
508
508
509 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
509 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
510 other 1
510 other 1
511
511
512 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
512 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
513 line 1
513 line 1
514
514
515
515
516 $ hg log -v --style compact
516 $ hg log -v --style compact
517 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
517 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
518 third
518 third
519
519
520 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
520 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
521 second
521 second
522
522
523 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
523 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
524 merge
524 merge
525
525
526 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
526 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
527 new head
527 new head
528
528
529 4 bbe44766e73d 1970-01-17 04:53 +0000 person
529 4 bbe44766e73d 1970-01-17 04:53 +0000 person
530 new branch
530 new branch
531
531
532 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
532 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
533 no user, no domain
533 no user, no domain
534
534
535 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
535 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
536 no person
536 no person
537
537
538 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
538 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
539 other 1
539 other 1
540 other 2
540 other 2
541
541
542 other 3
542 other 3
543
543
544 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
544 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
545 line 1
545 line 1
546 line 2
546 line 2
547
547
548
548
549 $ hg log --debug --style compact
549 $ hg log --debug --style compact
550 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
550 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
551 third
551 third
552
552
553 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
553 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
554 second
554 second
555
555
556 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
556 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
557 merge
557 merge
558
558
559 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
559 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
560 new head
560 new head
561
561
562 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
562 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
563 new branch
563 new branch
564
564
565 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
565 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
566 no user, no domain
566 no user, no domain
567
567
568 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
568 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
569 no person
569 no person
570
570
571 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
571 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
572 other 1
572 other 1
573 other 2
573 other 2
574
574
575 other 3
575 other 3
576
576
577 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
577 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
578 line 1
578 line 1
579 line 2
579 line 2
580
580
581
581
582 Test xml styles:
582 Test xml styles:
583
583
584 $ hg log --style xml -r 'not all()'
584 $ hg log --style xml -r 'not all()'
585 <?xml version="1.0"?>
585 <?xml version="1.0"?>
586 <log>
586 <log>
587 </log>
587 </log>
588
588
589 $ hg log --style xml
589 $ hg log --style xml
590 <?xml version="1.0"?>
590 <?xml version="1.0"?>
591 <log>
591 <log>
592 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
592 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
593 <tag>tip</tag>
593 <tag>tip</tag>
594 <author email="test">test</author>
594 <author email="test">test</author>
595 <date>2020-01-01T10:01:00+00:00</date>
595 <date>2020-01-01T10:01:00+00:00</date>
596 <msg xml:space="preserve">third</msg>
596 <msg xml:space="preserve">third</msg>
597 </logentry>
597 </logentry>
598 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
598 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
599 <parent revision="-1" node="0000000000000000000000000000000000000000" />
599 <parent revision="-1" node="0000000000000000000000000000000000000000" />
600 <author email="user@hostname">User Name</author>
600 <author email="user@hostname">User Name</author>
601 <date>1970-01-12T13:46:40+00:00</date>
601 <date>1970-01-12T13:46:40+00:00</date>
602 <msg xml:space="preserve">second</msg>
602 <msg xml:space="preserve">second</msg>
603 </logentry>
603 </logentry>
604 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
604 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
605 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
605 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
606 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
606 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
607 <author email="person">person</author>
607 <author email="person">person</author>
608 <date>1970-01-18T08:40:01+00:00</date>
608 <date>1970-01-18T08:40:01+00:00</date>
609 <msg xml:space="preserve">merge</msg>
609 <msg xml:space="preserve">merge</msg>
610 </logentry>
610 </logentry>
611 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
611 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
612 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
612 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
613 <author email="person">person</author>
613 <author email="person">person</author>
614 <date>1970-01-18T08:40:00+00:00</date>
614 <date>1970-01-18T08:40:00+00:00</date>
615 <msg xml:space="preserve">new head</msg>
615 <msg xml:space="preserve">new head</msg>
616 </logentry>
616 </logentry>
617 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
617 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
618 <branch>foo</branch>
618 <branch>foo</branch>
619 <author email="person">person</author>
619 <author email="person">person</author>
620 <date>1970-01-17T04:53:20+00:00</date>
620 <date>1970-01-17T04:53:20+00:00</date>
621 <msg xml:space="preserve">new branch</msg>
621 <msg xml:space="preserve">new branch</msg>
622 </logentry>
622 </logentry>
623 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
623 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
624 <author email="person">person</author>
624 <author email="person">person</author>
625 <date>1970-01-16T01:06:40+00:00</date>
625 <date>1970-01-16T01:06:40+00:00</date>
626 <msg xml:space="preserve">no user, no domain</msg>
626 <msg xml:space="preserve">no user, no domain</msg>
627 </logentry>
627 </logentry>
628 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
628 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
629 <author email="other@place">other</author>
629 <author email="other@place">other</author>
630 <date>1970-01-14T21:20:00+00:00</date>
630 <date>1970-01-14T21:20:00+00:00</date>
631 <msg xml:space="preserve">no person</msg>
631 <msg xml:space="preserve">no person</msg>
632 </logentry>
632 </logentry>
633 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
633 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
634 <author email="other@place">A. N. Other</author>
634 <author email="other@place">A. N. Other</author>
635 <date>1970-01-13T17:33:20+00:00</date>
635 <date>1970-01-13T17:33:20+00:00</date>
636 <msg xml:space="preserve">other 1
636 <msg xml:space="preserve">other 1
637 other 2
637 other 2
638
638
639 other 3</msg>
639 other 3</msg>
640 </logentry>
640 </logentry>
641 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
641 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
642 <author email="user@hostname">User Name</author>
642 <author email="user@hostname">User Name</author>
643 <date>1970-01-12T13:46:40+00:00</date>
643 <date>1970-01-12T13:46:40+00:00</date>
644 <msg xml:space="preserve">line 1
644 <msg xml:space="preserve">line 1
645 line 2</msg>
645 line 2</msg>
646 </logentry>
646 </logentry>
647 </log>
647 </log>
648
648
649 $ hg log -v --style xml
649 $ hg log -v --style xml
650 <?xml version="1.0"?>
650 <?xml version="1.0"?>
651 <log>
651 <log>
652 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
652 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
653 <tag>tip</tag>
653 <tag>tip</tag>
654 <author email="test">test</author>
654 <author email="test">test</author>
655 <date>2020-01-01T10:01:00+00:00</date>
655 <date>2020-01-01T10:01:00+00:00</date>
656 <msg xml:space="preserve">third</msg>
656 <msg xml:space="preserve">third</msg>
657 <paths>
657 <paths>
658 <path action="A">fourth</path>
658 <path action="A">fourth</path>
659 <path action="A">third</path>
659 <path action="A">third</path>
660 <path action="R">second</path>
660 <path action="R">second</path>
661 </paths>
661 </paths>
662 <copies>
662 <copies>
663 <copy source="second">fourth</copy>
663 <copy source="second">fourth</copy>
664 </copies>
664 </copies>
665 </logentry>
665 </logentry>
666 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
666 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
667 <parent revision="-1" node="0000000000000000000000000000000000000000" />
667 <parent revision="-1" node="0000000000000000000000000000000000000000" />
668 <author email="user@hostname">User Name</author>
668 <author email="user@hostname">User Name</author>
669 <date>1970-01-12T13:46:40+00:00</date>
669 <date>1970-01-12T13:46:40+00:00</date>
670 <msg xml:space="preserve">second</msg>
670 <msg xml:space="preserve">second</msg>
671 <paths>
671 <paths>
672 <path action="A">second</path>
672 <path action="A">second</path>
673 </paths>
673 </paths>
674 </logentry>
674 </logentry>
675 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
675 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
676 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
676 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
677 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
677 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
678 <author email="person">person</author>
678 <author email="person">person</author>
679 <date>1970-01-18T08:40:01+00:00</date>
679 <date>1970-01-18T08:40:01+00:00</date>
680 <msg xml:space="preserve">merge</msg>
680 <msg xml:space="preserve">merge</msg>
681 <paths>
681 <paths>
682 </paths>
682 </paths>
683 </logentry>
683 </logentry>
684 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
684 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
685 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
685 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
686 <author email="person">person</author>
686 <author email="person">person</author>
687 <date>1970-01-18T08:40:00+00:00</date>
687 <date>1970-01-18T08:40:00+00:00</date>
688 <msg xml:space="preserve">new head</msg>
688 <msg xml:space="preserve">new head</msg>
689 <paths>
689 <paths>
690 <path action="A">d</path>
690 <path action="A">d</path>
691 </paths>
691 </paths>
692 </logentry>
692 </logentry>
693 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
693 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
694 <branch>foo</branch>
694 <branch>foo</branch>
695 <author email="person">person</author>
695 <author email="person">person</author>
696 <date>1970-01-17T04:53:20+00:00</date>
696 <date>1970-01-17T04:53:20+00:00</date>
697 <msg xml:space="preserve">new branch</msg>
697 <msg xml:space="preserve">new branch</msg>
698 <paths>
698 <paths>
699 </paths>
699 </paths>
700 </logentry>
700 </logentry>
701 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
701 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
702 <author email="person">person</author>
702 <author email="person">person</author>
703 <date>1970-01-16T01:06:40+00:00</date>
703 <date>1970-01-16T01:06:40+00:00</date>
704 <msg xml:space="preserve">no user, no domain</msg>
704 <msg xml:space="preserve">no user, no domain</msg>
705 <paths>
705 <paths>
706 <path action="M">c</path>
706 <path action="M">c</path>
707 </paths>
707 </paths>
708 </logentry>
708 </logentry>
709 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
709 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
710 <author email="other@place">other</author>
710 <author email="other@place">other</author>
711 <date>1970-01-14T21:20:00+00:00</date>
711 <date>1970-01-14T21:20:00+00:00</date>
712 <msg xml:space="preserve">no person</msg>
712 <msg xml:space="preserve">no person</msg>
713 <paths>
713 <paths>
714 <path action="A">c</path>
714 <path action="A">c</path>
715 </paths>
715 </paths>
716 </logentry>
716 </logentry>
717 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
717 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
718 <author email="other@place">A. N. Other</author>
718 <author email="other@place">A. N. Other</author>
719 <date>1970-01-13T17:33:20+00:00</date>
719 <date>1970-01-13T17:33:20+00:00</date>
720 <msg xml:space="preserve">other 1
720 <msg xml:space="preserve">other 1
721 other 2
721 other 2
722
722
723 other 3</msg>
723 other 3</msg>
724 <paths>
724 <paths>
725 <path action="A">b</path>
725 <path action="A">b</path>
726 </paths>
726 </paths>
727 </logentry>
727 </logentry>
728 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
728 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
729 <author email="user@hostname">User Name</author>
729 <author email="user@hostname">User Name</author>
730 <date>1970-01-12T13:46:40+00:00</date>
730 <date>1970-01-12T13:46:40+00:00</date>
731 <msg xml:space="preserve">line 1
731 <msg xml:space="preserve">line 1
732 line 2</msg>
732 line 2</msg>
733 <paths>
733 <paths>
734 <path action="A">a</path>
734 <path action="A">a</path>
735 </paths>
735 </paths>
736 </logentry>
736 </logentry>
737 </log>
737 </log>
738
738
739 $ hg log --debug --style xml
739 $ hg log --debug --style xml
740 <?xml version="1.0"?>
740 <?xml version="1.0"?>
741 <log>
741 <log>
742 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
742 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
743 <tag>tip</tag>
743 <tag>tip</tag>
744 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
744 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
745 <parent revision="-1" node="0000000000000000000000000000000000000000" />
745 <parent revision="-1" node="0000000000000000000000000000000000000000" />
746 <author email="test">test</author>
746 <author email="test">test</author>
747 <date>2020-01-01T10:01:00+00:00</date>
747 <date>2020-01-01T10:01:00+00:00</date>
748 <msg xml:space="preserve">third</msg>
748 <msg xml:space="preserve">third</msg>
749 <paths>
749 <paths>
750 <path action="A">fourth</path>
750 <path action="A">fourth</path>
751 <path action="A">third</path>
751 <path action="A">third</path>
752 <path action="R">second</path>
752 <path action="R">second</path>
753 </paths>
753 </paths>
754 <copies>
754 <copies>
755 <copy source="second">fourth</copy>
755 <copy source="second">fourth</copy>
756 </copies>
756 </copies>
757 <extra key="branch">default</extra>
757 <extra key="branch">default</extra>
758 </logentry>
758 </logentry>
759 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
759 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
760 <parent revision="-1" node="0000000000000000000000000000000000000000" />
760 <parent revision="-1" node="0000000000000000000000000000000000000000" />
761 <parent revision="-1" node="0000000000000000000000000000000000000000" />
761 <parent revision="-1" node="0000000000000000000000000000000000000000" />
762 <author email="user@hostname">User Name</author>
762 <author email="user@hostname">User Name</author>
763 <date>1970-01-12T13:46:40+00:00</date>
763 <date>1970-01-12T13:46:40+00:00</date>
764 <msg xml:space="preserve">second</msg>
764 <msg xml:space="preserve">second</msg>
765 <paths>
765 <paths>
766 <path action="A">second</path>
766 <path action="A">second</path>
767 </paths>
767 </paths>
768 <extra key="branch">default</extra>
768 <extra key="branch">default</extra>
769 </logentry>
769 </logentry>
770 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
770 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
771 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
771 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
772 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
772 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
773 <author email="person">person</author>
773 <author email="person">person</author>
774 <date>1970-01-18T08:40:01+00:00</date>
774 <date>1970-01-18T08:40:01+00:00</date>
775 <msg xml:space="preserve">merge</msg>
775 <msg xml:space="preserve">merge</msg>
776 <paths>
776 <paths>
777 </paths>
777 </paths>
778 <extra key="branch">default</extra>
778 <extra key="branch">default</extra>
779 </logentry>
779 </logentry>
780 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
780 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
781 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
781 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
782 <parent revision="-1" node="0000000000000000000000000000000000000000" />
782 <parent revision="-1" node="0000000000000000000000000000000000000000" />
783 <author email="person">person</author>
783 <author email="person">person</author>
784 <date>1970-01-18T08:40:00+00:00</date>
784 <date>1970-01-18T08:40:00+00:00</date>
785 <msg xml:space="preserve">new head</msg>
785 <msg xml:space="preserve">new head</msg>
786 <paths>
786 <paths>
787 <path action="A">d</path>
787 <path action="A">d</path>
788 </paths>
788 </paths>
789 <extra key="branch">default</extra>
789 <extra key="branch">default</extra>
790 </logentry>
790 </logentry>
791 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
791 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
792 <branch>foo</branch>
792 <branch>foo</branch>
793 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
793 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
794 <parent revision="-1" node="0000000000000000000000000000000000000000" />
794 <parent revision="-1" node="0000000000000000000000000000000000000000" />
795 <author email="person">person</author>
795 <author email="person">person</author>
796 <date>1970-01-17T04:53:20+00:00</date>
796 <date>1970-01-17T04:53:20+00:00</date>
797 <msg xml:space="preserve">new branch</msg>
797 <msg xml:space="preserve">new branch</msg>
798 <paths>
798 <paths>
799 </paths>
799 </paths>
800 <extra key="branch">foo</extra>
800 <extra key="branch">foo</extra>
801 </logentry>
801 </logentry>
802 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
802 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
803 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
803 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
804 <parent revision="-1" node="0000000000000000000000000000000000000000" />
804 <parent revision="-1" node="0000000000000000000000000000000000000000" />
805 <author email="person">person</author>
805 <author email="person">person</author>
806 <date>1970-01-16T01:06:40+00:00</date>
806 <date>1970-01-16T01:06:40+00:00</date>
807 <msg xml:space="preserve">no user, no domain</msg>
807 <msg xml:space="preserve">no user, no domain</msg>
808 <paths>
808 <paths>
809 <path action="M">c</path>
809 <path action="M">c</path>
810 </paths>
810 </paths>
811 <extra key="branch">default</extra>
811 <extra key="branch">default</extra>
812 </logentry>
812 </logentry>
813 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
813 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
814 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
814 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
815 <parent revision="-1" node="0000000000000000000000000000000000000000" />
815 <parent revision="-1" node="0000000000000000000000000000000000000000" />
816 <author email="other@place">other</author>
816 <author email="other@place">other</author>
817 <date>1970-01-14T21:20:00+00:00</date>
817 <date>1970-01-14T21:20:00+00:00</date>
818 <msg xml:space="preserve">no person</msg>
818 <msg xml:space="preserve">no person</msg>
819 <paths>
819 <paths>
820 <path action="A">c</path>
820 <path action="A">c</path>
821 </paths>
821 </paths>
822 <extra key="branch">default</extra>
822 <extra key="branch">default</extra>
823 </logentry>
823 </logentry>
824 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
824 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
825 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
825 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
826 <parent revision="-1" node="0000000000000000000000000000000000000000" />
826 <parent revision="-1" node="0000000000000000000000000000000000000000" />
827 <author email="other@place">A. N. Other</author>
827 <author email="other@place">A. N. Other</author>
828 <date>1970-01-13T17:33:20+00:00</date>
828 <date>1970-01-13T17:33:20+00:00</date>
829 <msg xml:space="preserve">other 1
829 <msg xml:space="preserve">other 1
830 other 2
830 other 2
831
831
832 other 3</msg>
832 other 3</msg>
833 <paths>
833 <paths>
834 <path action="A">b</path>
834 <path action="A">b</path>
835 </paths>
835 </paths>
836 <extra key="branch">default</extra>
836 <extra key="branch">default</extra>
837 </logentry>
837 </logentry>
838 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
838 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
839 <parent revision="-1" node="0000000000000000000000000000000000000000" />
839 <parent revision="-1" node="0000000000000000000000000000000000000000" />
840 <parent revision="-1" node="0000000000000000000000000000000000000000" />
840 <parent revision="-1" node="0000000000000000000000000000000000000000" />
841 <author email="user@hostname">User Name</author>
841 <author email="user@hostname">User Name</author>
842 <date>1970-01-12T13:46:40+00:00</date>
842 <date>1970-01-12T13:46:40+00:00</date>
843 <msg xml:space="preserve">line 1
843 <msg xml:space="preserve">line 1
844 line 2</msg>
844 line 2</msg>
845 <paths>
845 <paths>
846 <path action="A">a</path>
846 <path action="A">a</path>
847 </paths>
847 </paths>
848 <extra key="branch">default</extra>
848 <extra key="branch">default</extra>
849 </logentry>
849 </logentry>
850 </log>
850 </log>
851
851
852
852
853 Test JSON style:
853 Test JSON style:
854
854
855 $ hg log -k nosuch -Tjson
855 $ hg log -k nosuch -Tjson
856 [
856 [
857 ]
857 ]
858
858
859 $ hg log -qr . -Tjson
859 $ hg log -qr . -Tjson
860 [
860 [
861 {
861 {
862 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
862 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
863 "rev": 8
863 "rev": 8
864 }
864 }
865 ]
865 ]
866
866
867 $ hg log -vpr . -Tjson --stat
867 $ hg log -vpr . -Tjson --stat
868 [
868 [
869 {
869 {
870 "bookmarks": [],
870 "bookmarks": [],
871 "branch": "default",
871 "branch": "default",
872 "date": [1577872860, 0],
872 "date": [1577872860, 0],
873 "desc": "third",
873 "desc": "third",
874 "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",
874 "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",
875 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
875 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
876 "files": ["fourth", "second", "third"],
876 "files": ["fourth", "second", "third"],
877 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
877 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
878 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
878 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
879 "phase": "draft",
879 "phase": "draft",
880 "rev": 8,
880 "rev": 8,
881 "tags": ["tip"],
881 "tags": ["tip"],
882 "user": "test"
882 "user": "test"
883 }
883 }
884 ]
884 ]
885
885
886 honor --git but not format-breaking diffopts
886 honor --git but not format-breaking diffopts
887 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
887 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
888 [
888 [
889 {
889 {
890 "bookmarks": [],
890 "bookmarks": [],
891 "branch": "default",
891 "branch": "default",
892 "date": [1577872860, 0],
892 "date": [1577872860, 0],
893 "desc": "third",
893 "desc": "third",
894 "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",
894 "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",
895 "files": ["fourth", "second", "third"],
895 "files": ["fourth", "second", "third"],
896 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
896 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
897 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
897 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
898 "phase": "draft",
898 "phase": "draft",
899 "rev": 8,
899 "rev": 8,
900 "tags": ["tip"],
900 "tags": ["tip"],
901 "user": "test"
901 "user": "test"
902 }
902 }
903 ]
903 ]
904
904
905 $ hg log -T json
905 $ hg log -T json
906 [
906 [
907 {
907 {
908 "bookmarks": [],
908 "bookmarks": [],
909 "branch": "default",
909 "branch": "default",
910 "date": [1577872860, 0],
910 "date": [1577872860, 0],
911 "desc": "third",
911 "desc": "third",
912 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
912 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
913 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
913 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
914 "phase": "draft",
914 "phase": "draft",
915 "rev": 8,
915 "rev": 8,
916 "tags": ["tip"],
916 "tags": ["tip"],
917 "user": "test"
917 "user": "test"
918 },
918 },
919 {
919 {
920 "bookmarks": [],
920 "bookmarks": [],
921 "branch": "default",
921 "branch": "default",
922 "date": [1000000, 0],
922 "date": [1000000, 0],
923 "desc": "second",
923 "desc": "second",
924 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
924 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
925 "parents": ["0000000000000000000000000000000000000000"],
925 "parents": ["0000000000000000000000000000000000000000"],
926 "phase": "draft",
926 "phase": "draft",
927 "rev": 7,
927 "rev": 7,
928 "tags": [],
928 "tags": [],
929 "user": "User Name <user@hostname>"
929 "user": "User Name <user@hostname>"
930 },
930 },
931 {
931 {
932 "bookmarks": [],
932 "bookmarks": [],
933 "branch": "default",
933 "branch": "default",
934 "date": [1500001, 0],
934 "date": [1500001, 0],
935 "desc": "merge",
935 "desc": "merge",
936 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
936 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
937 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
937 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
938 "phase": "draft",
938 "phase": "draft",
939 "rev": 6,
939 "rev": 6,
940 "tags": [],
940 "tags": [],
941 "user": "person"
941 "user": "person"
942 },
942 },
943 {
943 {
944 "bookmarks": [],
944 "bookmarks": [],
945 "branch": "default",
945 "branch": "default",
946 "date": [1500000, 0],
946 "date": [1500000, 0],
947 "desc": "new head",
947 "desc": "new head",
948 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
948 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
949 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
949 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
950 "phase": "draft",
950 "phase": "draft",
951 "rev": 5,
951 "rev": 5,
952 "tags": [],
952 "tags": [],
953 "user": "person"
953 "user": "person"
954 },
954 },
955 {
955 {
956 "bookmarks": [],
956 "bookmarks": [],
957 "branch": "foo",
957 "branch": "foo",
958 "date": [1400000, 0],
958 "date": [1400000, 0],
959 "desc": "new branch",
959 "desc": "new branch",
960 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
960 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
961 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
961 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
962 "phase": "draft",
962 "phase": "draft",
963 "rev": 4,
963 "rev": 4,
964 "tags": [],
964 "tags": [],
965 "user": "person"
965 "user": "person"
966 },
966 },
967 {
967 {
968 "bookmarks": [],
968 "bookmarks": [],
969 "branch": "default",
969 "branch": "default",
970 "date": [1300000, 0],
970 "date": [1300000, 0],
971 "desc": "no user, no domain",
971 "desc": "no user, no domain",
972 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
972 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
973 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
973 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
974 "phase": "draft",
974 "phase": "draft",
975 "rev": 3,
975 "rev": 3,
976 "tags": [],
976 "tags": [],
977 "user": "person"
977 "user": "person"
978 },
978 },
979 {
979 {
980 "bookmarks": [],
980 "bookmarks": [],
981 "branch": "default",
981 "branch": "default",
982 "date": [1200000, 0],
982 "date": [1200000, 0],
983 "desc": "no person",
983 "desc": "no person",
984 "node": "97054abb4ab824450e9164180baf491ae0078465",
984 "node": "97054abb4ab824450e9164180baf491ae0078465",
985 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
985 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
986 "phase": "draft",
986 "phase": "draft",
987 "rev": 2,
987 "rev": 2,
988 "tags": [],
988 "tags": [],
989 "user": "other@place"
989 "user": "other@place"
990 },
990 },
991 {
991 {
992 "bookmarks": [],
992 "bookmarks": [],
993 "branch": "default",
993 "branch": "default",
994 "date": [1100000, 0],
994 "date": [1100000, 0],
995 "desc": "other 1\nother 2\n\nother 3",
995 "desc": "other 1\nother 2\n\nother 3",
996 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
996 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
997 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
997 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
998 "phase": "draft",
998 "phase": "draft",
999 "rev": 1,
999 "rev": 1,
1000 "tags": [],
1000 "tags": [],
1001 "user": "A. N. Other <other@place>"
1001 "user": "A. N. Other <other@place>"
1002 },
1002 },
1003 {
1003 {
1004 "bookmarks": [],
1004 "bookmarks": [],
1005 "branch": "default",
1005 "branch": "default",
1006 "date": [1000000, 0],
1006 "date": [1000000, 0],
1007 "desc": "line 1\nline 2",
1007 "desc": "line 1\nline 2",
1008 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1008 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1009 "parents": ["0000000000000000000000000000000000000000"],
1009 "parents": ["0000000000000000000000000000000000000000"],
1010 "phase": "draft",
1010 "phase": "draft",
1011 "rev": 0,
1011 "rev": 0,
1012 "tags": [],
1012 "tags": [],
1013 "user": "User Name <user@hostname>"
1013 "user": "User Name <user@hostname>"
1014 }
1014 }
1015 ]
1015 ]
1016
1016
1017 $ hg heads -v -Tjson
1017 $ hg heads -v -Tjson
1018 [
1018 [
1019 {
1019 {
1020 "bookmarks": [],
1020 "bookmarks": [],
1021 "branch": "default",
1021 "branch": "default",
1022 "date": [1577872860, 0],
1022 "date": [1577872860, 0],
1023 "desc": "third",
1023 "desc": "third",
1024 "files": ["fourth", "second", "third"],
1024 "files": ["fourth", "second", "third"],
1025 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1025 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1026 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1026 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1027 "phase": "draft",
1027 "phase": "draft",
1028 "rev": 8,
1028 "rev": 8,
1029 "tags": ["tip"],
1029 "tags": ["tip"],
1030 "user": "test"
1030 "user": "test"
1031 },
1031 },
1032 {
1032 {
1033 "bookmarks": [],
1033 "bookmarks": [],
1034 "branch": "default",
1034 "branch": "default",
1035 "date": [1500001, 0],
1035 "date": [1500001, 0],
1036 "desc": "merge",
1036 "desc": "merge",
1037 "files": [],
1037 "files": [],
1038 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1038 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1039 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1039 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1040 "phase": "draft",
1040 "phase": "draft",
1041 "rev": 6,
1041 "rev": 6,
1042 "tags": [],
1042 "tags": [],
1043 "user": "person"
1043 "user": "person"
1044 },
1044 },
1045 {
1045 {
1046 "bookmarks": [],
1046 "bookmarks": [],
1047 "branch": "foo",
1047 "branch": "foo",
1048 "date": [1400000, 0],
1048 "date": [1400000, 0],
1049 "desc": "new branch",
1049 "desc": "new branch",
1050 "files": [],
1050 "files": [],
1051 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1051 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1052 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1052 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1053 "phase": "draft",
1053 "phase": "draft",
1054 "rev": 4,
1054 "rev": 4,
1055 "tags": [],
1055 "tags": [],
1056 "user": "person"
1056 "user": "person"
1057 }
1057 }
1058 ]
1058 ]
1059
1059
1060 $ hg log --debug -Tjson
1060 $ hg log --debug -Tjson
1061 [
1061 [
1062 {
1062 {
1063 "added": ["fourth", "third"],
1063 "added": ["fourth", "third"],
1064 "bookmarks": [],
1064 "bookmarks": [],
1065 "branch": "default",
1065 "branch": "default",
1066 "date": [1577872860, 0],
1066 "date": [1577872860, 0],
1067 "desc": "third",
1067 "desc": "third",
1068 "extra": {"branch": "default"},
1068 "extra": {"branch": "default"},
1069 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
1069 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
1070 "modified": [],
1070 "modified": [],
1071 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1071 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1072 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1072 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1073 "phase": "draft",
1073 "phase": "draft",
1074 "removed": ["second"],
1074 "removed": ["second"],
1075 "rev": 8,
1075 "rev": 8,
1076 "tags": ["tip"],
1076 "tags": ["tip"],
1077 "user": "test"
1077 "user": "test"
1078 },
1078 },
1079 {
1079 {
1080 "added": ["second"],
1080 "added": ["second"],
1081 "bookmarks": [],
1081 "bookmarks": [],
1082 "branch": "default",
1082 "branch": "default",
1083 "date": [1000000, 0],
1083 "date": [1000000, 0],
1084 "desc": "second",
1084 "desc": "second",
1085 "extra": {"branch": "default"},
1085 "extra": {"branch": "default"},
1086 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
1086 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
1087 "modified": [],
1087 "modified": [],
1088 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
1088 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
1089 "parents": ["0000000000000000000000000000000000000000"],
1089 "parents": ["0000000000000000000000000000000000000000"],
1090 "phase": "draft",
1090 "phase": "draft",
1091 "removed": [],
1091 "removed": [],
1092 "rev": 7,
1092 "rev": 7,
1093 "tags": [],
1093 "tags": [],
1094 "user": "User Name <user@hostname>"
1094 "user": "User Name <user@hostname>"
1095 },
1095 },
1096 {
1096 {
1097 "added": [],
1097 "added": [],
1098 "bookmarks": [],
1098 "bookmarks": [],
1099 "branch": "default",
1099 "branch": "default",
1100 "date": [1500001, 0],
1100 "date": [1500001, 0],
1101 "desc": "merge",
1101 "desc": "merge",
1102 "extra": {"branch": "default"},
1102 "extra": {"branch": "default"},
1103 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1103 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1104 "modified": [],
1104 "modified": [],
1105 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1105 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1106 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1106 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1107 "phase": "draft",
1107 "phase": "draft",
1108 "removed": [],
1108 "removed": [],
1109 "rev": 6,
1109 "rev": 6,
1110 "tags": [],
1110 "tags": [],
1111 "user": "person"
1111 "user": "person"
1112 },
1112 },
1113 {
1113 {
1114 "added": ["d"],
1114 "added": ["d"],
1115 "bookmarks": [],
1115 "bookmarks": [],
1116 "branch": "default",
1116 "branch": "default",
1117 "date": [1500000, 0],
1117 "date": [1500000, 0],
1118 "desc": "new head",
1118 "desc": "new head",
1119 "extra": {"branch": "default"},
1119 "extra": {"branch": "default"},
1120 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1120 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1121 "modified": [],
1121 "modified": [],
1122 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
1122 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
1123 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1123 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1124 "phase": "draft",
1124 "phase": "draft",
1125 "removed": [],
1125 "removed": [],
1126 "rev": 5,
1126 "rev": 5,
1127 "tags": [],
1127 "tags": [],
1128 "user": "person"
1128 "user": "person"
1129 },
1129 },
1130 {
1130 {
1131 "added": [],
1131 "added": [],
1132 "bookmarks": [],
1132 "bookmarks": [],
1133 "branch": "foo",
1133 "branch": "foo",
1134 "date": [1400000, 0],
1134 "date": [1400000, 0],
1135 "desc": "new branch",
1135 "desc": "new branch",
1136 "extra": {"branch": "foo"},
1136 "extra": {"branch": "foo"},
1137 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1137 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1138 "modified": [],
1138 "modified": [],
1139 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1139 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1140 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1140 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1141 "phase": "draft",
1141 "phase": "draft",
1142 "removed": [],
1142 "removed": [],
1143 "rev": 4,
1143 "rev": 4,
1144 "tags": [],
1144 "tags": [],
1145 "user": "person"
1145 "user": "person"
1146 },
1146 },
1147 {
1147 {
1148 "added": [],
1148 "added": [],
1149 "bookmarks": [],
1149 "bookmarks": [],
1150 "branch": "default",
1150 "branch": "default",
1151 "date": [1300000, 0],
1151 "date": [1300000, 0],
1152 "desc": "no user, no domain",
1152 "desc": "no user, no domain",
1153 "extra": {"branch": "default"},
1153 "extra": {"branch": "default"},
1154 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1154 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1155 "modified": ["c"],
1155 "modified": ["c"],
1156 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
1156 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
1157 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
1157 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
1158 "phase": "draft",
1158 "phase": "draft",
1159 "removed": [],
1159 "removed": [],
1160 "rev": 3,
1160 "rev": 3,
1161 "tags": [],
1161 "tags": [],
1162 "user": "person"
1162 "user": "person"
1163 },
1163 },
1164 {
1164 {
1165 "added": ["c"],
1165 "added": ["c"],
1166 "bookmarks": [],
1166 "bookmarks": [],
1167 "branch": "default",
1167 "branch": "default",
1168 "date": [1200000, 0],
1168 "date": [1200000, 0],
1169 "desc": "no person",
1169 "desc": "no person",
1170 "extra": {"branch": "default"},
1170 "extra": {"branch": "default"},
1171 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
1171 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
1172 "modified": [],
1172 "modified": [],
1173 "node": "97054abb4ab824450e9164180baf491ae0078465",
1173 "node": "97054abb4ab824450e9164180baf491ae0078465",
1174 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
1174 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
1175 "phase": "draft",
1175 "phase": "draft",
1176 "removed": [],
1176 "removed": [],
1177 "rev": 2,
1177 "rev": 2,
1178 "tags": [],
1178 "tags": [],
1179 "user": "other@place"
1179 "user": "other@place"
1180 },
1180 },
1181 {
1181 {
1182 "added": ["b"],
1182 "added": ["b"],
1183 "bookmarks": [],
1183 "bookmarks": [],
1184 "branch": "default",
1184 "branch": "default",
1185 "date": [1100000, 0],
1185 "date": [1100000, 0],
1186 "desc": "other 1\nother 2\n\nother 3",
1186 "desc": "other 1\nother 2\n\nother 3",
1187 "extra": {"branch": "default"},
1187 "extra": {"branch": "default"},
1188 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
1188 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
1189 "modified": [],
1189 "modified": [],
1190 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
1190 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
1191 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
1191 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
1192 "phase": "draft",
1192 "phase": "draft",
1193 "removed": [],
1193 "removed": [],
1194 "rev": 1,
1194 "rev": 1,
1195 "tags": [],
1195 "tags": [],
1196 "user": "A. N. Other <other@place>"
1196 "user": "A. N. Other <other@place>"
1197 },
1197 },
1198 {
1198 {
1199 "added": ["a"],
1199 "added": ["a"],
1200 "bookmarks": [],
1200 "bookmarks": [],
1201 "branch": "default",
1201 "branch": "default",
1202 "date": [1000000, 0],
1202 "date": [1000000, 0],
1203 "desc": "line 1\nline 2",
1203 "desc": "line 1\nline 2",
1204 "extra": {"branch": "default"},
1204 "extra": {"branch": "default"},
1205 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
1205 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
1206 "modified": [],
1206 "modified": [],
1207 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1207 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1208 "parents": ["0000000000000000000000000000000000000000"],
1208 "parents": ["0000000000000000000000000000000000000000"],
1209 "phase": "draft",
1209 "phase": "draft",
1210 "removed": [],
1210 "removed": [],
1211 "rev": 0,
1211 "rev": 0,
1212 "tags": [],
1212 "tags": [],
1213 "user": "User Name <user@hostname>"
1213 "user": "User Name <user@hostname>"
1214 }
1214 }
1215 ]
1215 ]
1216
1216
1217 Error if style not readable:
1217 Error if style not readable:
1218
1218
1219 #if unix-permissions no-root
1219 #if unix-permissions no-root
1220 $ touch q
1220 $ touch q
1221 $ chmod 0 q
1221 $ chmod 0 q
1222 $ hg log --style ./q
1222 $ hg log --style ./q
1223 abort: Permission denied: ./q
1223 abort: Permission denied: ./q
1224 [255]
1224 [255]
1225 #endif
1225 #endif
1226
1226
1227 Error if no style:
1227 Error if no style:
1228
1228
1229 $ hg log --style notexist
1229 $ hg log --style notexist
1230 abort: style 'notexist' not found
1230 abort: style 'notexist' not found
1231 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
1231 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
1232 [255]
1232 [255]
1233
1233
1234 $ hg log -T list
1234 $ hg log -T list
1235 available styles: bisect, changelog, compact, default, phases, show, status, xml
1235 available styles: bisect, changelog, compact, default, phases, show, status, xml
1236 abort: specify a template
1236 abort: specify a template
1237 [255]
1237 [255]
1238
1238
1239 Error if style missing key:
1239 Error if style missing key:
1240
1240
1241 $ echo 'q = q' > t
1241 $ echo 'q = q' > t
1242 $ hg log --style ./t
1242 $ hg log --style ./t
1243 abort: "changeset" not in template map
1243 abort: "changeset" not in template map
1244 [255]
1244 [255]
1245
1245
1246 Error if style missing value:
1246 Error if style missing value:
1247
1247
1248 $ echo 'changeset =' > t
1248 $ echo 'changeset =' > t
1249 $ hg log --style t
1249 $ hg log --style t
1250 hg: parse error at t:1: missing value
1250 hg: parse error at t:1: missing value
1251 [255]
1251 [255]
1252
1252
1253 Error if include fails:
1253 Error if include fails:
1254
1254
1255 $ echo 'changeset = q' >> t
1255 $ echo 'changeset = q' >> t
1256 #if unix-permissions no-root
1256 #if unix-permissions no-root
1257 $ hg log --style ./t
1257 $ hg log --style ./t
1258 abort: template file ./q: Permission denied
1258 abort: template file ./q: Permission denied
1259 [255]
1259 [255]
1260 $ rm -f q
1260 $ rm -f q
1261 #endif
1261 #endif
1262
1262
1263 Include works:
1263 Include works:
1264
1264
1265 $ echo '{rev}' > q
1265 $ echo '{rev}' > q
1266 $ hg log --style ./t
1266 $ hg log --style ./t
1267 8
1267 8
1268 7
1268 7
1269 6
1269 6
1270 5
1270 5
1271 4
1271 4
1272 3
1272 3
1273 2
1273 2
1274 1
1274 1
1275 0
1275 0
1276
1276
1277 Check that recursive reference does not fall into RuntimeError (issue4758):
1277 Check that recursive reference does not fall into RuntimeError (issue4758):
1278
1278
1279 common mistake:
1279 common mistake:
1280
1280
1281 $ cat << EOF > issue4758
1281 $ cat << EOF > issue4758
1282 > changeset = '{changeset}\n'
1282 > changeset = '{changeset}\n'
1283 > EOF
1283 > EOF
1284 $ hg log --style ./issue4758
1284 $ hg log --style ./issue4758
1285 abort: recursive reference 'changeset' in template
1285 abort: recursive reference 'changeset' in template
1286 [255]
1286 [255]
1287
1287
1288 circular reference:
1288 circular reference:
1289
1289
1290 $ cat << EOF > issue4758
1290 $ cat << EOF > issue4758
1291 > changeset = '{foo}'
1291 > changeset = '{foo}'
1292 > foo = '{changeset}'
1292 > foo = '{changeset}'
1293 > EOF
1293 > EOF
1294 $ hg log --style ./issue4758
1294 $ hg log --style ./issue4758
1295 abort: recursive reference 'foo' in template
1295 abort: recursive reference 'foo' in template
1296 [255]
1296 [255]
1297
1297
1298 buildmap() -> gettemplate(), where no thunk was made:
1298 buildmap() -> gettemplate(), where no thunk was made:
1299
1299
1300 $ cat << EOF > issue4758
1300 $ cat << EOF > issue4758
1301 > changeset = '{files % changeset}\n'
1301 > changeset = '{files % changeset}\n'
1302 > EOF
1302 > EOF
1303 $ hg log --style ./issue4758
1303 $ hg log --style ./issue4758
1304 abort: recursive reference 'changeset' in template
1304 abort: recursive reference 'changeset' in template
1305 [255]
1305 [255]
1306
1306
1307 not a recursion if a keyword of the same name exists:
1307 not a recursion if a keyword of the same name exists:
1308
1308
1309 $ cat << EOF > issue4758
1309 $ cat << EOF > issue4758
1310 > changeset = '{tags % rev}'
1310 > changeset = '{tags % rev}'
1311 > rev = '{rev} {tag}\n'
1311 > rev = '{rev} {tag}\n'
1312 > EOF
1312 > EOF
1313 $ hg log --style ./issue4758 -r tip
1313 $ hg log --style ./issue4758 -r tip
1314 8 tip
1314 8 tip
1315
1315
1316 Check that {phase} works correctly on parents:
1316 Check that {phase} works correctly on parents:
1317
1317
1318 $ cat << EOF > parentphase
1318 $ cat << EOF > parentphase
1319 > changeset_debug = '{rev} ({phase}):{parents}\n'
1319 > changeset_debug = '{rev} ({phase}):{parents}\n'
1320 > parent = ' {rev} ({phase})'
1320 > parent = ' {rev} ({phase})'
1321 > EOF
1321 > EOF
1322 $ hg phase -r 5 --public
1322 $ hg phase -r 5 --public
1323 $ hg phase -r 7 --secret --force
1323 $ hg phase -r 7 --secret --force
1324 $ hg log --debug -G --style ./parentphase
1324 $ hg log --debug -G --style ./parentphase
1325 @ 8 (secret): 7 (secret) -1 (public)
1325 @ 8 (secret): 7 (secret) -1 (public)
1326 |
1326 |
1327 o 7 (secret): -1 (public) -1 (public)
1327 o 7 (secret): -1 (public) -1 (public)
1328
1328
1329 o 6 (draft): 5 (public) 4 (draft)
1329 o 6 (draft): 5 (public) 4 (draft)
1330 |\
1330 |\
1331 | o 5 (public): 3 (public) -1 (public)
1331 | o 5 (public): 3 (public) -1 (public)
1332 | |
1332 | |
1333 o | 4 (draft): 3 (public) -1 (public)
1333 o | 4 (draft): 3 (public) -1 (public)
1334 |/
1334 |/
1335 o 3 (public): 2 (public) -1 (public)
1335 o 3 (public): 2 (public) -1 (public)
1336 |
1336 |
1337 o 2 (public): 1 (public) -1 (public)
1337 o 2 (public): 1 (public) -1 (public)
1338 |
1338 |
1339 o 1 (public): 0 (public) -1 (public)
1339 o 1 (public): 0 (public) -1 (public)
1340 |
1340 |
1341 o 0 (public): -1 (public) -1 (public)
1341 o 0 (public): -1 (public) -1 (public)
1342
1342
1343
1343
1344 Missing non-standard names give no error (backward compatibility):
1344 Missing non-standard names give no error (backward compatibility):
1345
1345
1346 $ echo "changeset = '{c}'" > t
1346 $ echo "changeset = '{c}'" > t
1347 $ hg log --style ./t
1347 $ hg log --style ./t
1348
1348
1349 Defining non-standard name works:
1349 Defining non-standard name works:
1350
1350
1351 $ cat <<EOF > t
1351 $ cat <<EOF > t
1352 > changeset = '{c}'
1352 > changeset = '{c}'
1353 > c = q
1353 > c = q
1354 > EOF
1354 > EOF
1355 $ hg log --style ./t
1355 $ hg log --style ./t
1356 8
1356 8
1357 7
1357 7
1358 6
1358 6
1359 5
1359 5
1360 4
1360 4
1361 3
1361 3
1362 2
1362 2
1363 1
1363 1
1364 0
1364 0
1365
1365
1366 ui.style works:
1366 ui.style works:
1367
1367
1368 $ echo '[ui]' > .hg/hgrc
1368 $ echo '[ui]' > .hg/hgrc
1369 $ echo 'style = t' >> .hg/hgrc
1369 $ echo 'style = t' >> .hg/hgrc
1370 $ hg log
1370 $ hg log
1371 8
1371 8
1372 7
1372 7
1373 6
1373 6
1374 5
1374 5
1375 4
1375 4
1376 3
1376 3
1377 2
1377 2
1378 1
1378 1
1379 0
1379 0
1380
1380
1381
1381
1382 Issue338:
1382 Issue338:
1383
1383
1384 $ hg log --style=changelog > changelog
1384 $ hg log --style=changelog > changelog
1385
1385
1386 $ cat changelog
1386 $ cat changelog
1387 2020-01-01 test <test>
1387 2020-01-01 test <test>
1388
1388
1389 * fourth, second, third:
1389 * fourth, second, third:
1390 third
1390 third
1391 [95c24699272e] [tip]
1391 [95c24699272e] [tip]
1392
1392
1393 1970-01-12 User Name <user@hostname>
1393 1970-01-12 User Name <user@hostname>
1394
1394
1395 * second:
1395 * second:
1396 second
1396 second
1397 [29114dbae42b]
1397 [29114dbae42b]
1398
1398
1399 1970-01-18 person <person>
1399 1970-01-18 person <person>
1400
1400
1401 * merge
1401 * merge
1402 [d41e714fe50d]
1402 [d41e714fe50d]
1403
1403
1404 * d:
1404 * d:
1405 new head
1405 new head
1406 [13207e5a10d9]
1406 [13207e5a10d9]
1407
1407
1408 1970-01-17 person <person>
1408 1970-01-17 person <person>
1409
1409
1410 * new branch
1410 * new branch
1411 [bbe44766e73d] <foo>
1411 [bbe44766e73d] <foo>
1412
1412
1413 1970-01-16 person <person>
1413 1970-01-16 person <person>
1414
1414
1415 * c:
1415 * c:
1416 no user, no domain
1416 no user, no domain
1417 [10e46f2dcbf4]
1417 [10e46f2dcbf4]
1418
1418
1419 1970-01-14 other <other@place>
1419 1970-01-14 other <other@place>
1420
1420
1421 * c:
1421 * c:
1422 no person
1422 no person
1423 [97054abb4ab8]
1423 [97054abb4ab8]
1424
1424
1425 1970-01-13 A. N. Other <other@place>
1425 1970-01-13 A. N. Other <other@place>
1426
1426
1427 * b:
1427 * b:
1428 other 1 other 2
1428 other 1 other 2
1429
1429
1430 other 3
1430 other 3
1431 [b608e9d1a3f0]
1431 [b608e9d1a3f0]
1432
1432
1433 1970-01-12 User Name <user@hostname>
1433 1970-01-12 User Name <user@hostname>
1434
1434
1435 * a:
1435 * a:
1436 line 1 line 2
1436 line 1 line 2
1437 [1e4e1b8f71e0]
1437 [1e4e1b8f71e0]
1438
1438
1439
1439
1440 Issue2130: xml output for 'hg heads' is malformed
1440 Issue2130: xml output for 'hg heads' is malformed
1441
1441
1442 $ hg heads --style changelog
1442 $ hg heads --style changelog
1443 2020-01-01 test <test>
1443 2020-01-01 test <test>
1444
1444
1445 * fourth, second, third:
1445 * fourth, second, third:
1446 third
1446 third
1447 [95c24699272e] [tip]
1447 [95c24699272e] [tip]
1448
1448
1449 1970-01-18 person <person>
1449 1970-01-18 person <person>
1450
1450
1451 * merge
1451 * merge
1452 [d41e714fe50d]
1452 [d41e714fe50d]
1453
1453
1454 1970-01-17 person <person>
1454 1970-01-17 person <person>
1455
1455
1456 * new branch
1456 * new branch
1457 [bbe44766e73d] <foo>
1457 [bbe44766e73d] <foo>
1458
1458
1459
1459
1460 Keys work:
1460 Keys work:
1461
1461
1462 $ for key in author branch branches date desc file_adds file_dels file_mods \
1462 $ for key in author branch branches date desc file_adds file_dels file_mods \
1463 > file_copies file_copies_switch files \
1463 > file_copies file_copies_switch files \
1464 > manifest node parents rev tags diffstat extras \
1464 > manifest node parents rev tags diffstat extras \
1465 > p1rev p2rev p1node p2node; do
1465 > p1rev p2rev p1node p2node; do
1466 > for mode in '' --verbose --debug; do
1466 > for mode in '' --verbose --debug; do
1467 > hg log $mode --template "$key$mode: {$key}\n"
1467 > hg log $mode --template "$key$mode: {$key}\n"
1468 > done
1468 > done
1469 > done
1469 > done
1470 author: test
1470 author: test
1471 author: User Name <user@hostname>
1471 author: User Name <user@hostname>
1472 author: person
1472 author: person
1473 author: person
1473 author: person
1474 author: person
1474 author: person
1475 author: person
1475 author: person
1476 author: other@place
1476 author: other@place
1477 author: A. N. Other <other@place>
1477 author: A. N. Other <other@place>
1478 author: User Name <user@hostname>
1478 author: User Name <user@hostname>
1479 author--verbose: test
1479 author--verbose: test
1480 author--verbose: User Name <user@hostname>
1480 author--verbose: User Name <user@hostname>
1481 author--verbose: person
1481 author--verbose: person
1482 author--verbose: person
1482 author--verbose: person
1483 author--verbose: person
1483 author--verbose: person
1484 author--verbose: person
1484 author--verbose: person
1485 author--verbose: other@place
1485 author--verbose: other@place
1486 author--verbose: A. N. Other <other@place>
1486 author--verbose: A. N. Other <other@place>
1487 author--verbose: User Name <user@hostname>
1487 author--verbose: User Name <user@hostname>
1488 author--debug: test
1488 author--debug: test
1489 author--debug: User Name <user@hostname>
1489 author--debug: User Name <user@hostname>
1490 author--debug: person
1490 author--debug: person
1491 author--debug: person
1491 author--debug: person
1492 author--debug: person
1492 author--debug: person
1493 author--debug: person
1493 author--debug: person
1494 author--debug: other@place
1494 author--debug: other@place
1495 author--debug: A. N. Other <other@place>
1495 author--debug: A. N. Other <other@place>
1496 author--debug: User Name <user@hostname>
1496 author--debug: User Name <user@hostname>
1497 branch: default
1497 branch: default
1498 branch: default
1498 branch: default
1499 branch: default
1499 branch: default
1500 branch: default
1500 branch: default
1501 branch: foo
1501 branch: foo
1502 branch: default
1502 branch: default
1503 branch: default
1503 branch: default
1504 branch: default
1504 branch: default
1505 branch: default
1505 branch: default
1506 branch--verbose: default
1506 branch--verbose: default
1507 branch--verbose: default
1507 branch--verbose: default
1508 branch--verbose: default
1508 branch--verbose: default
1509 branch--verbose: default
1509 branch--verbose: default
1510 branch--verbose: foo
1510 branch--verbose: foo
1511 branch--verbose: default
1511 branch--verbose: default
1512 branch--verbose: default
1512 branch--verbose: default
1513 branch--verbose: default
1513 branch--verbose: default
1514 branch--verbose: default
1514 branch--verbose: default
1515 branch--debug: default
1515 branch--debug: default
1516 branch--debug: default
1516 branch--debug: default
1517 branch--debug: default
1517 branch--debug: default
1518 branch--debug: default
1518 branch--debug: default
1519 branch--debug: foo
1519 branch--debug: foo
1520 branch--debug: default
1520 branch--debug: default
1521 branch--debug: default
1521 branch--debug: default
1522 branch--debug: default
1522 branch--debug: default
1523 branch--debug: default
1523 branch--debug: default
1524 branches:
1524 branches:
1525 branches:
1525 branches:
1526 branches:
1526 branches:
1527 branches:
1527 branches:
1528 branches: foo
1528 branches: foo
1529 branches:
1529 branches:
1530 branches:
1530 branches:
1531 branches:
1531 branches:
1532 branches:
1532 branches:
1533 branches--verbose:
1533 branches--verbose:
1534 branches--verbose:
1534 branches--verbose:
1535 branches--verbose:
1535 branches--verbose:
1536 branches--verbose:
1536 branches--verbose:
1537 branches--verbose: foo
1537 branches--verbose: foo
1538 branches--verbose:
1538 branches--verbose:
1539 branches--verbose:
1539 branches--verbose:
1540 branches--verbose:
1540 branches--verbose:
1541 branches--verbose:
1541 branches--verbose:
1542 branches--debug:
1542 branches--debug:
1543 branches--debug:
1543 branches--debug:
1544 branches--debug:
1544 branches--debug:
1545 branches--debug:
1545 branches--debug:
1546 branches--debug: foo
1546 branches--debug: foo
1547 branches--debug:
1547 branches--debug:
1548 branches--debug:
1548 branches--debug:
1549 branches--debug:
1549 branches--debug:
1550 branches--debug:
1550 branches--debug:
1551 date: 1577872860.00
1551 date: 1577872860.00
1552 date: 1000000.00
1552 date: 1000000.00
1553 date: 1500001.00
1553 date: 1500001.00
1554 date: 1500000.00
1554 date: 1500000.00
1555 date: 1400000.00
1555 date: 1400000.00
1556 date: 1300000.00
1556 date: 1300000.00
1557 date: 1200000.00
1557 date: 1200000.00
1558 date: 1100000.00
1558 date: 1100000.00
1559 date: 1000000.00
1559 date: 1000000.00
1560 date--verbose: 1577872860.00
1560 date--verbose: 1577872860.00
1561 date--verbose: 1000000.00
1561 date--verbose: 1000000.00
1562 date--verbose: 1500001.00
1562 date--verbose: 1500001.00
1563 date--verbose: 1500000.00
1563 date--verbose: 1500000.00
1564 date--verbose: 1400000.00
1564 date--verbose: 1400000.00
1565 date--verbose: 1300000.00
1565 date--verbose: 1300000.00
1566 date--verbose: 1200000.00
1566 date--verbose: 1200000.00
1567 date--verbose: 1100000.00
1567 date--verbose: 1100000.00
1568 date--verbose: 1000000.00
1568 date--verbose: 1000000.00
1569 date--debug: 1577872860.00
1569 date--debug: 1577872860.00
1570 date--debug: 1000000.00
1570 date--debug: 1000000.00
1571 date--debug: 1500001.00
1571 date--debug: 1500001.00
1572 date--debug: 1500000.00
1572 date--debug: 1500000.00
1573 date--debug: 1400000.00
1573 date--debug: 1400000.00
1574 date--debug: 1300000.00
1574 date--debug: 1300000.00
1575 date--debug: 1200000.00
1575 date--debug: 1200000.00
1576 date--debug: 1100000.00
1576 date--debug: 1100000.00
1577 date--debug: 1000000.00
1577 date--debug: 1000000.00
1578 desc: third
1578 desc: third
1579 desc: second
1579 desc: second
1580 desc: merge
1580 desc: merge
1581 desc: new head
1581 desc: new head
1582 desc: new branch
1582 desc: new branch
1583 desc: no user, no domain
1583 desc: no user, no domain
1584 desc: no person
1584 desc: no person
1585 desc: other 1
1585 desc: other 1
1586 other 2
1586 other 2
1587
1587
1588 other 3
1588 other 3
1589 desc: line 1
1589 desc: line 1
1590 line 2
1590 line 2
1591 desc--verbose: third
1591 desc--verbose: third
1592 desc--verbose: second
1592 desc--verbose: second
1593 desc--verbose: merge
1593 desc--verbose: merge
1594 desc--verbose: new head
1594 desc--verbose: new head
1595 desc--verbose: new branch
1595 desc--verbose: new branch
1596 desc--verbose: no user, no domain
1596 desc--verbose: no user, no domain
1597 desc--verbose: no person
1597 desc--verbose: no person
1598 desc--verbose: other 1
1598 desc--verbose: other 1
1599 other 2
1599 other 2
1600
1600
1601 other 3
1601 other 3
1602 desc--verbose: line 1
1602 desc--verbose: line 1
1603 line 2
1603 line 2
1604 desc--debug: third
1604 desc--debug: third
1605 desc--debug: second
1605 desc--debug: second
1606 desc--debug: merge
1606 desc--debug: merge
1607 desc--debug: new head
1607 desc--debug: new head
1608 desc--debug: new branch
1608 desc--debug: new branch
1609 desc--debug: no user, no domain
1609 desc--debug: no user, no domain
1610 desc--debug: no person
1610 desc--debug: no person
1611 desc--debug: other 1
1611 desc--debug: other 1
1612 other 2
1612 other 2
1613
1613
1614 other 3
1614 other 3
1615 desc--debug: line 1
1615 desc--debug: line 1
1616 line 2
1616 line 2
1617 file_adds: fourth third
1617 file_adds: fourth third
1618 file_adds: second
1618 file_adds: second
1619 file_adds:
1619 file_adds:
1620 file_adds: d
1620 file_adds: d
1621 file_adds:
1621 file_adds:
1622 file_adds:
1622 file_adds:
1623 file_adds: c
1623 file_adds: c
1624 file_adds: b
1624 file_adds: b
1625 file_adds: a
1625 file_adds: a
1626 file_adds--verbose: fourth third
1626 file_adds--verbose: fourth third
1627 file_adds--verbose: second
1627 file_adds--verbose: second
1628 file_adds--verbose:
1628 file_adds--verbose:
1629 file_adds--verbose: d
1629 file_adds--verbose: d
1630 file_adds--verbose:
1630 file_adds--verbose:
1631 file_adds--verbose:
1631 file_adds--verbose:
1632 file_adds--verbose: c
1632 file_adds--verbose: c
1633 file_adds--verbose: b
1633 file_adds--verbose: b
1634 file_adds--verbose: a
1634 file_adds--verbose: a
1635 file_adds--debug: fourth third
1635 file_adds--debug: fourth third
1636 file_adds--debug: second
1636 file_adds--debug: second
1637 file_adds--debug:
1637 file_adds--debug:
1638 file_adds--debug: d
1638 file_adds--debug: d
1639 file_adds--debug:
1639 file_adds--debug:
1640 file_adds--debug:
1640 file_adds--debug:
1641 file_adds--debug: c
1641 file_adds--debug: c
1642 file_adds--debug: b
1642 file_adds--debug: b
1643 file_adds--debug: a
1643 file_adds--debug: a
1644 file_dels: second
1644 file_dels: second
1645 file_dels:
1645 file_dels:
1646 file_dels:
1646 file_dels:
1647 file_dels:
1647 file_dels:
1648 file_dels:
1648 file_dels:
1649 file_dels:
1649 file_dels:
1650 file_dels:
1650 file_dels:
1651 file_dels:
1651 file_dels:
1652 file_dels:
1652 file_dels:
1653 file_dels--verbose: second
1653 file_dels--verbose: second
1654 file_dels--verbose:
1654 file_dels--verbose:
1655 file_dels--verbose:
1655 file_dels--verbose:
1656 file_dels--verbose:
1656 file_dels--verbose:
1657 file_dels--verbose:
1657 file_dels--verbose:
1658 file_dels--verbose:
1658 file_dels--verbose:
1659 file_dels--verbose:
1659 file_dels--verbose:
1660 file_dels--verbose:
1660 file_dels--verbose:
1661 file_dels--verbose:
1661 file_dels--verbose:
1662 file_dels--debug: second
1662 file_dels--debug: second
1663 file_dels--debug:
1663 file_dels--debug:
1664 file_dels--debug:
1664 file_dels--debug:
1665 file_dels--debug:
1665 file_dels--debug:
1666 file_dels--debug:
1666 file_dels--debug:
1667 file_dels--debug:
1667 file_dels--debug:
1668 file_dels--debug:
1668 file_dels--debug:
1669 file_dels--debug:
1669 file_dels--debug:
1670 file_dels--debug:
1670 file_dels--debug:
1671 file_mods:
1671 file_mods:
1672 file_mods:
1672 file_mods:
1673 file_mods:
1673 file_mods:
1674 file_mods:
1674 file_mods:
1675 file_mods:
1675 file_mods:
1676 file_mods: c
1676 file_mods: c
1677 file_mods:
1677 file_mods:
1678 file_mods:
1678 file_mods:
1679 file_mods:
1679 file_mods:
1680 file_mods--verbose:
1680 file_mods--verbose:
1681 file_mods--verbose:
1681 file_mods--verbose:
1682 file_mods--verbose:
1682 file_mods--verbose:
1683 file_mods--verbose:
1683 file_mods--verbose:
1684 file_mods--verbose:
1684 file_mods--verbose:
1685 file_mods--verbose: c
1685 file_mods--verbose: c
1686 file_mods--verbose:
1686 file_mods--verbose:
1687 file_mods--verbose:
1687 file_mods--verbose:
1688 file_mods--verbose:
1688 file_mods--verbose:
1689 file_mods--debug:
1689 file_mods--debug:
1690 file_mods--debug:
1690 file_mods--debug:
1691 file_mods--debug:
1691 file_mods--debug:
1692 file_mods--debug:
1692 file_mods--debug:
1693 file_mods--debug:
1693 file_mods--debug:
1694 file_mods--debug: c
1694 file_mods--debug: c
1695 file_mods--debug:
1695 file_mods--debug:
1696 file_mods--debug:
1696 file_mods--debug:
1697 file_mods--debug:
1697 file_mods--debug:
1698 file_copies: fourth (second)
1698 file_copies: fourth (second)
1699 file_copies:
1699 file_copies:
1700 file_copies:
1700 file_copies:
1701 file_copies:
1701 file_copies:
1702 file_copies:
1702 file_copies:
1703 file_copies:
1703 file_copies:
1704 file_copies:
1704 file_copies:
1705 file_copies:
1705 file_copies:
1706 file_copies:
1706 file_copies:
1707 file_copies--verbose: fourth (second)
1707 file_copies--verbose: fourth (second)
1708 file_copies--verbose:
1708 file_copies--verbose:
1709 file_copies--verbose:
1709 file_copies--verbose:
1710 file_copies--verbose:
1710 file_copies--verbose:
1711 file_copies--verbose:
1711 file_copies--verbose:
1712 file_copies--verbose:
1712 file_copies--verbose:
1713 file_copies--verbose:
1713 file_copies--verbose:
1714 file_copies--verbose:
1714 file_copies--verbose:
1715 file_copies--verbose:
1715 file_copies--verbose:
1716 file_copies--debug: fourth (second)
1716 file_copies--debug: fourth (second)
1717 file_copies--debug:
1717 file_copies--debug:
1718 file_copies--debug:
1718 file_copies--debug:
1719 file_copies--debug:
1719 file_copies--debug:
1720 file_copies--debug:
1720 file_copies--debug:
1721 file_copies--debug:
1721 file_copies--debug:
1722 file_copies--debug:
1722 file_copies--debug:
1723 file_copies--debug:
1723 file_copies--debug:
1724 file_copies--debug:
1724 file_copies--debug:
1725 file_copies_switch:
1725 file_copies_switch:
1726 file_copies_switch:
1726 file_copies_switch:
1727 file_copies_switch:
1727 file_copies_switch:
1728 file_copies_switch:
1728 file_copies_switch:
1729 file_copies_switch:
1729 file_copies_switch:
1730 file_copies_switch:
1730 file_copies_switch:
1731 file_copies_switch:
1731 file_copies_switch:
1732 file_copies_switch:
1732 file_copies_switch:
1733 file_copies_switch:
1733 file_copies_switch:
1734 file_copies_switch--verbose:
1734 file_copies_switch--verbose:
1735 file_copies_switch--verbose:
1735 file_copies_switch--verbose:
1736 file_copies_switch--verbose:
1736 file_copies_switch--verbose:
1737 file_copies_switch--verbose:
1737 file_copies_switch--verbose:
1738 file_copies_switch--verbose:
1738 file_copies_switch--verbose:
1739 file_copies_switch--verbose:
1739 file_copies_switch--verbose:
1740 file_copies_switch--verbose:
1740 file_copies_switch--verbose:
1741 file_copies_switch--verbose:
1741 file_copies_switch--verbose:
1742 file_copies_switch--verbose:
1742 file_copies_switch--verbose:
1743 file_copies_switch--debug:
1743 file_copies_switch--debug:
1744 file_copies_switch--debug:
1744 file_copies_switch--debug:
1745 file_copies_switch--debug:
1745 file_copies_switch--debug:
1746 file_copies_switch--debug:
1746 file_copies_switch--debug:
1747 file_copies_switch--debug:
1747 file_copies_switch--debug:
1748 file_copies_switch--debug:
1748 file_copies_switch--debug:
1749 file_copies_switch--debug:
1749 file_copies_switch--debug:
1750 file_copies_switch--debug:
1750 file_copies_switch--debug:
1751 file_copies_switch--debug:
1751 file_copies_switch--debug:
1752 files: fourth second third
1752 files: fourth second third
1753 files: second
1753 files: second
1754 files:
1754 files:
1755 files: d
1755 files: d
1756 files:
1756 files:
1757 files: c
1757 files: c
1758 files: c
1758 files: c
1759 files: b
1759 files: b
1760 files: a
1760 files: a
1761 files--verbose: fourth second third
1761 files--verbose: fourth second third
1762 files--verbose: second
1762 files--verbose: second
1763 files--verbose:
1763 files--verbose:
1764 files--verbose: d
1764 files--verbose: d
1765 files--verbose:
1765 files--verbose:
1766 files--verbose: c
1766 files--verbose: c
1767 files--verbose: c
1767 files--verbose: c
1768 files--verbose: b
1768 files--verbose: b
1769 files--verbose: a
1769 files--verbose: a
1770 files--debug: fourth second third
1770 files--debug: fourth second third
1771 files--debug: second
1771 files--debug: second
1772 files--debug:
1772 files--debug:
1773 files--debug: d
1773 files--debug: d
1774 files--debug:
1774 files--debug:
1775 files--debug: c
1775 files--debug: c
1776 files--debug: c
1776 files--debug: c
1777 files--debug: b
1777 files--debug: b
1778 files--debug: a
1778 files--debug: a
1779 manifest: 6:94961b75a2da
1779 manifest: 6:94961b75a2da
1780 manifest: 5:f2dbc354b94e
1780 manifest: 5:f2dbc354b94e
1781 manifest: 4:4dc3def4f9b4
1781 manifest: 4:4dc3def4f9b4
1782 manifest: 4:4dc3def4f9b4
1782 manifest: 4:4dc3def4f9b4
1783 manifest: 3:cb5a1327723b
1783 manifest: 3:cb5a1327723b
1784 manifest: 3:cb5a1327723b
1784 manifest: 3:cb5a1327723b
1785 manifest: 2:6e0e82995c35
1785 manifest: 2:6e0e82995c35
1786 manifest: 1:4e8d705b1e53
1786 manifest: 1:4e8d705b1e53
1787 manifest: 0:a0c8bcbbb45c
1787 manifest: 0:a0c8bcbbb45c
1788 manifest--verbose: 6:94961b75a2da
1788 manifest--verbose: 6:94961b75a2da
1789 manifest--verbose: 5:f2dbc354b94e
1789 manifest--verbose: 5:f2dbc354b94e
1790 manifest--verbose: 4:4dc3def4f9b4
1790 manifest--verbose: 4:4dc3def4f9b4
1791 manifest--verbose: 4:4dc3def4f9b4
1791 manifest--verbose: 4:4dc3def4f9b4
1792 manifest--verbose: 3:cb5a1327723b
1792 manifest--verbose: 3:cb5a1327723b
1793 manifest--verbose: 3:cb5a1327723b
1793 manifest--verbose: 3:cb5a1327723b
1794 manifest--verbose: 2:6e0e82995c35
1794 manifest--verbose: 2:6e0e82995c35
1795 manifest--verbose: 1:4e8d705b1e53
1795 manifest--verbose: 1:4e8d705b1e53
1796 manifest--verbose: 0:a0c8bcbbb45c
1796 manifest--verbose: 0:a0c8bcbbb45c
1797 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1797 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1798 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1798 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1799 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1799 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1800 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1800 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1801 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1801 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1802 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1802 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1803 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1803 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1804 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1804 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1805 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1805 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1806 node: 95c24699272ef57d062b8bccc32c878bf841784a
1806 node: 95c24699272ef57d062b8bccc32c878bf841784a
1807 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1807 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1808 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1808 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1809 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1809 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1810 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1810 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1811 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1811 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1812 node: 97054abb4ab824450e9164180baf491ae0078465
1812 node: 97054abb4ab824450e9164180baf491ae0078465
1813 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1813 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1814 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1814 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1815 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1815 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1816 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1816 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1817 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1817 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1818 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1818 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1819 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1819 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1820 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1820 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1821 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1821 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1822 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1822 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1823 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1823 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1824 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1824 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1825 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1825 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1826 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1826 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1827 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1827 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1828 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1828 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1829 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1829 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1830 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1830 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1831 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1831 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1832 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1832 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1833 parents:
1833 parents:
1834 parents: -1:000000000000
1834 parents: -1:000000000000
1835 parents: 5:13207e5a10d9 4:bbe44766e73d
1835 parents: 5:13207e5a10d9 4:bbe44766e73d
1836 parents: 3:10e46f2dcbf4
1836 parents: 3:10e46f2dcbf4
1837 parents:
1837 parents:
1838 parents:
1838 parents:
1839 parents:
1839 parents:
1840 parents:
1840 parents:
1841 parents:
1841 parents:
1842 parents--verbose:
1842 parents--verbose:
1843 parents--verbose: -1:000000000000
1843 parents--verbose: -1:000000000000
1844 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1844 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1845 parents--verbose: 3:10e46f2dcbf4
1845 parents--verbose: 3:10e46f2dcbf4
1846 parents--verbose:
1846 parents--verbose:
1847 parents--verbose:
1847 parents--verbose:
1848 parents--verbose:
1848 parents--verbose:
1849 parents--verbose:
1849 parents--verbose:
1850 parents--verbose:
1850 parents--verbose:
1851 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1851 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1852 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1852 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1853 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1853 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1854 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1854 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1855 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1855 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1856 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1856 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1857 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1857 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1858 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1858 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1859 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1859 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1860 rev: 8
1860 rev: 8
1861 rev: 7
1861 rev: 7
1862 rev: 6
1862 rev: 6
1863 rev: 5
1863 rev: 5
1864 rev: 4
1864 rev: 4
1865 rev: 3
1865 rev: 3
1866 rev: 2
1866 rev: 2
1867 rev: 1
1867 rev: 1
1868 rev: 0
1868 rev: 0
1869 rev--verbose: 8
1869 rev--verbose: 8
1870 rev--verbose: 7
1870 rev--verbose: 7
1871 rev--verbose: 6
1871 rev--verbose: 6
1872 rev--verbose: 5
1872 rev--verbose: 5
1873 rev--verbose: 4
1873 rev--verbose: 4
1874 rev--verbose: 3
1874 rev--verbose: 3
1875 rev--verbose: 2
1875 rev--verbose: 2
1876 rev--verbose: 1
1876 rev--verbose: 1
1877 rev--verbose: 0
1877 rev--verbose: 0
1878 rev--debug: 8
1878 rev--debug: 8
1879 rev--debug: 7
1879 rev--debug: 7
1880 rev--debug: 6
1880 rev--debug: 6
1881 rev--debug: 5
1881 rev--debug: 5
1882 rev--debug: 4
1882 rev--debug: 4
1883 rev--debug: 3
1883 rev--debug: 3
1884 rev--debug: 2
1884 rev--debug: 2
1885 rev--debug: 1
1885 rev--debug: 1
1886 rev--debug: 0
1886 rev--debug: 0
1887 tags: tip
1887 tags: tip
1888 tags:
1888 tags:
1889 tags:
1889 tags:
1890 tags:
1890 tags:
1891 tags:
1891 tags:
1892 tags:
1892 tags:
1893 tags:
1893 tags:
1894 tags:
1894 tags:
1895 tags:
1895 tags:
1896 tags--verbose: tip
1896 tags--verbose: tip
1897 tags--verbose:
1897 tags--verbose:
1898 tags--verbose:
1898 tags--verbose:
1899 tags--verbose:
1899 tags--verbose:
1900 tags--verbose:
1900 tags--verbose:
1901 tags--verbose:
1901 tags--verbose:
1902 tags--verbose:
1902 tags--verbose:
1903 tags--verbose:
1903 tags--verbose:
1904 tags--verbose:
1904 tags--verbose:
1905 tags--debug: tip
1905 tags--debug: tip
1906 tags--debug:
1906 tags--debug:
1907 tags--debug:
1907 tags--debug:
1908 tags--debug:
1908 tags--debug:
1909 tags--debug:
1909 tags--debug:
1910 tags--debug:
1910 tags--debug:
1911 tags--debug:
1911 tags--debug:
1912 tags--debug:
1912 tags--debug:
1913 tags--debug:
1913 tags--debug:
1914 diffstat: 3: +2/-1
1914 diffstat: 3: +2/-1
1915 diffstat: 1: +1/-0
1915 diffstat: 1: +1/-0
1916 diffstat: 0: +0/-0
1916 diffstat: 0: +0/-0
1917 diffstat: 1: +1/-0
1917 diffstat: 1: +1/-0
1918 diffstat: 0: +0/-0
1918 diffstat: 0: +0/-0
1919 diffstat: 1: +1/-0
1919 diffstat: 1: +1/-0
1920 diffstat: 1: +4/-0
1920 diffstat: 1: +4/-0
1921 diffstat: 1: +2/-0
1921 diffstat: 1: +2/-0
1922 diffstat: 1: +1/-0
1922 diffstat: 1: +1/-0
1923 diffstat--verbose: 3: +2/-1
1923 diffstat--verbose: 3: +2/-1
1924 diffstat--verbose: 1: +1/-0
1924 diffstat--verbose: 1: +1/-0
1925 diffstat--verbose: 0: +0/-0
1925 diffstat--verbose: 0: +0/-0
1926 diffstat--verbose: 1: +1/-0
1926 diffstat--verbose: 1: +1/-0
1927 diffstat--verbose: 0: +0/-0
1927 diffstat--verbose: 0: +0/-0
1928 diffstat--verbose: 1: +1/-0
1928 diffstat--verbose: 1: +1/-0
1929 diffstat--verbose: 1: +4/-0
1929 diffstat--verbose: 1: +4/-0
1930 diffstat--verbose: 1: +2/-0
1930 diffstat--verbose: 1: +2/-0
1931 diffstat--verbose: 1: +1/-0
1931 diffstat--verbose: 1: +1/-0
1932 diffstat--debug: 3: +2/-1
1932 diffstat--debug: 3: +2/-1
1933 diffstat--debug: 1: +1/-0
1933 diffstat--debug: 1: +1/-0
1934 diffstat--debug: 0: +0/-0
1934 diffstat--debug: 0: +0/-0
1935 diffstat--debug: 1: +1/-0
1935 diffstat--debug: 1: +1/-0
1936 diffstat--debug: 0: +0/-0
1936 diffstat--debug: 0: +0/-0
1937 diffstat--debug: 1: +1/-0
1937 diffstat--debug: 1: +1/-0
1938 diffstat--debug: 1: +4/-0
1938 diffstat--debug: 1: +4/-0
1939 diffstat--debug: 1: +2/-0
1939 diffstat--debug: 1: +2/-0
1940 diffstat--debug: 1: +1/-0
1940 diffstat--debug: 1: +1/-0
1941 extras: branch=default
1941 extras: branch=default
1942 extras: branch=default
1942 extras: branch=default
1943 extras: branch=default
1943 extras: branch=default
1944 extras: branch=default
1944 extras: branch=default
1945 extras: branch=foo
1945 extras: branch=foo
1946 extras: branch=default
1946 extras: branch=default
1947 extras: branch=default
1947 extras: branch=default
1948 extras: branch=default
1948 extras: branch=default
1949 extras: branch=default
1949 extras: branch=default
1950 extras--verbose: branch=default
1950 extras--verbose: branch=default
1951 extras--verbose: branch=default
1951 extras--verbose: branch=default
1952 extras--verbose: branch=default
1952 extras--verbose: branch=default
1953 extras--verbose: branch=default
1953 extras--verbose: branch=default
1954 extras--verbose: branch=foo
1954 extras--verbose: branch=foo
1955 extras--verbose: branch=default
1955 extras--verbose: branch=default
1956 extras--verbose: branch=default
1956 extras--verbose: branch=default
1957 extras--verbose: branch=default
1957 extras--verbose: branch=default
1958 extras--verbose: branch=default
1958 extras--verbose: branch=default
1959 extras--debug: branch=default
1959 extras--debug: branch=default
1960 extras--debug: branch=default
1960 extras--debug: branch=default
1961 extras--debug: branch=default
1961 extras--debug: branch=default
1962 extras--debug: branch=default
1962 extras--debug: branch=default
1963 extras--debug: branch=foo
1963 extras--debug: branch=foo
1964 extras--debug: branch=default
1964 extras--debug: branch=default
1965 extras--debug: branch=default
1965 extras--debug: branch=default
1966 extras--debug: branch=default
1966 extras--debug: branch=default
1967 extras--debug: branch=default
1967 extras--debug: branch=default
1968 p1rev: 7
1968 p1rev: 7
1969 p1rev: -1
1969 p1rev: -1
1970 p1rev: 5
1970 p1rev: 5
1971 p1rev: 3
1971 p1rev: 3
1972 p1rev: 3
1972 p1rev: 3
1973 p1rev: 2
1973 p1rev: 2
1974 p1rev: 1
1974 p1rev: 1
1975 p1rev: 0
1975 p1rev: 0
1976 p1rev: -1
1976 p1rev: -1
1977 p1rev--verbose: 7
1977 p1rev--verbose: 7
1978 p1rev--verbose: -1
1978 p1rev--verbose: -1
1979 p1rev--verbose: 5
1979 p1rev--verbose: 5
1980 p1rev--verbose: 3
1980 p1rev--verbose: 3
1981 p1rev--verbose: 3
1981 p1rev--verbose: 3
1982 p1rev--verbose: 2
1982 p1rev--verbose: 2
1983 p1rev--verbose: 1
1983 p1rev--verbose: 1
1984 p1rev--verbose: 0
1984 p1rev--verbose: 0
1985 p1rev--verbose: -1
1985 p1rev--verbose: -1
1986 p1rev--debug: 7
1986 p1rev--debug: 7
1987 p1rev--debug: -1
1987 p1rev--debug: -1
1988 p1rev--debug: 5
1988 p1rev--debug: 5
1989 p1rev--debug: 3
1989 p1rev--debug: 3
1990 p1rev--debug: 3
1990 p1rev--debug: 3
1991 p1rev--debug: 2
1991 p1rev--debug: 2
1992 p1rev--debug: 1
1992 p1rev--debug: 1
1993 p1rev--debug: 0
1993 p1rev--debug: 0
1994 p1rev--debug: -1
1994 p1rev--debug: -1
1995 p2rev: -1
1995 p2rev: -1
1996 p2rev: -1
1996 p2rev: -1
1997 p2rev: 4
1997 p2rev: 4
1998 p2rev: -1
1998 p2rev: -1
1999 p2rev: -1
1999 p2rev: -1
2000 p2rev: -1
2000 p2rev: -1
2001 p2rev: -1
2001 p2rev: -1
2002 p2rev: -1
2002 p2rev: -1
2003 p2rev: -1
2003 p2rev: -1
2004 p2rev--verbose: -1
2004 p2rev--verbose: -1
2005 p2rev--verbose: -1
2005 p2rev--verbose: -1
2006 p2rev--verbose: 4
2006 p2rev--verbose: 4
2007 p2rev--verbose: -1
2007 p2rev--verbose: -1
2008 p2rev--verbose: -1
2008 p2rev--verbose: -1
2009 p2rev--verbose: -1
2009 p2rev--verbose: -1
2010 p2rev--verbose: -1
2010 p2rev--verbose: -1
2011 p2rev--verbose: -1
2011 p2rev--verbose: -1
2012 p2rev--verbose: -1
2012 p2rev--verbose: -1
2013 p2rev--debug: -1
2013 p2rev--debug: -1
2014 p2rev--debug: -1
2014 p2rev--debug: -1
2015 p2rev--debug: 4
2015 p2rev--debug: 4
2016 p2rev--debug: -1
2016 p2rev--debug: -1
2017 p2rev--debug: -1
2017 p2rev--debug: -1
2018 p2rev--debug: -1
2018 p2rev--debug: -1
2019 p2rev--debug: -1
2019 p2rev--debug: -1
2020 p2rev--debug: -1
2020 p2rev--debug: -1
2021 p2rev--debug: -1
2021 p2rev--debug: -1
2022 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2022 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2023 p1node: 0000000000000000000000000000000000000000
2023 p1node: 0000000000000000000000000000000000000000
2024 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
2024 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
2025 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2025 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2026 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2026 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2027 p1node: 97054abb4ab824450e9164180baf491ae0078465
2027 p1node: 97054abb4ab824450e9164180baf491ae0078465
2028 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2028 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2029 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
2029 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
2030 p1node: 0000000000000000000000000000000000000000
2030 p1node: 0000000000000000000000000000000000000000
2031 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2031 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2032 p1node--verbose: 0000000000000000000000000000000000000000
2032 p1node--verbose: 0000000000000000000000000000000000000000
2033 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
2033 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
2034 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2034 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2035 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2035 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2036 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
2036 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
2037 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2037 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2038 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
2038 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
2039 p1node--verbose: 0000000000000000000000000000000000000000
2039 p1node--verbose: 0000000000000000000000000000000000000000
2040 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2040 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2041 p1node--debug: 0000000000000000000000000000000000000000
2041 p1node--debug: 0000000000000000000000000000000000000000
2042 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
2042 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
2043 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2043 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2044 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2044 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2045 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
2045 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
2046 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2046 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2047 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
2047 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
2048 p1node--debug: 0000000000000000000000000000000000000000
2048 p1node--debug: 0000000000000000000000000000000000000000
2049 p2node: 0000000000000000000000000000000000000000
2049 p2node: 0000000000000000000000000000000000000000
2050 p2node: 0000000000000000000000000000000000000000
2050 p2node: 0000000000000000000000000000000000000000
2051 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2051 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2052 p2node: 0000000000000000000000000000000000000000
2052 p2node: 0000000000000000000000000000000000000000
2053 p2node: 0000000000000000000000000000000000000000
2053 p2node: 0000000000000000000000000000000000000000
2054 p2node: 0000000000000000000000000000000000000000
2054 p2node: 0000000000000000000000000000000000000000
2055 p2node: 0000000000000000000000000000000000000000
2055 p2node: 0000000000000000000000000000000000000000
2056 p2node: 0000000000000000000000000000000000000000
2056 p2node: 0000000000000000000000000000000000000000
2057 p2node: 0000000000000000000000000000000000000000
2057 p2node: 0000000000000000000000000000000000000000
2058 p2node--verbose: 0000000000000000000000000000000000000000
2058 p2node--verbose: 0000000000000000000000000000000000000000
2059 p2node--verbose: 0000000000000000000000000000000000000000
2059 p2node--verbose: 0000000000000000000000000000000000000000
2060 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2060 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2061 p2node--verbose: 0000000000000000000000000000000000000000
2061 p2node--verbose: 0000000000000000000000000000000000000000
2062 p2node--verbose: 0000000000000000000000000000000000000000
2062 p2node--verbose: 0000000000000000000000000000000000000000
2063 p2node--verbose: 0000000000000000000000000000000000000000
2063 p2node--verbose: 0000000000000000000000000000000000000000
2064 p2node--verbose: 0000000000000000000000000000000000000000
2064 p2node--verbose: 0000000000000000000000000000000000000000
2065 p2node--verbose: 0000000000000000000000000000000000000000
2065 p2node--verbose: 0000000000000000000000000000000000000000
2066 p2node--verbose: 0000000000000000000000000000000000000000
2066 p2node--verbose: 0000000000000000000000000000000000000000
2067 p2node--debug: 0000000000000000000000000000000000000000
2067 p2node--debug: 0000000000000000000000000000000000000000
2068 p2node--debug: 0000000000000000000000000000000000000000
2068 p2node--debug: 0000000000000000000000000000000000000000
2069 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2069 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2070 p2node--debug: 0000000000000000000000000000000000000000
2070 p2node--debug: 0000000000000000000000000000000000000000
2071 p2node--debug: 0000000000000000000000000000000000000000
2071 p2node--debug: 0000000000000000000000000000000000000000
2072 p2node--debug: 0000000000000000000000000000000000000000
2072 p2node--debug: 0000000000000000000000000000000000000000
2073 p2node--debug: 0000000000000000000000000000000000000000
2073 p2node--debug: 0000000000000000000000000000000000000000
2074 p2node--debug: 0000000000000000000000000000000000000000
2074 p2node--debug: 0000000000000000000000000000000000000000
2075 p2node--debug: 0000000000000000000000000000000000000000
2075 p2node--debug: 0000000000000000000000000000000000000000
2076
2076
2077 Filters work:
2077 Filters work:
2078
2078
2079 $ hg log --template '{author|domain}\n'
2079 $ hg log --template '{author|domain}\n'
2080
2080
2081 hostname
2081 hostname
2082
2082
2083
2083
2084
2084
2085
2085
2086 place
2086 place
2087 place
2087 place
2088 hostname
2088 hostname
2089
2089
2090 $ hg log --template '{author|person}\n'
2090 $ hg log --template '{author|person}\n'
2091 test
2091 test
2092 User Name
2092 User Name
2093 person
2093 person
2094 person
2094 person
2095 person
2095 person
2096 person
2096 person
2097 other
2097 other
2098 A. N. Other
2098 A. N. Other
2099 User Name
2099 User Name
2100
2100
2101 $ hg log --template '{author|user}\n'
2101 $ hg log --template '{author|user}\n'
2102 test
2102 test
2103 user
2103 user
2104 person
2104 person
2105 person
2105 person
2106 person
2106 person
2107 person
2107 person
2108 other
2108 other
2109 other
2109 other
2110 user
2110 user
2111
2111
2112 $ hg log --template '{date|date}\n'
2112 $ hg log --template '{date|date}\n'
2113 Wed Jan 01 10:01:00 2020 +0000
2113 Wed Jan 01 10:01:00 2020 +0000
2114 Mon Jan 12 13:46:40 1970 +0000
2114 Mon Jan 12 13:46:40 1970 +0000
2115 Sun Jan 18 08:40:01 1970 +0000
2115 Sun Jan 18 08:40:01 1970 +0000
2116 Sun Jan 18 08:40:00 1970 +0000
2116 Sun Jan 18 08:40:00 1970 +0000
2117 Sat Jan 17 04:53:20 1970 +0000
2117 Sat Jan 17 04:53:20 1970 +0000
2118 Fri Jan 16 01:06:40 1970 +0000
2118 Fri Jan 16 01:06:40 1970 +0000
2119 Wed Jan 14 21:20:00 1970 +0000
2119 Wed Jan 14 21:20:00 1970 +0000
2120 Tue Jan 13 17:33:20 1970 +0000
2120 Tue Jan 13 17:33:20 1970 +0000
2121 Mon Jan 12 13:46:40 1970 +0000
2121 Mon Jan 12 13:46:40 1970 +0000
2122
2122
2123 $ hg log --template '{date|isodate}\n'
2123 $ hg log --template '{date|isodate}\n'
2124 2020-01-01 10:01 +0000
2124 2020-01-01 10:01 +0000
2125 1970-01-12 13:46 +0000
2125 1970-01-12 13:46 +0000
2126 1970-01-18 08:40 +0000
2126 1970-01-18 08:40 +0000
2127 1970-01-18 08:40 +0000
2127 1970-01-18 08:40 +0000
2128 1970-01-17 04:53 +0000
2128 1970-01-17 04:53 +0000
2129 1970-01-16 01:06 +0000
2129 1970-01-16 01:06 +0000
2130 1970-01-14 21:20 +0000
2130 1970-01-14 21:20 +0000
2131 1970-01-13 17:33 +0000
2131 1970-01-13 17:33 +0000
2132 1970-01-12 13:46 +0000
2132 1970-01-12 13:46 +0000
2133
2133
2134 $ hg log --template '{date|isodatesec}\n'
2134 $ hg log --template '{date|isodatesec}\n'
2135 2020-01-01 10:01:00 +0000
2135 2020-01-01 10:01:00 +0000
2136 1970-01-12 13:46:40 +0000
2136 1970-01-12 13:46:40 +0000
2137 1970-01-18 08:40:01 +0000
2137 1970-01-18 08:40:01 +0000
2138 1970-01-18 08:40:00 +0000
2138 1970-01-18 08:40:00 +0000
2139 1970-01-17 04:53:20 +0000
2139 1970-01-17 04:53:20 +0000
2140 1970-01-16 01:06:40 +0000
2140 1970-01-16 01:06:40 +0000
2141 1970-01-14 21:20:00 +0000
2141 1970-01-14 21:20:00 +0000
2142 1970-01-13 17:33:20 +0000
2142 1970-01-13 17:33:20 +0000
2143 1970-01-12 13:46:40 +0000
2143 1970-01-12 13:46:40 +0000
2144
2144
2145 $ hg log --template '{date|rfc822date}\n'
2145 $ hg log --template '{date|rfc822date}\n'
2146 Wed, 01 Jan 2020 10:01:00 +0000
2146 Wed, 01 Jan 2020 10:01:00 +0000
2147 Mon, 12 Jan 1970 13:46:40 +0000
2147 Mon, 12 Jan 1970 13:46:40 +0000
2148 Sun, 18 Jan 1970 08:40:01 +0000
2148 Sun, 18 Jan 1970 08:40:01 +0000
2149 Sun, 18 Jan 1970 08:40:00 +0000
2149 Sun, 18 Jan 1970 08:40:00 +0000
2150 Sat, 17 Jan 1970 04:53:20 +0000
2150 Sat, 17 Jan 1970 04:53:20 +0000
2151 Fri, 16 Jan 1970 01:06:40 +0000
2151 Fri, 16 Jan 1970 01:06:40 +0000
2152 Wed, 14 Jan 1970 21:20:00 +0000
2152 Wed, 14 Jan 1970 21:20:00 +0000
2153 Tue, 13 Jan 1970 17:33:20 +0000
2153 Tue, 13 Jan 1970 17:33:20 +0000
2154 Mon, 12 Jan 1970 13:46:40 +0000
2154 Mon, 12 Jan 1970 13:46:40 +0000
2155
2155
2156 $ hg log --template '{desc|firstline}\n'
2156 $ hg log --template '{desc|firstline}\n'
2157 third
2157 third
2158 second
2158 second
2159 merge
2159 merge
2160 new head
2160 new head
2161 new branch
2161 new branch
2162 no user, no domain
2162 no user, no domain
2163 no person
2163 no person
2164 other 1
2164 other 1
2165 line 1
2165 line 1
2166
2166
2167 $ hg log --template '{node|short}\n'
2167 $ hg log --template '{node|short}\n'
2168 95c24699272e
2168 95c24699272e
2169 29114dbae42b
2169 29114dbae42b
2170 d41e714fe50d
2170 d41e714fe50d
2171 13207e5a10d9
2171 13207e5a10d9
2172 bbe44766e73d
2172 bbe44766e73d
2173 10e46f2dcbf4
2173 10e46f2dcbf4
2174 97054abb4ab8
2174 97054abb4ab8
2175 b608e9d1a3f0
2175 b608e9d1a3f0
2176 1e4e1b8f71e0
2176 1e4e1b8f71e0
2177
2177
2178 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
2178 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
2179 <changeset author="test"/>
2179 <changeset author="test"/>
2180 <changeset author="User Name &lt;user@hostname&gt;"/>
2180 <changeset author="User Name &lt;user@hostname&gt;"/>
2181 <changeset author="person"/>
2181 <changeset author="person"/>
2182 <changeset author="person"/>
2182 <changeset author="person"/>
2183 <changeset author="person"/>
2183 <changeset author="person"/>
2184 <changeset author="person"/>
2184 <changeset author="person"/>
2185 <changeset author="other@place"/>
2185 <changeset author="other@place"/>
2186 <changeset author="A. N. Other &lt;other@place&gt;"/>
2186 <changeset author="A. N. Other &lt;other@place&gt;"/>
2187 <changeset author="User Name &lt;user@hostname&gt;"/>
2187 <changeset author="User Name &lt;user@hostname&gt;"/>
2188
2188
2189 $ hg log --template '{rev}: {children}\n'
2189 $ hg log --template '{rev}: {children}\n'
2190 8:
2190 8:
2191 7: 8:95c24699272e
2191 7: 8:95c24699272e
2192 6:
2192 6:
2193 5: 6:d41e714fe50d
2193 5: 6:d41e714fe50d
2194 4: 6:d41e714fe50d
2194 4: 6:d41e714fe50d
2195 3: 4:bbe44766e73d 5:13207e5a10d9
2195 3: 4:bbe44766e73d 5:13207e5a10d9
2196 2: 3:10e46f2dcbf4
2196 2: 3:10e46f2dcbf4
2197 1: 2:97054abb4ab8
2197 1: 2:97054abb4ab8
2198 0: 1:b608e9d1a3f0
2198 0: 1:b608e9d1a3f0
2199
2199
2200 Formatnode filter works:
2200 Formatnode filter works:
2201
2201
2202 $ hg -q log -r 0 --template '{node|formatnode}\n'
2202 $ hg -q log -r 0 --template '{node|formatnode}\n'
2203 1e4e1b8f71e0
2203 1e4e1b8f71e0
2204
2204
2205 $ hg log -r 0 --template '{node|formatnode}\n'
2205 $ hg log -r 0 --template '{node|formatnode}\n'
2206 1e4e1b8f71e0
2206 1e4e1b8f71e0
2207
2207
2208 $ hg -v log -r 0 --template '{node|formatnode}\n'
2208 $ hg -v log -r 0 --template '{node|formatnode}\n'
2209 1e4e1b8f71e0
2209 1e4e1b8f71e0
2210
2210
2211 $ hg --debug log -r 0 --template '{node|formatnode}\n'
2211 $ hg --debug log -r 0 --template '{node|formatnode}\n'
2212 1e4e1b8f71e05681d422154f5421e385fec3454f
2212 1e4e1b8f71e05681d422154f5421e385fec3454f
2213
2213
2214 Age filter:
2214 Age filter:
2215
2215
2216 $ hg init unstable-hash
2216 $ hg init unstable-hash
2217 $ cd unstable-hash
2217 $ cd unstable-hash
2218 $ hg log --template '{date|age}\n' > /dev/null || exit 1
2218 $ hg log --template '{date|age}\n' > /dev/null || exit 1
2219
2219
2220 >>> from __future__ import absolute_import
2220 >>> from __future__ import absolute_import
2221 >>> import datetime
2221 >>> import datetime
2222 >>> fp = open('a', 'wb')
2222 >>> fp = open('a', 'wb')
2223 >>> n = datetime.datetime.now() + datetime.timedelta(366 * 7)
2223 >>> n = datetime.datetime.now() + datetime.timedelta(366 * 7)
2224 >>> fp.write(b'%d-%d-%d 00:00' % (n.year, n.month, n.day)) and None
2224 >>> fp.write(b'%d-%d-%d 00:00' % (n.year, n.month, n.day)) and None
2225 >>> fp.close()
2225 >>> fp.close()
2226 $ hg add a
2226 $ hg add a
2227 $ hg commit -m future -d "`cat a`"
2227 $ hg commit -m future -d "`cat a`"
2228
2228
2229 $ hg log -l1 --template '{date|age}\n'
2229 $ hg log -l1 --template '{date|age}\n'
2230 7 years from now
2230 7 years from now
2231
2231
2232 $ cd ..
2232 $ cd ..
2233 $ rm -rf unstable-hash
2233 $ rm -rf unstable-hash
2234
2234
2235 Filename filters:
2235 Filename filters:
2236
2236
2237 $ hg debugtemplate '{"foo/bar"|basename}|{"foo/"|basename}|{"foo"|basename}|\n'
2237 $ hg debugtemplate '{"foo/bar"|basename}|{"foo/"|basename}|{"foo"|basename}|\n'
2238 bar||foo|
2238 bar||foo|
2239 $ hg debugtemplate '{"foo/bar"|dirname}|{"foo/"|dirname}|{"foo"|dirname}|\n'
2239 $ hg debugtemplate '{"foo/bar"|dirname}|{"foo/"|dirname}|{"foo"|dirname}|\n'
2240 foo|foo||
2240 foo|foo||
2241 $ hg debugtemplate '{"foo/bar"|stripdir}|{"foo/"|stripdir}|{"foo"|stripdir}|\n'
2241 $ hg debugtemplate '{"foo/bar"|stripdir}|{"foo/"|stripdir}|{"foo"|stripdir}|\n'
2242 foo|foo|foo|
2242 foo|foo|foo|
2243
2243
2244 Add a dummy commit to make up for the instability of the above:
2244 Add a dummy commit to make up for the instability of the above:
2245
2245
2246 $ echo a > a
2246 $ echo a > a
2247 $ hg add a
2247 $ hg add a
2248 $ hg ci -m future
2248 $ hg ci -m future
2249
2249
2250 Count filter:
2250 Count filter:
2251
2251
2252 $ hg log -l1 --template '{node|count} {node|short|count}\n'
2252 $ hg log -l1 --template '{node|count} {node|short|count}\n'
2253 40 12
2253 40 12
2254
2254
2255 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
2255 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
2256 0 1 4
2256 0 1 4
2257
2257
2258 $ hg log -G --template '{rev}: children: {children|count}, \
2258 $ hg log -G --template '{rev}: children: {children|count}, \
2259 > tags: {tags|count}, file_adds: {file_adds|count}, \
2259 > tags: {tags|count}, file_adds: {file_adds|count}, \
2260 > ancestors: {revset("ancestors(%s)", rev)|count}'
2260 > ancestors: {revset("ancestors(%s)", rev)|count}'
2261 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
2261 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
2262 |
2262 |
2263 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
2263 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
2264 |
2264 |
2265 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
2265 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
2266
2266
2267 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
2267 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
2268 |\
2268 |\
2269 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
2269 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
2270 | |
2270 | |
2271 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
2271 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
2272 |/
2272 |/
2273 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
2273 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
2274 |
2274 |
2275 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
2275 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
2276 |
2276 |
2277 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
2277 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
2278 |
2278 |
2279 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
2279 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
2280
2280
2281
2281
2282 $ hg log -l1 -T '{termwidth|count}\n'
2282 $ hg log -l1 -T '{termwidth|count}\n'
2283 hg: parse error: not countable
2283 hg: parse error: not countable
2284 (template filter 'count' is not compatible with keyword 'termwidth')
2284 (template filter 'count' is not compatible with keyword 'termwidth')
2285 [255]
2285 [255]
2286
2286
2287 Upper/lower filters:
2287 Upper/lower filters:
2288
2288
2289 $ hg log -r0 --template '{branch|upper}\n'
2289 $ hg log -r0 --template '{branch|upper}\n'
2290 DEFAULT
2290 DEFAULT
2291 $ hg log -r0 --template '{author|lower}\n'
2291 $ hg log -r0 --template '{author|lower}\n'
2292 user name <user@hostname>
2292 user name <user@hostname>
2293 $ hg log -r0 --template '{date|upper}\n'
2293 $ hg log -r0 --template '{date|upper}\n'
2294 1000000.00
2294 1000000.00
2295
2295
2296 Add a commit that does all possible modifications at once
2296 Add a commit that does all possible modifications at once
2297
2297
2298 $ echo modify >> third
2298 $ echo modify >> third
2299 $ touch b
2299 $ touch b
2300 $ hg add b
2300 $ hg add b
2301 $ hg mv fourth fifth
2301 $ hg mv fourth fifth
2302 $ hg rm a
2302 $ hg rm a
2303 $ hg ci -m "Modify, add, remove, rename"
2303 $ hg ci -m "Modify, add, remove, rename"
2304
2304
2305 Check the status template
2305 Check the status template
2306
2306
2307 $ cat <<EOF >> $HGRCPATH
2307 $ cat <<EOF >> $HGRCPATH
2308 > [extensions]
2308 > [extensions]
2309 > color=
2309 > color=
2310 > EOF
2310 > EOF
2311
2311
2312 $ hg log -T status -r 10
2312 $ hg log -T status -r 10
2313 changeset: 10:0f9759ec227a
2313 changeset: 10:0f9759ec227a
2314 tag: tip
2314 tag: tip
2315 user: test
2315 user: test
2316 date: Thu Jan 01 00:00:00 1970 +0000
2316 date: Thu Jan 01 00:00:00 1970 +0000
2317 summary: Modify, add, remove, rename
2317 summary: Modify, add, remove, rename
2318 files:
2318 files:
2319 M third
2319 M third
2320 A b
2320 A b
2321 A fifth
2321 A fifth
2322 R a
2322 R a
2323 R fourth
2323 R fourth
2324
2324
2325 $ hg log -T status -C -r 10
2325 $ hg log -T status -C -r 10
2326 changeset: 10:0f9759ec227a
2326 changeset: 10:0f9759ec227a
2327 tag: tip
2327 tag: tip
2328 user: test
2328 user: test
2329 date: Thu Jan 01 00:00:00 1970 +0000
2329 date: Thu Jan 01 00:00:00 1970 +0000
2330 summary: Modify, add, remove, rename
2330 summary: Modify, add, remove, rename
2331 files:
2331 files:
2332 M third
2332 M third
2333 A b
2333 A b
2334 A fifth
2334 A fifth
2335 fourth
2335 fourth
2336 R a
2336 R a
2337 R fourth
2337 R fourth
2338
2338
2339 $ hg log -T status -C -r 10 -v
2339 $ hg log -T status -C -r 10 -v
2340 changeset: 10:0f9759ec227a
2340 changeset: 10:0f9759ec227a
2341 tag: tip
2341 tag: tip
2342 user: test
2342 user: test
2343 date: Thu Jan 01 00:00:00 1970 +0000
2343 date: Thu Jan 01 00:00:00 1970 +0000
2344 description:
2344 description:
2345 Modify, add, remove, rename
2345 Modify, add, remove, rename
2346
2346
2347 files:
2347 files:
2348 M third
2348 M third
2349 A b
2349 A b
2350 A fifth
2350 A fifth
2351 fourth
2351 fourth
2352 R a
2352 R a
2353 R fourth
2353 R fourth
2354
2354
2355 $ hg log -T status -C -r 10 --debug
2355 $ hg log -T status -C -r 10 --debug
2356 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2356 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2357 tag: tip
2357 tag: tip
2358 phase: secret
2358 phase: secret
2359 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2359 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2360 parent: -1:0000000000000000000000000000000000000000
2360 parent: -1:0000000000000000000000000000000000000000
2361 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2361 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2362 user: test
2362 user: test
2363 date: Thu Jan 01 00:00:00 1970 +0000
2363 date: Thu Jan 01 00:00:00 1970 +0000
2364 extra: branch=default
2364 extra: branch=default
2365 description:
2365 description:
2366 Modify, add, remove, rename
2366 Modify, add, remove, rename
2367
2367
2368 files:
2368 files:
2369 M third
2369 M third
2370 A b
2370 A b
2371 A fifth
2371 A fifth
2372 fourth
2372 fourth
2373 R a
2373 R a
2374 R fourth
2374 R fourth
2375
2375
2376 $ hg log -T status -C -r 10 --quiet
2376 $ hg log -T status -C -r 10 --quiet
2377 10:0f9759ec227a
2377 10:0f9759ec227a
2378 $ hg --color=debug log -T status -r 10
2378 $ hg --color=debug log -T status -r 10
2379 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2379 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2380 [log.tag|tag: tip]
2380 [log.tag|tag: tip]
2381 [log.user|user: test]
2381 [log.user|user: test]
2382 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2382 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2383 [log.summary|summary: Modify, add, remove, rename]
2383 [log.summary|summary: Modify, add, remove, rename]
2384 [ui.note log.files|files:]
2384 [ui.note log.files|files:]
2385 [status.modified|M third]
2385 [status.modified|M third]
2386 [status.added|A b]
2386 [status.added|A b]
2387 [status.added|A fifth]
2387 [status.added|A fifth]
2388 [status.removed|R a]
2388 [status.removed|R a]
2389 [status.removed|R fourth]
2389 [status.removed|R fourth]
2390
2390
2391 $ hg --color=debug log -T status -C -r 10
2391 $ hg --color=debug log -T status -C -r 10
2392 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2392 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2393 [log.tag|tag: tip]
2393 [log.tag|tag: tip]
2394 [log.user|user: test]
2394 [log.user|user: test]
2395 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2395 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2396 [log.summary|summary: Modify, add, remove, rename]
2396 [log.summary|summary: Modify, add, remove, rename]
2397 [ui.note log.files|files:]
2397 [ui.note log.files|files:]
2398 [status.modified|M third]
2398 [status.modified|M third]
2399 [status.added|A b]
2399 [status.added|A b]
2400 [status.added|A fifth]
2400 [status.added|A fifth]
2401 [status.copied| fourth]
2401 [status.copied| fourth]
2402 [status.removed|R a]
2402 [status.removed|R a]
2403 [status.removed|R fourth]
2403 [status.removed|R fourth]
2404
2404
2405 $ hg --color=debug log -T status -C -r 10 -v
2405 $ hg --color=debug log -T status -C -r 10 -v
2406 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2406 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2407 [log.tag|tag: tip]
2407 [log.tag|tag: tip]
2408 [log.user|user: test]
2408 [log.user|user: test]
2409 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2409 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2410 [ui.note log.description|description:]
2410 [ui.note log.description|description:]
2411 [ui.note log.description|Modify, add, remove, rename]
2411 [ui.note log.description|Modify, add, remove, rename]
2412
2412
2413 [ui.note log.files|files:]
2413 [ui.note log.files|files:]
2414 [status.modified|M third]
2414 [status.modified|M third]
2415 [status.added|A b]
2415 [status.added|A b]
2416 [status.added|A fifth]
2416 [status.added|A fifth]
2417 [status.copied| fourth]
2417 [status.copied| fourth]
2418 [status.removed|R a]
2418 [status.removed|R a]
2419 [status.removed|R fourth]
2419 [status.removed|R fourth]
2420
2420
2421 $ hg --color=debug log -T status -C -r 10 --debug
2421 $ hg --color=debug log -T status -C -r 10 --debug
2422 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2422 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2423 [log.tag|tag: tip]
2423 [log.tag|tag: tip]
2424 [log.phase|phase: secret]
2424 [log.phase|phase: secret]
2425 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2425 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2426 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2426 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2427 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2427 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2428 [log.user|user: test]
2428 [log.user|user: test]
2429 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2429 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2430 [ui.debug log.extra|extra: branch=default]
2430 [ui.debug log.extra|extra: branch=default]
2431 [ui.note log.description|description:]
2431 [ui.note log.description|description:]
2432 [ui.note log.description|Modify, add, remove, rename]
2432 [ui.note log.description|Modify, add, remove, rename]
2433
2433
2434 [ui.note log.files|files:]
2434 [ui.note log.files|files:]
2435 [status.modified|M third]
2435 [status.modified|M third]
2436 [status.added|A b]
2436 [status.added|A b]
2437 [status.added|A fifth]
2437 [status.added|A fifth]
2438 [status.copied| fourth]
2438 [status.copied| fourth]
2439 [status.removed|R a]
2439 [status.removed|R a]
2440 [status.removed|R fourth]
2440 [status.removed|R fourth]
2441
2441
2442 $ hg --color=debug log -T status -C -r 10 --quiet
2442 $ hg --color=debug log -T status -C -r 10 --quiet
2443 [log.node|10:0f9759ec227a]
2443 [log.node|10:0f9759ec227a]
2444
2444
2445 Check the bisect template
2445 Check the bisect template
2446
2446
2447 $ hg bisect -g 1
2447 $ hg bisect -g 1
2448 $ hg bisect -b 3 --noupdate
2448 $ hg bisect -b 3 --noupdate
2449 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2449 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2450 $ hg log -T bisect -r 0:4
2450 $ hg log -T bisect -r 0:4
2451 changeset: 0:1e4e1b8f71e0
2451 changeset: 0:1e4e1b8f71e0
2452 bisect: good (implicit)
2452 bisect: good (implicit)
2453 user: User Name <user@hostname>
2453 user: User Name <user@hostname>
2454 date: Mon Jan 12 13:46:40 1970 +0000
2454 date: Mon Jan 12 13:46:40 1970 +0000
2455 summary: line 1
2455 summary: line 1
2456
2456
2457 changeset: 1:b608e9d1a3f0
2457 changeset: 1:b608e9d1a3f0
2458 bisect: good
2458 bisect: good
2459 user: A. N. Other <other@place>
2459 user: A. N. Other <other@place>
2460 date: Tue Jan 13 17:33:20 1970 +0000
2460 date: Tue Jan 13 17:33:20 1970 +0000
2461 summary: other 1
2461 summary: other 1
2462
2462
2463 changeset: 2:97054abb4ab8
2463 changeset: 2:97054abb4ab8
2464 bisect: untested
2464 bisect: untested
2465 user: other@place
2465 user: other@place
2466 date: Wed Jan 14 21:20:00 1970 +0000
2466 date: Wed Jan 14 21:20:00 1970 +0000
2467 summary: no person
2467 summary: no person
2468
2468
2469 changeset: 3:10e46f2dcbf4
2469 changeset: 3:10e46f2dcbf4
2470 bisect: bad
2470 bisect: bad
2471 user: person
2471 user: person
2472 date: Fri Jan 16 01:06:40 1970 +0000
2472 date: Fri Jan 16 01:06:40 1970 +0000
2473 summary: no user, no domain
2473 summary: no user, no domain
2474
2474
2475 changeset: 4:bbe44766e73d
2475 changeset: 4:bbe44766e73d
2476 bisect: bad (implicit)
2476 bisect: bad (implicit)
2477 branch: foo
2477 branch: foo
2478 user: person
2478 user: person
2479 date: Sat Jan 17 04:53:20 1970 +0000
2479 date: Sat Jan 17 04:53:20 1970 +0000
2480 summary: new branch
2480 summary: new branch
2481
2481
2482 $ hg log --debug -T bisect -r 0:4
2482 $ hg log --debug -T bisect -r 0:4
2483 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2483 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2484 bisect: good (implicit)
2484 bisect: good (implicit)
2485 phase: public
2485 phase: public
2486 parent: -1:0000000000000000000000000000000000000000
2486 parent: -1:0000000000000000000000000000000000000000
2487 parent: -1:0000000000000000000000000000000000000000
2487 parent: -1:0000000000000000000000000000000000000000
2488 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2488 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2489 user: User Name <user@hostname>
2489 user: User Name <user@hostname>
2490 date: Mon Jan 12 13:46:40 1970 +0000
2490 date: Mon Jan 12 13:46:40 1970 +0000
2491 files+: a
2491 files+: a
2492 extra: branch=default
2492 extra: branch=default
2493 description:
2493 description:
2494 line 1
2494 line 1
2495 line 2
2495 line 2
2496
2496
2497
2497
2498 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2498 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2499 bisect: good
2499 bisect: good
2500 phase: public
2500 phase: public
2501 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2501 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2502 parent: -1:0000000000000000000000000000000000000000
2502 parent: -1:0000000000000000000000000000000000000000
2503 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2503 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2504 user: A. N. Other <other@place>
2504 user: A. N. Other <other@place>
2505 date: Tue Jan 13 17:33:20 1970 +0000
2505 date: Tue Jan 13 17:33:20 1970 +0000
2506 files+: b
2506 files+: b
2507 extra: branch=default
2507 extra: branch=default
2508 description:
2508 description:
2509 other 1
2509 other 1
2510 other 2
2510 other 2
2511
2511
2512 other 3
2512 other 3
2513
2513
2514
2514
2515 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2515 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2516 bisect: untested
2516 bisect: untested
2517 phase: public
2517 phase: public
2518 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2518 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2519 parent: -1:0000000000000000000000000000000000000000
2519 parent: -1:0000000000000000000000000000000000000000
2520 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2520 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2521 user: other@place
2521 user: other@place
2522 date: Wed Jan 14 21:20:00 1970 +0000
2522 date: Wed Jan 14 21:20:00 1970 +0000
2523 files+: c
2523 files+: c
2524 extra: branch=default
2524 extra: branch=default
2525 description:
2525 description:
2526 no person
2526 no person
2527
2527
2528
2528
2529 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2529 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2530 bisect: bad
2530 bisect: bad
2531 phase: public
2531 phase: public
2532 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2532 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2533 parent: -1:0000000000000000000000000000000000000000
2533 parent: -1:0000000000000000000000000000000000000000
2534 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2534 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2535 user: person
2535 user: person
2536 date: Fri Jan 16 01:06:40 1970 +0000
2536 date: Fri Jan 16 01:06:40 1970 +0000
2537 files: c
2537 files: c
2538 extra: branch=default
2538 extra: branch=default
2539 description:
2539 description:
2540 no user, no domain
2540 no user, no domain
2541
2541
2542
2542
2543 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2543 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2544 bisect: bad (implicit)
2544 bisect: bad (implicit)
2545 branch: foo
2545 branch: foo
2546 phase: draft
2546 phase: draft
2547 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2547 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2548 parent: -1:0000000000000000000000000000000000000000
2548 parent: -1:0000000000000000000000000000000000000000
2549 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2549 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2550 user: person
2550 user: person
2551 date: Sat Jan 17 04:53:20 1970 +0000
2551 date: Sat Jan 17 04:53:20 1970 +0000
2552 extra: branch=foo
2552 extra: branch=foo
2553 description:
2553 description:
2554 new branch
2554 new branch
2555
2555
2556
2556
2557 $ hg log -v -T bisect -r 0:4
2557 $ hg log -v -T bisect -r 0:4
2558 changeset: 0:1e4e1b8f71e0
2558 changeset: 0:1e4e1b8f71e0
2559 bisect: good (implicit)
2559 bisect: good (implicit)
2560 user: User Name <user@hostname>
2560 user: User Name <user@hostname>
2561 date: Mon Jan 12 13:46:40 1970 +0000
2561 date: Mon Jan 12 13:46:40 1970 +0000
2562 files: a
2562 files: a
2563 description:
2563 description:
2564 line 1
2564 line 1
2565 line 2
2565 line 2
2566
2566
2567
2567
2568 changeset: 1:b608e9d1a3f0
2568 changeset: 1:b608e9d1a3f0
2569 bisect: good
2569 bisect: good
2570 user: A. N. Other <other@place>
2570 user: A. N. Other <other@place>
2571 date: Tue Jan 13 17:33:20 1970 +0000
2571 date: Tue Jan 13 17:33:20 1970 +0000
2572 files: b
2572 files: b
2573 description:
2573 description:
2574 other 1
2574 other 1
2575 other 2
2575 other 2
2576
2576
2577 other 3
2577 other 3
2578
2578
2579
2579
2580 changeset: 2:97054abb4ab8
2580 changeset: 2:97054abb4ab8
2581 bisect: untested
2581 bisect: untested
2582 user: other@place
2582 user: other@place
2583 date: Wed Jan 14 21:20:00 1970 +0000
2583 date: Wed Jan 14 21:20:00 1970 +0000
2584 files: c
2584 files: c
2585 description:
2585 description:
2586 no person
2586 no person
2587
2587
2588
2588
2589 changeset: 3:10e46f2dcbf4
2589 changeset: 3:10e46f2dcbf4
2590 bisect: bad
2590 bisect: bad
2591 user: person
2591 user: person
2592 date: Fri Jan 16 01:06:40 1970 +0000
2592 date: Fri Jan 16 01:06:40 1970 +0000
2593 files: c
2593 files: c
2594 description:
2594 description:
2595 no user, no domain
2595 no user, no domain
2596
2596
2597
2597
2598 changeset: 4:bbe44766e73d
2598 changeset: 4:bbe44766e73d
2599 bisect: bad (implicit)
2599 bisect: bad (implicit)
2600 branch: foo
2600 branch: foo
2601 user: person
2601 user: person
2602 date: Sat Jan 17 04:53:20 1970 +0000
2602 date: Sat Jan 17 04:53:20 1970 +0000
2603 description:
2603 description:
2604 new branch
2604 new branch
2605
2605
2606
2606
2607 $ hg --color=debug log -T bisect -r 0:4
2607 $ hg --color=debug log -T bisect -r 0:4
2608 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2608 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2609 [log.bisect bisect.good|bisect: good (implicit)]
2609 [log.bisect bisect.good|bisect: good (implicit)]
2610 [log.user|user: User Name <user@hostname>]
2610 [log.user|user: User Name <user@hostname>]
2611 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2611 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2612 [log.summary|summary: line 1]
2612 [log.summary|summary: line 1]
2613
2613
2614 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2614 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2615 [log.bisect bisect.good|bisect: good]
2615 [log.bisect bisect.good|bisect: good]
2616 [log.user|user: A. N. Other <other@place>]
2616 [log.user|user: A. N. Other <other@place>]
2617 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2617 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2618 [log.summary|summary: other 1]
2618 [log.summary|summary: other 1]
2619
2619
2620 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2620 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2621 [log.bisect bisect.untested|bisect: untested]
2621 [log.bisect bisect.untested|bisect: untested]
2622 [log.user|user: other@place]
2622 [log.user|user: other@place]
2623 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2623 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2624 [log.summary|summary: no person]
2624 [log.summary|summary: no person]
2625
2625
2626 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2626 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2627 [log.bisect bisect.bad|bisect: bad]
2627 [log.bisect bisect.bad|bisect: bad]
2628 [log.user|user: person]
2628 [log.user|user: person]
2629 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2629 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2630 [log.summary|summary: no user, no domain]
2630 [log.summary|summary: no user, no domain]
2631
2631
2632 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2632 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2633 [log.bisect bisect.bad|bisect: bad (implicit)]
2633 [log.bisect bisect.bad|bisect: bad (implicit)]
2634 [log.branch|branch: foo]
2634 [log.branch|branch: foo]
2635 [log.user|user: person]
2635 [log.user|user: person]
2636 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2636 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2637 [log.summary|summary: new branch]
2637 [log.summary|summary: new branch]
2638
2638
2639 $ hg --color=debug log --debug -T bisect -r 0:4
2639 $ hg --color=debug log --debug -T bisect -r 0:4
2640 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2640 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2641 [log.bisect bisect.good|bisect: good (implicit)]
2641 [log.bisect bisect.good|bisect: good (implicit)]
2642 [log.phase|phase: public]
2642 [log.phase|phase: public]
2643 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2643 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2644 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2644 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2645 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2645 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2646 [log.user|user: User Name <user@hostname>]
2646 [log.user|user: User Name <user@hostname>]
2647 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2647 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2648 [ui.debug log.files|files+: a]
2648 [ui.debug log.files|files+: a]
2649 [ui.debug log.extra|extra: branch=default]
2649 [ui.debug log.extra|extra: branch=default]
2650 [ui.note log.description|description:]
2650 [ui.note log.description|description:]
2651 [ui.note log.description|line 1
2651 [ui.note log.description|line 1
2652 line 2]
2652 line 2]
2653
2653
2654
2654
2655 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2655 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2656 [log.bisect bisect.good|bisect: good]
2656 [log.bisect bisect.good|bisect: good]
2657 [log.phase|phase: public]
2657 [log.phase|phase: public]
2658 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2658 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2659 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2659 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2660 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2660 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2661 [log.user|user: A. N. Other <other@place>]
2661 [log.user|user: A. N. Other <other@place>]
2662 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2662 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2663 [ui.debug log.files|files+: b]
2663 [ui.debug log.files|files+: b]
2664 [ui.debug log.extra|extra: branch=default]
2664 [ui.debug log.extra|extra: branch=default]
2665 [ui.note log.description|description:]
2665 [ui.note log.description|description:]
2666 [ui.note log.description|other 1
2666 [ui.note log.description|other 1
2667 other 2
2667 other 2
2668
2668
2669 other 3]
2669 other 3]
2670
2670
2671
2671
2672 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2672 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2673 [log.bisect bisect.untested|bisect: untested]
2673 [log.bisect bisect.untested|bisect: untested]
2674 [log.phase|phase: public]
2674 [log.phase|phase: public]
2675 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2675 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2676 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2676 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2677 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2677 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2678 [log.user|user: other@place]
2678 [log.user|user: other@place]
2679 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2679 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2680 [ui.debug log.files|files+: c]
2680 [ui.debug log.files|files+: c]
2681 [ui.debug log.extra|extra: branch=default]
2681 [ui.debug log.extra|extra: branch=default]
2682 [ui.note log.description|description:]
2682 [ui.note log.description|description:]
2683 [ui.note log.description|no person]
2683 [ui.note log.description|no person]
2684
2684
2685
2685
2686 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2686 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2687 [log.bisect bisect.bad|bisect: bad]
2687 [log.bisect bisect.bad|bisect: bad]
2688 [log.phase|phase: public]
2688 [log.phase|phase: public]
2689 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2689 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2690 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2690 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2691 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2691 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2692 [log.user|user: person]
2692 [log.user|user: person]
2693 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2693 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2694 [ui.debug log.files|files: c]
2694 [ui.debug log.files|files: c]
2695 [ui.debug log.extra|extra: branch=default]
2695 [ui.debug log.extra|extra: branch=default]
2696 [ui.note log.description|description:]
2696 [ui.note log.description|description:]
2697 [ui.note log.description|no user, no domain]
2697 [ui.note log.description|no user, no domain]
2698
2698
2699
2699
2700 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2700 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2701 [log.bisect bisect.bad|bisect: bad (implicit)]
2701 [log.bisect bisect.bad|bisect: bad (implicit)]
2702 [log.branch|branch: foo]
2702 [log.branch|branch: foo]
2703 [log.phase|phase: draft]
2703 [log.phase|phase: draft]
2704 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2704 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2705 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2705 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2706 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2706 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2707 [log.user|user: person]
2707 [log.user|user: person]
2708 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2708 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2709 [ui.debug log.extra|extra: branch=foo]
2709 [ui.debug log.extra|extra: branch=foo]
2710 [ui.note log.description|description:]
2710 [ui.note log.description|description:]
2711 [ui.note log.description|new branch]
2711 [ui.note log.description|new branch]
2712
2712
2713
2713
2714 $ hg --color=debug log -v -T bisect -r 0:4
2714 $ hg --color=debug log -v -T bisect -r 0:4
2715 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2715 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2716 [log.bisect bisect.good|bisect: good (implicit)]
2716 [log.bisect bisect.good|bisect: good (implicit)]
2717 [log.user|user: User Name <user@hostname>]
2717 [log.user|user: User Name <user@hostname>]
2718 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2718 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2719 [ui.note log.files|files: a]
2719 [ui.note log.files|files: a]
2720 [ui.note log.description|description:]
2720 [ui.note log.description|description:]
2721 [ui.note log.description|line 1
2721 [ui.note log.description|line 1
2722 line 2]
2722 line 2]
2723
2723
2724
2724
2725 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2725 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2726 [log.bisect bisect.good|bisect: good]
2726 [log.bisect bisect.good|bisect: good]
2727 [log.user|user: A. N. Other <other@place>]
2727 [log.user|user: A. N. Other <other@place>]
2728 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2728 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2729 [ui.note log.files|files: b]
2729 [ui.note log.files|files: b]
2730 [ui.note log.description|description:]
2730 [ui.note log.description|description:]
2731 [ui.note log.description|other 1
2731 [ui.note log.description|other 1
2732 other 2
2732 other 2
2733
2733
2734 other 3]
2734 other 3]
2735
2735
2736
2736
2737 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2737 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2738 [log.bisect bisect.untested|bisect: untested]
2738 [log.bisect bisect.untested|bisect: untested]
2739 [log.user|user: other@place]
2739 [log.user|user: other@place]
2740 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2740 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2741 [ui.note log.files|files: c]
2741 [ui.note log.files|files: c]
2742 [ui.note log.description|description:]
2742 [ui.note log.description|description:]
2743 [ui.note log.description|no person]
2743 [ui.note log.description|no person]
2744
2744
2745
2745
2746 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2746 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2747 [log.bisect bisect.bad|bisect: bad]
2747 [log.bisect bisect.bad|bisect: bad]
2748 [log.user|user: person]
2748 [log.user|user: person]
2749 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2749 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2750 [ui.note log.files|files: c]
2750 [ui.note log.files|files: c]
2751 [ui.note log.description|description:]
2751 [ui.note log.description|description:]
2752 [ui.note log.description|no user, no domain]
2752 [ui.note log.description|no user, no domain]
2753
2753
2754
2754
2755 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2755 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2756 [log.bisect bisect.bad|bisect: bad (implicit)]
2756 [log.bisect bisect.bad|bisect: bad (implicit)]
2757 [log.branch|branch: foo]
2757 [log.branch|branch: foo]
2758 [log.user|user: person]
2758 [log.user|user: person]
2759 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2759 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2760 [ui.note log.description|description:]
2760 [ui.note log.description|description:]
2761 [ui.note log.description|new branch]
2761 [ui.note log.description|new branch]
2762
2762
2763
2763
2764 $ hg bisect --reset
2764 $ hg bisect --reset
2765
2765
2766 Error on syntax:
2766 Error on syntax:
2767
2767
2768 $ echo 'x = "f' >> t
2768 $ echo 'x = "f' >> t
2769 $ hg log
2769 $ hg log
2770 hg: parse error at t:3: unmatched quotes
2770 hg: parse error at t:3: unmatched quotes
2771 [255]
2771 [255]
2772
2772
2773 $ hg log -T '{date'
2773 $ hg log -T '{date'
2774 hg: parse error at 1: unterminated template expansion
2774 hg: parse error at 1: unterminated template expansion
2775 ({date
2775 ({date
2776 ^ here)
2776 ^ here)
2777 [255]
2777 [255]
2778 $ hg log -T '{date(}'
2778 $ hg log -T '{date(}'
2779 hg: parse error at 6: not a prefix: end
2779 hg: parse error at 6: not a prefix: end
2780 ({date(}
2780 ({date(}
2781 ^ here)
2781 ^ here)
2782 [255]
2782 [255]
2783 $ hg log -T '{date)}'
2783 $ hg log -T '{date)}'
2784 hg: parse error at 5: invalid token
2784 hg: parse error at 5: invalid token
2785 ({date)}
2785 ({date)}
2786 ^ here)
2786 ^ here)
2787 [255]
2787 [255]
2788 $ hg log -T '{date date}'
2788 $ hg log -T '{date date}'
2789 hg: parse error at 6: invalid token
2789 hg: parse error at 6: invalid token
2790 ({date date}
2790 ({date date}
2791 ^ here)
2791 ^ here)
2792 [255]
2792 [255]
2793
2793
2794 $ hg log -T '{}'
2794 $ hg log -T '{}'
2795 hg: parse error at 1: not a prefix: end
2795 hg: parse error at 1: not a prefix: end
2796 ({}
2796 ({}
2797 ^ here)
2797 ^ here)
2798 [255]
2798 [255]
2799 $ hg debugtemplate -v '{()}'
2799 $ hg debugtemplate -v '{()}'
2800 (template
2800 (template
2801 (group
2801 (group
2802 None))
2802 None))
2803 hg: parse error: missing argument
2803 hg: parse error: missing argument
2804 [255]
2804 [255]
2805
2805
2806 Behind the scenes, this would throw TypeError without intype=bytes
2806 Behind the scenes, this would throw TypeError without intype=bytes
2807
2807
2808 $ hg log -l 3 --template '{date|obfuscate}\n'
2808 $ hg log -l 3 --template '{date|obfuscate}\n'
2809 &#48;&#46;&#48;&#48;
2809 &#48;&#46;&#48;&#48;
2810 &#48;&#46;&#48;&#48;
2810 &#48;&#46;&#48;&#48;
2811 &#49;&#53;&#55;&#55;&#56;&#55;&#50;&#56;&#54;&#48;&#46;&#48;&#48;
2811 &#49;&#53;&#55;&#55;&#56;&#55;&#50;&#56;&#54;&#48;&#46;&#48;&#48;
2812
2812
2813 Behind the scenes, this will throw a ValueError
2813 Behind the scenes, this will throw a ValueError
2814
2814
2815 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2815 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2816 hg: parse error: invalid date: 'Modify, add, remove, rename'
2816 hg: parse error: invalid date: 'Modify, add, remove, rename'
2817 (template filter 'shortdate' is not compatible with keyword 'desc')
2817 (template filter 'shortdate' is not compatible with keyword 'desc')
2818 [255]
2818 [255]
2819
2819
2820 Behind the scenes, this would throw AttributeError without intype=bytes
2820 Behind the scenes, this would throw AttributeError without intype=bytes
2821
2821
2822 $ hg log -l 3 --template 'line: {date|escape}\n'
2822 $ hg log -l 3 --template 'line: {date|escape}\n'
2823 line: 0.00
2823 line: 0.00
2824 line: 0.00
2824 line: 0.00
2825 line: 1577872860.00
2825 line: 1577872860.00
2826
2826
2827 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2827 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2828 hg: parse error: localdate expects a date information
2828 hg: parse error: localdate expects a date information
2829 [255]
2829 [255]
2830
2830
2831 Behind the scenes, this will throw ValueError
2831 Behind the scenes, this will throw ValueError
2832
2832
2833 $ hg tip --template '{author|email|date}\n'
2833 $ hg tip --template '{author|email|date}\n'
2834 hg: parse error: date expects a date information
2834 hg: parse error: date expects a date information
2835 [255]
2835 [255]
2836
2836
2837 $ hg tip -T '{author|email|shortdate}\n'
2837 $ hg tip -T '{author|email|shortdate}\n'
2838 hg: parse error: invalid date: 'test'
2838 hg: parse error: invalid date: 'test'
2839 (template filter 'shortdate' is not compatible with keyword 'author')
2839 (template filter 'shortdate' is not compatible with keyword 'author')
2840 [255]
2840 [255]
2841
2841
2842 $ hg tip -T '{get(extras, "branch")|shortdate}\n'
2842 $ hg tip -T '{get(extras, "branch")|shortdate}\n'
2843 hg: parse error: invalid date: 'default'
2843 hg: parse error: invalid date: 'default'
2844 (incompatible use of template filter 'shortdate')
2844 (incompatible use of template filter 'shortdate')
2845 [255]
2845 [255]
2846
2846
2847 Error in nested template:
2847 Error in nested template:
2848
2848
2849 $ hg log -T '{"date'
2849 $ hg log -T '{"date'
2850 hg: parse error at 2: unterminated string
2850 hg: parse error at 2: unterminated string
2851 ({"date
2851 ({"date
2852 ^ here)
2852 ^ here)
2853 [255]
2853 [255]
2854
2854
2855 $ hg log -T '{"foo{date|?}"}'
2855 $ hg log -T '{"foo{date|?}"}'
2856 hg: parse error at 11: syntax error
2856 hg: parse error at 11: syntax error
2857 ({"foo{date|?}"}
2857 ({"foo{date|?}"}
2858 ^ here)
2858 ^ here)
2859 [255]
2859 [255]
2860
2860
2861 Thrown an error if a template function doesn't exist
2861 Thrown an error if a template function doesn't exist
2862
2862
2863 $ hg tip --template '{foo()}\n'
2863 $ hg tip --template '{foo()}\n'
2864 hg: parse error: unknown function 'foo'
2864 hg: parse error: unknown function 'foo'
2865 [255]
2865 [255]
2866
2866
2867 Pass generator object created by template function to filter
2867 Pass generator object created by template function to filter
2868
2868
2869 $ hg log -l 1 --template '{if(author, author)|user}\n'
2869 $ hg log -l 1 --template '{if(author, author)|user}\n'
2870 test
2870 test
2871
2871
2872 Test index keyword:
2872 Test index keyword:
2873
2873
2874 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
2874 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
2875 10 0:a 1:b 2:fifth 3:fourth 4:third
2875 10 0:a 1:b 2:fifth 3:fourth 4:third
2876 11 0:a
2876 11 0:a
2877
2877
2878 $ hg branches -T '{index} {branch}\n'
2878 $ hg branches -T '{index} {branch}\n'
2879 0 default
2879 0 default
2880 1 foo
2880 1 foo
2881
2881
2882 Test diff function:
2882 Test diff function:
2883
2883
2884 $ hg diff -c 8
2884 $ hg diff -c 8
2885 diff -r 29114dbae42b -r 95c24699272e fourth
2885 diff -r 29114dbae42b -r 95c24699272e fourth
2886 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2886 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2887 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2887 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2888 @@ -0,0 +1,1 @@
2888 @@ -0,0 +1,1 @@
2889 +second
2889 +second
2890 diff -r 29114dbae42b -r 95c24699272e second
2890 diff -r 29114dbae42b -r 95c24699272e second
2891 --- a/second Mon Jan 12 13:46:40 1970 +0000
2891 --- a/second Mon Jan 12 13:46:40 1970 +0000
2892 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2892 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2893 @@ -1,1 +0,0 @@
2893 @@ -1,1 +0,0 @@
2894 -second
2894 -second
2895 diff -r 29114dbae42b -r 95c24699272e third
2895 diff -r 29114dbae42b -r 95c24699272e third
2896 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2896 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2897 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2897 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2898 @@ -0,0 +1,1 @@
2898 @@ -0,0 +1,1 @@
2899 +third
2899 +third
2900
2900
2901 $ hg log -r 8 -T "{diff()}"
2901 $ hg log -r 8 -T "{diff()}"
2902 diff -r 29114dbae42b -r 95c24699272e fourth
2902 diff -r 29114dbae42b -r 95c24699272e fourth
2903 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2903 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2904 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2904 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2905 @@ -0,0 +1,1 @@
2905 @@ -0,0 +1,1 @@
2906 +second
2906 +second
2907 diff -r 29114dbae42b -r 95c24699272e second
2907 diff -r 29114dbae42b -r 95c24699272e second
2908 --- a/second Mon Jan 12 13:46:40 1970 +0000
2908 --- a/second Mon Jan 12 13:46:40 1970 +0000
2909 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2909 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2910 @@ -1,1 +0,0 @@
2910 @@ -1,1 +0,0 @@
2911 -second
2911 -second
2912 diff -r 29114dbae42b -r 95c24699272e third
2912 diff -r 29114dbae42b -r 95c24699272e third
2913 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2913 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2914 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2914 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2915 @@ -0,0 +1,1 @@
2915 @@ -0,0 +1,1 @@
2916 +third
2916 +third
2917
2917
2918 $ hg log -r 8 -T "{diff('glob:f*')}"
2918 $ hg log -r 8 -T "{diff('glob:f*')}"
2919 diff -r 29114dbae42b -r 95c24699272e fourth
2919 diff -r 29114dbae42b -r 95c24699272e fourth
2920 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2920 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2921 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2921 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2922 @@ -0,0 +1,1 @@
2922 @@ -0,0 +1,1 @@
2923 +second
2923 +second
2924
2924
2925 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2925 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2926 diff -r 29114dbae42b -r 95c24699272e second
2926 diff -r 29114dbae42b -r 95c24699272e second
2927 --- a/second Mon Jan 12 13:46:40 1970 +0000
2927 --- a/second Mon Jan 12 13:46:40 1970 +0000
2928 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2928 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2929 @@ -1,1 +0,0 @@
2929 @@ -1,1 +0,0 @@
2930 -second
2930 -second
2931 diff -r 29114dbae42b -r 95c24699272e third
2931 diff -r 29114dbae42b -r 95c24699272e third
2932 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2932 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2933 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2933 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2934 @@ -0,0 +1,1 @@
2934 @@ -0,0 +1,1 @@
2935 +third
2935 +third
2936
2936
2937 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2937 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2938 diff -r 29114dbae42b -r 95c24699272e fourth
2938 diff -r 29114dbae42b -r 95c24699272e fourth
2939 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2939 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2940 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2940 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2941 @@ -0,0 +1,1 @@
2941 @@ -0,0 +1,1 @@
2942 +second
2942 +second
2943
2943
2944 ui verbosity:
2944 ui verbosity:
2945
2945
2946 $ hg log -l1 -T '{verbosity}\n'
2946 $ hg log -l1 -T '{verbosity}\n'
2947
2947
2948 $ hg log -l1 -T '{verbosity}\n' --debug
2948 $ hg log -l1 -T '{verbosity}\n' --debug
2949 debug
2949 debug
2950 $ hg log -l1 -T '{verbosity}\n' --quiet
2950 $ hg log -l1 -T '{verbosity}\n' --quiet
2951 quiet
2951 quiet
2952 $ hg log -l1 -T '{verbosity}\n' --verbose
2952 $ hg log -l1 -T '{verbosity}\n' --verbose
2953 verbose
2953 verbose
2954
2954
2955 $ cd ..
2955 $ cd ..
2956
2956
2957
2957
2958 latesttag:
2958 latesttag:
2959
2959
2960 $ hg init latesttag
2960 $ hg init latesttag
2961 $ cd latesttag
2961 $ cd latesttag
2962
2962
2963 $ echo a > file
2963 $ echo a > file
2964 $ hg ci -Am a -d '0 0'
2964 $ hg ci -Am a -d '0 0'
2965 adding file
2965 adding file
2966
2966
2967 $ echo b >> file
2967 $ echo b >> file
2968 $ hg ci -m b -d '1 0'
2968 $ hg ci -m b -d '1 0'
2969
2969
2970 $ echo c >> head1
2970 $ echo c >> head1
2971 $ hg ci -Am h1c -d '2 0'
2971 $ hg ci -Am h1c -d '2 0'
2972 adding head1
2972 adding head1
2973
2973
2974 $ hg update -q 1
2974 $ hg update -q 1
2975 $ echo d >> head2
2975 $ echo d >> head2
2976 $ hg ci -Am h2d -d '3 0'
2976 $ hg ci -Am h2d -d '3 0'
2977 adding head2
2977 adding head2
2978 created new head
2978 created new head
2979
2979
2980 $ echo e >> head2
2980 $ echo e >> head2
2981 $ hg ci -m h2e -d '4 0'
2981 $ hg ci -m h2e -d '4 0'
2982
2982
2983 $ hg merge -q
2983 $ hg merge -q
2984 $ hg ci -m merge -d '5 -3600'
2984 $ hg ci -m merge -d '5 -3600'
2985
2985
2986 No tag set:
2986 No tag set:
2987
2987
2988 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2988 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2989 @ 5: null+5
2989 @ 5: null+5
2990 |\
2990 |\
2991 | o 4: null+4
2991 | o 4: null+4
2992 | |
2992 | |
2993 | o 3: null+3
2993 | o 3: null+3
2994 | |
2994 | |
2995 o | 2: null+3
2995 o | 2: null+3
2996 |/
2996 |/
2997 o 1: null+2
2997 o 1: null+2
2998 |
2998 |
2999 o 0: null+1
2999 o 0: null+1
3000
3000
3001
3001
3002 One common tag: longest path wins for {latesttagdistance}:
3002 One common tag: longest path wins for {latesttagdistance}:
3003
3003
3004 $ hg tag -r 1 -m t1 -d '6 0' t1
3004 $ hg tag -r 1 -m t1 -d '6 0' t1
3005 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3005 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3006 @ 6: t1+4
3006 @ 6: t1+4
3007 |
3007 |
3008 o 5: t1+3
3008 o 5: t1+3
3009 |\
3009 |\
3010 | o 4: t1+2
3010 | o 4: t1+2
3011 | |
3011 | |
3012 | o 3: t1+1
3012 | o 3: t1+1
3013 | |
3013 | |
3014 o | 2: t1+1
3014 o | 2: t1+1
3015 |/
3015 |/
3016 o 1: t1+0
3016 o 1: t1+0
3017 |
3017 |
3018 o 0: null+1
3018 o 0: null+1
3019
3019
3020
3020
3021 One ancestor tag: closest wins:
3021 One ancestor tag: closest wins:
3022
3022
3023 $ hg tag -r 2 -m t2 -d '7 0' t2
3023 $ hg tag -r 2 -m t2 -d '7 0' t2
3024 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3024 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3025 @ 7: t2+3
3025 @ 7: t2+3
3026 |
3026 |
3027 o 6: t2+2
3027 o 6: t2+2
3028 |
3028 |
3029 o 5: t2+1
3029 o 5: t2+1
3030 |\
3030 |\
3031 | o 4: t1+2
3031 | o 4: t1+2
3032 | |
3032 | |
3033 | o 3: t1+1
3033 | o 3: t1+1
3034 | |
3034 | |
3035 o | 2: t2+0
3035 o | 2: t2+0
3036 |/
3036 |/
3037 o 1: t1+0
3037 o 1: t1+0
3038 |
3038 |
3039 o 0: null+1
3039 o 0: null+1
3040
3040
3041
3041
3042 Two branch tags: more recent wins if same number of changes:
3042 Two branch tags: more recent wins if same number of changes:
3043
3043
3044 $ hg tag -r 3 -m t3 -d '8 0' t3
3044 $ hg tag -r 3 -m t3 -d '8 0' t3
3045 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3045 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3046 @ 8: t3+5
3046 @ 8: t3+5
3047 |
3047 |
3048 o 7: t3+4
3048 o 7: t3+4
3049 |
3049 |
3050 o 6: t3+3
3050 o 6: t3+3
3051 |
3051 |
3052 o 5: t3+2
3052 o 5: t3+2
3053 |\
3053 |\
3054 | o 4: t3+1
3054 | o 4: t3+1
3055 | |
3055 | |
3056 | o 3: t3+0
3056 | o 3: t3+0
3057 | |
3057 | |
3058 o | 2: t2+0
3058 o | 2: t2+0
3059 |/
3059 |/
3060 o 1: t1+0
3060 o 1: t1+0
3061 |
3061 |
3062 o 0: null+1
3062 o 0: null+1
3063
3063
3064
3064
3065 Two branch tags: fewest changes wins:
3065 Two branch tags: fewest changes wins:
3066
3066
3067 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
3067 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
3068 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3068 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3069 @ 9: t4+5,6
3069 @ 9: t4+5,6
3070 |
3070 |
3071 o 8: t4+4,5
3071 o 8: t4+4,5
3072 |
3072 |
3073 o 7: t4+3,4
3073 o 7: t4+3,4
3074 |
3074 |
3075 o 6: t4+2,3
3075 o 6: t4+2,3
3076 |
3076 |
3077 o 5: t4+1,2
3077 o 5: t4+1,2
3078 |\
3078 |\
3079 | o 4: t4+0,0
3079 | o 4: t4+0,0
3080 | |
3080 | |
3081 | o 3: t3+0,0
3081 | o 3: t3+0,0
3082 | |
3082 | |
3083 o | 2: t2+0,0
3083 o | 2: t2+0,0
3084 |/
3084 |/
3085 o 1: t1+0,0
3085 o 1: t1+0,0
3086 |
3086 |
3087 o 0: null+1,1
3087 o 0: null+1,1
3088
3088
3089
3089
3090 Merged tag overrides:
3090 Merged tag overrides:
3091
3091
3092 $ hg tag -r 5 -m t5 -d '9 0' t5
3092 $ hg tag -r 5 -m t5 -d '9 0' t5
3093 $ hg tag -r 3 -m at3 -d '10 0' at3
3093 $ hg tag -r 3 -m at3 -d '10 0' at3
3094 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3094 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3095 @ 11: t5+6
3095 @ 11: t5+6
3096 |
3096 |
3097 o 10: t5+5
3097 o 10: t5+5
3098 |
3098 |
3099 o 9: t5+4
3099 o 9: t5+4
3100 |
3100 |
3101 o 8: t5+3
3101 o 8: t5+3
3102 |
3102 |
3103 o 7: t5+2
3103 o 7: t5+2
3104 |
3104 |
3105 o 6: t5+1
3105 o 6: t5+1
3106 |
3106 |
3107 o 5: t5+0
3107 o 5: t5+0
3108 |\
3108 |\
3109 | o 4: t4+0
3109 | o 4: t4+0
3110 | |
3110 | |
3111 | o 3: at3:t3+0
3111 | o 3: at3:t3+0
3112 | |
3112 | |
3113 o | 2: t2+0
3113 o | 2: t2+0
3114 |/
3114 |/
3115 o 1: t1+0
3115 o 1: t1+0
3116 |
3116 |
3117 o 0: null+1
3117 o 0: null+1
3118
3118
3119
3119
3120 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3120 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3121 @ 11: t5+6,6
3121 @ 11: t5+6,6
3122 |
3122 |
3123 o 10: t5+5,5
3123 o 10: t5+5,5
3124 |
3124 |
3125 o 9: t5+4,4
3125 o 9: t5+4,4
3126 |
3126 |
3127 o 8: t5+3,3
3127 o 8: t5+3,3
3128 |
3128 |
3129 o 7: t5+2,2
3129 o 7: t5+2,2
3130 |
3130 |
3131 o 6: t5+1,1
3131 o 6: t5+1,1
3132 |
3132 |
3133 o 5: t5+0,0
3133 o 5: t5+0,0
3134 |\
3134 |\
3135 | o 4: t4+0,0
3135 | o 4: t4+0,0
3136 | |
3136 | |
3137 | o 3: at3+0,0 t3+0,0
3137 | o 3: at3+0,0 t3+0,0
3138 | |
3138 | |
3139 o | 2: t2+0,0
3139 o | 2: t2+0,0
3140 |/
3140 |/
3141 o 1: t1+0,0
3141 o 1: t1+0,0
3142 |
3142 |
3143 o 0: null+1,1
3143 o 0: null+1,1
3144
3144
3145
3145
3146 $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
3146 $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
3147 @ 11: t3, C: 9, D: 8
3147 @ 11: t3, C: 9, D: 8
3148 |
3148 |
3149 o 10: t3, C: 8, D: 7
3149 o 10: t3, C: 8, D: 7
3150 |
3150 |
3151 o 9: t3, C: 7, D: 6
3151 o 9: t3, C: 7, D: 6
3152 |
3152 |
3153 o 8: t3, C: 6, D: 5
3153 o 8: t3, C: 6, D: 5
3154 |
3154 |
3155 o 7: t3, C: 5, D: 4
3155 o 7: t3, C: 5, D: 4
3156 |
3156 |
3157 o 6: t3, C: 4, D: 3
3157 o 6: t3, C: 4, D: 3
3158 |
3158 |
3159 o 5: t3, C: 3, D: 2
3159 o 5: t3, C: 3, D: 2
3160 |\
3160 |\
3161 | o 4: t3, C: 1, D: 1
3161 | o 4: t3, C: 1, D: 1
3162 | |
3162 | |
3163 | o 3: t3, C: 0, D: 0
3163 | o 3: t3, C: 0, D: 0
3164 | |
3164 | |
3165 o | 2: t1, C: 1, D: 1
3165 o | 2: t1, C: 1, D: 1
3166 |/
3166 |/
3167 o 1: t1, C: 0, D: 0
3167 o 1: t1, C: 0, D: 0
3168 |
3168 |
3169 o 0: null, C: 1, D: 1
3169 o 0: null, C: 1, D: 1
3170
3170
3171
3171
3172 $ cd ..
3172 $ cd ..
3173
3173
3174
3174
3175 Style path expansion: issue1948 - ui.style option doesn't work on OSX
3175 Style path expansion: issue1948 - ui.style option doesn't work on OSX
3176 if it is a relative path
3176 if it is a relative path
3177
3177
3178 $ mkdir -p home/styles
3178 $ mkdir -p home/styles
3179
3179
3180 $ cat > home/styles/teststyle <<EOF
3180 $ cat > home/styles/teststyle <<EOF
3181 > changeset = 'test {rev}:{node|short}\n'
3181 > changeset = 'test {rev}:{node|short}\n'
3182 > EOF
3182 > EOF
3183
3183
3184 $ HOME=`pwd`/home; export HOME
3184 $ HOME=`pwd`/home; export HOME
3185
3185
3186 $ cat > latesttag/.hg/hgrc <<EOF
3186 $ cat > latesttag/.hg/hgrc <<EOF
3187 > [ui]
3187 > [ui]
3188 > style = ~/styles/teststyle
3188 > style = ~/styles/teststyle
3189 > EOF
3189 > EOF
3190
3190
3191 $ hg -R latesttag tip
3191 $ hg -R latesttag tip
3192 test 11:97e5943b523a
3192 test 11:97e5943b523a
3193
3193
3194 Test recursive showlist template (issue1989):
3194 Test recursive showlist template (issue1989):
3195
3195
3196 $ cat > style1989 <<EOF
3196 $ cat > style1989 <<EOF
3197 > changeset = '{file_mods}{manifest}{extras}'
3197 > changeset = '{file_mods}{manifest}{extras}'
3198 > file_mod = 'M|{author|person}\n'
3198 > file_mod = 'M|{author|person}\n'
3199 > manifest = '{rev},{author}\n'
3199 > manifest = '{rev},{author}\n'
3200 > extra = '{key}: {author}\n'
3200 > extra = '{key}: {author}\n'
3201 > EOF
3201 > EOF
3202
3202
3203 $ hg -R latesttag log -r tip --style=style1989
3203 $ hg -R latesttag log -r tip --style=style1989
3204 M|test
3204 M|test
3205 11,test
3205 11,test
3206 branch: test
3206 branch: test
3207
3207
3208 Test new-style inline templating:
3208 Test new-style inline templating:
3209
3209
3210 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
3210 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
3211 modified files: .hgtags
3211 modified files: .hgtags
3212
3212
3213
3213
3214 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
3214 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
3215 hg: parse error: keyword 'rev' is not iterable of mappings
3215 hg: parse error: keyword 'rev' is not iterable of mappings
3216 [255]
3216 [255]
3217 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
3217 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
3218 hg: parse error: None is not iterable of mappings
3218 hg: parse error: None is not iterable of mappings
3219 [255]
3219 [255]
3220 $ hg log -R latesttag -r tip -T '{extras % "{key}\n" % "{key}\n"}'
3220 $ hg log -R latesttag -r tip -T '{extras % "{key}\n" % "{key}\n"}'
3221 hg: parse error: list of strings is not mappable
3221 hg: parse error: list of strings is not mappable
3222 [255]
3222 [255]
3223
3223
3224 Test new-style inline templating of non-list/dict type:
3224 Test new-style inline templating of non-list/dict type:
3225
3225
3226 $ hg log -R latesttag -r tip -T '{manifest}\n'
3226 $ hg log -R latesttag -r tip -T '{manifest}\n'
3227 11:2bc6e9006ce2
3227 11:2bc6e9006ce2
3228 $ hg log -R latesttag -r tip -T 'string length: {manifest|count}\n'
3228 $ hg log -R latesttag -r tip -T 'string length: {manifest|count}\n'
3229 string length: 15
3229 string length: 15
3230 $ hg log -R latesttag -r tip -T '{manifest % "{rev}:{node}"}\n'
3230 $ hg log -R latesttag -r tip -T '{manifest % "{rev}:{node}"}\n'
3231 11:2bc6e9006ce29882383a22d39fd1f4e66dd3e2fc
3231 11:2bc6e9006ce29882383a22d39fd1f4e66dd3e2fc
3232
3232
3233 $ hg log -R latesttag -r tip -T '{get(extras, "branch") % "{key}: {value}\n"}'
3233 $ hg log -R latesttag -r tip -T '{get(extras, "branch") % "{key}: {value}\n"}'
3234 branch: default
3234 branch: default
3235 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "{key}\n"}'
3235 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "{key}\n"}'
3236 hg: parse error: None is not iterable of mappings
3236 hg: parse error: None is not iterable of mappings
3237 [255]
3237 [255]
3238 $ hg log -R latesttag -r tip -T '{min(extras) % "{key}: {value}\n"}'
3238 $ hg log -R latesttag -r tip -T '{min(extras) % "{key}: {value}\n"}'
3239 branch: default
3239 branch: default
3240 $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}'
3240 $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}'
3241 0:ce3cec86e6c2
3241 0:ce3cec86e6c2
3242 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
3242 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
3243 9:fbc7cd862e9c
3243 9:fbc7cd862e9c
3244
3244
3245 Test manifest/get() can be join()-ed as before, though it's silly:
3245 Test manifest/get() can be join()-ed as before, though it's silly:
3246
3246
3247 $ hg log -R latesttag -r tip -T '{join(manifest, "")}\n'
3247 $ hg log -R latesttag -r tip -T '{join(manifest, "")}\n'
3248 11:2bc6e9006ce2
3248 11:2bc6e9006ce2
3249 $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), "")}\n'
3249 $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), "")}\n'
3250 default
3250 default
3251
3251
3252 Test min/max of integers
3252 Test min/max of integers
3253
3253
3254 $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'
3254 $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'
3255 9
3255 9
3256 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
3256 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
3257 10
3257 10
3258
3258
3259 Test min/max over map operation:
3259 Test min/max over map operation:
3260
3260
3261 $ hg log -R latesttag -r3 -T '{min(tags % "{tag}")}\n'
3261 $ hg log -R latesttag -r3 -T '{min(tags % "{tag}")}\n'
3262 at3
3262 at3
3263 $ hg log -R latesttag -r3 -T '{max(tags % "{tag}")}\n'
3263 $ hg log -R latesttag -r3 -T '{max(tags % "{tag}")}\n'
3264 t3
3264 t3
3265
3265
3266 Test min/max of if() result
3266 Test min/max of if() result
3267
3267
3268 $ cd latesttag
3268 $ cd latesttag
3269 $ hg log -l1 -T '{min(if(true, revset("9:10"), ""))}\n'
3269 $ hg log -l1 -T '{min(if(true, revset("9:10"), ""))}\n'
3270 9
3270 9
3271 $ hg log -l1 -T '{max(if(false, "", revset("9:10")))}\n'
3271 $ hg log -l1 -T '{max(if(false, "", revset("9:10")))}\n'
3272 10
3272 10
3273 $ hg log -l1 -T '{min(ifcontains("a", "aa", revset("9:10"), ""))}\n'
3273 $ hg log -l1 -T '{min(ifcontains("a", "aa", revset("9:10"), ""))}\n'
3274 9
3274 9
3275 $ hg log -l1 -T '{max(ifcontains("a", "bb", "", revset("9:10")))}\n'
3275 $ hg log -l1 -T '{max(ifcontains("a", "bb", "", revset("9:10")))}\n'
3276 10
3276 10
3277 $ hg log -l1 -T '{min(ifeq(0, 0, revset("9:10"), ""))}\n'
3277 $ hg log -l1 -T '{min(ifeq(0, 0, revset("9:10"), ""))}\n'
3278 9
3278 9
3279 $ hg log -l1 -T '{max(ifeq(0, 1, "", revset("9:10")))}\n'
3279 $ hg log -l1 -T '{max(ifeq(0, 1, "", revset("9:10")))}\n'
3280 10
3280 10
3281 $ cd ..
3281 $ cd ..
3282
3282
3283 Test laziness of if() then/else clause
3283 Test laziness of if() then/else clause
3284
3284
3285 $ hg debugtemplate '{count(0)}'
3285 $ hg debugtemplate '{count(0)}'
3286 hg: parse error: not countable
3286 hg: parse error: not countable
3287 (incompatible use of template filter 'count')
3287 (incompatible use of template filter 'count')
3288 [255]
3288 [255]
3289 $ hg debugtemplate '{if(true, "", count(0))}'
3289 $ hg debugtemplate '{if(true, "", count(0))}'
3290 $ hg debugtemplate '{if(false, count(0), "")}'
3290 $ hg debugtemplate '{if(false, count(0), "")}'
3291 $ hg debugtemplate '{ifcontains("a", "aa", "", count(0))}'
3291 $ hg debugtemplate '{ifcontains("a", "aa", "", count(0))}'
3292 $ hg debugtemplate '{ifcontains("a", "bb", count(0), "")}'
3292 $ hg debugtemplate '{ifcontains("a", "bb", count(0), "")}'
3293 $ hg debugtemplate '{ifeq(0, 0, "", count(0))}'
3293 $ hg debugtemplate '{ifeq(0, 0, "", count(0))}'
3294 $ hg debugtemplate '{ifeq(0, 1, count(0), "")}'
3294 $ hg debugtemplate '{ifeq(0, 1, count(0), "")}'
3295
3295
3296 Test dot operator precedence:
3296 Test dot operator precedence:
3297
3297
3298 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
3298 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
3299 (template
3299 (template
3300 (|
3300 (|
3301 (.
3301 (.
3302 (symbol 'manifest')
3302 (symbol 'manifest')
3303 (symbol 'node'))
3303 (symbol 'node'))
3304 (symbol 'short'))
3304 (symbol 'short'))
3305 (string '\n'))
3305 (string '\n'))
3306 89f4071fec70
3306 89f4071fec70
3307
3307
3308 (the following examples are invalid, but seem natural in parsing POV)
3308 (the following examples are invalid, but seem natural in parsing POV)
3309
3309
3310 $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null
3310 $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null
3311 (template
3311 (template
3312 (|
3312 (|
3313 (symbol 'foo')
3313 (symbol 'foo')
3314 (.
3314 (.
3315 (symbol 'bar')
3315 (symbol 'bar')
3316 (symbol 'baz')))
3316 (symbol 'baz')))
3317 (string '\n'))
3317 (string '\n'))
3318 [255]
3318 [255]
3319 $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null
3319 $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null
3320 (template
3320 (template
3321 (.
3321 (.
3322 (symbol 'foo')
3322 (symbol 'foo')
3323 (func
3323 (func
3324 (symbol 'bar')
3324 (symbol 'bar')
3325 None))
3325 None))
3326 (string '\n'))
3326 (string '\n'))
3327 [255]
3327 [255]
3328
3328
3329 Test evaluation of dot operator:
3329 Test evaluation of dot operator:
3330
3330
3331 $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n'
3331 $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n'
3332 ce3cec86e6c26bd9bdfc590a6b92abc9680f1796
3332 ce3cec86e6c26bd9bdfc590a6b92abc9680f1796
3333 $ hg log -R latesttag -r0 -T '{extras.branch}\n'
3333 $ hg log -R latesttag -r0 -T '{extras.branch}\n'
3334 default
3334 default
3335
3335
3336 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
3336 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
3337 hg: parse error: keyword 'author' has no member
3337 hg: parse error: keyword 'author' has no member
3338 [255]
3338 [255]
3339 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
3339 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
3340 hg: parse error: 'a' has no member
3340 hg: parse error: 'a' has no member
3341 [255]
3341 [255]
3342
3342
3343 Test the sub function of templating for expansion:
3343 Test the sub function of templating for expansion:
3344
3344
3345 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
3345 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
3346 xx
3346 xx
3347
3347
3348 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
3348 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
3349 hg: parse error: sub got an invalid pattern: [
3349 hg: parse error: sub got an invalid pattern: [
3350 [255]
3350 [255]
3351 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
3351 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
3352 hg: parse error: sub got an invalid replacement: \1
3352 hg: parse error: sub got an invalid replacement: \1
3353 [255]
3353 [255]
3354
3354
3355 Test the strip function with chars specified:
3355 Test the strip function with chars specified:
3356
3356
3357 $ hg log -R latesttag --template '{desc}\n'
3357 $ hg log -R latesttag --template '{desc}\n'
3358 at3
3358 at3
3359 t5
3359 t5
3360 t4
3360 t4
3361 t3
3361 t3
3362 t2
3362 t2
3363 t1
3363 t1
3364 merge
3364 merge
3365 h2e
3365 h2e
3366 h2d
3366 h2d
3367 h1c
3367 h1c
3368 b
3368 b
3369 a
3369 a
3370
3370
3371 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
3371 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
3372 at3
3372 at3
3373 5
3373 5
3374 4
3374 4
3375 3
3375 3
3376 2
3376 2
3377 1
3377 1
3378 merg
3378 merg
3379 h2
3379 h2
3380 h2d
3380 h2d
3381 h1c
3381 h1c
3382 b
3382 b
3383 a
3383 a
3384
3384
3385 Test date format:
3385 Test date format:
3386
3386
3387 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
3387 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
3388 date: 70 01 01 10 +0000
3388 date: 70 01 01 10 +0000
3389 date: 70 01 01 09 +0000
3389 date: 70 01 01 09 +0000
3390 date: 70 01 01 04 +0000
3390 date: 70 01 01 04 +0000
3391 date: 70 01 01 08 +0000
3391 date: 70 01 01 08 +0000
3392 date: 70 01 01 07 +0000
3392 date: 70 01 01 07 +0000
3393 date: 70 01 01 06 +0000
3393 date: 70 01 01 06 +0000
3394 date: 70 01 01 05 +0100
3394 date: 70 01 01 05 +0100
3395 date: 70 01 01 04 +0000
3395 date: 70 01 01 04 +0000
3396 date: 70 01 01 03 +0000
3396 date: 70 01 01 03 +0000
3397 date: 70 01 01 02 +0000
3397 date: 70 01 01 02 +0000
3398 date: 70 01 01 01 +0000
3398 date: 70 01 01 01 +0000
3399 date: 70 01 01 00 +0000
3399 date: 70 01 01 00 +0000
3400
3400
3401 Test invalid date:
3401 Test invalid date:
3402
3402
3403 $ hg log -R latesttag -T '{date(rev)}\n'
3403 $ hg log -R latesttag -T '{date(rev)}\n'
3404 hg: parse error: date expects a date information
3404 hg: parse error: date expects a date information
3405 [255]
3405 [255]
3406
3406
3407 Test integer literal:
3407 Test integer literal:
3408
3408
3409 $ hg debugtemplate -v '{(0)}\n'
3409 $ hg debugtemplate -v '{(0)}\n'
3410 (template
3410 (template
3411 (group
3411 (group
3412 (integer '0'))
3412 (integer '0'))
3413 (string '\n'))
3413 (string '\n'))
3414 0
3414 0
3415 $ hg debugtemplate -v '{(123)}\n'
3415 $ hg debugtemplate -v '{(123)}\n'
3416 (template
3416 (template
3417 (group
3417 (group
3418 (integer '123'))
3418 (integer '123'))
3419 (string '\n'))
3419 (string '\n'))
3420 123
3420 123
3421 $ hg debugtemplate -v '{(-4)}\n'
3421 $ hg debugtemplate -v '{(-4)}\n'
3422 (template
3422 (template
3423 (group
3423 (group
3424 (negate
3424 (negate
3425 (integer '4')))
3425 (integer '4')))
3426 (string '\n'))
3426 (string '\n'))
3427 -4
3427 -4
3428 $ hg debugtemplate '{(-)}\n'
3428 $ hg debugtemplate '{(-)}\n'
3429 hg: parse error at 3: not a prefix: )
3429 hg: parse error at 3: not a prefix: )
3430 ({(-)}\n
3430 ({(-)}\n
3431 ^ here)
3431 ^ here)
3432 [255]
3432 [255]
3433 $ hg debugtemplate '{(-a)}\n'
3433 $ hg debugtemplate '{(-a)}\n'
3434 hg: parse error: negation needs an integer argument
3434 hg: parse error: negation needs an integer argument
3435 [255]
3435 [255]
3436
3436
3437 top-level integer literal is interpreted as symbol (i.e. variable name):
3437 top-level integer literal is interpreted as symbol (i.e. variable name):
3438
3438
3439 $ hg debugtemplate -D 1=one -v '{1}\n'
3439 $ hg debugtemplate -D 1=one -v '{1}\n'
3440 (template
3440 (template
3441 (integer '1')
3441 (integer '1')
3442 (string '\n'))
3442 (string '\n'))
3443 one
3443 one
3444 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
3444 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
3445 (template
3445 (template
3446 (func
3446 (func
3447 (symbol 'if')
3447 (symbol 'if')
3448 (list
3448 (list
3449 (string 't')
3449 (string 't')
3450 (template
3450 (template
3451 (integer '1'))))
3451 (integer '1'))))
3452 (string '\n'))
3452 (string '\n'))
3453 one
3453 one
3454 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
3454 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
3455 (template
3455 (template
3456 (|
3456 (|
3457 (integer '1')
3457 (integer '1')
3458 (symbol 'stringify'))
3458 (symbol 'stringify'))
3459 (string '\n'))
3459 (string '\n'))
3460 one
3460 one
3461
3461
3462 unless explicit symbol is expected:
3462 unless explicit symbol is expected:
3463
3463
3464 $ hg log -Ra -r0 -T '{desc|1}\n'
3464 $ hg log -Ra -r0 -T '{desc|1}\n'
3465 hg: parse error: expected a symbol, got 'integer'
3465 hg: parse error: expected a symbol, got 'integer'
3466 [255]
3466 [255]
3467 $ hg log -Ra -r0 -T '{1()}\n'
3467 $ hg log -Ra -r0 -T '{1()}\n'
3468 hg: parse error: expected a symbol, got 'integer'
3468 hg: parse error: expected a symbol, got 'integer'
3469 [255]
3469 [255]
3470
3470
3471 Test string literal:
3471 Test string literal:
3472
3472
3473 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
3473 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
3474 (template
3474 (template
3475 (string 'string with no template fragment')
3475 (string 'string with no template fragment')
3476 (string '\n'))
3476 (string '\n'))
3477 string with no template fragment
3477 string with no template fragment
3478 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
3478 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
3479 (template
3479 (template
3480 (template
3480 (template
3481 (string 'template: ')
3481 (string 'template: ')
3482 (symbol 'rev'))
3482 (symbol 'rev'))
3483 (string '\n'))
3483 (string '\n'))
3484 template: 0
3484 template: 0
3485 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
3485 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
3486 (template
3486 (template
3487 (string 'rawstring: {rev}')
3487 (string 'rawstring: {rev}')
3488 (string '\n'))
3488 (string '\n'))
3489 rawstring: {rev}
3489 rawstring: {rev}
3490 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
3490 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
3491 (template
3491 (template
3492 (%
3492 (%
3493 (symbol 'files')
3493 (symbol 'files')
3494 (string 'rawstring: {file}'))
3494 (string 'rawstring: {file}'))
3495 (string '\n'))
3495 (string '\n'))
3496 rawstring: {file}
3496 rawstring: {file}
3497
3497
3498 Test string escaping:
3498 Test string escaping:
3499
3499
3500 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3500 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3501 >
3501 >
3502 <>\n<[>
3502 <>\n<[>
3503 <>\n<]>
3503 <>\n<]>
3504 <>\n<
3504 <>\n<
3505
3505
3506 $ hg log -R latesttag -r 0 \
3506 $ hg log -R latesttag -r 0 \
3507 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3507 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3508 >
3508 >
3509 <>\n<[>
3509 <>\n<[>
3510 <>\n<]>
3510 <>\n<]>
3511 <>\n<
3511 <>\n<
3512
3512
3513 $ hg log -R latesttag -r 0 -T esc \
3513 $ hg log -R latesttag -r 0 -T esc \
3514 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3514 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3515 >
3515 >
3516 <>\n<[>
3516 <>\n<[>
3517 <>\n<]>
3517 <>\n<]>
3518 <>\n<
3518 <>\n<
3519
3519
3520 $ cat <<'EOF' > esctmpl
3520 $ cat <<'EOF' > esctmpl
3521 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3521 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3522 > EOF
3522 > EOF
3523 $ hg log -R latesttag -r 0 --style ./esctmpl
3523 $ hg log -R latesttag -r 0 --style ./esctmpl
3524 >
3524 >
3525 <>\n<[>
3525 <>\n<[>
3526 <>\n<]>
3526 <>\n<]>
3527 <>\n<
3527 <>\n<
3528
3528
3529 Test string escaping of quotes:
3529 Test string escaping of quotes:
3530
3530
3531 $ hg log -Ra -r0 -T '{"\""}\n'
3531 $ hg log -Ra -r0 -T '{"\""}\n'
3532 "
3532 "
3533 $ hg log -Ra -r0 -T '{"\\\""}\n'
3533 $ hg log -Ra -r0 -T '{"\\\""}\n'
3534 \"
3534 \"
3535 $ hg log -Ra -r0 -T '{r"\""}\n'
3535 $ hg log -Ra -r0 -T '{r"\""}\n'
3536 \"
3536 \"
3537 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3537 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3538 \\\"
3538 \\\"
3539
3539
3540
3540
3541 $ hg log -Ra -r0 -T '{"\""}\n'
3541 $ hg log -Ra -r0 -T '{"\""}\n'
3542 "
3542 "
3543 $ hg log -Ra -r0 -T '{"\\\""}\n'
3543 $ hg log -Ra -r0 -T '{"\\\""}\n'
3544 \"
3544 \"
3545 $ hg log -Ra -r0 -T '{r"\""}\n'
3545 $ hg log -Ra -r0 -T '{r"\""}\n'
3546 \"
3546 \"
3547 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3547 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3548 \\\"
3548 \\\"
3549
3549
3550 Test exception in quoted template. single backslash before quotation mark is
3550 Test exception in quoted template. single backslash before quotation mark is
3551 stripped before parsing:
3551 stripped before parsing:
3552
3552
3553 $ cat <<'EOF' > escquotetmpl
3553 $ cat <<'EOF' > escquotetmpl
3554 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
3554 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
3555 > EOF
3555 > EOF
3556 $ cd latesttag
3556 $ cd latesttag
3557 $ hg log -r 2 --style ../escquotetmpl
3557 $ hg log -r 2 --style ../escquotetmpl
3558 " \" \" \\" head1
3558 " \" \" \\" head1
3559
3559
3560 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
3560 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
3561 valid
3561 valid
3562 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
3562 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
3563 valid
3563 valid
3564
3564
3565 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
3565 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
3566 _evalifliteral() templates (issue4733):
3566 _evalifliteral() templates (issue4733):
3567
3567
3568 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
3568 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
3569 "2
3569 "2
3570 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
3570 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
3571 "2
3571 "2
3572 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
3572 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
3573 "2
3573 "2
3574
3574
3575 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
3575 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
3576 \"
3576 \"
3577 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
3577 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
3578 \"
3578 \"
3579 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3579 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3580 \"
3580 \"
3581
3581
3582 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
3582 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
3583 \\\"
3583 \\\"
3584 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
3584 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
3585 \\\"
3585 \\\"
3586 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3586 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3587 \\\"
3587 \\\"
3588
3588
3589 escaped single quotes and errors:
3589 escaped single quotes and errors:
3590
3590
3591 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
3591 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
3592 foo
3592 foo
3593 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
3593 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
3594 foo
3594 foo
3595 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3595 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3596 hg: parse error at 21: unterminated string
3596 hg: parse error at 21: unterminated string
3597 ({if(rev, "{if(rev, \")}")}\n
3597 ({if(rev, "{if(rev, \")}")}\n
3598 ^ here)
3598 ^ here)
3599 [255]
3599 [255]
3600 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3600 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3601 hg: parse error: trailing \ in string
3601 hg: parse error: trailing \ in string
3602 [255]
3602 [255]
3603 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3603 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3604 hg: parse error: trailing \ in string
3604 hg: parse error: trailing \ in string
3605 [255]
3605 [255]
3606
3606
3607 $ cd ..
3607 $ cd ..
3608
3608
3609 Test leading backslashes:
3609 Test leading backslashes:
3610
3610
3611 $ cd latesttag
3611 $ cd latesttag
3612 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3612 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3613 {rev} {file}
3613 {rev} {file}
3614 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3614 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3615 \2 \head1
3615 \2 \head1
3616 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3616 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3617 \{rev} \{file}
3617 \{rev} \{file}
3618 $ cd ..
3618 $ cd ..
3619
3619
3620 Test leading backslashes in "if" expression (issue4714):
3620 Test leading backslashes in "if" expression (issue4714):
3621
3621
3622 $ cd latesttag
3622 $ cd latesttag
3623 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3623 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3624 {rev} \{rev}
3624 {rev} \{rev}
3625 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3625 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3626 \2 \\{rev}
3626 \2 \\{rev}
3627 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3627 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3628 \{rev} \\\{rev}
3628 \{rev} \\\{rev}
3629 $ cd ..
3629 $ cd ..
3630
3630
3631 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3631 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3632
3632
3633 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3633 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3634 \x6e
3634 \x6e
3635 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3635 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3636 \x5c\x786e
3636 \x5c\x786e
3637 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3637 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3638 \x6e
3638 \x6e
3639 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3639 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3640 \x5c\x786e
3640 \x5c\x786e
3641
3641
3642 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3642 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3643 \x6e
3643 \x6e
3644 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3644 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3645 \x5c\x786e
3645 \x5c\x786e
3646 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3646 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3647 \x6e
3647 \x6e
3648 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3648 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3649 \x5c\x786e
3649 \x5c\x786e
3650
3650
3651 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3651 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3652 fourth
3652 fourth
3653 second
3653 second
3654 third
3654 third
3655 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3655 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3656 fourth\nsecond\nthird
3656 fourth\nsecond\nthird
3657
3657
3658 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3658 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3659 <p>
3659 <p>
3660 1st
3660 1st
3661 </p>
3661 </p>
3662 <p>
3662 <p>
3663 2nd
3663 2nd
3664 </p>
3664 </p>
3665 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3665 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3666 <p>
3666 <p>
3667 1st\n\n2nd
3667 1st\n\n2nd
3668 </p>
3668 </p>
3669 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3669 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3670 1st
3670 1st
3671
3671
3672 2nd
3672 2nd
3673
3673
3674 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3674 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3675 o perso
3675 o perso
3676 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3676 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3677 no person
3677 no person
3678 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3678 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3679 o perso
3679 o perso
3680 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3680 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3681 no perso
3681 no perso
3682
3682
3683 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3683 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3684 -o perso-
3684 -o perso-
3685 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3685 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3686 no person
3686 no person
3687 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3687 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3688 \x2do perso\x2d
3688 \x2do perso\x2d
3689 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3689 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3690 -o perso-
3690 -o perso-
3691 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3691 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3692 \x2do perso\x6e
3692 \x2do perso\x6e
3693
3693
3694 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3694 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3695 fourth
3695 fourth
3696 second
3696 second
3697 third
3697 third
3698
3698
3699 Test string escaping in nested expression:
3699 Test string escaping in nested expression:
3700
3700
3701 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3701 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3702 fourth\x6esecond\x6ethird
3702 fourth\x6esecond\x6ethird
3703 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3703 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3704 fourth\x6esecond\x6ethird
3704 fourth\x6esecond\x6ethird
3705
3705
3706 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3706 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3707 fourth\x6esecond\x6ethird
3707 fourth\x6esecond\x6ethird
3708 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3708 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3709 fourth\x5c\x786esecond\x5c\x786ethird
3709 fourth\x5c\x786esecond\x5c\x786ethird
3710
3710
3711 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3711 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3712 3:\x6eo user, \x6eo domai\x6e
3712 3:\x6eo user, \x6eo domai\x6e
3713 4:\x5c\x786eew bra\x5c\x786ech
3713 4:\x5c\x786eew bra\x5c\x786ech
3714
3714
3715 Test quotes in nested expression are evaluated just like a $(command)
3715 Test quotes in nested expression are evaluated just like a $(command)
3716 substitution in POSIX shells:
3716 substitution in POSIX shells:
3717
3717
3718 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3718 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3719 8:95c24699272e
3719 8:95c24699272e
3720 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3720 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3721 {8} "95c24699272e"
3721 {8} "95c24699272e"
3722
3722
3723 Test recursive evaluation:
3723 Test recursive evaluation:
3724
3724
3725 $ hg init r
3725 $ hg init r
3726 $ cd r
3726 $ cd r
3727 $ echo a > a
3727 $ echo a > a
3728 $ hg ci -Am '{rev}'
3728 $ hg ci -Am '{rev}'
3729 adding a
3729 adding a
3730 $ hg log -r 0 --template '{if(rev, desc)}\n'
3730 $ hg log -r 0 --template '{if(rev, desc)}\n'
3731 {rev}
3731 {rev}
3732 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3732 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3733 test 0
3733 test 0
3734
3734
3735 $ hg branch -q 'text.{rev}'
3735 $ hg branch -q 'text.{rev}'
3736 $ echo aa >> aa
3736 $ echo aa >> aa
3737 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3737 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3738
3738
3739 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3739 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3740 {node|short}desc to
3740 {node|short}desc to
3741 text.{rev}be wrapped
3741 text.{rev}be wrapped
3742 text.{rev}desc to be
3742 text.{rev}desc to be
3743 text.{rev}wrapped (no-eol)
3743 text.{rev}wrapped (no-eol)
3744 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3744 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3745 bcc7ff960b8e:desc to
3745 bcc7ff960b8e:desc to
3746 text.1:be wrapped
3746 text.1:be wrapped
3747 text.1:desc to be
3747 text.1:desc to be
3748 text.1:wrapped (no-eol)
3748 text.1:wrapped (no-eol)
3749 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3749 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3750 hg: parse error: fill expects an integer width
3750 hg: parse error: fill expects an integer width
3751 [255]
3751 [255]
3752
3752
3753 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
3753 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
3754 bcc7ff960b8e:desc to be
3754 bcc7ff960b8e:desc to be
3755 termwidth.1:wrapped desc
3755 termwidth.1:wrapped desc
3756 termwidth.1:to be wrapped (no-eol)
3756 termwidth.1:to be wrapped (no-eol)
3757
3757
3758 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3758 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3759 {node|short} (no-eol)
3759 {node|short} (no-eol)
3760 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3760 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3761 bcc-ff---b-e (no-eol)
3761 bcc-ff---b-e (no-eol)
3762
3762
3763 $ cat >> .hg/hgrc <<EOF
3763 $ cat >> .hg/hgrc <<EOF
3764 > [extensions]
3764 > [extensions]
3765 > color=
3765 > color=
3766 > [color]
3766 > [color]
3767 > mode=ansi
3767 > mode=ansi
3768 > text.{rev} = red
3768 > text.{rev} = red
3769 > text.1 = green
3769 > text.1 = green
3770 > EOF
3770 > EOF
3771 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3771 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3772 \x1b[0;31mtext\x1b[0m (esc)
3772 \x1b[0;31mtext\x1b[0m (esc)
3773 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3773 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3774 \x1b[0;32mtext\x1b[0m (esc)
3774 \x1b[0;32mtext\x1b[0m (esc)
3775
3775
3776 color effect can be specified without quoting:
3776 color effect can be specified without quoting:
3777
3777
3778 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
3778 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
3779 \x1b[0;31mtext\x1b[0m (esc)
3779 \x1b[0;31mtext\x1b[0m (esc)
3780
3780
3781 color effects can be nested (issue5413)
3781 color effects can be nested (issue5413)
3782
3782
3783 $ hg debugtemplate --color=always \
3783 $ hg debugtemplate --color=always \
3784 > '{label(red, "red{label(magenta, "ma{label(cyan, "cyan")}{label(yellow, "yellow")}genta")}")}\n'
3784 > '{label(red, "red{label(magenta, "ma{label(cyan, "cyan")}{label(yellow, "yellow")}genta")}")}\n'
3785 \x1b[0;31mred\x1b[0;35mma\x1b[0;36mcyan\x1b[0m\x1b[0;31m\x1b[0;35m\x1b[0;33myellow\x1b[0m\x1b[0;31m\x1b[0;35mgenta\x1b[0m (esc)
3785 \x1b[0;31mred\x1b[0;35mma\x1b[0;36mcyan\x1b[0m\x1b[0;31m\x1b[0;35m\x1b[0;33myellow\x1b[0m\x1b[0;31m\x1b[0;35mgenta\x1b[0m (esc)
3786
3786
3787 pad() should interact well with color codes (issue5416)
3787 pad() should interact well with color codes (issue5416)
3788
3788
3789 $ hg debugtemplate --color=always \
3789 $ hg debugtemplate --color=always \
3790 > '{pad(label(red, "red"), 5, label(cyan, "-"))}\n'
3790 > '{pad(label(red, "red"), 5, label(cyan, "-"))}\n'
3791 \x1b[0;31mred\x1b[0m\x1b[0;36m-\x1b[0m\x1b[0;36m-\x1b[0m (esc)
3791 \x1b[0;31mred\x1b[0m\x1b[0;36m-\x1b[0m\x1b[0;36m-\x1b[0m (esc)
3792
3792
3793 label should be no-op if color is disabled:
3793 label should be no-op if color is disabled:
3794
3794
3795 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
3795 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
3796 text
3796 text
3797 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
3797 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
3798 text
3798 text
3799
3799
3800 Test branches inside if statement:
3800 Test branches inside if statement:
3801
3801
3802 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3802 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3803 no
3803 no
3804
3804
3805 Test dict constructor:
3805 Test dict constructor:
3806
3806
3807 $ hg log -r 0 -T '{dict(y=node|short, x=rev)}\n'
3807 $ hg log -r 0 -T '{dict(y=node|short, x=rev)}\n'
3808 y=f7769ec2ab97 x=0
3808 y=f7769ec2ab97 x=0
3809 $ hg log -r 0 -T '{dict(x=rev, y=node|short) % "{key}={value}\n"}'
3809 $ hg log -r 0 -T '{dict(x=rev, y=node|short) % "{key}={value}\n"}'
3810 x=0
3810 x=0
3811 y=f7769ec2ab97
3811 y=f7769ec2ab97
3812 $ hg log -r 0 -T '{dict(x=rev, y=node|short)|json}\n'
3812 $ hg log -r 0 -T '{dict(x=rev, y=node|short)|json}\n'
3813 {"x": 0, "y": "f7769ec2ab97"}
3813 {"x": 0, "y": "f7769ec2ab97"}
3814 $ hg log -r 0 -T '{dict()|json}\n'
3814 $ hg log -r 0 -T '{dict()|json}\n'
3815 {}
3815 {}
3816
3816
3817 $ hg log -r 0 -T '{dict(rev, node=node|short)}\n'
3817 $ hg log -r 0 -T '{dict(rev, node=node|short)}\n'
3818 rev=0 node=f7769ec2ab97
3818 rev=0 node=f7769ec2ab97
3819 $ hg log -r 0 -T '{dict(rev, node|short)}\n'
3819 $ hg log -r 0 -T '{dict(rev, node|short)}\n'
3820 rev=0 node=f7769ec2ab97
3820 rev=0 node=f7769ec2ab97
3821
3821
3822 $ hg log -r 0 -T '{dict(rev, rev=rev)}\n'
3822 $ hg log -r 0 -T '{dict(rev, rev=rev)}\n'
3823 hg: parse error: duplicated dict key 'rev' inferred
3823 hg: parse error: duplicated dict key 'rev' inferred
3824 [255]
3824 [255]
3825 $ hg log -r 0 -T '{dict(node, node|short)}\n'
3825 $ hg log -r 0 -T '{dict(node, node|short)}\n'
3826 hg: parse error: duplicated dict key 'node' inferred
3826 hg: parse error: duplicated dict key 'node' inferred
3827 [255]
3827 [255]
3828 $ hg log -r 0 -T '{dict(1 + 2)}'
3828 $ hg log -r 0 -T '{dict(1 + 2)}'
3829 hg: parse error: dict key cannot be inferred
3829 hg: parse error: dict key cannot be inferred
3830 [255]
3830 [255]
3831
3831
3832 $ hg log -r 0 -T '{dict(x=rev, x=node)}'
3832 $ hg log -r 0 -T '{dict(x=rev, x=node)}'
3833 hg: parse error: dict got multiple values for keyword argument 'x'
3833 hg: parse error: dict got multiple values for keyword argument 'x'
3834 [255]
3834 [255]
3835
3835
3836 Test get function:
3836 Test get function:
3837
3837
3838 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3838 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3839 default
3839 default
3840 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3840 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3841 default
3841 default
3842 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3842 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3843 hg: parse error: get() expects a dict as first argument
3843 hg: parse error: get() expects a dict as first argument
3844 [255]
3844 [255]
3845
3845
3846 Test json filter applied to hybrid object:
3846 Test json filter applied to hybrid object:
3847
3847
3848 $ hg log -r0 -T '{files|json}\n'
3848 $ hg log -r0 -T '{files|json}\n'
3849 ["a"]
3849 ["a"]
3850 $ hg log -r0 -T '{extras|json}\n'
3850 $ hg log -r0 -T '{extras|json}\n'
3851 {"branch": "default"}
3851 {"branch": "default"}
3852
3852
3853 Test json filter applied to map result:
3853 Test json filter applied to map result:
3854
3854
3855 $ hg log -r0 -T '{json(extras % "{key}")}\n'
3855 $ hg log -r0 -T '{json(extras % "{key}")}\n'
3856 ["branch"]
3856 ["branch"]
3857
3857
3858 Test localdate(date, tz) function:
3858 Test localdate(date, tz) function:
3859
3859
3860 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3860 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3861 1970-01-01 09:00 +0900
3861 1970-01-01 09:00 +0900
3862 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3862 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3863 1970-01-01 00:00 +0000
3863 1970-01-01 00:00 +0000
3864 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "blahUTC")|isodate}\n'
3864 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "blahUTC")|isodate}\n'
3865 hg: parse error: localdate expects a timezone
3865 hg: parse error: localdate expects a timezone
3866 [255]
3866 [255]
3867 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3867 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3868 1970-01-01 02:00 +0200
3868 1970-01-01 02:00 +0200
3869 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3869 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3870 1970-01-01 00:00 +0000
3870 1970-01-01 00:00 +0000
3871 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3871 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3872 1970-01-01 00:00 +0000
3872 1970-01-01 00:00 +0000
3873 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3873 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3874 hg: parse error: localdate expects a timezone
3874 hg: parse error: localdate expects a timezone
3875 [255]
3875 [255]
3876 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3876 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3877 hg: parse error: localdate expects a timezone
3877 hg: parse error: localdate expects a timezone
3878 [255]
3878 [255]
3879
3879
3880 Test shortest(node) function:
3880 Test shortest(node) function:
3881
3881
3882 $ echo b > b
3882 $ echo b > b
3883 $ hg ci -qAm b
3883 $ hg ci -qAm b
3884 $ hg log --template '{shortest(node)}\n'
3884 $ hg log --template '{shortest(node)}\n'
3885 e777
3885 e777
3886 bcc7
3886 bcc7
3887 f776
3887 f776
3888 $ hg log --template '{shortest(node, 10)}\n'
3888 $ hg log --template '{shortest(node, 10)}\n'
3889 e777603221
3889 e777603221
3890 bcc7ff960b
3890 bcc7ff960b
3891 f7769ec2ab
3891 f7769ec2ab
3892 $ hg log --template '{node|shortest}\n' -l1
3892 $ hg log --template '{node|shortest}\n' -l1
3893 e777
3893 e777
3894
3894
3895 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
3895 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
3896 f7769ec2ab
3896 f7769ec2ab
3897 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
3897 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
3898 hg: parse error: shortest() expects an integer minlength
3898 hg: parse error: shortest() expects an integer minlength
3899 [255]
3899 [255]
3900
3900
3901 $ hg log -r 'wdir()' -T '{node|shortest}\n'
3901 $ hg log -r 'wdir()' -T '{node|shortest}\n'
3902 ffff
3902 ffff
3903
3903
3904 $ hg log --template '{shortest("f")}\n' -l1
3904 $ hg log --template '{shortest("f")}\n' -l1
3905 f
3905 f
3906
3906
3907 $ hg log --template '{shortest("0123456789012345678901234567890123456789")}\n' -l1
3907 $ hg log --template '{shortest("0123456789012345678901234567890123456789")}\n' -l1
3908 0123456789012345678901234567890123456789
3908 0123456789012345678901234567890123456789
3909
3909
3910 $ hg log --template '{shortest("01234567890123456789012345678901234567890123456789")}\n' -l1
3910 $ hg log --template '{shortest("01234567890123456789012345678901234567890123456789")}\n' -l1
3911 01234567890123456789012345678901234567890123456789
3911 01234567890123456789012345678901234567890123456789
3912
3912
3913 $ hg log --template '{shortest("not a hex string")}\n' -l1
3913 $ hg log --template '{shortest("not a hex string")}\n' -l1
3914 not a hex string
3914 not a hex string
3915
3915
3916 $ hg log --template '{shortest("not a hex string, but it'\''s 40 bytes long")}\n' -l1
3916 $ hg log --template '{shortest("not a hex string, but it'\''s 40 bytes long")}\n' -l1
3917 not a hex string, but it's 40 bytes long
3917 not a hex string, but it's 40 bytes long
3918
3918
3919 $ hg log --template '{shortest("ffffffffffffffffffffffffffffffffffffffff")}\n' -l1
3920 ffff
3921
3922 $ hg log --template '{shortest("fffffff")}\n' -l1
3923 ffff
3924
3925 $ hg log --template '{shortest("ff")}\n' -l1
3926 ffff
3927
3919 $ cd ..
3928 $ cd ..
3920
3929
3921 Test shortest(node) with the repo having short hash collision:
3930 Test shortest(node) with the repo having short hash collision:
3922
3931
3923 $ hg init hashcollision
3932 $ hg init hashcollision
3924 $ cd hashcollision
3933 $ cd hashcollision
3925 $ cat <<EOF >> .hg/hgrc
3934 $ cat <<EOF >> .hg/hgrc
3926 > [experimental]
3935 > [experimental]
3927 > evolution.createmarkers=True
3936 > evolution.createmarkers=True
3928 > EOF
3937 > EOF
3929 $ echo 0 > a
3938 $ echo 0 > a
3930 $ hg ci -qAm 0
3939 $ hg ci -qAm 0
3931 $ for i in 17 129 248 242 480 580 617 1057 2857 4025; do
3940 $ for i in 17 129 248 242 480 580 617 1057 2857 4025; do
3932 > hg up -q 0
3941 > hg up -q 0
3933 > echo $i > a
3942 > echo $i > a
3934 > hg ci -qm $i
3943 > hg ci -qm $i
3935 > done
3944 > done
3936 $ hg up -q null
3945 $ hg up -q null
3937 $ hg log -r0: -T '{rev}:{node}\n'
3946 $ hg log -r0: -T '{rev}:{node}\n'
3938 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
3947 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
3939 1:11424df6dc1dd4ea255eae2b58eaca7831973bbc
3948 1:11424df6dc1dd4ea255eae2b58eaca7831973bbc
3940 2:11407b3f1b9c3e76a79c1ec5373924df096f0499
3949 2:11407b3f1b9c3e76a79c1ec5373924df096f0499
3941 3:11dd92fe0f39dfdaacdaa5f3997edc533875cfc4
3950 3:11dd92fe0f39dfdaacdaa5f3997edc533875cfc4
3942 4:10776689e627b465361ad5c296a20a487e153ca4
3951 4:10776689e627b465361ad5c296a20a487e153ca4
3943 5:a00be79088084cb3aff086ab799f8790e01a976b
3952 5:a00be79088084cb3aff086ab799f8790e01a976b
3944 6:a0b0acd79b4498d0052993d35a6a748dd51d13e6
3953 6:a0b0acd79b4498d0052993d35a6a748dd51d13e6
3945 7:a0457b3450b8e1b778f1163b31a435802987fe5d
3954 7:a0457b3450b8e1b778f1163b31a435802987fe5d
3946 8:c56256a09cd28e5764f32e8e2810d0f01e2e357a
3955 8:c56256a09cd28e5764f32e8e2810d0f01e2e357a
3947 9:c5623987d205cd6d9d8389bfc40fff9dbb670b48
3956 9:c5623987d205cd6d9d8389bfc40fff9dbb670b48
3948 10:c562ddd9c94164376c20b86b0b4991636a3bf84f
3957 10:c562ddd9c94164376c20b86b0b4991636a3bf84f
3949 $ hg debugobsolete a00be79088084cb3aff086ab799f8790e01a976b
3958 $ hg debugobsolete a00be79088084cb3aff086ab799f8790e01a976b
3950 obsoleted 1 changesets
3959 obsoleted 1 changesets
3951 $ hg debugobsolete c5623987d205cd6d9d8389bfc40fff9dbb670b48
3960 $ hg debugobsolete c5623987d205cd6d9d8389bfc40fff9dbb670b48
3952 obsoleted 1 changesets
3961 obsoleted 1 changesets
3953 $ hg debugobsolete c562ddd9c94164376c20b86b0b4991636a3bf84f
3962 $ hg debugobsolete c562ddd9c94164376c20b86b0b4991636a3bf84f
3954 obsoleted 1 changesets
3963 obsoleted 1 changesets
3955
3964
3956 nodes starting with '11' (we don't have the revision number '11' though)
3965 nodes starting with '11' (we don't have the revision number '11' though)
3957
3966
3958 $ hg log -r 1:3 -T '{rev}:{shortest(node, 0)}\n'
3967 $ hg log -r 1:3 -T '{rev}:{shortest(node, 0)}\n'
3959 1:1142
3968 1:1142
3960 2:1140
3969 2:1140
3961 3:11d
3970 3:11d
3962
3971
3963 '5:a00' is hidden, but still we have two nodes starting with 'a0'
3972 '5:a00' is hidden, but still we have two nodes starting with 'a0'
3964
3973
3965 $ hg log -r 6:7 -T '{rev}:{shortest(node, 0)}\n'
3974 $ hg log -r 6:7 -T '{rev}:{shortest(node, 0)}\n'
3966 6:a0b
3975 6:a0b
3967 7:a04
3976 7:a04
3968
3977
3969 node '10' conflicts with the revision number '10' even if it is hidden
3978 node '10' conflicts with the revision number '10' even if it is hidden
3970 (we could exclude hidden revision numbers, but currently we don't)
3979 (we could exclude hidden revision numbers, but currently we don't)
3971
3980
3972 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n'
3981 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n'
3973 4:107
3982 4:107
3974 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden
3983 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden
3975 4:107
3984 4:107
3976
3985
3977 node 'c562' should be unique if the other 'c562' nodes are hidden
3986 node 'c562' should be unique if the other 'c562' nodes are hidden
3978 (but we don't try the slow path to filter out hidden nodes for now)
3987 (but we don't try the slow path to filter out hidden nodes for now)
3979
3988
3980 $ hg log -r 8 -T '{rev}:{node|shortest}\n'
3989 $ hg log -r 8 -T '{rev}:{node|shortest}\n'
3981 8:c5625
3990 8:c5625
3982 $ hg log -r 8:10 -T '{rev}:{node|shortest}\n' --hidden
3991 $ hg log -r 8:10 -T '{rev}:{node|shortest}\n' --hidden
3983 8:c5625
3992 8:c5625
3984 9:c5623
3993 9:c5623
3985 10:c562d
3994 10:c562d
3986
3995
3987 $ cd ..
3996 $ cd ..
3988
3997
3989 Test pad function
3998 Test pad function
3990
3999
3991 $ cd r
4000 $ cd r
3992
4001
3993 $ hg log --template '{pad(rev, 20)} {author|user}\n'
4002 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3994 2 test
4003 2 test
3995 1 {node|short}
4004 1 {node|short}
3996 0 test
4005 0 test
3997
4006
3998 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
4007 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3999 2 test
4008 2 test
4000 1 {node|short}
4009 1 {node|short}
4001 0 test
4010 0 test
4002
4011
4003 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
4012 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
4004 2------------------- test
4013 2------------------- test
4005 1------------------- {node|short}
4014 1------------------- {node|short}
4006 0------------------- test
4015 0------------------- test
4007
4016
4008 Test template string in pad function
4017 Test template string in pad function
4009
4018
4010 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
4019 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
4011 {0} test
4020 {0} test
4012
4021
4013 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
4022 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
4014 \{rev} test
4023 \{rev} test
4015
4024
4016 Test width argument passed to pad function
4025 Test width argument passed to pad function
4017
4026
4018 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
4027 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
4019 0 test
4028 0 test
4020 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
4029 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
4021 hg: parse error: pad() expects an integer width
4030 hg: parse error: pad() expects an integer width
4022 [255]
4031 [255]
4023
4032
4024 Test invalid fillchar passed to pad function
4033 Test invalid fillchar passed to pad function
4025
4034
4026 $ hg log -r 0 -T '{pad(rev, 10, "")}\n'
4035 $ hg log -r 0 -T '{pad(rev, 10, "")}\n'
4027 hg: parse error: pad() expects a single fill character
4036 hg: parse error: pad() expects a single fill character
4028 [255]
4037 [255]
4029 $ hg log -r 0 -T '{pad(rev, 10, "--")}\n'
4038 $ hg log -r 0 -T '{pad(rev, 10, "--")}\n'
4030 hg: parse error: pad() expects a single fill character
4039 hg: parse error: pad() expects a single fill character
4031 [255]
4040 [255]
4032
4041
4033 Test boolean argument passed to pad function
4042 Test boolean argument passed to pad function
4034
4043
4035 no crash
4044 no crash
4036
4045
4037 $ hg log -r 0 -T '{pad(rev, 10, "-", "f{"oo"}")}\n'
4046 $ hg log -r 0 -T '{pad(rev, 10, "-", "f{"oo"}")}\n'
4038 ---------0
4047 ---------0
4039
4048
4040 string/literal
4049 string/literal
4041
4050
4042 $ hg log -r 0 -T '{pad(rev, 10, "-", "false")}\n'
4051 $ hg log -r 0 -T '{pad(rev, 10, "-", "false")}\n'
4043 ---------0
4052 ---------0
4044 $ hg log -r 0 -T '{pad(rev, 10, "-", false)}\n'
4053 $ hg log -r 0 -T '{pad(rev, 10, "-", false)}\n'
4045 0---------
4054 0---------
4046 $ hg log -r 0 -T '{pad(rev, 10, "-", "")}\n'
4055 $ hg log -r 0 -T '{pad(rev, 10, "-", "")}\n'
4047 0---------
4056 0---------
4048
4057
4049 unknown keyword is evaluated to ''
4058 unknown keyword is evaluated to ''
4050
4059
4051 $ hg log -r 0 -T '{pad(rev, 10, "-", unknownkeyword)}\n'
4060 $ hg log -r 0 -T '{pad(rev, 10, "-", unknownkeyword)}\n'
4052 0---------
4061 0---------
4053
4062
4054 Test separate function
4063 Test separate function
4055
4064
4056 $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
4065 $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
4057 a-b-c
4066 a-b-c
4058 $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
4067 $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
4059 0:f7769ec2ab97 test default
4068 0:f7769ec2ab97 test default
4060 $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
4069 $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
4061 a \x1b[0;31mb\x1b[0m c d (esc)
4070 a \x1b[0;31mb\x1b[0m c d (esc)
4062
4071
4063 Test boolean expression/literal passed to if function
4072 Test boolean expression/literal passed to if function
4064
4073
4065 $ hg log -r 0 -T '{if(rev, "rev 0 is True")}\n'
4074 $ hg log -r 0 -T '{if(rev, "rev 0 is True")}\n'
4066 rev 0 is True
4075 rev 0 is True
4067 $ hg log -r 0 -T '{if(0, "literal 0 is True as well")}\n'
4076 $ hg log -r 0 -T '{if(0, "literal 0 is True as well")}\n'
4068 literal 0 is True as well
4077 literal 0 is True as well
4069 $ hg log -r 0 -T '{if("", "", "empty string is False")}\n'
4078 $ hg log -r 0 -T '{if("", "", "empty string is False")}\n'
4070 empty string is False
4079 empty string is False
4071 $ hg log -r 0 -T '{if(revset(r"0 - 0"), "", "empty list is False")}\n'
4080 $ hg log -r 0 -T '{if(revset(r"0 - 0"), "", "empty list is False")}\n'
4072 empty list is False
4081 empty list is False
4073 $ hg log -r 0 -T '{if(true, "true is True")}\n'
4082 $ hg log -r 0 -T '{if(true, "true is True")}\n'
4074 true is True
4083 true is True
4075 $ hg log -r 0 -T '{if(false, "", "false is False")}\n'
4084 $ hg log -r 0 -T '{if(false, "", "false is False")}\n'
4076 false is False
4085 false is False
4077 $ hg log -r 0 -T '{if("false", "non-empty string is True")}\n'
4086 $ hg log -r 0 -T '{if("false", "non-empty string is True")}\n'
4078 non-empty string is True
4087 non-empty string is True
4079
4088
4080 Test ifcontains function
4089 Test ifcontains function
4081
4090
4082 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
4091 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
4083 2 is in the string
4092 2 is in the string
4084 1 is not
4093 1 is not
4085 0 is in the string
4094 0 is in the string
4086
4095
4087 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
4096 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
4088 2 is in the string
4097 2 is in the string
4089 1 is not
4098 1 is not
4090 0 is in the string
4099 0 is in the string
4091
4100
4092 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
4101 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
4093 2 did not add a
4102 2 did not add a
4094 1 did not add a
4103 1 did not add a
4095 0 added a
4104 0 added a
4096
4105
4097 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
4106 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
4098 2 is parent of 1
4107 2 is parent of 1
4099 1
4108 1
4100 0
4109 0
4101
4110
4102 Test revset function
4111 Test revset function
4103
4112
4104 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
4113 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
4105 2 current rev
4114 2 current rev
4106 1 not current rev
4115 1 not current rev
4107 0 not current rev
4116 0 not current rev
4108
4117
4109 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
4118 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
4110 2 match rev
4119 2 match rev
4111 1 match rev
4120 1 match rev
4112 0 not match rev
4121 0 not match rev
4113
4122
4114 $ hg log -T '{ifcontains(desc, revset(":"), "", "type not match")}\n' -l1
4123 $ hg log -T '{ifcontains(desc, revset(":"), "", "type not match")}\n' -l1
4115 type not match
4124 type not match
4116
4125
4117 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
4126 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
4118 2 Parents: 1
4127 2 Parents: 1
4119 1 Parents: 0
4128 1 Parents: 0
4120 0 Parents:
4129 0 Parents:
4121
4130
4122 $ cat >> .hg/hgrc <<EOF
4131 $ cat >> .hg/hgrc <<EOF
4123 > [revsetalias]
4132 > [revsetalias]
4124 > myparents(\$1) = parents(\$1)
4133 > myparents(\$1) = parents(\$1)
4125 > EOF
4134 > EOF
4126 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
4135 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
4127 2 Parents: 1
4136 2 Parents: 1
4128 1 Parents: 0
4137 1 Parents: 0
4129 0 Parents:
4138 0 Parents:
4130
4139
4131 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
4140 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
4132 Rev: 2
4141 Rev: 2
4133 Ancestor: 0
4142 Ancestor: 0
4134 Ancestor: 1
4143 Ancestor: 1
4135 Ancestor: 2
4144 Ancestor: 2
4136
4145
4137 Rev: 1
4146 Rev: 1
4138 Ancestor: 0
4147 Ancestor: 0
4139 Ancestor: 1
4148 Ancestor: 1
4140
4149
4141 Rev: 0
4150 Rev: 0
4142 Ancestor: 0
4151 Ancestor: 0
4143
4152
4144 $ hg log --template '{revset("TIP"|lower)}\n' -l1
4153 $ hg log --template '{revset("TIP"|lower)}\n' -l1
4145 2
4154 2
4146
4155
4147 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
4156 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
4148 2
4157 2
4149
4158
4150 a list template is evaluated for each item of revset/parents
4159 a list template is evaluated for each item of revset/parents
4151
4160
4152 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
4161 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
4153 2 p: 1:bcc7ff960b8e
4162 2 p: 1:bcc7ff960b8e
4154 1 p: 0:f7769ec2ab97
4163 1 p: 0:f7769ec2ab97
4155 0 p:
4164 0 p:
4156
4165
4157 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
4166 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
4158 2 p: 1:bcc7ff960b8e -1:000000000000
4167 2 p: 1:bcc7ff960b8e -1:000000000000
4159 1 p: 0:f7769ec2ab97 -1:000000000000
4168 1 p: 0:f7769ec2ab97 -1:000000000000
4160 0 p: -1:000000000000 -1:000000000000
4169 0 p: -1:000000000000 -1:000000000000
4161
4170
4162 therefore, 'revcache' should be recreated for each rev
4171 therefore, 'revcache' should be recreated for each rev
4163
4172
4164 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
4173 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
4165 2 aa b
4174 2 aa b
4166 p
4175 p
4167 1
4176 1
4168 p a
4177 p a
4169 0 a
4178 0 a
4170 p
4179 p
4171
4180
4172 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
4181 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
4173 2 aa b
4182 2 aa b
4174 p
4183 p
4175 1
4184 1
4176 p a
4185 p a
4177 0 a
4186 0 a
4178 p
4187 p
4179
4188
4180 a revset item must be evaluated as an integer revision, not an offset from tip
4189 a revset item must be evaluated as an integer revision, not an offset from tip
4181
4190
4182 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
4191 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
4183 -1:000000000000
4192 -1:000000000000
4184 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
4193 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
4185 -1:000000000000
4194 -1:000000000000
4186
4195
4187 join() should pick '{rev}' from revset items:
4196 join() should pick '{rev}' from revset items:
4188
4197
4189 $ hg log -R ../a -T '{join(revset("parents(%d)", rev), ", ")}\n' -r6
4198 $ hg log -R ../a -T '{join(revset("parents(%d)", rev), ", ")}\n' -r6
4190 4, 5
4199 4, 5
4191
4200
4192 on the other hand, parents are formatted as '{rev}:{node|formatnode}' by
4201 on the other hand, parents are formatted as '{rev}:{node|formatnode}' by
4193 default. join() should agree with the default formatting:
4202 default. join() should agree with the default formatting:
4194
4203
4195 $ hg log -R ../a -T '{join(parents, ", ")}\n' -r6
4204 $ hg log -R ../a -T '{join(parents, ", ")}\n' -r6
4196 5:13207e5a10d9, 4:bbe44766e73d
4205 5:13207e5a10d9, 4:bbe44766e73d
4197
4206
4198 $ hg log -R ../a -T '{join(parents, ",\n")}\n' -r6 --debug
4207 $ hg log -R ../a -T '{join(parents, ",\n")}\n' -r6 --debug
4199 5:13207e5a10d9fd28ec424934298e176197f2c67f,
4208 5:13207e5a10d9fd28ec424934298e176197f2c67f,
4200 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
4209 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
4201
4210
4202 Invalid arguments passed to revset()
4211 Invalid arguments passed to revset()
4203
4212
4204 $ hg log -T '{revset("%whatever", 0)}\n'
4213 $ hg log -T '{revset("%whatever", 0)}\n'
4205 hg: parse error: unexpected revspec format character w
4214 hg: parse error: unexpected revspec format character w
4206 [255]
4215 [255]
4207 $ hg log -T '{revset("%lwhatever", files)}\n'
4216 $ hg log -T '{revset("%lwhatever", files)}\n'
4208 hg: parse error: unexpected revspec format character w
4217 hg: parse error: unexpected revspec format character w
4209 [255]
4218 [255]
4210 $ hg log -T '{revset("%s %s", 0)}\n'
4219 $ hg log -T '{revset("%s %s", 0)}\n'
4211 hg: parse error: missing argument for revspec
4220 hg: parse error: missing argument for revspec
4212 [255]
4221 [255]
4213 $ hg log -T '{revset("", 0)}\n'
4222 $ hg log -T '{revset("", 0)}\n'
4214 hg: parse error: too many revspec arguments specified
4223 hg: parse error: too many revspec arguments specified
4215 [255]
4224 [255]
4216 $ hg log -T '{revset("%s", 0, 1)}\n'
4225 $ hg log -T '{revset("%s", 0, 1)}\n'
4217 hg: parse error: too many revspec arguments specified
4226 hg: parse error: too many revspec arguments specified
4218 [255]
4227 [255]
4219 $ hg log -T '{revset("%", 0)}\n'
4228 $ hg log -T '{revset("%", 0)}\n'
4220 hg: parse error: incomplete revspec format character
4229 hg: parse error: incomplete revspec format character
4221 [255]
4230 [255]
4222 $ hg log -T '{revset("%l", 0)}\n'
4231 $ hg log -T '{revset("%l", 0)}\n'
4223 hg: parse error: incomplete revspec format character
4232 hg: parse error: incomplete revspec format character
4224 [255]
4233 [255]
4225 $ hg log -T '{revset("%d", 'foo')}\n'
4234 $ hg log -T '{revset("%d", 'foo')}\n'
4226 hg: parse error: invalid argument for revspec
4235 hg: parse error: invalid argument for revspec
4227 [255]
4236 [255]
4228 $ hg log -T '{revset("%ld", files)}\n'
4237 $ hg log -T '{revset("%ld", files)}\n'
4229 hg: parse error: invalid argument for revspec
4238 hg: parse error: invalid argument for revspec
4230 [255]
4239 [255]
4231 $ hg log -T '{revset("%ls", 0)}\n'
4240 $ hg log -T '{revset("%ls", 0)}\n'
4232 hg: parse error: invalid argument for revspec
4241 hg: parse error: invalid argument for revspec
4233 [255]
4242 [255]
4234 $ hg log -T '{revset("%b", 'foo')}\n'
4243 $ hg log -T '{revset("%b", 'foo')}\n'
4235 hg: parse error: invalid argument for revspec
4244 hg: parse error: invalid argument for revspec
4236 [255]
4245 [255]
4237 $ hg log -T '{revset("%lb", files)}\n'
4246 $ hg log -T '{revset("%lb", files)}\n'
4238 hg: parse error: invalid argument for revspec
4247 hg: parse error: invalid argument for revspec
4239 [255]
4248 [255]
4240 $ hg log -T '{revset("%r", 0)}\n'
4249 $ hg log -T '{revset("%r", 0)}\n'
4241 hg: parse error: invalid argument for revspec
4250 hg: parse error: invalid argument for revspec
4242 [255]
4251 [255]
4243
4252
4244 Test 'originalnode'
4253 Test 'originalnode'
4245
4254
4246 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
4255 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
4247 000000000000 bcc7ff960b8e
4256 000000000000 bcc7ff960b8e
4248 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
4257 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
4249 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
4258 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
4250
4259
4251 Test files function
4260 Test files function
4252
4261
4253 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
4262 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
4254 2
4263 2
4255 a
4264 a
4256 aa
4265 aa
4257 b
4266 b
4258 1
4267 1
4259 a
4268 a
4260 0
4269 0
4261 a
4270 a
4262
4271
4263 $ hg log -T "{rev}\n{join(files('aa'), '\n')}\n"
4272 $ hg log -T "{rev}\n{join(files('aa'), '\n')}\n"
4264 2
4273 2
4265 aa
4274 aa
4266 1
4275 1
4267
4276
4268 0
4277 0
4269
4278
4270
4279
4271 Test relpath function
4280 Test relpath function
4272
4281
4273 $ hg log -r0 -T '{files % "{file|relpath}\n"}'
4282 $ hg log -r0 -T '{files % "{file|relpath}\n"}'
4274 a
4283 a
4275 $ cd ..
4284 $ cd ..
4276 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
4285 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
4277 r/a
4286 r/a
4278 $ cd r
4287 $ cd r
4279
4288
4280 Test active bookmark templating
4289 Test active bookmark templating
4281
4290
4282 $ hg book foo
4291 $ hg book foo
4283 $ hg book bar
4292 $ hg book bar
4284 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
4293 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
4285 2 bar* foo
4294 2 bar* foo
4286 1
4295 1
4287 0
4296 0
4288 $ hg log --template "{rev} {activebookmark}\n"
4297 $ hg log --template "{rev} {activebookmark}\n"
4289 2 bar
4298 2 bar
4290 1
4299 1
4291 0
4300 0
4292 $ hg bookmarks --inactive bar
4301 $ hg bookmarks --inactive bar
4293 $ hg log --template "{rev} {activebookmark}\n"
4302 $ hg log --template "{rev} {activebookmark}\n"
4294 2
4303 2
4295 1
4304 1
4296 0
4305 0
4297 $ hg book -r1 baz
4306 $ hg book -r1 baz
4298 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
4307 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
4299 2 bar foo
4308 2 bar foo
4300 1 baz
4309 1 baz
4301 0
4310 0
4302 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
4311 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
4303 2 t
4312 2 t
4304 1 f
4313 1 f
4305 0 f
4314 0 f
4306
4315
4307 Test namespaces dict
4316 Test namespaces dict
4308
4317
4309 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
4318 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
4310 2
4319 2
4311 bookmarks color=bookmark builtin=True
4320 bookmarks color=bookmark builtin=True
4312 bar,foo
4321 bar,foo
4313 tags color=tag builtin=True
4322 tags color=tag builtin=True
4314 tip
4323 tip
4315 branches color=branch builtin=True
4324 branches color=branch builtin=True
4316 text.{rev}
4325 text.{rev}
4317 revnames color=revname builtin=False
4326 revnames color=revname builtin=False
4318 r2
4327 r2
4319
4328
4320 1
4329 1
4321 bookmarks color=bookmark builtin=True
4330 bookmarks color=bookmark builtin=True
4322 baz
4331 baz
4323 tags color=tag builtin=True
4332 tags color=tag builtin=True
4324
4333
4325 branches color=branch builtin=True
4334 branches color=branch builtin=True
4326 text.{rev}
4335 text.{rev}
4327 revnames color=revname builtin=False
4336 revnames color=revname builtin=False
4328 r1
4337 r1
4329
4338
4330 0
4339 0
4331 bookmarks color=bookmark builtin=True
4340 bookmarks color=bookmark builtin=True
4332
4341
4333 tags color=tag builtin=True
4342 tags color=tag builtin=True
4334
4343
4335 branches color=branch builtin=True
4344 branches color=branch builtin=True
4336 default
4345 default
4337 revnames color=revname builtin=False
4346 revnames color=revname builtin=False
4338 r0
4347 r0
4339
4348
4340 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
4349 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
4341 bookmarks: bar foo
4350 bookmarks: bar foo
4342 tags: tip
4351 tags: tip
4343 branches: text.{rev}
4352 branches: text.{rev}
4344 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
4353 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
4345 bookmarks:
4354 bookmarks:
4346 bar
4355 bar
4347 foo
4356 foo
4348 tags:
4357 tags:
4349 tip
4358 tip
4350 branches:
4359 branches:
4351 text.{rev}
4360 text.{rev}
4352 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
4361 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
4353 bar
4362 bar
4354 foo
4363 foo
4355 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
4364 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
4356 bar
4365 bar
4357 foo
4366 foo
4358
4367
4359 Test stringify on sub expressions
4368 Test stringify on sub expressions
4360
4369
4361 $ cd ..
4370 $ cd ..
4362 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
4371 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
4363 fourth, second, third
4372 fourth, second, third
4364 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
4373 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
4365 abc
4374 abc
4366
4375
4367 Test splitlines
4376 Test splitlines
4368
4377
4369 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
4378 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
4370 @ foo Modify, add, remove, rename
4379 @ foo Modify, add, remove, rename
4371 |
4380 |
4372 o foo future
4381 o foo future
4373 |
4382 |
4374 o foo third
4383 o foo third
4375 |
4384 |
4376 o foo second
4385 o foo second
4377
4386
4378 o foo merge
4387 o foo merge
4379 |\
4388 |\
4380 | o foo new head
4389 | o foo new head
4381 | |
4390 | |
4382 o | foo new branch
4391 o | foo new branch
4383 |/
4392 |/
4384 o foo no user, no domain
4393 o foo no user, no domain
4385 |
4394 |
4386 o foo no person
4395 o foo no person
4387 |
4396 |
4388 o foo other 1
4397 o foo other 1
4389 | foo other 2
4398 | foo other 2
4390 | foo
4399 | foo
4391 | foo other 3
4400 | foo other 3
4392 o foo line 1
4401 o foo line 1
4393 foo line 2
4402 foo line 2
4394
4403
4395 $ hg log -R a -r0 -T '{desc|splitlines}\n'
4404 $ hg log -R a -r0 -T '{desc|splitlines}\n'
4396 line 1 line 2
4405 line 1 line 2
4397 $ hg log -R a -r0 -T '{join(desc|splitlines, "|")}\n'
4406 $ hg log -R a -r0 -T '{join(desc|splitlines, "|")}\n'
4398 line 1|line 2
4407 line 1|line 2
4399
4408
4400 Test startswith
4409 Test startswith
4401 $ hg log -Gv -R a --template "{startswith(desc)}"
4410 $ hg log -Gv -R a --template "{startswith(desc)}"
4402 hg: parse error: startswith expects two arguments
4411 hg: parse error: startswith expects two arguments
4403 [255]
4412 [255]
4404
4413
4405 $ hg log -Gv -R a --template "{startswith('line', desc)}"
4414 $ hg log -Gv -R a --template "{startswith('line', desc)}"
4406 @
4415 @
4407 |
4416 |
4408 o
4417 o
4409 |
4418 |
4410 o
4419 o
4411 |
4420 |
4412 o
4421 o
4413
4422
4414 o
4423 o
4415 |\
4424 |\
4416 | o
4425 | o
4417 | |
4426 | |
4418 o |
4427 o |
4419 |/
4428 |/
4420 o
4429 o
4421 |
4430 |
4422 o
4431 o
4423 |
4432 |
4424 o
4433 o
4425 |
4434 |
4426 o line 1
4435 o line 1
4427 line 2
4436 line 2
4428
4437
4429 Test bad template with better error message
4438 Test bad template with better error message
4430
4439
4431 $ hg log -Gv -R a --template '{desc|user()}'
4440 $ hg log -Gv -R a --template '{desc|user()}'
4432 hg: parse error: expected a symbol, got 'func'
4441 hg: parse error: expected a symbol, got 'func'
4433 [255]
4442 [255]
4434
4443
4435 Test word function (including index out of bounds graceful failure)
4444 Test word function (including index out of bounds graceful failure)
4436
4445
4437 $ hg log -Gv -R a --template "{word('1', desc)}"
4446 $ hg log -Gv -R a --template "{word('1', desc)}"
4438 @ add,
4447 @ add,
4439 |
4448 |
4440 o
4449 o
4441 |
4450 |
4442 o
4451 o
4443 |
4452 |
4444 o
4453 o
4445
4454
4446 o
4455 o
4447 |\
4456 |\
4448 | o head
4457 | o head
4449 | |
4458 | |
4450 o | branch
4459 o | branch
4451 |/
4460 |/
4452 o user,
4461 o user,
4453 |
4462 |
4454 o person
4463 o person
4455 |
4464 |
4456 o 1
4465 o 1
4457 |
4466 |
4458 o 1
4467 o 1
4459
4468
4460
4469
4461 Test word third parameter used as splitter
4470 Test word third parameter used as splitter
4462
4471
4463 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
4472 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
4464 @ M
4473 @ M
4465 |
4474 |
4466 o future
4475 o future
4467 |
4476 |
4468 o third
4477 o third
4469 |
4478 |
4470 o sec
4479 o sec
4471
4480
4472 o merge
4481 o merge
4473 |\
4482 |\
4474 | o new head
4483 | o new head
4475 | |
4484 | |
4476 o | new branch
4485 o | new branch
4477 |/
4486 |/
4478 o n
4487 o n
4479 |
4488 |
4480 o n
4489 o n
4481 |
4490 |
4482 o
4491 o
4483 |
4492 |
4484 o line 1
4493 o line 1
4485 line 2
4494 line 2
4486
4495
4487 Test word error messages for not enough and too many arguments
4496 Test word error messages for not enough and too many arguments
4488
4497
4489 $ hg log -Gv -R a --template "{word('0')}"
4498 $ hg log -Gv -R a --template "{word('0')}"
4490 hg: parse error: word expects two or three arguments, got 1
4499 hg: parse error: word expects two or three arguments, got 1
4491 [255]
4500 [255]
4492
4501
4493 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
4502 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
4494 hg: parse error: word expects two or three arguments, got 7
4503 hg: parse error: word expects two or three arguments, got 7
4495 [255]
4504 [255]
4496
4505
4497 Test word for integer literal
4506 Test word for integer literal
4498
4507
4499 $ hg log -R a --template "{word(2, desc)}\n" -r0
4508 $ hg log -R a --template "{word(2, desc)}\n" -r0
4500 line
4509 line
4501
4510
4502 Test word for invalid numbers
4511 Test word for invalid numbers
4503
4512
4504 $ hg log -Gv -R a --template "{word('a', desc)}"
4513 $ hg log -Gv -R a --template "{word('a', desc)}"
4505 hg: parse error: word expects an integer index
4514 hg: parse error: word expects an integer index
4506 [255]
4515 [255]
4507
4516
4508 Test word for out of range
4517 Test word for out of range
4509
4518
4510 $ hg log -R a --template "{word(10000, desc)}"
4519 $ hg log -R a --template "{word(10000, desc)}"
4511 $ hg log -R a --template "{word(-10000, desc)}"
4520 $ hg log -R a --template "{word(-10000, desc)}"
4512
4521
4513 Test indent and not adding to empty lines
4522 Test indent and not adding to empty lines
4514
4523
4515 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
4524 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
4516 -----
4525 -----
4517 > line 1
4526 > line 1
4518 >> line 2
4527 >> line 2
4519 -----
4528 -----
4520 > other 1
4529 > other 1
4521 >> other 2
4530 >> other 2
4522
4531
4523 >> other 3
4532 >> other 3
4524
4533
4525 Test with non-strings like dates
4534 Test with non-strings like dates
4526
4535
4527 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
4536 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
4528 1200000.00
4537 1200000.00
4529 1300000.00
4538 1300000.00
4530
4539
4531 Test broken string escapes:
4540 Test broken string escapes:
4532
4541
4533 $ hg log -T "bogus\\" -R a
4542 $ hg log -T "bogus\\" -R a
4534 hg: parse error: trailing \ in string
4543 hg: parse error: trailing \ in string
4535 [255]
4544 [255]
4536 $ hg log -T "\\xy" -R a
4545 $ hg log -T "\\xy" -R a
4537 hg: parse error: invalid \x escape* (glob)
4546 hg: parse error: invalid \x escape* (glob)
4538 [255]
4547 [255]
4539
4548
4540 json filter should escape HTML tags so that the output can be embedded in hgweb:
4549 json filter should escape HTML tags so that the output can be embedded in hgweb:
4541
4550
4542 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
4551 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
4543 "\u003cfoo@example.org\u003e"
4552 "\u003cfoo@example.org\u003e"
4544
4553
4545 Templater supports aliases of symbol and func() styles:
4554 Templater supports aliases of symbol and func() styles:
4546
4555
4547 $ hg clone -q a aliases
4556 $ hg clone -q a aliases
4548 $ cd aliases
4557 $ cd aliases
4549 $ cat <<EOF >> .hg/hgrc
4558 $ cat <<EOF >> .hg/hgrc
4550 > [templatealias]
4559 > [templatealias]
4551 > r = rev
4560 > r = rev
4552 > rn = "{r}:{node|short}"
4561 > rn = "{r}:{node|short}"
4553 > status(c, files) = files % "{c} {file}\n"
4562 > status(c, files) = files % "{c} {file}\n"
4554 > utcdate(d) = localdate(d, "UTC")
4563 > utcdate(d) = localdate(d, "UTC")
4555 > EOF
4564 > EOF
4556
4565
4557 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
4566 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
4558 (template
4567 (template
4559 (symbol 'rn')
4568 (symbol 'rn')
4560 (string ' ')
4569 (string ' ')
4561 (|
4570 (|
4562 (func
4571 (func
4563 (symbol 'utcdate')
4572 (symbol 'utcdate')
4564 (symbol 'date'))
4573 (symbol 'date'))
4565 (symbol 'isodate'))
4574 (symbol 'isodate'))
4566 (string '\n'))
4575 (string '\n'))
4567 * expanded:
4576 * expanded:
4568 (template
4577 (template
4569 (template
4578 (template
4570 (symbol 'rev')
4579 (symbol 'rev')
4571 (string ':')
4580 (string ':')
4572 (|
4581 (|
4573 (symbol 'node')
4582 (symbol 'node')
4574 (symbol 'short')))
4583 (symbol 'short')))
4575 (string ' ')
4584 (string ' ')
4576 (|
4585 (|
4577 (func
4586 (func
4578 (symbol 'localdate')
4587 (symbol 'localdate')
4579 (list
4588 (list
4580 (symbol 'date')
4589 (symbol 'date')
4581 (string 'UTC')))
4590 (string 'UTC')))
4582 (symbol 'isodate'))
4591 (symbol 'isodate'))
4583 (string '\n'))
4592 (string '\n'))
4584 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4593 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4585
4594
4586 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
4595 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
4587 (template
4596 (template
4588 (func
4597 (func
4589 (symbol 'status')
4598 (symbol 'status')
4590 (list
4599 (list
4591 (string 'A')
4600 (string 'A')
4592 (symbol 'file_adds'))))
4601 (symbol 'file_adds'))))
4593 * expanded:
4602 * expanded:
4594 (template
4603 (template
4595 (%
4604 (%
4596 (symbol 'file_adds')
4605 (symbol 'file_adds')
4597 (template
4606 (template
4598 (string 'A')
4607 (string 'A')
4599 (string ' ')
4608 (string ' ')
4600 (symbol 'file')
4609 (symbol 'file')
4601 (string '\n'))))
4610 (string '\n'))))
4602 A a
4611 A a
4603
4612
4604 A unary function alias can be called as a filter:
4613 A unary function alias can be called as a filter:
4605
4614
4606 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
4615 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
4607 (template
4616 (template
4608 (|
4617 (|
4609 (|
4618 (|
4610 (symbol 'date')
4619 (symbol 'date')
4611 (symbol 'utcdate'))
4620 (symbol 'utcdate'))
4612 (symbol 'isodate'))
4621 (symbol 'isodate'))
4613 (string '\n'))
4622 (string '\n'))
4614 * expanded:
4623 * expanded:
4615 (template
4624 (template
4616 (|
4625 (|
4617 (func
4626 (func
4618 (symbol 'localdate')
4627 (symbol 'localdate')
4619 (list
4628 (list
4620 (symbol 'date')
4629 (symbol 'date')
4621 (string 'UTC')))
4630 (string 'UTC')))
4622 (symbol 'isodate'))
4631 (symbol 'isodate'))
4623 (string '\n'))
4632 (string '\n'))
4624 1970-01-12 13:46 +0000
4633 1970-01-12 13:46 +0000
4625
4634
4626 Aliases should be applied only to command arguments and templates in hgrc.
4635 Aliases should be applied only to command arguments and templates in hgrc.
4627 Otherwise, our stock styles and web templates could be corrupted:
4636 Otherwise, our stock styles and web templates could be corrupted:
4628
4637
4629 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
4638 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
4630 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4639 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4631
4640
4632 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
4641 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
4633 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4642 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4634
4643
4635 $ cat <<EOF > tmpl
4644 $ cat <<EOF > tmpl
4636 > changeset = 'nothing expanded:{rn}\n'
4645 > changeset = 'nothing expanded:{rn}\n'
4637 > EOF
4646 > EOF
4638 $ hg log -r0 --style ./tmpl
4647 $ hg log -r0 --style ./tmpl
4639 nothing expanded:
4648 nothing expanded:
4640
4649
4641 Aliases in formatter:
4650 Aliases in formatter:
4642
4651
4643 $ hg branches -T '{pad(branch, 7)} {rn}\n'
4652 $ hg branches -T '{pad(branch, 7)} {rn}\n'
4644 default 6:d41e714fe50d
4653 default 6:d41e714fe50d
4645 foo 4:bbe44766e73d
4654 foo 4:bbe44766e73d
4646
4655
4647 Aliases should honor HGPLAIN:
4656 Aliases should honor HGPLAIN:
4648
4657
4649 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
4658 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
4650 nothing expanded:
4659 nothing expanded:
4651 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
4660 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
4652 0:1e4e1b8f71e0
4661 0:1e4e1b8f71e0
4653
4662
4654 Unparsable alias:
4663 Unparsable alias:
4655
4664
4656 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
4665 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
4657 (template
4666 (template
4658 (symbol 'bad'))
4667 (symbol 'bad'))
4659 abort: bad definition of template alias "bad": at 2: not a prefix: end
4668 abort: bad definition of template alias "bad": at 2: not a prefix: end
4660 [255]
4669 [255]
4661 $ hg log --config templatealias.bad='x(' -T '{bad}'
4670 $ hg log --config templatealias.bad='x(' -T '{bad}'
4662 abort: bad definition of template alias "bad": at 2: not a prefix: end
4671 abort: bad definition of template alias "bad": at 2: not a prefix: end
4663 [255]
4672 [255]
4664
4673
4665 $ cd ..
4674 $ cd ..
4666
4675
4667 Set up repository for non-ascii encoding tests:
4676 Set up repository for non-ascii encoding tests:
4668
4677
4669 $ hg init nonascii
4678 $ hg init nonascii
4670 $ cd nonascii
4679 $ cd nonascii
4671 $ $PYTHON <<EOF
4680 $ $PYTHON <<EOF
4672 > open('latin1', 'wb').write(b'\xe9')
4681 > open('latin1', 'wb').write(b'\xe9')
4673 > open('utf-8', 'wb').write(b'\xc3\xa9')
4682 > open('utf-8', 'wb').write(b'\xc3\xa9')
4674 > EOF
4683 > EOF
4675 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
4684 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
4676 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
4685 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
4677
4686
4678 json filter should try round-trip conversion to utf-8:
4687 json filter should try round-trip conversion to utf-8:
4679
4688
4680 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
4689 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
4681 "\u00e9"
4690 "\u00e9"
4682 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
4691 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
4683 "non-ascii branch: \u00e9"
4692 "non-ascii branch: \u00e9"
4684
4693
4685 json filter takes input as utf-8b:
4694 json filter takes input as utf-8b:
4686
4695
4687 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
4696 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
4688 "\u00e9"
4697 "\u00e9"
4689 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
4698 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
4690 "\udce9"
4699 "\udce9"
4691
4700
4692 utf8 filter:
4701 utf8 filter:
4693
4702
4694 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
4703 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
4695 round-trip: c3a9
4704 round-trip: c3a9
4696 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
4705 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
4697 decoded: c3a9
4706 decoded: c3a9
4698 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
4707 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
4699 abort: decoding near * (glob)
4708 abort: decoding near * (glob)
4700 [255]
4709 [255]
4701 $ hg log -T "coerced to string: {rev|utf8}\n" -r0
4710 $ hg log -T "coerced to string: {rev|utf8}\n" -r0
4702 coerced to string: 0
4711 coerced to string: 0
4703
4712
4704 pad width:
4713 pad width:
4705
4714
4706 $ HGENCODING=utf-8 hg debugtemplate "{pad('`cat utf-8`', 2, '-')}\n"
4715 $ HGENCODING=utf-8 hg debugtemplate "{pad('`cat utf-8`', 2, '-')}\n"
4707 \xc3\xa9- (esc)
4716 \xc3\xa9- (esc)
4708
4717
4709 $ cd ..
4718 $ cd ..
4710
4719
4711 Test that template function in extension is registered as expected
4720 Test that template function in extension is registered as expected
4712
4721
4713 $ cd a
4722 $ cd a
4714
4723
4715 $ cat <<EOF > $TESTTMP/customfunc.py
4724 $ cat <<EOF > $TESTTMP/customfunc.py
4716 > from mercurial import registrar
4725 > from mercurial import registrar
4717 >
4726 >
4718 > templatefunc = registrar.templatefunc()
4727 > templatefunc = registrar.templatefunc()
4719 >
4728 >
4720 > @templatefunc(b'custom()')
4729 > @templatefunc(b'custom()')
4721 > def custom(context, mapping, args):
4730 > def custom(context, mapping, args):
4722 > return b'custom'
4731 > return b'custom'
4723 > EOF
4732 > EOF
4724 $ cat <<EOF > .hg/hgrc
4733 $ cat <<EOF > .hg/hgrc
4725 > [extensions]
4734 > [extensions]
4726 > customfunc = $TESTTMP/customfunc.py
4735 > customfunc = $TESTTMP/customfunc.py
4727 > EOF
4736 > EOF
4728
4737
4729 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
4738 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
4730 custom
4739 custom
4731
4740
4732 $ cd ..
4741 $ cd ..
4733
4742
4734 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
4743 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
4735 printed graphwidths 3, 5, 7, etc. should all line up in their respective
4744 printed graphwidths 3, 5, 7, etc. should all line up in their respective
4736 columns. We don't care about other aspects of the graph rendering here.
4745 columns. We don't care about other aspects of the graph rendering here.
4737
4746
4738 $ hg init graphwidth
4747 $ hg init graphwidth
4739 $ cd graphwidth
4748 $ cd graphwidth
4740
4749
4741 $ wrappabletext="a a a a a a a a a a a a"
4750 $ wrappabletext="a a a a a a a a a a a a"
4742
4751
4743 $ printf "first\n" > file
4752 $ printf "first\n" > file
4744 $ hg add file
4753 $ hg add file
4745 $ hg commit -m "$wrappabletext"
4754 $ hg commit -m "$wrappabletext"
4746
4755
4747 $ printf "first\nsecond\n" > file
4756 $ printf "first\nsecond\n" > file
4748 $ hg commit -m "$wrappabletext"
4757 $ hg commit -m "$wrappabletext"
4749
4758
4750 $ hg checkout 0
4759 $ hg checkout 0
4751 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4760 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4752 $ printf "third\nfirst\n" > file
4761 $ printf "third\nfirst\n" > file
4753 $ hg commit -m "$wrappabletext"
4762 $ hg commit -m "$wrappabletext"
4754 created new head
4763 created new head
4755
4764
4756 $ hg merge
4765 $ hg merge
4757 merging file
4766 merging file
4758 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
4767 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
4759 (branch merge, don't forget to commit)
4768 (branch merge, don't forget to commit)
4760
4769
4761 $ hg log --graph -T "{graphwidth}"
4770 $ hg log --graph -T "{graphwidth}"
4762 @ 3
4771 @ 3
4763 |
4772 |
4764 | @ 5
4773 | @ 5
4765 |/
4774 |/
4766 o 3
4775 o 3
4767
4776
4768 $ hg commit -m "$wrappabletext"
4777 $ hg commit -m "$wrappabletext"
4769
4778
4770 $ hg log --graph -T "{graphwidth}"
4779 $ hg log --graph -T "{graphwidth}"
4771 @ 5
4780 @ 5
4772 |\
4781 |\
4773 | o 5
4782 | o 5
4774 | |
4783 | |
4775 o | 5
4784 o | 5
4776 |/
4785 |/
4777 o 3
4786 o 3
4778
4787
4779
4788
4780 $ hg checkout 0
4789 $ hg checkout 0
4781 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4790 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4782 $ printf "third\nfirst\nsecond\n" > file
4791 $ printf "third\nfirst\nsecond\n" > file
4783 $ hg commit -m "$wrappabletext"
4792 $ hg commit -m "$wrappabletext"
4784 created new head
4793 created new head
4785
4794
4786 $ hg log --graph -T "{graphwidth}"
4795 $ hg log --graph -T "{graphwidth}"
4787 @ 3
4796 @ 3
4788 |
4797 |
4789 | o 7
4798 | o 7
4790 | |\
4799 | |\
4791 +---o 7
4800 +---o 7
4792 | |
4801 | |
4793 | o 5
4802 | o 5
4794 |/
4803 |/
4795 o 3
4804 o 3
4796
4805
4797
4806
4798 $ hg log --graph -T "{graphwidth}" -r 3
4807 $ hg log --graph -T "{graphwidth}" -r 3
4799 o 5
4808 o 5
4800 |\
4809 |\
4801 ~ ~
4810 ~ ~
4802
4811
4803 $ hg log --graph -T "{graphwidth}" -r 1
4812 $ hg log --graph -T "{graphwidth}" -r 1
4804 o 3
4813 o 3
4805 |
4814 |
4806 ~
4815 ~
4807
4816
4808 $ hg merge
4817 $ hg merge
4809 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4818 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4810 (branch merge, don't forget to commit)
4819 (branch merge, don't forget to commit)
4811 $ hg commit -m "$wrappabletext"
4820 $ hg commit -m "$wrappabletext"
4812
4821
4813 $ printf "seventh\n" >> file
4822 $ printf "seventh\n" >> file
4814 $ hg commit -m "$wrappabletext"
4823 $ hg commit -m "$wrappabletext"
4815
4824
4816 $ hg log --graph -T "{graphwidth}"
4825 $ hg log --graph -T "{graphwidth}"
4817 @ 3
4826 @ 3
4818 |
4827 |
4819 o 5
4828 o 5
4820 |\
4829 |\
4821 | o 5
4830 | o 5
4822 | |
4831 | |
4823 o | 7
4832 o | 7
4824 |\ \
4833 |\ \
4825 | o | 7
4834 | o | 7
4826 | |/
4835 | |/
4827 o / 5
4836 o / 5
4828 |/
4837 |/
4829 o 3
4838 o 3
4830
4839
4831
4840
4832 The point of graphwidth is to allow wrapping that accounts for the space taken
4841 The point of graphwidth is to allow wrapping that accounts for the space taken
4833 by the graph.
4842 by the graph.
4834
4843
4835 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
4844 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
4836 @ a a a a
4845 @ a a a a
4837 | a a a a
4846 | a a a a
4838 | a a a a
4847 | a a a a
4839 o a a a
4848 o a a a
4840 |\ a a a
4849 |\ a a a
4841 | | a a a
4850 | | a a a
4842 | | a a a
4851 | | a a a
4843 | o a a a
4852 | o a a a
4844 | | a a a
4853 | | a a a
4845 | | a a a
4854 | | a a a
4846 | | a a a
4855 | | a a a
4847 o | a a
4856 o | a a
4848 |\ \ a a
4857 |\ \ a a
4849 | | | a a
4858 | | | a a
4850 | | | a a
4859 | | | a a
4851 | | | a a
4860 | | | a a
4852 | | | a a
4861 | | | a a
4853 | o | a a
4862 | o | a a
4854 | |/ a a
4863 | |/ a a
4855 | | a a
4864 | | a a
4856 | | a a
4865 | | a a
4857 | | a a
4866 | | a a
4858 | | a a
4867 | | a a
4859 o | a a a
4868 o | a a a
4860 |/ a a a
4869 |/ a a a
4861 | a a a
4870 | a a a
4862 | a a a
4871 | a a a
4863 o a a a a
4872 o a a a a
4864 a a a a
4873 a a a a
4865 a a a a
4874 a a a a
4866
4875
4867 Something tricky happens when there are elided nodes; the next drawn row of
4876 Something tricky happens when there are elided nodes; the next drawn row of
4868 edges can be more than one column wider, but the graph width only increases by
4877 edges can be more than one column wider, but the graph width only increases by
4869 one column. The remaining columns are added in between the nodes.
4878 one column. The remaining columns are added in between the nodes.
4870
4879
4871 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
4880 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
4872 o 5
4881 o 5
4873 |\
4882 |\
4874 | \
4883 | \
4875 | :\
4884 | :\
4876 o : : 7
4885 o : : 7
4877 :/ /
4886 :/ /
4878 : o 5
4887 : o 5
4879 :/
4888 :/
4880 o 3
4889 o 3
4881
4890
4882
4891
4883 $ cd ..
4892 $ cd ..
4884
4893
General Comments 0
You need to be logged in to leave comments. Login now