##// END OF EJS Templates
templater: always map over a wrapped object...
Yuya Nishihara -
r38231:7701c2d4 default
parent child Browse files
Show More
@@ -1,731 +1,708 b''
1 # templateutil.py - utility for template evaluation
1 # templateutil.py - utility for template evaluation
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 abc
10 import abc
11 import types
11 import types
12
12
13 from .i18n import _
13 from .i18n import _
14 from . import (
14 from . import (
15 error,
15 error,
16 pycompat,
16 pycompat,
17 util,
17 util,
18 )
18 )
19 from .utils import (
19 from .utils import (
20 dateutil,
20 dateutil,
21 stringutil,
21 stringutil,
22 )
22 )
23
23
24 class ResourceUnavailable(error.Abort):
24 class ResourceUnavailable(error.Abort):
25 pass
25 pass
26
26
27 class TemplateNotFound(error.Abort):
27 class TemplateNotFound(error.Abort):
28 pass
28 pass
29
29
30 class wrapped(object):
30 class wrapped(object):
31 """Object requiring extra conversion prior to displaying or processing
31 """Object requiring extra conversion prior to displaying or processing
32 as value
32 as value
33
33
34 Use unwrapvalue(), unwrapastype(), or unwraphybrid() to obtain the inner
34 Use unwrapvalue(), unwrapastype(), or unwraphybrid() to obtain the inner
35 object.
35 object.
36 """
36 """
37
37
38 __metaclass__ = abc.ABCMeta
38 __metaclass__ = abc.ABCMeta
39
39
40 @abc.abstractmethod
40 @abc.abstractmethod
41 def itermaps(self, context):
41 def itermaps(self, context):
42 """Yield each template mapping"""
42 """Yield each template mapping"""
43
43
44 @abc.abstractmethod
44 @abc.abstractmethod
45 def join(self, context, mapping, sep):
45 def join(self, context, mapping, sep):
46 """Join items with the separator; Returns a bytes or (possibly nested)
46 """Join items with the separator; Returns a bytes or (possibly nested)
47 generator of bytes
47 generator of bytes
48
48
49 A pre-configured template may be rendered per item if this container
49 A pre-configured template may be rendered per item if this container
50 holds unprintable items.
50 holds unprintable items.
51 """
51 """
52
52
53 @abc.abstractmethod
53 @abc.abstractmethod
54 def show(self, context, mapping):
54 def show(self, context, mapping):
55 """Return a bytes or (possibly nested) generator of bytes representing
55 """Return a bytes or (possibly nested) generator of bytes representing
56 the underlying object
56 the underlying object
57
57
58 A pre-configured template may be rendered if the underlying object is
58 A pre-configured template may be rendered if the underlying object is
59 not printable.
59 not printable.
60 """
60 """
61
61
62 @abc.abstractmethod
62 @abc.abstractmethod
63 def tovalue(self, context, mapping):
63 def tovalue(self, context, mapping):
64 """Move the inner value object out or create a value representation
64 """Move the inner value object out or create a value representation
65
65
66 A returned value must be serializable by templaterfilters.json().
66 A returned value must be serializable by templaterfilters.json().
67 """
67 """
68
68
69 class wrappedbytes(wrapped):
69 class wrappedbytes(wrapped):
70 """Wrapper for byte string"""
70 """Wrapper for byte string"""
71
71
72 def __init__(self, value):
72 def __init__(self, value):
73 self._value = value
73 self._value = value
74
74
75 def itermaps(self, context):
75 def itermaps(self, context):
76 raise error.ParseError(_('%r is not iterable of mappings')
76 raise error.ParseError(_('%r is not iterable of mappings')
77 % pycompat.bytestr(self._value))
77 % pycompat.bytestr(self._value))
78
78
79 def join(self, context, mapping, sep):
79 def join(self, context, mapping, sep):
80 return joinitems(pycompat.iterbytestr(self._value), sep)
80 return joinitems(pycompat.iterbytestr(self._value), sep)
81
81
82 def show(self, context, mapping):
82 def show(self, context, mapping):
83 return self._value
83 return self._value
84
84
85 def tovalue(self, context, mapping):
85 def tovalue(self, context, mapping):
86 return self._value
86 return self._value
87
87
88 class wrappedvalue(wrapped):
88 class wrappedvalue(wrapped):
89 """Generic wrapper for pure non-list/dict/bytes value"""
89 """Generic wrapper for pure non-list/dict/bytes value"""
90
90
91 def __init__(self, value):
91 def __init__(self, value):
92 self._value = value
92 self._value = value
93
93
94 def itermaps(self, context):
94 def itermaps(self, context):
95 raise error.ParseError(_('%r is not iterable of mappings')
95 raise error.ParseError(_('%r is not iterable of mappings')
96 % self._value)
96 % self._value)
97
97
98 def join(self, context, mapping, sep):
98 def join(self, context, mapping, sep):
99 raise error.ParseError(_('%r is not iterable') % self._value)
99 raise error.ParseError(_('%r is not iterable') % self._value)
100
100
101 def show(self, context, mapping):
101 def show(self, context, mapping):
102 return pycompat.bytestr(self._value)
102 return pycompat.bytestr(self._value)
103
103
104 def tovalue(self, context, mapping):
104 def tovalue(self, context, mapping):
105 return self._value
105 return self._value
106
106
107 # stub for representing a date type; may be a real date type that can
107 # stub for representing a date type; may be a real date type that can
108 # provide a readable string value
108 # provide a readable string value
109 class date(object):
109 class date(object):
110 pass
110 pass
111
111
112 class hybrid(wrapped):
112 class hybrid(wrapped):
113 """Wrapper for list or dict to support legacy template
113 """Wrapper for list or dict to support legacy template
114
114
115 This class allows us to handle both:
115 This class allows us to handle both:
116 - "{files}" (legacy command-line-specific list hack) and
116 - "{files}" (legacy command-line-specific list hack) and
117 - "{files % '{file}\n'}" (hgweb-style with inlining and function support)
117 - "{files % '{file}\n'}" (hgweb-style with inlining and function support)
118 and to access raw values:
118 and to access raw values:
119 - "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
119 - "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
120 - "{get(extras, key)}"
120 - "{get(extras, key)}"
121 - "{files|json}"
121 - "{files|json}"
122 """
122 """
123
123
124 def __init__(self, gen, values, makemap, joinfmt, keytype=None):
124 def __init__(self, gen, values, makemap, joinfmt, keytype=None):
125 self._gen = gen # generator or function returning generator
125 self._gen = gen # generator or function returning generator
126 self._values = values
126 self._values = values
127 self._makemap = makemap
127 self._makemap = makemap
128 self._joinfmt = joinfmt
128 self._joinfmt = joinfmt
129 self.keytype = keytype # hint for 'x in y' where type(x) is unresolved
129 self.keytype = keytype # hint for 'x in y' where type(x) is unresolved
130
130
131 def itermaps(self, context):
131 def itermaps(self, context):
132 makemap = self._makemap
132 makemap = self._makemap
133 for x in self._values:
133 for x in self._values:
134 yield makemap(x)
134 yield makemap(x)
135
135
136 def join(self, context, mapping, sep):
136 def join(self, context, mapping, sep):
137 # TODO: switch gen to (context, mapping) API?
137 # TODO: switch gen to (context, mapping) API?
138 return joinitems((self._joinfmt(x) for x in self._values), sep)
138 return joinitems((self._joinfmt(x) for x in self._values), sep)
139
139
140 def show(self, context, mapping):
140 def show(self, context, mapping):
141 # TODO: switch gen to (context, mapping) API?
141 # TODO: switch gen to (context, mapping) API?
142 gen = self._gen
142 gen = self._gen
143 if gen is None:
143 if gen is None:
144 return self.join(context, mapping, ' ')
144 return self.join(context, mapping, ' ')
145 if callable(gen):
145 if callable(gen):
146 return gen()
146 return gen()
147 return gen
147 return gen
148
148
149 def tovalue(self, context, mapping):
149 def tovalue(self, context, mapping):
150 # TODO: return self._values and get rid of proxy methods
150 # TODO: return self._values and get rid of proxy methods
151 return self
151 return self
152
152
153 def __contains__(self, x):
153 def __contains__(self, x):
154 return x in self._values
154 return x in self._values
155 def __getitem__(self, key):
155 def __getitem__(self, key):
156 return self._values[key]
156 return self._values[key]
157 def __len__(self):
157 def __len__(self):
158 return len(self._values)
158 return len(self._values)
159 def __iter__(self):
159 def __iter__(self):
160 return iter(self._values)
160 return iter(self._values)
161 def __getattr__(self, name):
161 def __getattr__(self, name):
162 if name not in (r'get', r'items', r'iteritems', r'iterkeys',
162 if name not in (r'get', r'items', r'iteritems', r'iterkeys',
163 r'itervalues', r'keys', r'values'):
163 r'itervalues', r'keys', r'values'):
164 raise AttributeError(name)
164 raise AttributeError(name)
165 return getattr(self._values, name)
165 return getattr(self._values, name)
166
166
167 class mappable(wrapped):
167 class mappable(wrapped):
168 """Wrapper for non-list/dict object to support map operation
168 """Wrapper for non-list/dict object to support map operation
169
169
170 This class allows us to handle both:
170 This class allows us to handle both:
171 - "{manifest}"
171 - "{manifest}"
172 - "{manifest % '{rev}:{node}'}"
172 - "{manifest % '{rev}:{node}'}"
173 - "{manifest.rev}"
173 - "{manifest.rev}"
174
174
175 Unlike a hybrid, this does not simulate the behavior of the underling
175 Unlike a hybrid, this does not simulate the behavior of the underling
176 value.
176 value.
177 """
177 """
178
178
179 def __init__(self, gen, key, value, makemap):
179 def __init__(self, gen, key, value, makemap):
180 self._gen = gen # generator or function returning generator
180 self._gen = gen # generator or function returning generator
181 self._key = key
181 self._key = key
182 self._value = value # may be generator of strings
182 self._value = value # may be generator of strings
183 self._makemap = makemap
183 self._makemap = makemap
184
184
185 def tomap(self):
185 def tomap(self):
186 return self._makemap(self._key)
186 return self._makemap(self._key)
187
187
188 def itermaps(self, context):
188 def itermaps(self, context):
189 yield self.tomap()
189 yield self.tomap()
190
190
191 def join(self, context, mapping, sep):
191 def join(self, context, mapping, sep):
192 w = makewrapped(context, mapping, self._value)
192 w = makewrapped(context, mapping, self._value)
193 return w.join(context, mapping, sep)
193 return w.join(context, mapping, sep)
194
194
195 def show(self, context, mapping):
195 def show(self, context, mapping):
196 # TODO: switch gen to (context, mapping) API?
196 # TODO: switch gen to (context, mapping) API?
197 gen = self._gen
197 gen = self._gen
198 if gen is None:
198 if gen is None:
199 return pycompat.bytestr(self._value)
199 return pycompat.bytestr(self._value)
200 if callable(gen):
200 if callable(gen):
201 return gen()
201 return gen()
202 return gen
202 return gen
203
203
204 def tovalue(self, context, mapping):
204 def tovalue(self, context, mapping):
205 return _unthunk(context, mapping, self._value)
205 return _unthunk(context, mapping, self._value)
206
206
207 class _mappingsequence(wrapped):
207 class _mappingsequence(wrapped):
208 """Wrapper for sequence of template mappings
208 """Wrapper for sequence of template mappings
209
209
210 This represents an inner template structure (i.e. a list of dicts),
210 This represents an inner template structure (i.e. a list of dicts),
211 which can also be rendered by the specified named/literal template.
211 which can also be rendered by the specified named/literal template.
212
212
213 Template mappings may be nested.
213 Template mappings may be nested.
214 """
214 """
215
215
216 def __init__(self, name=None, tmpl=None, sep=''):
216 def __init__(self, name=None, tmpl=None, sep=''):
217 if name is not None and tmpl is not None:
217 if name is not None and tmpl is not None:
218 raise error.ProgrammingError('name and tmpl are mutually exclusive')
218 raise error.ProgrammingError('name and tmpl are mutually exclusive')
219 self._name = name
219 self._name = name
220 self._tmpl = tmpl
220 self._tmpl = tmpl
221 self._defaultsep = sep
221 self._defaultsep = sep
222
222
223 def join(self, context, mapping, sep):
223 def join(self, context, mapping, sep):
224 mapsiter = _iteroverlaymaps(context, mapping, self.itermaps(context))
224 mapsiter = _iteroverlaymaps(context, mapping, self.itermaps(context))
225 if self._name:
225 if self._name:
226 itemiter = (context.process(self._name, m) for m in mapsiter)
226 itemiter = (context.process(self._name, m) for m in mapsiter)
227 elif self._tmpl:
227 elif self._tmpl:
228 itemiter = (context.expand(self._tmpl, m) for m in mapsiter)
228 itemiter = (context.expand(self._tmpl, m) for m in mapsiter)
229 else:
229 else:
230 raise error.ParseError(_('not displayable without template'))
230 raise error.ParseError(_('not displayable without template'))
231 return joinitems(itemiter, sep)
231 return joinitems(itemiter, sep)
232
232
233 def show(self, context, mapping):
233 def show(self, context, mapping):
234 return self.join(context, mapping, self._defaultsep)
234 return self.join(context, mapping, self._defaultsep)
235
235
236 def tovalue(self, context, mapping):
236 def tovalue(self, context, mapping):
237 knownres = context.knownresourcekeys()
237 knownres = context.knownresourcekeys()
238 items = []
238 items = []
239 for nm in self.itermaps(context):
239 for nm in self.itermaps(context):
240 # drop internal resources (recursively) which shouldn't be displayed
240 # drop internal resources (recursively) which shouldn't be displayed
241 lm = context.overlaymap(mapping, nm)
241 lm = context.overlaymap(mapping, nm)
242 items.append({k: unwrapvalue(context, lm, v)
242 items.append({k: unwrapvalue(context, lm, v)
243 for k, v in nm.iteritems() if k not in knownres})
243 for k, v in nm.iteritems() if k not in knownres})
244 return items
244 return items
245
245
246 class mappinggenerator(_mappingsequence):
246 class mappinggenerator(_mappingsequence):
247 """Wrapper for generator of template mappings
247 """Wrapper for generator of template mappings
248
248
249 The function ``make(context, *args)`` should return a generator of
249 The function ``make(context, *args)`` should return a generator of
250 mapping dicts.
250 mapping dicts.
251 """
251 """
252
252
253 def __init__(self, make, args=(), name=None, tmpl=None, sep=''):
253 def __init__(self, make, args=(), name=None, tmpl=None, sep=''):
254 super(mappinggenerator, self).__init__(name, tmpl, sep)
254 super(mappinggenerator, self).__init__(name, tmpl, sep)
255 self._make = make
255 self._make = make
256 self._args = args
256 self._args = args
257
257
258 def itermaps(self, context):
258 def itermaps(self, context):
259 return self._make(context, *self._args)
259 return self._make(context, *self._args)
260
260
261 class mappinglist(_mappingsequence):
261 class mappinglist(_mappingsequence):
262 """Wrapper for list of template mappings"""
262 """Wrapper for list of template mappings"""
263
263
264 def __init__(self, mappings, name=None, tmpl=None, sep=''):
264 def __init__(self, mappings, name=None, tmpl=None, sep=''):
265 super(mappinglist, self).__init__(name, tmpl, sep)
265 super(mappinglist, self).__init__(name, tmpl, sep)
266 self._mappings = mappings
266 self._mappings = mappings
267
267
268 def itermaps(self, context):
268 def itermaps(self, context):
269 return iter(self._mappings)
269 return iter(self._mappings)
270
270
271 class mappedgenerator(wrapped):
271 class mappedgenerator(wrapped):
272 """Wrapper for generator of strings which acts as a list
272 """Wrapper for generator of strings which acts as a list
273
273
274 The function ``make(context, *args)`` should return a generator of
274 The function ``make(context, *args)`` should return a generator of
275 byte strings, or a generator of (possibly nested) generators of byte
275 byte strings, or a generator of (possibly nested) generators of byte
276 strings (i.e. a generator for a list of byte strings.)
276 strings (i.e. a generator for a list of byte strings.)
277 """
277 """
278
278
279 def __init__(self, make, args=()):
279 def __init__(self, make, args=()):
280 self._make = make
280 self._make = make
281 self._args = args
281 self._args = args
282
282
283 def _gen(self, context):
283 def _gen(self, context):
284 return self._make(context, *self._args)
284 return self._make(context, *self._args)
285
285
286 def itermaps(self, context):
286 def itermaps(self, context):
287 raise error.ParseError(_('list of strings is not mappable'))
287 raise error.ParseError(_('list of strings is not mappable'))
288
288
289 def join(self, context, mapping, sep):
289 def join(self, context, mapping, sep):
290 return joinitems(self._gen(context), sep)
290 return joinitems(self._gen(context), sep)
291
291
292 def show(self, context, mapping):
292 def show(self, context, mapping):
293 return self.join(context, mapping, '')
293 return self.join(context, mapping, '')
294
294
295 def tovalue(self, context, mapping):
295 def tovalue(self, context, mapping):
296 return [stringify(context, mapping, x) for x in self._gen(context)]
296 return [stringify(context, mapping, x) for x in self._gen(context)]
297
297
298 def hybriddict(data, key='key', value='value', fmt=None, gen=None):
298 def hybriddict(data, key='key', value='value', fmt=None, gen=None):
299 """Wrap data to support both dict-like and string-like operations"""
299 """Wrap data to support both dict-like and string-like operations"""
300 prefmt = pycompat.identity
300 prefmt = pycompat.identity
301 if fmt is None:
301 if fmt is None:
302 fmt = '%s=%s'
302 fmt = '%s=%s'
303 prefmt = pycompat.bytestr
303 prefmt = pycompat.bytestr
304 return hybrid(gen, data, lambda k: {key: k, value: data[k]},
304 return hybrid(gen, data, lambda k: {key: k, value: data[k]},
305 lambda k: fmt % (prefmt(k), prefmt(data[k])))
305 lambda k: fmt % (prefmt(k), prefmt(data[k])))
306
306
307 def hybridlist(data, name, fmt=None, gen=None):
307 def hybridlist(data, name, fmt=None, gen=None):
308 """Wrap data to support both list-like and string-like operations"""
308 """Wrap data to support both list-like and string-like operations"""
309 prefmt = pycompat.identity
309 prefmt = pycompat.identity
310 if fmt is None:
310 if fmt is None:
311 fmt = '%s'
311 fmt = '%s'
312 prefmt = pycompat.bytestr
312 prefmt = pycompat.bytestr
313 return hybrid(gen, data, lambda x: {name: x}, lambda x: fmt % prefmt(x))
313 return hybrid(gen, data, lambda x: {name: x}, lambda x: fmt % prefmt(x))
314
314
315 def unwraphybrid(context, mapping, thing):
315 def unwraphybrid(context, mapping, thing):
316 """Return an object which can be stringified possibly by using a legacy
316 """Return an object which can be stringified possibly by using a legacy
317 template"""
317 template"""
318 if not isinstance(thing, wrapped):
318 if not isinstance(thing, wrapped):
319 return thing
319 return thing
320 return thing.show(context, mapping)
320 return thing.show(context, mapping)
321
321
322 def wraphybridvalue(container, key, value):
322 def wraphybridvalue(container, key, value):
323 """Wrap an element of hybrid container to be mappable
323 """Wrap an element of hybrid container to be mappable
324
324
325 The key is passed to the makemap function of the given container, which
325 The key is passed to the makemap function of the given container, which
326 should be an item generated by iter(container).
326 should be an item generated by iter(container).
327 """
327 """
328 makemap = getattr(container, '_makemap', None)
328 makemap = getattr(container, '_makemap', None)
329 if makemap is None:
329 if makemap is None:
330 return value
330 return value
331 if util.safehasattr(value, '_makemap'):
331 if util.safehasattr(value, '_makemap'):
332 # a nested hybrid list/dict, which has its own way of map operation
332 # a nested hybrid list/dict, which has its own way of map operation
333 return value
333 return value
334 return mappable(None, key, value, makemap)
334 return mappable(None, key, value, makemap)
335
335
336 def compatdict(context, mapping, name, data, key='key', value='value',
336 def compatdict(context, mapping, name, data, key='key', value='value',
337 fmt=None, plural=None, separator=' '):
337 fmt=None, plural=None, separator=' '):
338 """Wrap data like hybriddict(), but also supports old-style list template
338 """Wrap data like hybriddict(), but also supports old-style list template
339
339
340 This exists for backward compatibility with the old-style template. Use
340 This exists for backward compatibility with the old-style template. Use
341 hybriddict() for new template keywords.
341 hybriddict() for new template keywords.
342 """
342 """
343 c = [{key: k, value: v} for k, v in data.iteritems()]
343 c = [{key: k, value: v} for k, v in data.iteritems()]
344 f = _showcompatlist(context, mapping, name, c, plural, separator)
344 f = _showcompatlist(context, mapping, name, c, plural, separator)
345 return hybriddict(data, key=key, value=value, fmt=fmt, gen=f)
345 return hybriddict(data, key=key, value=value, fmt=fmt, gen=f)
346
346
347 def compatlist(context, mapping, name, data, element=None, fmt=None,
347 def compatlist(context, mapping, name, data, element=None, fmt=None,
348 plural=None, separator=' '):
348 plural=None, separator=' '):
349 """Wrap data like hybridlist(), but also supports old-style list template
349 """Wrap data like hybridlist(), but also supports old-style list template
350
350
351 This exists for backward compatibility with the old-style template. Use
351 This exists for backward compatibility with the old-style template. Use
352 hybridlist() for new template keywords.
352 hybridlist() for new template keywords.
353 """
353 """
354 f = _showcompatlist(context, mapping, name, data, plural, separator)
354 f = _showcompatlist(context, mapping, name, data, plural, separator)
355 return hybridlist(data, name=element or name, fmt=fmt, gen=f)
355 return hybridlist(data, name=element or name, fmt=fmt, gen=f)
356
356
357 def _showcompatlist(context, mapping, name, values, plural=None, separator=' '):
357 def _showcompatlist(context, mapping, name, values, plural=None, separator=' '):
358 """Return a generator that renders old-style list template
358 """Return a generator that renders old-style list template
359
359
360 name is name of key in template map.
360 name is name of key in template map.
361 values is list of strings or dicts.
361 values is list of strings or dicts.
362 plural is plural of name, if not simply name + 's'.
362 plural is plural of name, if not simply name + 's'.
363 separator is used to join values as a string
363 separator is used to join values as a string
364
364
365 expansion works like this, given name 'foo'.
365 expansion works like this, given name 'foo'.
366
366
367 if values is empty, expand 'no_foos'.
367 if values is empty, expand 'no_foos'.
368
368
369 if 'foo' not in template map, return values as a string,
369 if 'foo' not in template map, return values as a string,
370 joined by 'separator'.
370 joined by 'separator'.
371
371
372 expand 'start_foos'.
372 expand 'start_foos'.
373
373
374 for each value, expand 'foo'. if 'last_foo' in template
374 for each value, expand 'foo'. if 'last_foo' in template
375 map, expand it instead of 'foo' for last key.
375 map, expand it instead of 'foo' for last key.
376
376
377 expand 'end_foos'.
377 expand 'end_foos'.
378 """
378 """
379 if not plural:
379 if not plural:
380 plural = name + 's'
380 plural = name + 's'
381 if not values:
381 if not values:
382 noname = 'no_' + plural
382 noname = 'no_' + plural
383 if context.preload(noname):
383 if context.preload(noname):
384 yield context.process(noname, mapping)
384 yield context.process(noname, mapping)
385 return
385 return
386 if not context.preload(name):
386 if not context.preload(name):
387 if isinstance(values[0], bytes):
387 if isinstance(values[0], bytes):
388 yield separator.join(values)
388 yield separator.join(values)
389 else:
389 else:
390 for v in values:
390 for v in values:
391 r = dict(v)
391 r = dict(v)
392 r.update(mapping)
392 r.update(mapping)
393 yield r
393 yield r
394 return
394 return
395 startname = 'start_' + plural
395 startname = 'start_' + plural
396 if context.preload(startname):
396 if context.preload(startname):
397 yield context.process(startname, mapping)
397 yield context.process(startname, mapping)
398 def one(v, tag=name):
398 def one(v, tag=name):
399 vmapping = {}
399 vmapping = {}
400 try:
400 try:
401 vmapping.update(v)
401 vmapping.update(v)
402 # Python 2 raises ValueError if the type of v is wrong. Python
402 # Python 2 raises ValueError if the type of v is wrong. Python
403 # 3 raises TypeError.
403 # 3 raises TypeError.
404 except (AttributeError, TypeError, ValueError):
404 except (AttributeError, TypeError, ValueError):
405 try:
405 try:
406 # Python 2 raises ValueError trying to destructure an e.g.
406 # Python 2 raises ValueError trying to destructure an e.g.
407 # bytes. Python 3 raises TypeError.
407 # bytes. Python 3 raises TypeError.
408 for a, b in v:
408 for a, b in v:
409 vmapping[a] = b
409 vmapping[a] = b
410 except (TypeError, ValueError):
410 except (TypeError, ValueError):
411 vmapping[name] = v
411 vmapping[name] = v
412 vmapping = context.overlaymap(mapping, vmapping)
412 vmapping = context.overlaymap(mapping, vmapping)
413 return context.process(tag, vmapping)
413 return context.process(tag, vmapping)
414 lastname = 'last_' + name
414 lastname = 'last_' + name
415 if context.preload(lastname):
415 if context.preload(lastname):
416 last = values.pop()
416 last = values.pop()
417 else:
417 else:
418 last = None
418 last = None
419 for v in values:
419 for v in values:
420 yield one(v)
420 yield one(v)
421 if last is not None:
421 if last is not None:
422 yield one(last, tag=lastname)
422 yield one(last, tag=lastname)
423 endname = 'end_' + plural
423 endname = 'end_' + plural
424 if context.preload(endname):
424 if context.preload(endname):
425 yield context.process(endname, mapping)
425 yield context.process(endname, mapping)
426
426
427 def flatten(context, mapping, thing):
427 def flatten(context, mapping, thing):
428 """Yield a single stream from a possibly nested set of iterators"""
428 """Yield a single stream from a possibly nested set of iterators"""
429 thing = unwraphybrid(context, mapping, thing)
429 thing = unwraphybrid(context, mapping, thing)
430 if isinstance(thing, bytes):
430 if isinstance(thing, bytes):
431 yield thing
431 yield thing
432 elif isinstance(thing, str):
432 elif isinstance(thing, str):
433 # We can only hit this on Python 3, and it's here to guard
433 # We can only hit this on Python 3, and it's here to guard
434 # against infinite recursion.
434 # against infinite recursion.
435 raise error.ProgrammingError('Mercurial IO including templates is done'
435 raise error.ProgrammingError('Mercurial IO including templates is done'
436 ' with bytes, not strings, got %r' % thing)
436 ' with bytes, not strings, got %r' % thing)
437 elif thing is None:
437 elif thing is None:
438 pass
438 pass
439 elif not util.safehasattr(thing, '__iter__'):
439 elif not util.safehasattr(thing, '__iter__'):
440 yield pycompat.bytestr(thing)
440 yield pycompat.bytestr(thing)
441 else:
441 else:
442 for i in thing:
442 for i in thing:
443 i = unwraphybrid(context, mapping, i)
443 i = unwraphybrid(context, mapping, i)
444 if isinstance(i, bytes):
444 if isinstance(i, bytes):
445 yield i
445 yield i
446 elif i is None:
446 elif i is None:
447 pass
447 pass
448 elif not util.safehasattr(i, '__iter__'):
448 elif not util.safehasattr(i, '__iter__'):
449 yield pycompat.bytestr(i)
449 yield pycompat.bytestr(i)
450 else:
450 else:
451 for j in flatten(context, mapping, i):
451 for j in flatten(context, mapping, i):
452 yield j
452 yield j
453
453
454 def stringify(context, mapping, thing):
454 def stringify(context, mapping, thing):
455 """Turn values into bytes by converting into text and concatenating them"""
455 """Turn values into bytes by converting into text and concatenating them"""
456 if isinstance(thing, bytes):
456 if isinstance(thing, bytes):
457 return thing # retain localstr to be round-tripped
457 return thing # retain localstr to be round-tripped
458 return b''.join(flatten(context, mapping, thing))
458 return b''.join(flatten(context, mapping, thing))
459
459
460 def findsymbolicname(arg):
460 def findsymbolicname(arg):
461 """Find symbolic name for the given compiled expression; returns None
461 """Find symbolic name for the given compiled expression; returns None
462 if nothing found reliably"""
462 if nothing found reliably"""
463 while True:
463 while True:
464 func, data = arg
464 func, data = arg
465 if func is runsymbol:
465 if func is runsymbol:
466 return data
466 return data
467 elif func is runfilter:
467 elif func is runfilter:
468 arg = data[0]
468 arg = data[0]
469 else:
469 else:
470 return None
470 return None
471
471
472 def _unthunk(context, mapping, thing):
472 def _unthunk(context, mapping, thing):
473 """Evaluate a lazy byte string into value"""
473 """Evaluate a lazy byte string into value"""
474 if not isinstance(thing, types.GeneratorType):
474 if not isinstance(thing, types.GeneratorType):
475 return thing
475 return thing
476 return stringify(context, mapping, thing)
476 return stringify(context, mapping, thing)
477
477
478 def evalrawexp(context, mapping, arg):
478 def evalrawexp(context, mapping, arg):
479 """Evaluate given argument as a bare template object which may require
479 """Evaluate given argument as a bare template object which may require
480 further processing (such as folding generator of strings)"""
480 further processing (such as folding generator of strings)"""
481 func, data = arg
481 func, data = arg
482 return func(context, mapping, data)
482 return func(context, mapping, data)
483
483
484 def evalwrapped(context, mapping, arg):
484 def evalwrapped(context, mapping, arg):
485 """Evaluate given argument to wrapped object"""
485 """Evaluate given argument to wrapped object"""
486 thing = evalrawexp(context, mapping, arg)
486 thing = evalrawexp(context, mapping, arg)
487 return makewrapped(context, mapping, thing)
487 return makewrapped(context, mapping, thing)
488
488
489 def makewrapped(context, mapping, thing):
489 def makewrapped(context, mapping, thing):
490 """Lift object to a wrapped type"""
490 """Lift object to a wrapped type"""
491 if isinstance(thing, wrapped):
491 if isinstance(thing, wrapped):
492 return thing
492 return thing
493 thing = _unthunk(context, mapping, thing)
493 thing = _unthunk(context, mapping, thing)
494 if isinstance(thing, bytes):
494 if isinstance(thing, bytes):
495 return wrappedbytes(thing)
495 return wrappedbytes(thing)
496 return wrappedvalue(thing)
496 return wrappedvalue(thing)
497
497
498 def evalfuncarg(context, mapping, arg):
498 def evalfuncarg(context, mapping, arg):
499 """Evaluate given argument as value type"""
499 """Evaluate given argument as value type"""
500 return unwrapvalue(context, mapping, evalrawexp(context, mapping, arg))
500 return unwrapvalue(context, mapping, evalrawexp(context, mapping, arg))
501
501
502 def unwrapvalue(context, mapping, thing):
502 def unwrapvalue(context, mapping, thing):
503 """Move the inner value object out of the wrapper"""
503 """Move the inner value object out of the wrapper"""
504 if isinstance(thing, wrapped):
504 if isinstance(thing, wrapped):
505 return thing.tovalue(context, mapping)
505 return thing.tovalue(context, mapping)
506 # evalrawexp() may return string, generator of strings or arbitrary object
506 # evalrawexp() may return string, generator of strings or arbitrary object
507 # such as date tuple, but filter does not want generator.
507 # such as date tuple, but filter does not want generator.
508 return _unthunk(context, mapping, thing)
508 return _unthunk(context, mapping, thing)
509
509
510 def evalboolean(context, mapping, arg):
510 def evalboolean(context, mapping, arg):
511 """Evaluate given argument as boolean, but also takes boolean literals"""
511 """Evaluate given argument as boolean, but also takes boolean literals"""
512 func, data = arg
512 func, data = arg
513 if func is runsymbol:
513 if func is runsymbol:
514 thing = func(context, mapping, data, default=None)
514 thing = func(context, mapping, data, default=None)
515 if thing is None:
515 if thing is None:
516 # not a template keyword, takes as a boolean literal
516 # not a template keyword, takes as a boolean literal
517 thing = stringutil.parsebool(data)
517 thing = stringutil.parsebool(data)
518 else:
518 else:
519 thing = func(context, mapping, data)
519 thing = func(context, mapping, data)
520 if isinstance(thing, wrapped):
520 if isinstance(thing, wrapped):
521 thing = thing.tovalue(context, mapping)
521 thing = thing.tovalue(context, mapping)
522 if isinstance(thing, bool):
522 if isinstance(thing, bool):
523 return thing
523 return thing
524 # other objects are evaluated as strings, which means 0 is True, but
524 # other objects are evaluated as strings, which means 0 is True, but
525 # empty dict/list should be False as they are expected to be ''
525 # empty dict/list should be False as they are expected to be ''
526 return bool(stringify(context, mapping, thing))
526 return bool(stringify(context, mapping, thing))
527
527
528 def evaldate(context, mapping, arg, err=None):
528 def evaldate(context, mapping, arg, err=None):
529 """Evaluate given argument as a date tuple or a date string; returns
529 """Evaluate given argument as a date tuple or a date string; returns
530 a (unixtime, offset) tuple"""
530 a (unixtime, offset) tuple"""
531 thing = evalrawexp(context, mapping, arg)
531 thing = evalrawexp(context, mapping, arg)
532 return unwrapdate(context, mapping, thing, err)
532 return unwrapdate(context, mapping, thing, err)
533
533
534 def unwrapdate(context, mapping, thing, err=None):
534 def unwrapdate(context, mapping, thing, err=None):
535 thing = unwrapvalue(context, mapping, thing)
535 thing = unwrapvalue(context, mapping, thing)
536 try:
536 try:
537 return dateutil.parsedate(thing)
537 return dateutil.parsedate(thing)
538 except AttributeError:
538 except AttributeError:
539 raise error.ParseError(err or _('not a date tuple nor a string'))
539 raise error.ParseError(err or _('not a date tuple nor a string'))
540 except error.ParseError:
540 except error.ParseError:
541 if not err:
541 if not err:
542 raise
542 raise
543 raise error.ParseError(err)
543 raise error.ParseError(err)
544
544
545 def evalinteger(context, mapping, arg, err=None):
545 def evalinteger(context, mapping, arg, err=None):
546 thing = evalrawexp(context, mapping, arg)
546 thing = evalrawexp(context, mapping, arg)
547 return unwrapinteger(context, mapping, thing, err)
547 return unwrapinteger(context, mapping, thing, err)
548
548
549 def unwrapinteger(context, mapping, thing, err=None):
549 def unwrapinteger(context, mapping, thing, err=None):
550 thing = unwrapvalue(context, mapping, thing)
550 thing = unwrapvalue(context, mapping, thing)
551 try:
551 try:
552 return int(thing)
552 return int(thing)
553 except (TypeError, ValueError):
553 except (TypeError, ValueError):
554 raise error.ParseError(err or _('not an integer'))
554 raise error.ParseError(err or _('not an integer'))
555
555
556 def evalstring(context, mapping, arg):
556 def evalstring(context, mapping, arg):
557 return stringify(context, mapping, evalrawexp(context, mapping, arg))
557 return stringify(context, mapping, evalrawexp(context, mapping, arg))
558
558
559 def evalstringliteral(context, mapping, arg):
559 def evalstringliteral(context, mapping, arg):
560 """Evaluate given argument as string template, but returns symbol name
560 """Evaluate given argument as string template, but returns symbol name
561 if it is unknown"""
561 if it is unknown"""
562 func, data = arg
562 func, data = arg
563 if func is runsymbol:
563 if func is runsymbol:
564 thing = func(context, mapping, data, default=data)
564 thing = func(context, mapping, data, default=data)
565 else:
565 else:
566 thing = func(context, mapping, data)
566 thing = func(context, mapping, data)
567 return stringify(context, mapping, thing)
567 return stringify(context, mapping, thing)
568
568
569 _unwrapfuncbytype = {
569 _unwrapfuncbytype = {
570 None: unwrapvalue,
570 None: unwrapvalue,
571 bytes: stringify,
571 bytes: stringify,
572 date: unwrapdate,
572 date: unwrapdate,
573 int: unwrapinteger,
573 int: unwrapinteger,
574 }
574 }
575
575
576 def unwrapastype(context, mapping, thing, typ):
576 def unwrapastype(context, mapping, thing, typ):
577 """Move the inner value object out of the wrapper and coerce its type"""
577 """Move the inner value object out of the wrapper and coerce its type"""
578 try:
578 try:
579 f = _unwrapfuncbytype[typ]
579 f = _unwrapfuncbytype[typ]
580 except KeyError:
580 except KeyError:
581 raise error.ProgrammingError('invalid type specified: %r' % typ)
581 raise error.ProgrammingError('invalid type specified: %r' % typ)
582 return f(context, mapping, thing)
582 return f(context, mapping, thing)
583
583
584 def runinteger(context, mapping, data):
584 def runinteger(context, mapping, data):
585 return int(data)
585 return int(data)
586
586
587 def runstring(context, mapping, data):
587 def runstring(context, mapping, data):
588 return data
588 return data
589
589
590 def _recursivesymbolblocker(key):
590 def _recursivesymbolblocker(key):
591 def showrecursion(**args):
591 def showrecursion(**args):
592 raise error.Abort(_("recursive reference '%s' in template") % key)
592 raise error.Abort(_("recursive reference '%s' in template") % key)
593 return showrecursion
593 return showrecursion
594
594
595 def runsymbol(context, mapping, key, default=''):
595 def runsymbol(context, mapping, key, default=''):
596 v = context.symbol(mapping, key)
596 v = context.symbol(mapping, key)
597 if v is None:
597 if v is None:
598 # put poison to cut recursion. we can't move this to parsing phase
598 # put poison to cut recursion. we can't move this to parsing phase
599 # because "x = {x}" is allowed if "x" is a keyword. (issue4758)
599 # because "x = {x}" is allowed if "x" is a keyword. (issue4758)
600 safemapping = mapping.copy()
600 safemapping = mapping.copy()
601 safemapping[key] = _recursivesymbolblocker(key)
601 safemapping[key] = _recursivesymbolblocker(key)
602 try:
602 try:
603 v = context.process(key, safemapping)
603 v = context.process(key, safemapping)
604 except TemplateNotFound:
604 except TemplateNotFound:
605 v = default
605 v = default
606 if callable(v) and getattr(v, '_requires', None) is None:
606 if callable(v) and getattr(v, '_requires', None) is None:
607 # old templatekw: expand all keywords and resources
607 # old templatekw: expand all keywords and resources
608 # (TODO: deprecate this after porting web template keywords to new API)
608 # (TODO: deprecate this after porting web template keywords to new API)
609 props = {k: context._resources.lookup(context, mapping, k)
609 props = {k: context._resources.lookup(context, mapping, k)
610 for k in context._resources.knownkeys()}
610 for k in context._resources.knownkeys()}
611 # pass context to _showcompatlist() through templatekw._showlist()
611 # pass context to _showcompatlist() through templatekw._showlist()
612 props['templ'] = context
612 props['templ'] = context
613 props.update(mapping)
613 props.update(mapping)
614 return v(**pycompat.strkwargs(props))
614 return v(**pycompat.strkwargs(props))
615 if callable(v):
615 if callable(v):
616 # new templatekw
616 # new templatekw
617 try:
617 try:
618 return v(context, mapping)
618 return v(context, mapping)
619 except ResourceUnavailable:
619 except ResourceUnavailable:
620 # unsupported keyword is mapped to empty just like unknown keyword
620 # unsupported keyword is mapped to empty just like unknown keyword
621 return None
621 return None
622 return v
622 return v
623
623
624 def runtemplate(context, mapping, template):
624 def runtemplate(context, mapping, template):
625 for arg in template:
625 for arg in template:
626 yield evalrawexp(context, mapping, arg)
626 yield evalrawexp(context, mapping, arg)
627
627
628 def runfilter(context, mapping, data):
628 def runfilter(context, mapping, data):
629 arg, filt = data
629 arg, filt = data
630 thing = evalrawexp(context, mapping, arg)
630 thing = evalrawexp(context, mapping, arg)
631 intype = getattr(filt, '_intype', None)
631 intype = getattr(filt, '_intype', None)
632 try:
632 try:
633 thing = unwrapastype(context, mapping, thing, intype)
633 thing = unwrapastype(context, mapping, thing, intype)
634 return filt(thing)
634 return filt(thing)
635 except error.ParseError as e:
635 except error.ParseError as e:
636 raise error.ParseError(bytes(e), hint=_formatfiltererror(arg, filt))
636 raise error.ParseError(bytes(e), hint=_formatfiltererror(arg, filt))
637
637
638 def _formatfiltererror(arg, filt):
638 def _formatfiltererror(arg, filt):
639 fn = pycompat.sysbytes(filt.__name__)
639 fn = pycompat.sysbytes(filt.__name__)
640 sym = findsymbolicname(arg)
640 sym = findsymbolicname(arg)
641 if not sym:
641 if not sym:
642 return _("incompatible use of template filter '%s'") % fn
642 return _("incompatible use of template filter '%s'") % fn
643 return (_("template filter '%s' is not compatible with keyword '%s'")
643 return (_("template filter '%s' is not compatible with keyword '%s'")
644 % (fn, sym))
644 % (fn, sym))
645
645
646 def _checkeditermaps(darg, d):
647 try:
648 for v in d:
649 if not isinstance(v, dict):
650 raise TypeError
651 yield v
652 except TypeError:
653 sym = findsymbolicname(darg)
654 if sym:
655 raise error.ParseError(_("keyword '%s' is not iterable of mappings")
656 % sym)
657 else:
658 raise error.ParseError(_("%r is not iterable of mappings") % d)
659
660 def _iteroverlaymaps(context, origmapping, newmappings):
646 def _iteroverlaymaps(context, origmapping, newmappings):
661 """Generate combined mappings from the original mapping and an iterable
647 """Generate combined mappings from the original mapping and an iterable
662 of partial mappings to override the original"""
648 of partial mappings to override the original"""
663 for i, nm in enumerate(newmappings):
649 for i, nm in enumerate(newmappings):
664 lm = context.overlaymap(origmapping, nm)
650 lm = context.overlaymap(origmapping, nm)
665 lm['index'] = i
651 lm['index'] = i
666 yield lm
652 yield lm
667
653
668 def _applymap(context, mapping, diter, targ):
654 def _applymap(context, mapping, d, targ):
669 for lm in _iteroverlaymaps(context, mapping, diter):
655 for lm in _iteroverlaymaps(context, mapping, d.itermaps(context)):
670 yield evalrawexp(context, lm, targ)
656 yield evalrawexp(context, lm, targ)
671
657
672 def runmap(context, mapping, data):
658 def runmap(context, mapping, data):
673 darg, targ = data
659 darg, targ = data
674 d = evalrawexp(context, mapping, darg)
660 d = evalwrapped(context, mapping, darg)
675 # TODO: a generator should be rejected because it is a thunk of lazy
661 return mappedgenerator(_applymap, args=(mapping, d, targ))
676 # string, but we can't because hgweb abuses generator as a keyword
677 # that returns a list of dicts.
678 # TODO: drop _checkeditermaps() and pass 'd' to mappedgenerator so it
679 # can be restarted.
680 if isinstance(d, wrapped):
681 diter = d.itermaps(context)
682 else:
683 diter = _checkeditermaps(darg, d)
684 return mappedgenerator(_applymap, args=(mapping, diter, targ))
685
662
686 def runmember(context, mapping, data):
663 def runmember(context, mapping, data):
687 darg, memb = data
664 darg, memb = data
688 d = evalrawexp(context, mapping, darg)
665 d = evalrawexp(context, mapping, darg)
689 if util.safehasattr(d, 'tomap'):
666 if util.safehasattr(d, 'tomap'):
690 lm = context.overlaymap(mapping, d.tomap())
667 lm = context.overlaymap(mapping, d.tomap())
691 return runsymbol(context, lm, memb)
668 return runsymbol(context, lm, memb)
692 if util.safehasattr(d, 'get'):
669 if util.safehasattr(d, 'get'):
693 return getdictitem(d, memb)
670 return getdictitem(d, memb)
694
671
695 sym = findsymbolicname(darg)
672 sym = findsymbolicname(darg)
696 if sym:
673 if sym:
697 raise error.ParseError(_("keyword '%s' has no member") % sym)
674 raise error.ParseError(_("keyword '%s' has no member") % sym)
698 else:
675 else:
699 raise error.ParseError(_("%r has no member") % pycompat.bytestr(d))
676 raise error.ParseError(_("%r has no member") % pycompat.bytestr(d))
700
677
701 def runnegate(context, mapping, data):
678 def runnegate(context, mapping, data):
702 data = evalinteger(context, mapping, data,
679 data = evalinteger(context, mapping, data,
703 _('negation needs an integer argument'))
680 _('negation needs an integer argument'))
704 return -data
681 return -data
705
682
706 def runarithmetic(context, mapping, data):
683 def runarithmetic(context, mapping, data):
707 func, left, right = data
684 func, left, right = data
708 left = evalinteger(context, mapping, left,
685 left = evalinteger(context, mapping, left,
709 _('arithmetic only defined on integers'))
686 _('arithmetic only defined on integers'))
710 right = evalinteger(context, mapping, right,
687 right = evalinteger(context, mapping, right,
711 _('arithmetic only defined on integers'))
688 _('arithmetic only defined on integers'))
712 try:
689 try:
713 return func(left, right)
690 return func(left, right)
714 except ZeroDivisionError:
691 except ZeroDivisionError:
715 raise error.Abort(_('division by zero is not defined'))
692 raise error.Abort(_('division by zero is not defined'))
716
693
717 def getdictitem(dictarg, key):
694 def getdictitem(dictarg, key):
718 val = dictarg.get(key)
695 val = dictarg.get(key)
719 if val is None:
696 if val is None:
720 return
697 return
721 return wraphybridvalue(dictarg, key, val)
698 return wraphybridvalue(dictarg, key, val)
722
699
723 def joinitems(itemiter, sep):
700 def joinitems(itemiter, sep):
724 """Join items with the separator; Returns generator of bytes"""
701 """Join items with the separator; Returns generator of bytes"""
725 first = True
702 first = True
726 for x in itemiter:
703 for x in itemiter:
727 if first:
704 if first:
728 first = False
705 first = False
729 elif sep:
706 elif sep:
730 yield sep
707 yield sep
731 yield x
708 yield x
@@ -1,4911 +1,4911 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo a > a
3 $ echo a > a
4 $ hg add a
4 $ hg add a
5 $ echo line 1 > b
5 $ echo line 1 > b
6 $ echo line 2 >> b
6 $ echo line 2 >> b
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
8
8
9 $ hg add b
9 $ hg add b
10 $ echo other 1 > c
10 $ echo other 1 > c
11 $ echo other 2 >> c
11 $ echo other 2 >> c
12 $ echo >> c
12 $ echo >> c
13 $ echo other 3 >> c
13 $ echo other 3 >> c
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
15
15
16 $ hg add c
16 $ hg add c
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
18 $ echo c >> c
18 $ echo c >> c
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
20
20
21 $ echo foo > .hg/branch
21 $ echo foo > .hg/branch
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
23
23
24 $ hg co -q 3
24 $ hg co -q 3
25 $ echo other 4 >> d
25 $ echo other 4 >> d
26 $ hg add d
26 $ hg add d
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
28
28
29 $ hg merge -q foo
29 $ hg merge -q foo
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
31
31
32 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: 11 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 string, though it's silly:
3245 Test manifest/get() can be join()-ed as string, 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 1.1.:.2.b.c.6.e.9.0.0.6.c.e.2
3248 1.1.:.2.b.c.6.e.9.0.0.6.c.e.2
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 d.e.f.a.u.l.t
3250 d.e.f.a.u.l.t
3251
3251
3252 Test join() over string
3252 Test join() over string
3253
3253
3254 $ hg log -R latesttag -r tip -T '{join(rev|stringify, ".")}\n'
3254 $ hg log -R latesttag -r tip -T '{join(rev|stringify, ".")}\n'
3255 1.1
3255 1.1
3256
3256
3257 Test join() over uniterable
3257 Test join() over uniterable
3258
3258
3259 $ hg log -R latesttag -r tip -T '{join(rev, "")}\n'
3259 $ hg log -R latesttag -r tip -T '{join(rev, "")}\n'
3260 hg: parse error: 11 is not iterable
3260 hg: parse error: 11 is not iterable
3261 [255]
3261 [255]
3262
3262
3263 Test min/max of integers
3263 Test min/max of integers
3264
3264
3265 $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'
3265 $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'
3266 9
3266 9
3267 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
3267 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
3268 10
3268 10
3269
3269
3270 Test min/max over map operation:
3270 Test min/max over map operation:
3271
3271
3272 $ hg log -R latesttag -r3 -T '{min(tags % "{tag}")}\n'
3272 $ hg log -R latesttag -r3 -T '{min(tags % "{tag}")}\n'
3273 at3
3273 at3
3274 $ hg log -R latesttag -r3 -T '{max(tags % "{tag}")}\n'
3274 $ hg log -R latesttag -r3 -T '{max(tags % "{tag}")}\n'
3275 t3
3275 t3
3276
3276
3277 Test min/max of if() result
3277 Test min/max of if() result
3278
3278
3279 $ cd latesttag
3279 $ cd latesttag
3280 $ hg log -l1 -T '{min(if(true, revset("9:10"), ""))}\n'
3280 $ hg log -l1 -T '{min(if(true, revset("9:10"), ""))}\n'
3281 9
3281 9
3282 $ hg log -l1 -T '{max(if(false, "", revset("9:10")))}\n'
3282 $ hg log -l1 -T '{max(if(false, "", revset("9:10")))}\n'
3283 10
3283 10
3284 $ hg log -l1 -T '{min(ifcontains("a", "aa", revset("9:10"), ""))}\n'
3284 $ hg log -l1 -T '{min(ifcontains("a", "aa", revset("9:10"), ""))}\n'
3285 9
3285 9
3286 $ hg log -l1 -T '{max(ifcontains("a", "bb", "", revset("9:10")))}\n'
3286 $ hg log -l1 -T '{max(ifcontains("a", "bb", "", revset("9:10")))}\n'
3287 10
3287 10
3288 $ hg log -l1 -T '{min(ifeq(0, 0, revset("9:10"), ""))}\n'
3288 $ hg log -l1 -T '{min(ifeq(0, 0, revset("9:10"), ""))}\n'
3289 9
3289 9
3290 $ hg log -l1 -T '{max(ifeq(0, 1, "", revset("9:10")))}\n'
3290 $ hg log -l1 -T '{max(ifeq(0, 1, "", revset("9:10")))}\n'
3291 10
3291 10
3292 $ cd ..
3292 $ cd ..
3293
3293
3294 Test laziness of if() then/else clause
3294 Test laziness of if() then/else clause
3295
3295
3296 $ hg debugtemplate '{count(0)}'
3296 $ hg debugtemplate '{count(0)}'
3297 hg: parse error: not countable
3297 hg: parse error: not countable
3298 (incompatible use of template filter 'count')
3298 (incompatible use of template filter 'count')
3299 [255]
3299 [255]
3300 $ hg debugtemplate '{if(true, "", count(0))}'
3300 $ hg debugtemplate '{if(true, "", count(0))}'
3301 $ hg debugtemplate '{if(false, count(0), "")}'
3301 $ hg debugtemplate '{if(false, count(0), "")}'
3302 $ hg debugtemplate '{ifcontains("a", "aa", "", count(0))}'
3302 $ hg debugtemplate '{ifcontains("a", "aa", "", count(0))}'
3303 $ hg debugtemplate '{ifcontains("a", "bb", count(0), "")}'
3303 $ hg debugtemplate '{ifcontains("a", "bb", count(0), "")}'
3304 $ hg debugtemplate '{ifeq(0, 0, "", count(0))}'
3304 $ hg debugtemplate '{ifeq(0, 0, "", count(0))}'
3305 $ hg debugtemplate '{ifeq(0, 1, count(0), "")}'
3305 $ hg debugtemplate '{ifeq(0, 1, count(0), "")}'
3306
3306
3307 Test dot operator precedence:
3307 Test dot operator precedence:
3308
3308
3309 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
3309 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
3310 (template
3310 (template
3311 (|
3311 (|
3312 (.
3312 (.
3313 (symbol 'manifest')
3313 (symbol 'manifest')
3314 (symbol 'node'))
3314 (symbol 'node'))
3315 (symbol 'short'))
3315 (symbol 'short'))
3316 (string '\n'))
3316 (string '\n'))
3317 89f4071fec70
3317 89f4071fec70
3318
3318
3319 (the following examples are invalid, but seem natural in parsing POV)
3319 (the following examples are invalid, but seem natural in parsing POV)
3320
3320
3321 $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null
3321 $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null
3322 (template
3322 (template
3323 (|
3323 (|
3324 (symbol 'foo')
3324 (symbol 'foo')
3325 (.
3325 (.
3326 (symbol 'bar')
3326 (symbol 'bar')
3327 (symbol 'baz')))
3327 (symbol 'baz')))
3328 (string '\n'))
3328 (string '\n'))
3329 [255]
3329 [255]
3330 $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null
3330 $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null
3331 (template
3331 (template
3332 (.
3332 (.
3333 (symbol 'foo')
3333 (symbol 'foo')
3334 (func
3334 (func
3335 (symbol 'bar')
3335 (symbol 'bar')
3336 None))
3336 None))
3337 (string '\n'))
3337 (string '\n'))
3338 [255]
3338 [255]
3339
3339
3340 Test evaluation of dot operator:
3340 Test evaluation of dot operator:
3341
3341
3342 $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n'
3342 $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n'
3343 ce3cec86e6c26bd9bdfc590a6b92abc9680f1796
3343 ce3cec86e6c26bd9bdfc590a6b92abc9680f1796
3344 $ hg log -R latesttag -r0 -T '{extras.branch}\n'
3344 $ hg log -R latesttag -r0 -T '{extras.branch}\n'
3345 default
3345 default
3346
3346
3347 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
3347 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
3348 hg: parse error: keyword 'author' has no member
3348 hg: parse error: keyword 'author' has no member
3349 [255]
3349 [255]
3350 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
3350 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
3351 hg: parse error: 'a' has no member
3351 hg: parse error: 'a' has no member
3352 [255]
3352 [255]
3353
3353
3354 Test the sub function of templating for expansion:
3354 Test the sub function of templating for expansion:
3355
3355
3356 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
3356 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
3357 xx
3357 xx
3358
3358
3359 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
3359 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
3360 hg: parse error: sub got an invalid pattern: [
3360 hg: parse error: sub got an invalid pattern: [
3361 [255]
3361 [255]
3362 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
3362 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
3363 hg: parse error: sub got an invalid replacement: \1
3363 hg: parse error: sub got an invalid replacement: \1
3364 [255]
3364 [255]
3365
3365
3366 Test the strip function with chars specified:
3366 Test the strip function with chars specified:
3367
3367
3368 $ hg log -R latesttag --template '{desc}\n'
3368 $ hg log -R latesttag --template '{desc}\n'
3369 at3
3369 at3
3370 t5
3370 t5
3371 t4
3371 t4
3372 t3
3372 t3
3373 t2
3373 t2
3374 t1
3374 t1
3375 merge
3375 merge
3376 h2e
3376 h2e
3377 h2d
3377 h2d
3378 h1c
3378 h1c
3379 b
3379 b
3380 a
3380 a
3381
3381
3382 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
3382 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
3383 at3
3383 at3
3384 5
3384 5
3385 4
3385 4
3386 3
3386 3
3387 2
3387 2
3388 1
3388 1
3389 merg
3389 merg
3390 h2
3390 h2
3391 h2d
3391 h2d
3392 h1c
3392 h1c
3393 b
3393 b
3394 a
3394 a
3395
3395
3396 Test date format:
3396 Test date format:
3397
3397
3398 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
3398 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
3399 date: 70 01 01 10 +0000
3399 date: 70 01 01 10 +0000
3400 date: 70 01 01 09 +0000
3400 date: 70 01 01 09 +0000
3401 date: 70 01 01 04 +0000
3401 date: 70 01 01 04 +0000
3402 date: 70 01 01 08 +0000
3402 date: 70 01 01 08 +0000
3403 date: 70 01 01 07 +0000
3403 date: 70 01 01 07 +0000
3404 date: 70 01 01 06 +0000
3404 date: 70 01 01 06 +0000
3405 date: 70 01 01 05 +0100
3405 date: 70 01 01 05 +0100
3406 date: 70 01 01 04 +0000
3406 date: 70 01 01 04 +0000
3407 date: 70 01 01 03 +0000
3407 date: 70 01 01 03 +0000
3408 date: 70 01 01 02 +0000
3408 date: 70 01 01 02 +0000
3409 date: 70 01 01 01 +0000
3409 date: 70 01 01 01 +0000
3410 date: 70 01 01 00 +0000
3410 date: 70 01 01 00 +0000
3411
3411
3412 Test invalid date:
3412 Test invalid date:
3413
3413
3414 $ hg log -R latesttag -T '{date(rev)}\n'
3414 $ hg log -R latesttag -T '{date(rev)}\n'
3415 hg: parse error: date expects a date information
3415 hg: parse error: date expects a date information
3416 [255]
3416 [255]
3417
3417
3418 Test integer literal:
3418 Test integer literal:
3419
3419
3420 $ hg debugtemplate -v '{(0)}\n'
3420 $ hg debugtemplate -v '{(0)}\n'
3421 (template
3421 (template
3422 (group
3422 (group
3423 (integer '0'))
3423 (integer '0'))
3424 (string '\n'))
3424 (string '\n'))
3425 0
3425 0
3426 $ hg debugtemplate -v '{(123)}\n'
3426 $ hg debugtemplate -v '{(123)}\n'
3427 (template
3427 (template
3428 (group
3428 (group
3429 (integer '123'))
3429 (integer '123'))
3430 (string '\n'))
3430 (string '\n'))
3431 123
3431 123
3432 $ hg debugtemplate -v '{(-4)}\n'
3432 $ hg debugtemplate -v '{(-4)}\n'
3433 (template
3433 (template
3434 (group
3434 (group
3435 (negate
3435 (negate
3436 (integer '4')))
3436 (integer '4')))
3437 (string '\n'))
3437 (string '\n'))
3438 -4
3438 -4
3439 $ hg debugtemplate '{(-)}\n'
3439 $ hg debugtemplate '{(-)}\n'
3440 hg: parse error at 3: not a prefix: )
3440 hg: parse error at 3: not a prefix: )
3441 ({(-)}\n
3441 ({(-)}\n
3442 ^ here)
3442 ^ here)
3443 [255]
3443 [255]
3444 $ hg debugtemplate '{(-a)}\n'
3444 $ hg debugtemplate '{(-a)}\n'
3445 hg: parse error: negation needs an integer argument
3445 hg: parse error: negation needs an integer argument
3446 [255]
3446 [255]
3447
3447
3448 top-level integer literal is interpreted as symbol (i.e. variable name):
3448 top-level integer literal is interpreted as symbol (i.e. variable name):
3449
3449
3450 $ hg debugtemplate -D 1=one -v '{1}\n'
3450 $ hg debugtemplate -D 1=one -v '{1}\n'
3451 (template
3451 (template
3452 (integer '1')
3452 (integer '1')
3453 (string '\n'))
3453 (string '\n'))
3454 one
3454 one
3455 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
3455 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
3456 (template
3456 (template
3457 (func
3457 (func
3458 (symbol 'if')
3458 (symbol 'if')
3459 (list
3459 (list
3460 (string 't')
3460 (string 't')
3461 (template
3461 (template
3462 (integer '1'))))
3462 (integer '1'))))
3463 (string '\n'))
3463 (string '\n'))
3464 one
3464 one
3465 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
3465 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
3466 (template
3466 (template
3467 (|
3467 (|
3468 (integer '1')
3468 (integer '1')
3469 (symbol 'stringify'))
3469 (symbol 'stringify'))
3470 (string '\n'))
3470 (string '\n'))
3471 one
3471 one
3472
3472
3473 unless explicit symbol is expected:
3473 unless explicit symbol is expected:
3474
3474
3475 $ hg log -Ra -r0 -T '{desc|1}\n'
3475 $ hg log -Ra -r0 -T '{desc|1}\n'
3476 hg: parse error: expected a symbol, got 'integer'
3476 hg: parse error: expected a symbol, got 'integer'
3477 [255]
3477 [255]
3478 $ hg log -Ra -r0 -T '{1()}\n'
3478 $ hg log -Ra -r0 -T '{1()}\n'
3479 hg: parse error: expected a symbol, got 'integer'
3479 hg: parse error: expected a symbol, got 'integer'
3480 [255]
3480 [255]
3481
3481
3482 Test string literal:
3482 Test string literal:
3483
3483
3484 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
3484 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
3485 (template
3485 (template
3486 (string 'string with no template fragment')
3486 (string 'string with no template fragment')
3487 (string '\n'))
3487 (string '\n'))
3488 string with no template fragment
3488 string with no template fragment
3489 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
3489 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
3490 (template
3490 (template
3491 (template
3491 (template
3492 (string 'template: ')
3492 (string 'template: ')
3493 (symbol 'rev'))
3493 (symbol 'rev'))
3494 (string '\n'))
3494 (string '\n'))
3495 template: 0
3495 template: 0
3496 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
3496 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
3497 (template
3497 (template
3498 (string 'rawstring: {rev}')
3498 (string 'rawstring: {rev}')
3499 (string '\n'))
3499 (string '\n'))
3500 rawstring: {rev}
3500 rawstring: {rev}
3501 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
3501 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
3502 (template
3502 (template
3503 (%
3503 (%
3504 (symbol 'files')
3504 (symbol 'files')
3505 (string 'rawstring: {file}'))
3505 (string 'rawstring: {file}'))
3506 (string '\n'))
3506 (string '\n'))
3507 rawstring: {file}
3507 rawstring: {file}
3508
3508
3509 Test string escaping:
3509 Test string escaping:
3510
3510
3511 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3511 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3512 >
3512 >
3513 <>\n<[>
3513 <>\n<[>
3514 <>\n<]>
3514 <>\n<]>
3515 <>\n<
3515 <>\n<
3516
3516
3517 $ hg log -R latesttag -r 0 \
3517 $ hg log -R latesttag -r 0 \
3518 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3518 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3519 >
3519 >
3520 <>\n<[>
3520 <>\n<[>
3521 <>\n<]>
3521 <>\n<]>
3522 <>\n<
3522 <>\n<
3523
3523
3524 $ hg log -R latesttag -r 0 -T esc \
3524 $ hg log -R latesttag -r 0 -T esc \
3525 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3525 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3526 >
3526 >
3527 <>\n<[>
3527 <>\n<[>
3528 <>\n<]>
3528 <>\n<]>
3529 <>\n<
3529 <>\n<
3530
3530
3531 $ cat <<'EOF' > esctmpl
3531 $ cat <<'EOF' > esctmpl
3532 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3532 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3533 > EOF
3533 > EOF
3534 $ hg log -R latesttag -r 0 --style ./esctmpl
3534 $ hg log -R latesttag -r 0 --style ./esctmpl
3535 >
3535 >
3536 <>\n<[>
3536 <>\n<[>
3537 <>\n<]>
3537 <>\n<]>
3538 <>\n<
3538 <>\n<
3539
3539
3540 Test string escaping of quotes:
3540 Test string escaping of quotes:
3541
3541
3542 $ hg log -Ra -r0 -T '{"\""}\n'
3542 $ hg log -Ra -r0 -T '{"\""}\n'
3543 "
3543 "
3544 $ hg log -Ra -r0 -T '{"\\\""}\n'
3544 $ hg log -Ra -r0 -T '{"\\\""}\n'
3545 \"
3545 \"
3546 $ hg log -Ra -r0 -T '{r"\""}\n'
3546 $ hg log -Ra -r0 -T '{r"\""}\n'
3547 \"
3547 \"
3548 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3548 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3549 \\\"
3549 \\\"
3550
3550
3551
3551
3552 $ hg log -Ra -r0 -T '{"\""}\n'
3552 $ hg log -Ra -r0 -T '{"\""}\n'
3553 "
3553 "
3554 $ hg log -Ra -r0 -T '{"\\\""}\n'
3554 $ hg log -Ra -r0 -T '{"\\\""}\n'
3555 \"
3555 \"
3556 $ hg log -Ra -r0 -T '{r"\""}\n'
3556 $ hg log -Ra -r0 -T '{r"\""}\n'
3557 \"
3557 \"
3558 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3558 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3559 \\\"
3559 \\\"
3560
3560
3561 Test exception in quoted template. single backslash before quotation mark is
3561 Test exception in quoted template. single backslash before quotation mark is
3562 stripped before parsing:
3562 stripped before parsing:
3563
3563
3564 $ cat <<'EOF' > escquotetmpl
3564 $ cat <<'EOF' > escquotetmpl
3565 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
3565 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
3566 > EOF
3566 > EOF
3567 $ cd latesttag
3567 $ cd latesttag
3568 $ hg log -r 2 --style ../escquotetmpl
3568 $ hg log -r 2 --style ../escquotetmpl
3569 " \" \" \\" head1
3569 " \" \" \\" head1
3570
3570
3571 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
3571 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
3572 valid
3572 valid
3573 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
3573 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
3574 valid
3574 valid
3575
3575
3576 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
3576 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
3577 _evalifliteral() templates (issue4733):
3577 _evalifliteral() templates (issue4733):
3578
3578
3579 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
3579 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
3580 "2
3580 "2
3581 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
3581 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
3582 "2
3582 "2
3583 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
3583 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
3584 "2
3584 "2
3585
3585
3586 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
3586 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
3587 \"
3587 \"
3588 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
3588 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
3589 \"
3589 \"
3590 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3590 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3591 \"
3591 \"
3592
3592
3593 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
3593 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
3594 \\\"
3594 \\\"
3595 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
3595 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
3596 \\\"
3596 \\\"
3597 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3597 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3598 \\\"
3598 \\\"
3599
3599
3600 escaped single quotes and errors:
3600 escaped single quotes and errors:
3601
3601
3602 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
3602 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
3603 foo
3603 foo
3604 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
3604 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
3605 foo
3605 foo
3606 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3606 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3607 hg: parse error at 21: unterminated string
3607 hg: parse error at 21: unterminated string
3608 ({if(rev, "{if(rev, \")}")}\n
3608 ({if(rev, "{if(rev, \")}")}\n
3609 ^ here)
3609 ^ here)
3610 [255]
3610 [255]
3611 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3611 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3612 hg: parse error: trailing \ in string
3612 hg: parse error: trailing \ in string
3613 [255]
3613 [255]
3614 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3614 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3615 hg: parse error: trailing \ in string
3615 hg: parse error: trailing \ in string
3616 [255]
3616 [255]
3617
3617
3618 $ cd ..
3618 $ cd ..
3619
3619
3620 Test leading backslashes:
3620 Test leading backslashes:
3621
3621
3622 $ cd latesttag
3622 $ cd latesttag
3623 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3623 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3624 {rev} {file}
3624 {rev} {file}
3625 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3625 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3626 \2 \head1
3626 \2 \head1
3627 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3627 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3628 \{rev} \{file}
3628 \{rev} \{file}
3629 $ cd ..
3629 $ cd ..
3630
3630
3631 Test leading backslashes in "if" expression (issue4714):
3631 Test leading backslashes in "if" expression (issue4714):
3632
3632
3633 $ cd latesttag
3633 $ cd latesttag
3634 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3634 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3635 {rev} \{rev}
3635 {rev} \{rev}
3636 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3636 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3637 \2 \\{rev}
3637 \2 \\{rev}
3638 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3638 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3639 \{rev} \\\{rev}
3639 \{rev} \\\{rev}
3640 $ cd ..
3640 $ cd ..
3641
3641
3642 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3642 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3643
3643
3644 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3644 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3645 \x6e
3645 \x6e
3646 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3646 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3647 \x5c\x786e
3647 \x5c\x786e
3648 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3648 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3649 \x6e
3649 \x6e
3650 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3650 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3651 \x5c\x786e
3651 \x5c\x786e
3652
3652
3653 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3653 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3654 \x6e
3654 \x6e
3655 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3655 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3656 \x5c\x786e
3656 \x5c\x786e
3657 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3657 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3658 \x6e
3658 \x6e
3659 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3659 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3660 \x5c\x786e
3660 \x5c\x786e
3661
3661
3662 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3662 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3663 fourth
3663 fourth
3664 second
3664 second
3665 third
3665 third
3666 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3666 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3667 fourth\nsecond\nthird
3667 fourth\nsecond\nthird
3668
3668
3669 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3669 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3670 <p>
3670 <p>
3671 1st
3671 1st
3672 </p>
3672 </p>
3673 <p>
3673 <p>
3674 2nd
3674 2nd
3675 </p>
3675 </p>
3676 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3676 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3677 <p>
3677 <p>
3678 1st\n\n2nd
3678 1st\n\n2nd
3679 </p>
3679 </p>
3680 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3680 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3681 1st
3681 1st
3682
3682
3683 2nd
3683 2nd
3684
3684
3685 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3685 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3686 o perso
3686 o perso
3687 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3687 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3688 no person
3688 no person
3689 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3689 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3690 o perso
3690 o perso
3691 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3691 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3692 no perso
3692 no perso
3693
3693
3694 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3694 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3695 -o perso-
3695 -o perso-
3696 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3696 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3697 no person
3697 no person
3698 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3698 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3699 \x2do perso\x2d
3699 \x2do perso\x2d
3700 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3700 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3701 -o perso-
3701 -o perso-
3702 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3702 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3703 \x2do perso\x6e
3703 \x2do perso\x6e
3704
3704
3705 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3705 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3706 fourth
3706 fourth
3707 second
3707 second
3708 third
3708 third
3709
3709
3710 Test string escaping in nested expression:
3710 Test string escaping in nested expression:
3711
3711
3712 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3712 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3713 fourth\x6esecond\x6ethird
3713 fourth\x6esecond\x6ethird
3714 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3714 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3715 fourth\x6esecond\x6ethird
3715 fourth\x6esecond\x6ethird
3716
3716
3717 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3717 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3718 fourth\x6esecond\x6ethird
3718 fourth\x6esecond\x6ethird
3719 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3719 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3720 fourth\x5c\x786esecond\x5c\x786ethird
3720 fourth\x5c\x786esecond\x5c\x786ethird
3721
3721
3722 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3722 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3723 3:\x6eo user, \x6eo domai\x6e
3723 3:\x6eo user, \x6eo domai\x6e
3724 4:\x5c\x786eew bra\x5c\x786ech
3724 4:\x5c\x786eew bra\x5c\x786ech
3725
3725
3726 Test quotes in nested expression are evaluated just like a $(command)
3726 Test quotes in nested expression are evaluated just like a $(command)
3727 substitution in POSIX shells:
3727 substitution in POSIX shells:
3728
3728
3729 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3729 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3730 8:95c24699272e
3730 8:95c24699272e
3731 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3731 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3732 {8} "95c24699272e"
3732 {8} "95c24699272e"
3733
3733
3734 Test recursive evaluation:
3734 Test recursive evaluation:
3735
3735
3736 $ hg init r
3736 $ hg init r
3737 $ cd r
3737 $ cd r
3738 $ echo a > a
3738 $ echo a > a
3739 $ hg ci -Am '{rev}'
3739 $ hg ci -Am '{rev}'
3740 adding a
3740 adding a
3741 $ hg log -r 0 --template '{if(rev, desc)}\n'
3741 $ hg log -r 0 --template '{if(rev, desc)}\n'
3742 {rev}
3742 {rev}
3743 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3743 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3744 test 0
3744 test 0
3745
3745
3746 $ hg branch -q 'text.{rev}'
3746 $ hg branch -q 'text.{rev}'
3747 $ echo aa >> aa
3747 $ echo aa >> aa
3748 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3748 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3749
3749
3750 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3750 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3751 {node|short}desc to
3751 {node|short}desc to
3752 text.{rev}be wrapped
3752 text.{rev}be wrapped
3753 text.{rev}desc to be
3753 text.{rev}desc to be
3754 text.{rev}wrapped (no-eol)
3754 text.{rev}wrapped (no-eol)
3755 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3755 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3756 bcc7ff960b8e:desc to
3756 bcc7ff960b8e:desc to
3757 text.1:be wrapped
3757 text.1:be wrapped
3758 text.1:desc to be
3758 text.1:desc to be
3759 text.1:wrapped (no-eol)
3759 text.1:wrapped (no-eol)
3760 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3760 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3761 hg: parse error: fill expects an integer width
3761 hg: parse error: fill expects an integer width
3762 [255]
3762 [255]
3763
3763
3764 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
3764 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
3765 bcc7ff960b8e:desc to be
3765 bcc7ff960b8e:desc to be
3766 termwidth.1:wrapped desc
3766 termwidth.1:wrapped desc
3767 termwidth.1:to be wrapped (no-eol)
3767 termwidth.1:to be wrapped (no-eol)
3768
3768
3769 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3769 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3770 {node|short} (no-eol)
3770 {node|short} (no-eol)
3771 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3771 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3772 bcc-ff---b-e (no-eol)
3772 bcc-ff---b-e (no-eol)
3773
3773
3774 $ cat >> .hg/hgrc <<EOF
3774 $ cat >> .hg/hgrc <<EOF
3775 > [extensions]
3775 > [extensions]
3776 > color=
3776 > color=
3777 > [color]
3777 > [color]
3778 > mode=ansi
3778 > mode=ansi
3779 > text.{rev} = red
3779 > text.{rev} = red
3780 > text.1 = green
3780 > text.1 = green
3781 > EOF
3781 > EOF
3782 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3782 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3783 \x1b[0;31mtext\x1b[0m (esc)
3783 \x1b[0;31mtext\x1b[0m (esc)
3784 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3784 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3785 \x1b[0;32mtext\x1b[0m (esc)
3785 \x1b[0;32mtext\x1b[0m (esc)
3786
3786
3787 color effect can be specified without quoting:
3787 color effect can be specified without quoting:
3788
3788
3789 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
3789 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
3790 \x1b[0;31mtext\x1b[0m (esc)
3790 \x1b[0;31mtext\x1b[0m (esc)
3791
3791
3792 color effects can be nested (issue5413)
3792 color effects can be nested (issue5413)
3793
3793
3794 $ hg debugtemplate --color=always \
3794 $ hg debugtemplate --color=always \
3795 > '{label(red, "red{label(magenta, "ma{label(cyan, "cyan")}{label(yellow, "yellow")}genta")}")}\n'
3795 > '{label(red, "red{label(magenta, "ma{label(cyan, "cyan")}{label(yellow, "yellow")}genta")}")}\n'
3796 \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)
3796 \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)
3797
3797
3798 pad() should interact well with color codes (issue5416)
3798 pad() should interact well with color codes (issue5416)
3799
3799
3800 $ hg debugtemplate --color=always \
3800 $ hg debugtemplate --color=always \
3801 > '{pad(label(red, "red"), 5, label(cyan, "-"))}\n'
3801 > '{pad(label(red, "red"), 5, label(cyan, "-"))}\n'
3802 \x1b[0;31mred\x1b[0m\x1b[0;36m-\x1b[0m\x1b[0;36m-\x1b[0m (esc)
3802 \x1b[0;31mred\x1b[0m\x1b[0;36m-\x1b[0m\x1b[0;36m-\x1b[0m (esc)
3803
3803
3804 label should be no-op if color is disabled:
3804 label should be no-op if color is disabled:
3805
3805
3806 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
3806 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
3807 text
3807 text
3808 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
3808 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
3809 text
3809 text
3810
3810
3811 Test branches inside if statement:
3811 Test branches inside if statement:
3812
3812
3813 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3813 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3814 no
3814 no
3815
3815
3816 Test dict constructor:
3816 Test dict constructor:
3817
3817
3818 $ hg log -r 0 -T '{dict(y=node|short, x=rev)}\n'
3818 $ hg log -r 0 -T '{dict(y=node|short, x=rev)}\n'
3819 y=f7769ec2ab97 x=0
3819 y=f7769ec2ab97 x=0
3820 $ hg log -r 0 -T '{dict(x=rev, y=node|short) % "{key}={value}\n"}'
3820 $ hg log -r 0 -T '{dict(x=rev, y=node|short) % "{key}={value}\n"}'
3821 x=0
3821 x=0
3822 y=f7769ec2ab97
3822 y=f7769ec2ab97
3823 $ hg log -r 0 -T '{dict(x=rev, y=node|short)|json}\n'
3823 $ hg log -r 0 -T '{dict(x=rev, y=node|short)|json}\n'
3824 {"x": 0, "y": "f7769ec2ab97"}
3824 {"x": 0, "y": "f7769ec2ab97"}
3825 $ hg log -r 0 -T '{dict()|json}\n'
3825 $ hg log -r 0 -T '{dict()|json}\n'
3826 {}
3826 {}
3827
3827
3828 $ hg log -r 0 -T '{dict(rev, node=node|short)}\n'
3828 $ hg log -r 0 -T '{dict(rev, node=node|short)}\n'
3829 rev=0 node=f7769ec2ab97
3829 rev=0 node=f7769ec2ab97
3830 $ hg log -r 0 -T '{dict(rev, node|short)}\n'
3830 $ hg log -r 0 -T '{dict(rev, node|short)}\n'
3831 rev=0 node=f7769ec2ab97
3831 rev=0 node=f7769ec2ab97
3832
3832
3833 $ hg log -r 0 -T '{dict(rev, rev=rev)}\n'
3833 $ hg log -r 0 -T '{dict(rev, rev=rev)}\n'
3834 hg: parse error: duplicated dict key 'rev' inferred
3834 hg: parse error: duplicated dict key 'rev' inferred
3835 [255]
3835 [255]
3836 $ hg log -r 0 -T '{dict(node, node|short)}\n'
3836 $ hg log -r 0 -T '{dict(node, node|short)}\n'
3837 hg: parse error: duplicated dict key 'node' inferred
3837 hg: parse error: duplicated dict key 'node' inferred
3838 [255]
3838 [255]
3839 $ hg log -r 0 -T '{dict(1 + 2)}'
3839 $ hg log -r 0 -T '{dict(1 + 2)}'
3840 hg: parse error: dict key cannot be inferred
3840 hg: parse error: dict key cannot be inferred
3841 [255]
3841 [255]
3842
3842
3843 $ hg log -r 0 -T '{dict(x=rev, x=node)}'
3843 $ hg log -r 0 -T '{dict(x=rev, x=node)}'
3844 hg: parse error: dict got multiple values for keyword argument 'x'
3844 hg: parse error: dict got multiple values for keyword argument 'x'
3845 [255]
3845 [255]
3846
3846
3847 Test get function:
3847 Test get function:
3848
3848
3849 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3849 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3850 default
3850 default
3851 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3851 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3852 default
3852 default
3853 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3853 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3854 hg: parse error: get() expects a dict as first argument
3854 hg: parse error: get() expects a dict as first argument
3855 [255]
3855 [255]
3856
3856
3857 Test json filter applied to hybrid object:
3857 Test json filter applied to hybrid object:
3858
3858
3859 $ hg log -r0 -T '{files|json}\n'
3859 $ hg log -r0 -T '{files|json}\n'
3860 ["a"]
3860 ["a"]
3861 $ hg log -r0 -T '{extras|json}\n'
3861 $ hg log -r0 -T '{extras|json}\n'
3862 {"branch": "default"}
3862 {"branch": "default"}
3863
3863
3864 Test json filter applied to map result:
3864 Test json filter applied to map result:
3865
3865
3866 $ hg log -r0 -T '{json(extras % "{key}")}\n'
3866 $ hg log -r0 -T '{json(extras % "{key}")}\n'
3867 ["branch"]
3867 ["branch"]
3868
3868
3869 Test localdate(date, tz) function:
3869 Test localdate(date, tz) function:
3870
3870
3871 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3871 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3872 1970-01-01 09:00 +0900
3872 1970-01-01 09:00 +0900
3873 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3873 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3874 1970-01-01 00:00 +0000
3874 1970-01-01 00:00 +0000
3875 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "blahUTC")|isodate}\n'
3875 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "blahUTC")|isodate}\n'
3876 hg: parse error: localdate expects a timezone
3876 hg: parse error: localdate expects a timezone
3877 [255]
3877 [255]
3878 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3878 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3879 1970-01-01 02:00 +0200
3879 1970-01-01 02:00 +0200
3880 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3880 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3881 1970-01-01 00:00 +0000
3881 1970-01-01 00:00 +0000
3882 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3882 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3883 1970-01-01 00:00 +0000
3883 1970-01-01 00:00 +0000
3884 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3884 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3885 hg: parse error: localdate expects a timezone
3885 hg: parse error: localdate expects a timezone
3886 [255]
3886 [255]
3887 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3887 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3888 hg: parse error: localdate expects a timezone
3888 hg: parse error: localdate expects a timezone
3889 [255]
3889 [255]
3890
3890
3891 Test shortest(node) function:
3891 Test shortest(node) function:
3892
3892
3893 $ echo b > b
3893 $ echo b > b
3894 $ hg ci -qAm b
3894 $ hg ci -qAm b
3895 $ hg log --template '{shortest(node)}\n'
3895 $ hg log --template '{shortest(node)}\n'
3896 e777
3896 e777
3897 bcc7
3897 bcc7
3898 f776
3898 f776
3899 $ hg log --template '{shortest(node, 10)}\n'
3899 $ hg log --template '{shortest(node, 10)}\n'
3900 e777603221
3900 e777603221
3901 bcc7ff960b
3901 bcc7ff960b
3902 f7769ec2ab
3902 f7769ec2ab
3903 $ hg log --template '{node|shortest}\n' -l1
3903 $ hg log --template '{node|shortest}\n' -l1
3904 e777
3904 e777
3905
3905
3906 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
3906 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
3907 f7769ec2ab
3907 f7769ec2ab
3908 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
3908 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
3909 hg: parse error: shortest() expects an integer minlength
3909 hg: parse error: shortest() expects an integer minlength
3910 [255]
3910 [255]
3911
3911
3912 $ hg log -r 'wdir()' -T '{node|shortest}\n'
3912 $ hg log -r 'wdir()' -T '{node|shortest}\n'
3913 ffff
3913 ffff
3914
3914
3915 $ hg log --template '{shortest("f")}\n' -l1
3915 $ hg log --template '{shortest("f")}\n' -l1
3916 f
3916 f
3917
3917
3918 $ hg log --template '{shortest("0123456789012345678901234567890123456789")}\n' -l1
3918 $ hg log --template '{shortest("0123456789012345678901234567890123456789")}\n' -l1
3919 0123456789012345678901234567890123456789
3919 0123456789012345678901234567890123456789
3920
3920
3921 $ hg log --template '{shortest("01234567890123456789012345678901234567890123456789")}\n' -l1
3921 $ hg log --template '{shortest("01234567890123456789012345678901234567890123456789")}\n' -l1
3922 01234567890123456789012345678901234567890123456789
3922 01234567890123456789012345678901234567890123456789
3923
3923
3924 $ hg log --template '{shortest("not a hex string")}\n' -l1
3924 $ hg log --template '{shortest("not a hex string")}\n' -l1
3925 not a hex string
3925 not a hex string
3926
3926
3927 $ hg log --template '{shortest("not a hex string, but it'\''s 40 bytes long")}\n' -l1
3927 $ hg log --template '{shortest("not a hex string, but it'\''s 40 bytes long")}\n' -l1
3928 not a hex string, but it's 40 bytes long
3928 not a hex string, but it's 40 bytes long
3929
3929
3930 $ hg log --template '{shortest("ffffffffffffffffffffffffffffffffffffffff")}\n' -l1
3930 $ hg log --template '{shortest("ffffffffffffffffffffffffffffffffffffffff")}\n' -l1
3931 ffff
3931 ffff
3932
3932
3933 $ hg log --template '{shortest("fffffff")}\n' -l1
3933 $ hg log --template '{shortest("fffffff")}\n' -l1
3934 ffff
3934 ffff
3935
3935
3936 $ hg log --template '{shortest("ff")}\n' -l1
3936 $ hg log --template '{shortest("ff")}\n' -l1
3937 ffff
3937 ffff
3938
3938
3939 $ cd ..
3939 $ cd ..
3940
3940
3941 Test shortest(node) with the repo having short hash collision:
3941 Test shortest(node) with the repo having short hash collision:
3942
3942
3943 $ hg init hashcollision
3943 $ hg init hashcollision
3944 $ cd hashcollision
3944 $ cd hashcollision
3945 $ cat <<EOF >> .hg/hgrc
3945 $ cat <<EOF >> .hg/hgrc
3946 > [experimental]
3946 > [experimental]
3947 > evolution.createmarkers=True
3947 > evolution.createmarkers=True
3948 > EOF
3948 > EOF
3949 $ echo 0 > a
3949 $ echo 0 > a
3950 $ hg ci -qAm 0
3950 $ hg ci -qAm 0
3951 $ for i in 17 129 248 242 480 580 617 1057 2857 4025; do
3951 $ for i in 17 129 248 242 480 580 617 1057 2857 4025; do
3952 > hg up -q 0
3952 > hg up -q 0
3953 > echo $i > a
3953 > echo $i > a
3954 > hg ci -qm $i
3954 > hg ci -qm $i
3955 > done
3955 > done
3956 $ hg up -q null
3956 $ hg up -q null
3957 $ hg log -r0: -T '{rev}:{node}\n'
3957 $ hg log -r0: -T '{rev}:{node}\n'
3958 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
3958 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
3959 1:11424df6dc1dd4ea255eae2b58eaca7831973bbc
3959 1:11424df6dc1dd4ea255eae2b58eaca7831973bbc
3960 2:11407b3f1b9c3e76a79c1ec5373924df096f0499
3960 2:11407b3f1b9c3e76a79c1ec5373924df096f0499
3961 3:11dd92fe0f39dfdaacdaa5f3997edc533875cfc4
3961 3:11dd92fe0f39dfdaacdaa5f3997edc533875cfc4
3962 4:10776689e627b465361ad5c296a20a487e153ca4
3962 4:10776689e627b465361ad5c296a20a487e153ca4
3963 5:a00be79088084cb3aff086ab799f8790e01a976b
3963 5:a00be79088084cb3aff086ab799f8790e01a976b
3964 6:a0b0acd79b4498d0052993d35a6a748dd51d13e6
3964 6:a0b0acd79b4498d0052993d35a6a748dd51d13e6
3965 7:a0457b3450b8e1b778f1163b31a435802987fe5d
3965 7:a0457b3450b8e1b778f1163b31a435802987fe5d
3966 8:c56256a09cd28e5764f32e8e2810d0f01e2e357a
3966 8:c56256a09cd28e5764f32e8e2810d0f01e2e357a
3967 9:c5623987d205cd6d9d8389bfc40fff9dbb670b48
3967 9:c5623987d205cd6d9d8389bfc40fff9dbb670b48
3968 10:c562ddd9c94164376c20b86b0b4991636a3bf84f
3968 10:c562ddd9c94164376c20b86b0b4991636a3bf84f
3969 $ hg debugobsolete a00be79088084cb3aff086ab799f8790e01a976b
3969 $ hg debugobsolete a00be79088084cb3aff086ab799f8790e01a976b
3970 obsoleted 1 changesets
3970 obsoleted 1 changesets
3971 $ hg debugobsolete c5623987d205cd6d9d8389bfc40fff9dbb670b48
3971 $ hg debugobsolete c5623987d205cd6d9d8389bfc40fff9dbb670b48
3972 obsoleted 1 changesets
3972 obsoleted 1 changesets
3973 $ hg debugobsolete c562ddd9c94164376c20b86b0b4991636a3bf84f
3973 $ hg debugobsolete c562ddd9c94164376c20b86b0b4991636a3bf84f
3974 obsoleted 1 changesets
3974 obsoleted 1 changesets
3975
3975
3976 nodes starting with '11' (we don't have the revision number '11' though)
3976 nodes starting with '11' (we don't have the revision number '11' though)
3977
3977
3978 $ hg log -r 1:3 -T '{rev}:{shortest(node, 0)}\n'
3978 $ hg log -r 1:3 -T '{rev}:{shortest(node, 0)}\n'
3979 1:1142
3979 1:1142
3980 2:1140
3980 2:1140
3981 3:11d
3981 3:11d
3982
3982
3983 '5:a00' is hidden, but still we have two nodes starting with 'a0'
3983 '5:a00' is hidden, but still we have two nodes starting with 'a0'
3984
3984
3985 $ hg log -r 6:7 -T '{rev}:{shortest(node, 0)}\n'
3985 $ hg log -r 6:7 -T '{rev}:{shortest(node, 0)}\n'
3986 6:a0b
3986 6:a0b
3987 7:a04
3987 7:a04
3988
3988
3989 node '10' conflicts with the revision number '10' even if it is hidden
3989 node '10' conflicts with the revision number '10' even if it is hidden
3990 (we could exclude hidden revision numbers, but currently we don't)
3990 (we could exclude hidden revision numbers, but currently we don't)
3991
3991
3992 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n'
3992 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n'
3993 4:107
3993 4:107
3994 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden
3994 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden
3995 4:107
3995 4:107
3996
3996
3997 node 'c562' should be unique if the other 'c562' nodes are hidden
3997 node 'c562' should be unique if the other 'c562' nodes are hidden
3998 (but we don't try the slow path to filter out hidden nodes for now)
3998 (but we don't try the slow path to filter out hidden nodes for now)
3999
3999
4000 $ hg log -r 8 -T '{rev}:{node|shortest}\n'
4000 $ hg log -r 8 -T '{rev}:{node|shortest}\n'
4001 8:c5625
4001 8:c5625
4002 $ hg log -r 8:10 -T '{rev}:{node|shortest}\n' --hidden
4002 $ hg log -r 8:10 -T '{rev}:{node|shortest}\n' --hidden
4003 8:c5625
4003 8:c5625
4004 9:c5623
4004 9:c5623
4005 10:c562d
4005 10:c562d
4006
4006
4007 $ cd ..
4007 $ cd ..
4008
4008
4009 Test pad function
4009 Test pad function
4010
4010
4011 $ cd r
4011 $ cd r
4012
4012
4013 $ hg log --template '{pad(rev, 20)} {author|user}\n'
4013 $ hg log --template '{pad(rev, 20)} {author|user}\n'
4014 2 test
4014 2 test
4015 1 {node|short}
4015 1 {node|short}
4016 0 test
4016 0 test
4017
4017
4018 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
4018 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
4019 2 test
4019 2 test
4020 1 {node|short}
4020 1 {node|short}
4021 0 test
4021 0 test
4022
4022
4023 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
4023 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
4024 2------------------- test
4024 2------------------- test
4025 1------------------- {node|short}
4025 1------------------- {node|short}
4026 0------------------- test
4026 0------------------- test
4027
4027
4028 Test template string in pad function
4028 Test template string in pad function
4029
4029
4030 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
4030 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
4031 {0} test
4031 {0} test
4032
4032
4033 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
4033 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
4034 \{rev} test
4034 \{rev} test
4035
4035
4036 Test width argument passed to pad function
4036 Test width argument passed to pad function
4037
4037
4038 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
4038 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
4039 0 test
4039 0 test
4040 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
4040 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
4041 hg: parse error: pad() expects an integer width
4041 hg: parse error: pad() expects an integer width
4042 [255]
4042 [255]
4043
4043
4044 Test invalid fillchar passed to pad function
4044 Test invalid fillchar passed to pad function
4045
4045
4046 $ hg log -r 0 -T '{pad(rev, 10, "")}\n'
4046 $ hg log -r 0 -T '{pad(rev, 10, "")}\n'
4047 hg: parse error: pad() expects a single fill character
4047 hg: parse error: pad() expects a single fill character
4048 [255]
4048 [255]
4049 $ hg log -r 0 -T '{pad(rev, 10, "--")}\n'
4049 $ hg log -r 0 -T '{pad(rev, 10, "--")}\n'
4050 hg: parse error: pad() expects a single fill character
4050 hg: parse error: pad() expects a single fill character
4051 [255]
4051 [255]
4052
4052
4053 Test boolean argument passed to pad function
4053 Test boolean argument passed to pad function
4054
4054
4055 no crash
4055 no crash
4056
4056
4057 $ hg log -r 0 -T '{pad(rev, 10, "-", "f{"oo"}")}\n'
4057 $ hg log -r 0 -T '{pad(rev, 10, "-", "f{"oo"}")}\n'
4058 ---------0
4058 ---------0
4059
4059
4060 string/literal
4060 string/literal
4061
4061
4062 $ hg log -r 0 -T '{pad(rev, 10, "-", "false")}\n'
4062 $ hg log -r 0 -T '{pad(rev, 10, "-", "false")}\n'
4063 ---------0
4063 ---------0
4064 $ hg log -r 0 -T '{pad(rev, 10, "-", false)}\n'
4064 $ hg log -r 0 -T '{pad(rev, 10, "-", false)}\n'
4065 0---------
4065 0---------
4066 $ hg log -r 0 -T '{pad(rev, 10, "-", "")}\n'
4066 $ hg log -r 0 -T '{pad(rev, 10, "-", "")}\n'
4067 0---------
4067 0---------
4068
4068
4069 unknown keyword is evaluated to ''
4069 unknown keyword is evaluated to ''
4070
4070
4071 $ hg log -r 0 -T '{pad(rev, 10, "-", unknownkeyword)}\n'
4071 $ hg log -r 0 -T '{pad(rev, 10, "-", unknownkeyword)}\n'
4072 0---------
4072 0---------
4073
4073
4074 Test separate function
4074 Test separate function
4075
4075
4076 $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
4076 $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
4077 a-b-c
4077 a-b-c
4078 $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
4078 $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
4079 0:f7769ec2ab97 test default
4079 0:f7769ec2ab97 test default
4080 $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
4080 $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
4081 a \x1b[0;31mb\x1b[0m c d (esc)
4081 a \x1b[0;31mb\x1b[0m c d (esc)
4082
4082
4083 Test boolean expression/literal passed to if function
4083 Test boolean expression/literal passed to if function
4084
4084
4085 $ hg log -r 0 -T '{if(rev, "rev 0 is True")}\n'
4085 $ hg log -r 0 -T '{if(rev, "rev 0 is True")}\n'
4086 rev 0 is True
4086 rev 0 is True
4087 $ hg log -r 0 -T '{if(0, "literal 0 is True as well")}\n'
4087 $ hg log -r 0 -T '{if(0, "literal 0 is True as well")}\n'
4088 literal 0 is True as well
4088 literal 0 is True as well
4089 $ hg log -r 0 -T '{if("", "", "empty string is False")}\n'
4089 $ hg log -r 0 -T '{if("", "", "empty string is False")}\n'
4090 empty string is False
4090 empty string is False
4091 $ hg log -r 0 -T '{if(revset(r"0 - 0"), "", "empty list is False")}\n'
4091 $ hg log -r 0 -T '{if(revset(r"0 - 0"), "", "empty list is False")}\n'
4092 empty list is False
4092 empty list is False
4093 $ hg log -r 0 -T '{if(true, "true is True")}\n'
4093 $ hg log -r 0 -T '{if(true, "true is True")}\n'
4094 true is True
4094 true is True
4095 $ hg log -r 0 -T '{if(false, "", "false is False")}\n'
4095 $ hg log -r 0 -T '{if(false, "", "false is False")}\n'
4096 false is False
4096 false is False
4097 $ hg log -r 0 -T '{if("false", "non-empty string is True")}\n'
4097 $ hg log -r 0 -T '{if("false", "non-empty string is True")}\n'
4098 non-empty string is True
4098 non-empty string is True
4099
4099
4100 Test ifcontains function
4100 Test ifcontains function
4101
4101
4102 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
4102 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
4103 2 is in the string
4103 2 is in the string
4104 1 is not
4104 1 is not
4105 0 is in the string
4105 0 is in the string
4106
4106
4107 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
4107 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
4108 2 is in the string
4108 2 is in the string
4109 1 is not
4109 1 is not
4110 0 is in the string
4110 0 is in the string
4111
4111
4112 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
4112 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
4113 2 did not add a
4113 2 did not add a
4114 1 did not add a
4114 1 did not add a
4115 0 added a
4115 0 added a
4116
4116
4117 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
4117 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
4118 2 is parent of 1
4118 2 is parent of 1
4119 1
4119 1
4120 0
4120 0
4121
4121
4122 Test revset function
4122 Test revset function
4123
4123
4124 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
4124 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
4125 2 current rev
4125 2 current rev
4126 1 not current rev
4126 1 not current rev
4127 0 not current rev
4127 0 not current rev
4128
4128
4129 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
4129 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
4130 2 match rev
4130 2 match rev
4131 1 match rev
4131 1 match rev
4132 0 not match rev
4132 0 not match rev
4133
4133
4134 $ hg log -T '{ifcontains(desc, revset(":"), "", "type not match")}\n' -l1
4134 $ hg log -T '{ifcontains(desc, revset(":"), "", "type not match")}\n' -l1
4135 type not match
4135 type not match
4136
4136
4137 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
4137 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
4138 2 Parents: 1
4138 2 Parents: 1
4139 1 Parents: 0
4139 1 Parents: 0
4140 0 Parents:
4140 0 Parents:
4141
4141
4142 $ cat >> .hg/hgrc <<EOF
4142 $ cat >> .hg/hgrc <<EOF
4143 > [revsetalias]
4143 > [revsetalias]
4144 > myparents(\$1) = parents(\$1)
4144 > myparents(\$1) = parents(\$1)
4145 > EOF
4145 > EOF
4146 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
4146 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
4147 2 Parents: 1
4147 2 Parents: 1
4148 1 Parents: 0
4148 1 Parents: 0
4149 0 Parents:
4149 0 Parents:
4150
4150
4151 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
4151 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
4152 Rev: 2
4152 Rev: 2
4153 Ancestor: 0
4153 Ancestor: 0
4154 Ancestor: 1
4154 Ancestor: 1
4155 Ancestor: 2
4155 Ancestor: 2
4156
4156
4157 Rev: 1
4157 Rev: 1
4158 Ancestor: 0
4158 Ancestor: 0
4159 Ancestor: 1
4159 Ancestor: 1
4160
4160
4161 Rev: 0
4161 Rev: 0
4162 Ancestor: 0
4162 Ancestor: 0
4163
4163
4164 $ hg log --template '{revset("TIP"|lower)}\n' -l1
4164 $ hg log --template '{revset("TIP"|lower)}\n' -l1
4165 2
4165 2
4166
4166
4167 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
4167 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
4168 2
4168 2
4169
4169
4170 a list template is evaluated for each item of revset/parents
4170 a list template is evaluated for each item of revset/parents
4171
4171
4172 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
4172 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
4173 2 p: 1:bcc7ff960b8e
4173 2 p: 1:bcc7ff960b8e
4174 1 p: 0:f7769ec2ab97
4174 1 p: 0:f7769ec2ab97
4175 0 p:
4175 0 p:
4176
4176
4177 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
4177 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
4178 2 p: 1:bcc7ff960b8e -1:000000000000
4178 2 p: 1:bcc7ff960b8e -1:000000000000
4179 1 p: 0:f7769ec2ab97 -1:000000000000
4179 1 p: 0:f7769ec2ab97 -1:000000000000
4180 0 p: -1:000000000000 -1:000000000000
4180 0 p: -1:000000000000 -1:000000000000
4181
4181
4182 therefore, 'revcache' should be recreated for each rev
4182 therefore, 'revcache' should be recreated for each rev
4183
4183
4184 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
4184 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
4185 2 aa b
4185 2 aa b
4186 p
4186 p
4187 1
4187 1
4188 p a
4188 p a
4189 0 a
4189 0 a
4190 p
4190 p
4191
4191
4192 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
4192 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
4193 2 aa b
4193 2 aa b
4194 p
4194 p
4195 1
4195 1
4196 p a
4196 p a
4197 0 a
4197 0 a
4198 p
4198 p
4199
4199
4200 a revset item must be evaluated as an integer revision, not an offset from tip
4200 a revset item must be evaluated as an integer revision, not an offset from tip
4201
4201
4202 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
4202 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
4203 -1:000000000000
4203 -1:000000000000
4204 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
4204 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
4205 -1:000000000000
4205 -1:000000000000
4206
4206
4207 join() should pick '{rev}' from revset items:
4207 join() should pick '{rev}' from revset items:
4208
4208
4209 $ hg log -R ../a -T '{join(revset("parents(%d)", rev), ", ")}\n' -r6
4209 $ hg log -R ../a -T '{join(revset("parents(%d)", rev), ", ")}\n' -r6
4210 4, 5
4210 4, 5
4211
4211
4212 on the other hand, parents are formatted as '{rev}:{node|formatnode}' by
4212 on the other hand, parents are formatted as '{rev}:{node|formatnode}' by
4213 default. join() should agree with the default formatting:
4213 default. join() should agree with the default formatting:
4214
4214
4215 $ hg log -R ../a -T '{join(parents, ", ")}\n' -r6
4215 $ hg log -R ../a -T '{join(parents, ", ")}\n' -r6
4216 5:13207e5a10d9, 4:bbe44766e73d
4216 5:13207e5a10d9, 4:bbe44766e73d
4217
4217
4218 $ hg log -R ../a -T '{join(parents, ",\n")}\n' -r6 --debug
4218 $ hg log -R ../a -T '{join(parents, ",\n")}\n' -r6 --debug
4219 5:13207e5a10d9fd28ec424934298e176197f2c67f,
4219 5:13207e5a10d9fd28ec424934298e176197f2c67f,
4220 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
4220 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
4221
4221
4222 Invalid arguments passed to revset()
4222 Invalid arguments passed to revset()
4223
4223
4224 $ hg log -T '{revset("%whatever", 0)}\n'
4224 $ hg log -T '{revset("%whatever", 0)}\n'
4225 hg: parse error: unexpected revspec format character w
4225 hg: parse error: unexpected revspec format character w
4226 [255]
4226 [255]
4227 $ hg log -T '{revset("%lwhatever", files)}\n'
4227 $ hg log -T '{revset("%lwhatever", files)}\n'
4228 hg: parse error: unexpected revspec format character w
4228 hg: parse error: unexpected revspec format character w
4229 [255]
4229 [255]
4230 $ hg log -T '{revset("%s %s", 0)}\n'
4230 $ hg log -T '{revset("%s %s", 0)}\n'
4231 hg: parse error: missing argument for revspec
4231 hg: parse error: missing argument for revspec
4232 [255]
4232 [255]
4233 $ hg log -T '{revset("", 0)}\n'
4233 $ hg log -T '{revset("", 0)}\n'
4234 hg: parse error: too many revspec arguments specified
4234 hg: parse error: too many revspec arguments specified
4235 [255]
4235 [255]
4236 $ hg log -T '{revset("%s", 0, 1)}\n'
4236 $ hg log -T '{revset("%s", 0, 1)}\n'
4237 hg: parse error: too many revspec arguments specified
4237 hg: parse error: too many revspec arguments specified
4238 [255]
4238 [255]
4239 $ hg log -T '{revset("%", 0)}\n'
4239 $ hg log -T '{revset("%", 0)}\n'
4240 hg: parse error: incomplete revspec format character
4240 hg: parse error: incomplete revspec format character
4241 [255]
4241 [255]
4242 $ hg log -T '{revset("%l", 0)}\n'
4242 $ hg log -T '{revset("%l", 0)}\n'
4243 hg: parse error: incomplete revspec format character
4243 hg: parse error: incomplete revspec format character
4244 [255]
4244 [255]
4245 $ hg log -T '{revset("%d", 'foo')}\n'
4245 $ hg log -T '{revset("%d", 'foo')}\n'
4246 hg: parse error: invalid argument for revspec
4246 hg: parse error: invalid argument for revspec
4247 [255]
4247 [255]
4248 $ hg log -T '{revset("%ld", files)}\n'
4248 $ hg log -T '{revset("%ld", files)}\n'
4249 hg: parse error: invalid argument for revspec
4249 hg: parse error: invalid argument for revspec
4250 [255]
4250 [255]
4251 $ hg log -T '{revset("%ls", 0)}\n'
4251 $ hg log -T '{revset("%ls", 0)}\n'
4252 hg: parse error: invalid argument for revspec
4252 hg: parse error: invalid argument for revspec
4253 [255]
4253 [255]
4254 $ hg log -T '{revset("%b", 'foo')}\n'
4254 $ hg log -T '{revset("%b", 'foo')}\n'
4255 hg: parse error: invalid argument for revspec
4255 hg: parse error: invalid argument for revspec
4256 [255]
4256 [255]
4257 $ hg log -T '{revset("%lb", files)}\n'
4257 $ hg log -T '{revset("%lb", files)}\n'
4258 hg: parse error: invalid argument for revspec
4258 hg: parse error: invalid argument for revspec
4259 [255]
4259 [255]
4260 $ hg log -T '{revset("%r", 0)}\n'
4260 $ hg log -T '{revset("%r", 0)}\n'
4261 hg: parse error: invalid argument for revspec
4261 hg: parse error: invalid argument for revspec
4262 [255]
4262 [255]
4263
4263
4264 Test 'originalnode'
4264 Test 'originalnode'
4265
4265
4266 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
4266 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
4267 000000000000 bcc7ff960b8e
4267 000000000000 bcc7ff960b8e
4268 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
4268 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
4269 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
4269 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
4270
4270
4271 Test files function
4271 Test files function
4272
4272
4273 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
4273 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
4274 2
4274 2
4275 a
4275 a
4276 aa
4276 aa
4277 b
4277 b
4278 1
4278 1
4279 a
4279 a
4280 0
4280 0
4281 a
4281 a
4282
4282
4283 $ hg log -T "{rev}\n{join(files('aa'), '\n')}\n"
4283 $ hg log -T "{rev}\n{join(files('aa'), '\n')}\n"
4284 2
4284 2
4285 aa
4285 aa
4286 1
4286 1
4287
4287
4288 0
4288 0
4289
4289
4290
4290
4291 Test relpath function
4291 Test relpath function
4292
4292
4293 $ hg log -r0 -T '{files % "{file|relpath}\n"}'
4293 $ hg log -r0 -T '{files % "{file|relpath}\n"}'
4294 a
4294 a
4295 $ cd ..
4295 $ cd ..
4296 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
4296 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
4297 r/a
4297 r/a
4298 $ cd r
4298 $ cd r
4299
4299
4300 Test active bookmark templating
4300 Test active bookmark templating
4301
4301
4302 $ hg book foo
4302 $ hg book foo
4303 $ hg book bar
4303 $ hg book bar
4304 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
4304 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
4305 2 bar* foo
4305 2 bar* foo
4306 1
4306 1
4307 0
4307 0
4308 $ hg log --template "{rev} {activebookmark}\n"
4308 $ hg log --template "{rev} {activebookmark}\n"
4309 2 bar
4309 2 bar
4310 1
4310 1
4311 0
4311 0
4312 $ hg bookmarks --inactive bar
4312 $ hg bookmarks --inactive bar
4313 $ hg log --template "{rev} {activebookmark}\n"
4313 $ hg log --template "{rev} {activebookmark}\n"
4314 2
4314 2
4315 1
4315 1
4316 0
4316 0
4317 $ hg book -r1 baz
4317 $ hg book -r1 baz
4318 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
4318 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
4319 2 bar foo
4319 2 bar foo
4320 1 baz
4320 1 baz
4321 0
4321 0
4322 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
4322 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
4323 2 t
4323 2 t
4324 1 f
4324 1 f
4325 0 f
4325 0 f
4326
4326
4327 Test namespaces dict
4327 Test namespaces dict
4328
4328
4329 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
4329 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
4330 2
4330 2
4331 bookmarks color=bookmark builtin=True
4331 bookmarks color=bookmark builtin=True
4332 bar,foo
4332 bar,foo
4333 tags color=tag builtin=True
4333 tags color=tag builtin=True
4334 tip
4334 tip
4335 branches color=branch builtin=True
4335 branches color=branch builtin=True
4336 text.{rev}
4336 text.{rev}
4337 revnames color=revname builtin=False
4337 revnames color=revname builtin=False
4338 r2
4338 r2
4339
4339
4340 1
4340 1
4341 bookmarks color=bookmark builtin=True
4341 bookmarks color=bookmark builtin=True
4342 baz
4342 baz
4343 tags color=tag builtin=True
4343 tags color=tag builtin=True
4344
4344
4345 branches color=branch builtin=True
4345 branches color=branch builtin=True
4346 text.{rev}
4346 text.{rev}
4347 revnames color=revname builtin=False
4347 revnames color=revname builtin=False
4348 r1
4348 r1
4349
4349
4350 0
4350 0
4351 bookmarks color=bookmark builtin=True
4351 bookmarks color=bookmark builtin=True
4352
4352
4353 tags color=tag builtin=True
4353 tags color=tag builtin=True
4354
4354
4355 branches color=branch builtin=True
4355 branches color=branch builtin=True
4356 default
4356 default
4357 revnames color=revname builtin=False
4357 revnames color=revname builtin=False
4358 r0
4358 r0
4359
4359
4360 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
4360 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
4361 bookmarks: bar foo
4361 bookmarks: bar foo
4362 tags: tip
4362 tags: tip
4363 branches: text.{rev}
4363 branches: text.{rev}
4364 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
4364 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
4365 bookmarks:
4365 bookmarks:
4366 bar
4366 bar
4367 foo
4367 foo
4368 tags:
4368 tags:
4369 tip
4369 tip
4370 branches:
4370 branches:
4371 text.{rev}
4371 text.{rev}
4372 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
4372 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
4373 bar
4373 bar
4374 foo
4374 foo
4375 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
4375 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
4376 bar
4376 bar
4377 foo
4377 foo
4378
4378
4379 Test stringify on sub expressions
4379 Test stringify on sub expressions
4380
4380
4381 $ cd ..
4381 $ cd ..
4382 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
4382 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
4383 fourth, second, third
4383 fourth, second, third
4384 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
4384 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
4385 abc
4385 abc
4386
4386
4387 Test splitlines
4387 Test splitlines
4388
4388
4389 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
4389 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
4390 @ foo Modify, add, remove, rename
4390 @ foo Modify, add, remove, rename
4391 |
4391 |
4392 o foo future
4392 o foo future
4393 |
4393 |
4394 o foo third
4394 o foo third
4395 |
4395 |
4396 o foo second
4396 o foo second
4397
4397
4398 o foo merge
4398 o foo merge
4399 |\
4399 |\
4400 | o foo new head
4400 | o foo new head
4401 | |
4401 | |
4402 o | foo new branch
4402 o | foo new branch
4403 |/
4403 |/
4404 o foo no user, no domain
4404 o foo no user, no domain
4405 |
4405 |
4406 o foo no person
4406 o foo no person
4407 |
4407 |
4408 o foo other 1
4408 o foo other 1
4409 | foo other 2
4409 | foo other 2
4410 | foo
4410 | foo
4411 | foo other 3
4411 | foo other 3
4412 o foo line 1
4412 o foo line 1
4413 foo line 2
4413 foo line 2
4414
4414
4415 $ hg log -R a -r0 -T '{desc|splitlines}\n'
4415 $ hg log -R a -r0 -T '{desc|splitlines}\n'
4416 line 1 line 2
4416 line 1 line 2
4417 $ hg log -R a -r0 -T '{join(desc|splitlines, "|")}\n'
4417 $ hg log -R a -r0 -T '{join(desc|splitlines, "|")}\n'
4418 line 1|line 2
4418 line 1|line 2
4419
4419
4420 Test startswith
4420 Test startswith
4421 $ hg log -Gv -R a --template "{startswith(desc)}"
4421 $ hg log -Gv -R a --template "{startswith(desc)}"
4422 hg: parse error: startswith expects two arguments
4422 hg: parse error: startswith expects two arguments
4423 [255]
4423 [255]
4424
4424
4425 $ hg log -Gv -R a --template "{startswith('line', desc)}"
4425 $ hg log -Gv -R a --template "{startswith('line', desc)}"
4426 @
4426 @
4427 |
4427 |
4428 o
4428 o
4429 |
4429 |
4430 o
4430 o
4431 |
4431 |
4432 o
4432 o
4433
4433
4434 o
4434 o
4435 |\
4435 |\
4436 | o
4436 | o
4437 | |
4437 | |
4438 o |
4438 o |
4439 |/
4439 |/
4440 o
4440 o
4441 |
4441 |
4442 o
4442 o
4443 |
4443 |
4444 o
4444 o
4445 |
4445 |
4446 o line 1
4446 o line 1
4447 line 2
4447 line 2
4448
4448
4449 Test bad template with better error message
4449 Test bad template with better error message
4450
4450
4451 $ hg log -Gv -R a --template '{desc|user()}'
4451 $ hg log -Gv -R a --template '{desc|user()}'
4452 hg: parse error: expected a symbol, got 'func'
4452 hg: parse error: expected a symbol, got 'func'
4453 [255]
4453 [255]
4454
4454
4455 Test word function (including index out of bounds graceful failure)
4455 Test word function (including index out of bounds graceful failure)
4456
4456
4457 $ hg log -Gv -R a --template "{word('1', desc)}"
4457 $ hg log -Gv -R a --template "{word('1', desc)}"
4458 @ add,
4458 @ add,
4459 |
4459 |
4460 o
4460 o
4461 |
4461 |
4462 o
4462 o
4463 |
4463 |
4464 o
4464 o
4465
4465
4466 o
4466 o
4467 |\
4467 |\
4468 | o head
4468 | o head
4469 | |
4469 | |
4470 o | branch
4470 o | branch
4471 |/
4471 |/
4472 o user,
4472 o user,
4473 |
4473 |
4474 o person
4474 o person
4475 |
4475 |
4476 o 1
4476 o 1
4477 |
4477 |
4478 o 1
4478 o 1
4479
4479
4480
4480
4481 Test word third parameter used as splitter
4481 Test word third parameter used as splitter
4482
4482
4483 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
4483 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
4484 @ M
4484 @ M
4485 |
4485 |
4486 o future
4486 o future
4487 |
4487 |
4488 o third
4488 o third
4489 |
4489 |
4490 o sec
4490 o sec
4491
4491
4492 o merge
4492 o merge
4493 |\
4493 |\
4494 | o new head
4494 | o new head
4495 | |
4495 | |
4496 o | new branch
4496 o | new branch
4497 |/
4497 |/
4498 o n
4498 o n
4499 |
4499 |
4500 o n
4500 o n
4501 |
4501 |
4502 o
4502 o
4503 |
4503 |
4504 o line 1
4504 o line 1
4505 line 2
4505 line 2
4506
4506
4507 Test word error messages for not enough and too many arguments
4507 Test word error messages for not enough and too many arguments
4508
4508
4509 $ hg log -Gv -R a --template "{word('0')}"
4509 $ hg log -Gv -R a --template "{word('0')}"
4510 hg: parse error: word expects two or three arguments, got 1
4510 hg: parse error: word expects two or three arguments, got 1
4511 [255]
4511 [255]
4512
4512
4513 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
4513 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
4514 hg: parse error: word expects two or three arguments, got 7
4514 hg: parse error: word expects two or three arguments, got 7
4515 [255]
4515 [255]
4516
4516
4517 Test word for integer literal
4517 Test word for integer literal
4518
4518
4519 $ hg log -R a --template "{word(2, desc)}\n" -r0
4519 $ hg log -R a --template "{word(2, desc)}\n" -r0
4520 line
4520 line
4521
4521
4522 Test word for invalid numbers
4522 Test word for invalid numbers
4523
4523
4524 $ hg log -Gv -R a --template "{word('a', desc)}"
4524 $ hg log -Gv -R a --template "{word('a', desc)}"
4525 hg: parse error: word expects an integer index
4525 hg: parse error: word expects an integer index
4526 [255]
4526 [255]
4527
4527
4528 Test word for out of range
4528 Test word for out of range
4529
4529
4530 $ hg log -R a --template "{word(10000, desc)}"
4530 $ hg log -R a --template "{word(10000, desc)}"
4531 $ hg log -R a --template "{word(-10000, desc)}"
4531 $ hg log -R a --template "{word(-10000, desc)}"
4532
4532
4533 Test indent and not adding to empty lines
4533 Test indent and not adding to empty lines
4534
4534
4535 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
4535 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
4536 -----
4536 -----
4537 > line 1
4537 > line 1
4538 >> line 2
4538 >> line 2
4539 -----
4539 -----
4540 > other 1
4540 > other 1
4541 >> other 2
4541 >> other 2
4542
4542
4543 >> other 3
4543 >> other 3
4544
4544
4545 Test with non-strings like dates
4545 Test with non-strings like dates
4546
4546
4547 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
4547 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
4548 1200000.00
4548 1200000.00
4549 1300000.00
4549 1300000.00
4550
4550
4551 Test broken string escapes:
4551 Test broken string escapes:
4552
4552
4553 $ hg log -T "bogus\\" -R a
4553 $ hg log -T "bogus\\" -R a
4554 hg: parse error: trailing \ in string
4554 hg: parse error: trailing \ in string
4555 [255]
4555 [255]
4556 $ hg log -T "\\xy" -R a
4556 $ hg log -T "\\xy" -R a
4557 hg: parse error: invalid \x escape* (glob)
4557 hg: parse error: invalid \x escape* (glob)
4558 [255]
4558 [255]
4559
4559
4560 json filter should escape HTML tags so that the output can be embedded in hgweb:
4560 json filter should escape HTML tags so that the output can be embedded in hgweb:
4561
4561
4562 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
4562 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
4563 "\u003cfoo@example.org\u003e"
4563 "\u003cfoo@example.org\u003e"
4564
4564
4565 Templater supports aliases of symbol and func() styles:
4565 Templater supports aliases of symbol and func() styles:
4566
4566
4567 $ hg clone -q a aliases
4567 $ hg clone -q a aliases
4568 $ cd aliases
4568 $ cd aliases
4569 $ cat <<EOF >> .hg/hgrc
4569 $ cat <<EOF >> .hg/hgrc
4570 > [templatealias]
4570 > [templatealias]
4571 > r = rev
4571 > r = rev
4572 > rn = "{r}:{node|short}"
4572 > rn = "{r}:{node|short}"
4573 > status(c, files) = files % "{c} {file}\n"
4573 > status(c, files) = files % "{c} {file}\n"
4574 > utcdate(d) = localdate(d, "UTC")
4574 > utcdate(d) = localdate(d, "UTC")
4575 > EOF
4575 > EOF
4576
4576
4577 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
4577 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
4578 (template
4578 (template
4579 (symbol 'rn')
4579 (symbol 'rn')
4580 (string ' ')
4580 (string ' ')
4581 (|
4581 (|
4582 (func
4582 (func
4583 (symbol 'utcdate')
4583 (symbol 'utcdate')
4584 (symbol 'date'))
4584 (symbol 'date'))
4585 (symbol 'isodate'))
4585 (symbol 'isodate'))
4586 (string '\n'))
4586 (string '\n'))
4587 * expanded:
4587 * expanded:
4588 (template
4588 (template
4589 (template
4589 (template
4590 (symbol 'rev')
4590 (symbol 'rev')
4591 (string ':')
4591 (string ':')
4592 (|
4592 (|
4593 (symbol 'node')
4593 (symbol 'node')
4594 (symbol 'short')))
4594 (symbol 'short')))
4595 (string ' ')
4595 (string ' ')
4596 (|
4596 (|
4597 (func
4597 (func
4598 (symbol 'localdate')
4598 (symbol 'localdate')
4599 (list
4599 (list
4600 (symbol 'date')
4600 (symbol 'date')
4601 (string 'UTC')))
4601 (string 'UTC')))
4602 (symbol 'isodate'))
4602 (symbol 'isodate'))
4603 (string '\n'))
4603 (string '\n'))
4604 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4604 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4605
4605
4606 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
4606 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
4607 (template
4607 (template
4608 (func
4608 (func
4609 (symbol 'status')
4609 (symbol 'status')
4610 (list
4610 (list
4611 (string 'A')
4611 (string 'A')
4612 (symbol 'file_adds'))))
4612 (symbol 'file_adds'))))
4613 * expanded:
4613 * expanded:
4614 (template
4614 (template
4615 (%
4615 (%
4616 (symbol 'file_adds')
4616 (symbol 'file_adds')
4617 (template
4617 (template
4618 (string 'A')
4618 (string 'A')
4619 (string ' ')
4619 (string ' ')
4620 (symbol 'file')
4620 (symbol 'file')
4621 (string '\n'))))
4621 (string '\n'))))
4622 A a
4622 A a
4623
4623
4624 A unary function alias can be called as a filter:
4624 A unary function alias can be called as a filter:
4625
4625
4626 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
4626 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
4627 (template
4627 (template
4628 (|
4628 (|
4629 (|
4629 (|
4630 (symbol 'date')
4630 (symbol 'date')
4631 (symbol 'utcdate'))
4631 (symbol 'utcdate'))
4632 (symbol 'isodate'))
4632 (symbol 'isodate'))
4633 (string '\n'))
4633 (string '\n'))
4634 * expanded:
4634 * expanded:
4635 (template
4635 (template
4636 (|
4636 (|
4637 (func
4637 (func
4638 (symbol 'localdate')
4638 (symbol 'localdate')
4639 (list
4639 (list
4640 (symbol 'date')
4640 (symbol 'date')
4641 (string 'UTC')))
4641 (string 'UTC')))
4642 (symbol 'isodate'))
4642 (symbol 'isodate'))
4643 (string '\n'))
4643 (string '\n'))
4644 1970-01-12 13:46 +0000
4644 1970-01-12 13:46 +0000
4645
4645
4646 Aliases should be applied only to command arguments and templates in hgrc.
4646 Aliases should be applied only to command arguments and templates in hgrc.
4647 Otherwise, our stock styles and web templates could be corrupted:
4647 Otherwise, our stock styles and web templates could be corrupted:
4648
4648
4649 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
4649 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
4650 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4650 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4651
4651
4652 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
4652 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
4653 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4653 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4654
4654
4655 $ cat <<EOF > tmpl
4655 $ cat <<EOF > tmpl
4656 > changeset = 'nothing expanded:{rn}\n'
4656 > changeset = 'nothing expanded:{rn}\n'
4657 > EOF
4657 > EOF
4658 $ hg log -r0 --style ./tmpl
4658 $ hg log -r0 --style ./tmpl
4659 nothing expanded:
4659 nothing expanded:
4660
4660
4661 Aliases in formatter:
4661 Aliases in formatter:
4662
4662
4663 $ hg branches -T '{pad(branch, 7)} {rn}\n'
4663 $ hg branches -T '{pad(branch, 7)} {rn}\n'
4664 default 6:d41e714fe50d
4664 default 6:d41e714fe50d
4665 foo 4:bbe44766e73d
4665 foo 4:bbe44766e73d
4666
4666
4667 Aliases should honor HGPLAIN:
4667 Aliases should honor HGPLAIN:
4668
4668
4669 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
4669 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
4670 nothing expanded:
4670 nothing expanded:
4671 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
4671 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
4672 0:1e4e1b8f71e0
4672 0:1e4e1b8f71e0
4673
4673
4674 Unparsable alias:
4674 Unparsable alias:
4675
4675
4676 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
4676 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
4677 (template
4677 (template
4678 (symbol 'bad'))
4678 (symbol 'bad'))
4679 abort: bad definition of template alias "bad": at 2: not a prefix: end
4679 abort: bad definition of template alias "bad": at 2: not a prefix: end
4680 [255]
4680 [255]
4681 $ hg log --config templatealias.bad='x(' -T '{bad}'
4681 $ hg log --config templatealias.bad='x(' -T '{bad}'
4682 abort: bad definition of template alias "bad": at 2: not a prefix: end
4682 abort: bad definition of template alias "bad": at 2: not a prefix: end
4683 [255]
4683 [255]
4684
4684
4685 $ cd ..
4685 $ cd ..
4686
4686
4687 Set up repository for non-ascii encoding tests:
4687 Set up repository for non-ascii encoding tests:
4688
4688
4689 $ hg init nonascii
4689 $ hg init nonascii
4690 $ cd nonascii
4690 $ cd nonascii
4691 $ $PYTHON <<EOF
4691 $ $PYTHON <<EOF
4692 > open('latin1', 'wb').write(b'\xe9')
4692 > open('latin1', 'wb').write(b'\xe9')
4693 > open('utf-8', 'wb').write(b'\xc3\xa9')
4693 > open('utf-8', 'wb').write(b'\xc3\xa9')
4694 > EOF
4694 > EOF
4695 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
4695 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
4696 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
4696 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
4697
4697
4698 json filter should try round-trip conversion to utf-8:
4698 json filter should try round-trip conversion to utf-8:
4699
4699
4700 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
4700 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
4701 "\u00e9"
4701 "\u00e9"
4702 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
4702 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
4703 "non-ascii branch: \u00e9"
4703 "non-ascii branch: \u00e9"
4704
4704
4705 json filter should take input as utf-8 if it was converted from utf-8:
4705 json filter should take input as utf-8 if it was converted from utf-8:
4706
4706
4707 $ HGENCODING=latin-1 hg log -T "{branch|json}\n" -r0
4707 $ HGENCODING=latin-1 hg log -T "{branch|json}\n" -r0
4708 "\u00e9"
4708 "\u00e9"
4709 $ HGENCODING=latin-1 hg log -T "{desc|json}\n" -r0
4709 $ HGENCODING=latin-1 hg log -T "{desc|json}\n" -r0
4710 "non-ascii branch: \u00e9"
4710 "non-ascii branch: \u00e9"
4711
4711
4712 json filter takes input as utf-8b:
4712 json filter takes input as utf-8b:
4713
4713
4714 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
4714 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
4715 "\u00e9"
4715 "\u00e9"
4716 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
4716 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
4717 "\udce9"
4717 "\udce9"
4718
4718
4719 utf8 filter:
4719 utf8 filter:
4720
4720
4721 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
4721 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
4722 round-trip: c3a9
4722 round-trip: c3a9
4723 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
4723 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
4724 decoded: c3a9
4724 decoded: c3a9
4725 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
4725 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
4726 abort: decoding near * (glob)
4726 abort: decoding near * (glob)
4727 [255]
4727 [255]
4728 $ hg log -T "coerced to string: {rev|utf8}\n" -r0
4728 $ hg log -T "coerced to string: {rev|utf8}\n" -r0
4729 coerced to string: 0
4729 coerced to string: 0
4730
4730
4731 pad width:
4731 pad width:
4732
4732
4733 $ HGENCODING=utf-8 hg debugtemplate "{pad('`cat utf-8`', 2, '-')}\n"
4733 $ HGENCODING=utf-8 hg debugtemplate "{pad('`cat utf-8`', 2, '-')}\n"
4734 \xc3\xa9- (esc)
4734 \xc3\xa9- (esc)
4735
4735
4736 $ cd ..
4736 $ cd ..
4737
4737
4738 Test that template function in extension is registered as expected
4738 Test that template function in extension is registered as expected
4739
4739
4740 $ cd a
4740 $ cd a
4741
4741
4742 $ cat <<EOF > $TESTTMP/customfunc.py
4742 $ cat <<EOF > $TESTTMP/customfunc.py
4743 > from mercurial import registrar
4743 > from mercurial import registrar
4744 >
4744 >
4745 > templatefunc = registrar.templatefunc()
4745 > templatefunc = registrar.templatefunc()
4746 >
4746 >
4747 > @templatefunc(b'custom()')
4747 > @templatefunc(b'custom()')
4748 > def custom(context, mapping, args):
4748 > def custom(context, mapping, args):
4749 > return b'custom'
4749 > return b'custom'
4750 > EOF
4750 > EOF
4751 $ cat <<EOF > .hg/hgrc
4751 $ cat <<EOF > .hg/hgrc
4752 > [extensions]
4752 > [extensions]
4753 > customfunc = $TESTTMP/customfunc.py
4753 > customfunc = $TESTTMP/customfunc.py
4754 > EOF
4754 > EOF
4755
4755
4756 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
4756 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
4757 custom
4757 custom
4758
4758
4759 $ cd ..
4759 $ cd ..
4760
4760
4761 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
4761 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
4762 printed graphwidths 3, 5, 7, etc. should all line up in their respective
4762 printed graphwidths 3, 5, 7, etc. should all line up in their respective
4763 columns. We don't care about other aspects of the graph rendering here.
4763 columns. We don't care about other aspects of the graph rendering here.
4764
4764
4765 $ hg init graphwidth
4765 $ hg init graphwidth
4766 $ cd graphwidth
4766 $ cd graphwidth
4767
4767
4768 $ wrappabletext="a a a a a a a a a a a a"
4768 $ wrappabletext="a a a a a a a a a a a a"
4769
4769
4770 $ printf "first\n" > file
4770 $ printf "first\n" > file
4771 $ hg add file
4771 $ hg add file
4772 $ hg commit -m "$wrappabletext"
4772 $ hg commit -m "$wrappabletext"
4773
4773
4774 $ printf "first\nsecond\n" > file
4774 $ printf "first\nsecond\n" > file
4775 $ hg commit -m "$wrappabletext"
4775 $ hg commit -m "$wrappabletext"
4776
4776
4777 $ hg checkout 0
4777 $ hg checkout 0
4778 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4778 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4779 $ printf "third\nfirst\n" > file
4779 $ printf "third\nfirst\n" > file
4780 $ hg commit -m "$wrappabletext"
4780 $ hg commit -m "$wrappabletext"
4781 created new head
4781 created new head
4782
4782
4783 $ hg merge
4783 $ hg merge
4784 merging file
4784 merging file
4785 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
4785 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
4786 (branch merge, don't forget to commit)
4786 (branch merge, don't forget to commit)
4787
4787
4788 $ hg log --graph -T "{graphwidth}"
4788 $ hg log --graph -T "{graphwidth}"
4789 @ 3
4789 @ 3
4790 |
4790 |
4791 | @ 5
4791 | @ 5
4792 |/
4792 |/
4793 o 3
4793 o 3
4794
4794
4795 $ hg commit -m "$wrappabletext"
4795 $ hg commit -m "$wrappabletext"
4796
4796
4797 $ hg log --graph -T "{graphwidth}"
4797 $ hg log --graph -T "{graphwidth}"
4798 @ 5
4798 @ 5
4799 |\
4799 |\
4800 | o 5
4800 | o 5
4801 | |
4801 | |
4802 o | 5
4802 o | 5
4803 |/
4803 |/
4804 o 3
4804 o 3
4805
4805
4806
4806
4807 $ hg checkout 0
4807 $ hg checkout 0
4808 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4808 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4809 $ printf "third\nfirst\nsecond\n" > file
4809 $ printf "third\nfirst\nsecond\n" > file
4810 $ hg commit -m "$wrappabletext"
4810 $ hg commit -m "$wrappabletext"
4811 created new head
4811 created new head
4812
4812
4813 $ hg log --graph -T "{graphwidth}"
4813 $ hg log --graph -T "{graphwidth}"
4814 @ 3
4814 @ 3
4815 |
4815 |
4816 | o 7
4816 | o 7
4817 | |\
4817 | |\
4818 +---o 7
4818 +---o 7
4819 | |
4819 | |
4820 | o 5
4820 | o 5
4821 |/
4821 |/
4822 o 3
4822 o 3
4823
4823
4824
4824
4825 $ hg log --graph -T "{graphwidth}" -r 3
4825 $ hg log --graph -T "{graphwidth}" -r 3
4826 o 5
4826 o 5
4827 |\
4827 |\
4828 ~ ~
4828 ~ ~
4829
4829
4830 $ hg log --graph -T "{graphwidth}" -r 1
4830 $ hg log --graph -T "{graphwidth}" -r 1
4831 o 3
4831 o 3
4832 |
4832 |
4833 ~
4833 ~
4834
4834
4835 $ hg merge
4835 $ hg merge
4836 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4836 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4837 (branch merge, don't forget to commit)
4837 (branch merge, don't forget to commit)
4838 $ hg commit -m "$wrappabletext"
4838 $ hg commit -m "$wrappabletext"
4839
4839
4840 $ printf "seventh\n" >> file
4840 $ printf "seventh\n" >> file
4841 $ hg commit -m "$wrappabletext"
4841 $ hg commit -m "$wrappabletext"
4842
4842
4843 $ hg log --graph -T "{graphwidth}"
4843 $ hg log --graph -T "{graphwidth}"
4844 @ 3
4844 @ 3
4845 |
4845 |
4846 o 5
4846 o 5
4847 |\
4847 |\
4848 | o 5
4848 | o 5
4849 | |
4849 | |
4850 o | 7
4850 o | 7
4851 |\ \
4851 |\ \
4852 | o | 7
4852 | o | 7
4853 | |/
4853 | |/
4854 o / 5
4854 o / 5
4855 |/
4855 |/
4856 o 3
4856 o 3
4857
4857
4858
4858
4859 The point of graphwidth is to allow wrapping that accounts for the space taken
4859 The point of graphwidth is to allow wrapping that accounts for the space taken
4860 by the graph.
4860 by the graph.
4861
4861
4862 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
4862 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
4863 @ a a a a
4863 @ a a a a
4864 | a a a a
4864 | a a a a
4865 | a a a a
4865 | a a a a
4866 o a a a
4866 o a a a
4867 |\ a a a
4867 |\ a a a
4868 | | a a a
4868 | | a a a
4869 | | a a a
4869 | | a a a
4870 | o a a a
4870 | o a a a
4871 | | a a a
4871 | | a a a
4872 | | a a a
4872 | | a a a
4873 | | a a a
4873 | | a a a
4874 o | a a
4874 o | a a
4875 |\ \ a a
4875 |\ \ a a
4876 | | | a a
4876 | | | a a
4877 | | | a a
4877 | | | a a
4878 | | | a a
4878 | | | a a
4879 | | | a a
4879 | | | a a
4880 | o | a a
4880 | o | a a
4881 | |/ a a
4881 | |/ a a
4882 | | a a
4882 | | a a
4883 | | a a
4883 | | a a
4884 | | a a
4884 | | a a
4885 | | a a
4885 | | a a
4886 o | a a a
4886 o | a a a
4887 |/ a a a
4887 |/ a a a
4888 | a a a
4888 | a a a
4889 | a a a
4889 | a a a
4890 o a a a a
4890 o a a a a
4891 a a a a
4891 a a a a
4892 a a a a
4892 a a a a
4893
4893
4894 Something tricky happens when there are elided nodes; the next drawn row of
4894 Something tricky happens when there are elided nodes; the next drawn row of
4895 edges can be more than one column wider, but the graph width only increases by
4895 edges can be more than one column wider, but the graph width only increases by
4896 one column. The remaining columns are added in between the nodes.
4896 one column. The remaining columns are added in between the nodes.
4897
4897
4898 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
4898 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
4899 o 5
4899 o 5
4900 |\
4900 |\
4901 | \
4901 | \
4902 | :\
4902 | :\
4903 o : : 7
4903 o : : 7
4904 :/ /
4904 :/ /
4905 : o 5
4905 : o 5
4906 :/
4906 :/
4907 o 3
4907 o 3
4908
4908
4909
4909
4910 $ cd ..
4910 $ cd ..
4911
4911
General Comments 0
You need to be logged in to leave comments. Login now