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