##// END OF EJS Templates
formatter: populate ctx from repo and node value...
Yuya Nishihara -
r39659:34ecc0a0 default
parent child Browse files
Show More
@@ -1,665 +1,678 b''
1 # formatter.py - generic output formatting for mercurial
1 # formatter.py - generic output formatting for mercurial
2 #
2 #
3 # Copyright 2012 Matt Mackall <mpm@selenic.com>
3 # Copyright 2012 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 """Generic output formatting for Mercurial
8 """Generic output formatting for Mercurial
9
9
10 The formatter provides API to show data in various ways. The following
10 The formatter provides API to show data in various ways. The following
11 functions should be used in place of ui.write():
11 functions should be used in place of ui.write():
12
12
13 - fm.write() for unconditional output
13 - fm.write() for unconditional output
14 - fm.condwrite() to show some extra data conditionally in plain output
14 - fm.condwrite() to show some extra data conditionally in plain output
15 - fm.context() to provide changectx to template output
15 - fm.context() to provide changectx to template output
16 - fm.data() to provide extra data to JSON or template output
16 - fm.data() to provide extra data to JSON or template output
17 - fm.plain() to show raw text that isn't provided to JSON or template output
17 - fm.plain() to show raw text that isn't provided to JSON or template output
18
18
19 To show structured data (e.g. date tuples, dicts, lists), apply fm.format*()
19 To show structured data (e.g. date tuples, dicts, lists), apply fm.format*()
20 beforehand so the data is converted to the appropriate data type. Use
20 beforehand so the data is converted to the appropriate data type. Use
21 fm.isplain() if you need to convert or format data conditionally which isn't
21 fm.isplain() if you need to convert or format data conditionally which isn't
22 supported by the formatter API.
22 supported by the formatter API.
23
23
24 To build nested structure (i.e. a list of dicts), use fm.nested().
24 To build nested structure (i.e. a list of dicts), use fm.nested().
25
25
26 See also https://www.mercurial-scm.org/wiki/GenericTemplatingPlan
26 See also https://www.mercurial-scm.org/wiki/GenericTemplatingPlan
27
27
28 fm.condwrite() vs 'if cond:':
28 fm.condwrite() vs 'if cond:':
29
29
30 In most cases, use fm.condwrite() so users can selectively show the data
30 In most cases, use fm.condwrite() so users can selectively show the data
31 in template output. If it's costly to build data, use plain 'if cond:' with
31 in template output. If it's costly to build data, use plain 'if cond:' with
32 fm.write().
32 fm.write().
33
33
34 fm.nested() vs fm.formatdict() (or fm.formatlist()):
34 fm.nested() vs fm.formatdict() (or fm.formatlist()):
35
35
36 fm.nested() should be used to form a tree structure (a list of dicts of
36 fm.nested() should be used to form a tree structure (a list of dicts of
37 lists of dicts...) which can be accessed through template keywords, e.g.
37 lists of dicts...) which can be accessed through template keywords, e.g.
38 "{foo % "{bar % {...}} {baz % {...}}"}". On the other hand, fm.formatdict()
38 "{foo % "{bar % {...}} {baz % {...}}"}". On the other hand, fm.formatdict()
39 exports a dict-type object to template, which can be accessed by e.g.
39 exports a dict-type object to template, which can be accessed by e.g.
40 "{get(foo, key)}" function.
40 "{get(foo, key)}" function.
41
41
42 Doctest helper:
42 Doctest helper:
43
43
44 >>> def show(fn, verbose=False, **opts):
44 >>> def show(fn, verbose=False, **opts):
45 ... import sys
45 ... import sys
46 ... from . import ui as uimod
46 ... from . import ui as uimod
47 ... ui = uimod.ui()
47 ... ui = uimod.ui()
48 ... ui.verbose = verbose
48 ... ui.verbose = verbose
49 ... ui.pushbuffer()
49 ... ui.pushbuffer()
50 ... try:
50 ... try:
51 ... return fn(ui, ui.formatter(pycompat.sysbytes(fn.__name__),
51 ... return fn(ui, ui.formatter(pycompat.sysbytes(fn.__name__),
52 ... pycompat.byteskwargs(opts)))
52 ... pycompat.byteskwargs(opts)))
53 ... finally:
53 ... finally:
54 ... print(pycompat.sysstr(ui.popbuffer()), end='')
54 ... print(pycompat.sysstr(ui.popbuffer()), end='')
55
55
56 Basic example:
56 Basic example:
57
57
58 >>> def files(ui, fm):
58 >>> def files(ui, fm):
59 ... files = [(b'foo', 123, (0, 0)), (b'bar', 456, (1, 0))]
59 ... files = [(b'foo', 123, (0, 0)), (b'bar', 456, (1, 0))]
60 ... for f in files:
60 ... for f in files:
61 ... fm.startitem()
61 ... fm.startitem()
62 ... fm.write(b'path', b'%s', f[0])
62 ... fm.write(b'path', b'%s', f[0])
63 ... fm.condwrite(ui.verbose, b'date', b' %s',
63 ... fm.condwrite(ui.verbose, b'date', b' %s',
64 ... fm.formatdate(f[2], b'%Y-%m-%d %H:%M:%S'))
64 ... fm.formatdate(f[2], b'%Y-%m-%d %H:%M:%S'))
65 ... fm.data(size=f[1])
65 ... fm.data(size=f[1])
66 ... fm.plain(b'\\n')
66 ... fm.plain(b'\\n')
67 ... fm.end()
67 ... fm.end()
68 >>> show(files)
68 >>> show(files)
69 foo
69 foo
70 bar
70 bar
71 >>> show(files, verbose=True)
71 >>> show(files, verbose=True)
72 foo 1970-01-01 00:00:00
72 foo 1970-01-01 00:00:00
73 bar 1970-01-01 00:00:01
73 bar 1970-01-01 00:00:01
74 >>> show(files, template=b'json')
74 >>> show(files, template=b'json')
75 [
75 [
76 {
76 {
77 "date": [0, 0],
77 "date": [0, 0],
78 "path": "foo",
78 "path": "foo",
79 "size": 123
79 "size": 123
80 },
80 },
81 {
81 {
82 "date": [1, 0],
82 "date": [1, 0],
83 "path": "bar",
83 "path": "bar",
84 "size": 456
84 "size": 456
85 }
85 }
86 ]
86 ]
87 >>> show(files, template=b'path: {path}\\ndate: {date|rfc3339date}\\n')
87 >>> show(files, template=b'path: {path}\\ndate: {date|rfc3339date}\\n')
88 path: foo
88 path: foo
89 date: 1970-01-01T00:00:00+00:00
89 date: 1970-01-01T00:00:00+00:00
90 path: bar
90 path: bar
91 date: 1970-01-01T00:00:01+00:00
91 date: 1970-01-01T00:00:01+00:00
92
92
93 Nested example:
93 Nested example:
94
94
95 >>> def subrepos(ui, fm):
95 >>> def subrepos(ui, fm):
96 ... fm.startitem()
96 ... fm.startitem()
97 ... fm.write(b'reponame', b'[%s]\\n', b'baz')
97 ... fm.write(b'reponame', b'[%s]\\n', b'baz')
98 ... files(ui, fm.nested(b'files', tmpl=b'{reponame}'))
98 ... files(ui, fm.nested(b'files', tmpl=b'{reponame}'))
99 ... fm.end()
99 ... fm.end()
100 >>> show(subrepos)
100 >>> show(subrepos)
101 [baz]
101 [baz]
102 foo
102 foo
103 bar
103 bar
104 >>> show(subrepos, template=b'{reponame}: {join(files % "{path}", ", ")}\\n')
104 >>> show(subrepos, template=b'{reponame}: {join(files % "{path}", ", ")}\\n')
105 baz: foo, bar
105 baz: foo, bar
106 """
106 """
107
107
108 from __future__ import absolute_import, print_function
108 from __future__ import absolute_import, print_function
109
109
110 import contextlib
110 import contextlib
111 import itertools
111 import itertools
112 import os
112 import os
113
113
114 from .i18n import _
114 from .i18n import _
115 from .node import (
115 from .node import (
116 hex,
116 hex,
117 short,
117 short,
118 )
118 )
119 from .thirdparty import (
119 from .thirdparty import (
120 attr,
120 attr,
121 )
121 )
122
122
123 from . import (
123 from . import (
124 error,
124 error,
125 pycompat,
125 pycompat,
126 templatefilters,
126 templatefilters,
127 templatefuncs,
127 templatefuncs,
128 templatekw,
128 templatekw,
129 templater,
129 templater,
130 templateutil,
130 templateutil,
131 util,
131 util,
132 )
132 )
133 from .utils import dateutil
133 from .utils import dateutil
134
134
135 pickle = util.pickle
135 pickle = util.pickle
136
136
137 class _nullconverter(object):
137 class _nullconverter(object):
138 '''convert non-primitive data types to be processed by formatter'''
138 '''convert non-primitive data types to be processed by formatter'''
139
139
140 # set to True if context object should be stored as item
140 # set to True if context object should be stored as item
141 storecontext = False
141 storecontext = False
142
142
143 @staticmethod
143 @staticmethod
144 def wrapnested(data, tmpl, sep):
144 def wrapnested(data, tmpl, sep):
145 '''wrap nested data by appropriate type'''
145 '''wrap nested data by appropriate type'''
146 return data
146 return data
147 @staticmethod
147 @staticmethod
148 def formatdate(date, fmt):
148 def formatdate(date, fmt):
149 '''convert date tuple to appropriate format'''
149 '''convert date tuple to appropriate format'''
150 # timestamp can be float, but the canonical form should be int
150 # timestamp can be float, but the canonical form should be int
151 ts, tz = date
151 ts, tz = date
152 return (int(ts), tz)
152 return (int(ts), tz)
153 @staticmethod
153 @staticmethod
154 def formatdict(data, key, value, fmt, sep):
154 def formatdict(data, key, value, fmt, sep):
155 '''convert dict or key-value pairs to appropriate dict format'''
155 '''convert dict or key-value pairs to appropriate dict format'''
156 # use plain dict instead of util.sortdict so that data can be
156 # use plain dict instead of util.sortdict so that data can be
157 # serialized as a builtin dict in pickle output
157 # serialized as a builtin dict in pickle output
158 return dict(data)
158 return dict(data)
159 @staticmethod
159 @staticmethod
160 def formatlist(data, name, fmt, sep):
160 def formatlist(data, name, fmt, sep):
161 '''convert iterable to appropriate list format'''
161 '''convert iterable to appropriate list format'''
162 return list(data)
162 return list(data)
163
163
164 class baseformatter(object):
164 class baseformatter(object):
165 def __init__(self, ui, topic, opts, converter):
165 def __init__(self, ui, topic, opts, converter):
166 self._ui = ui
166 self._ui = ui
167 self._topic = topic
167 self._topic = topic
168 self._opts = opts
168 self._opts = opts
169 self._converter = converter
169 self._converter = converter
170 self._item = None
170 self._item = None
171 # function to convert node to string suitable for this output
171 # function to convert node to string suitable for this output
172 self.hexfunc = hex
172 self.hexfunc = hex
173 def __enter__(self):
173 def __enter__(self):
174 return self
174 return self
175 def __exit__(self, exctype, excvalue, traceback):
175 def __exit__(self, exctype, excvalue, traceback):
176 if exctype is None:
176 if exctype is None:
177 self.end()
177 self.end()
178 def _showitem(self):
178 def _showitem(self):
179 '''show a formatted item once all data is collected'''
179 '''show a formatted item once all data is collected'''
180 def startitem(self):
180 def startitem(self):
181 '''begin an item in the format list'''
181 '''begin an item in the format list'''
182 if self._item is not None:
182 if self._item is not None:
183 self._showitem()
183 self._showitem()
184 self._item = {}
184 self._item = {}
185 def formatdate(self, date, fmt='%a %b %d %H:%M:%S %Y %1%2'):
185 def formatdate(self, date, fmt='%a %b %d %H:%M:%S %Y %1%2'):
186 '''convert date tuple to appropriate format'''
186 '''convert date tuple to appropriate format'''
187 return self._converter.formatdate(date, fmt)
187 return self._converter.formatdate(date, fmt)
188 def formatdict(self, data, key='key', value='value', fmt=None, sep=' '):
188 def formatdict(self, data, key='key', value='value', fmt=None, sep=' '):
189 '''convert dict or key-value pairs to appropriate dict format'''
189 '''convert dict or key-value pairs to appropriate dict format'''
190 return self._converter.formatdict(data, key, value, fmt, sep)
190 return self._converter.formatdict(data, key, value, fmt, sep)
191 def formatlist(self, data, name, fmt=None, sep=' '):
191 def formatlist(self, data, name, fmt=None, sep=' '):
192 '''convert iterable to appropriate list format'''
192 '''convert iterable to appropriate list format'''
193 # name is mandatory argument for now, but it could be optional if
193 # name is mandatory argument for now, but it could be optional if
194 # we have default template keyword, e.g. {item}
194 # we have default template keyword, e.g. {item}
195 return self._converter.formatlist(data, name, fmt, sep)
195 return self._converter.formatlist(data, name, fmt, sep)
196 def contexthint(self, datafields):
196 def contexthint(self, datafields):
197 '''set of context object keys to be required given datafields set'''
197 '''set of context object keys to be required given datafields set'''
198 return set()
198 return set()
199 def context(self, **ctxs):
199 def context(self, **ctxs):
200 '''insert context objects to be used to render template keywords'''
200 '''insert context objects to be used to render template keywords'''
201 ctxs = pycompat.byteskwargs(ctxs)
201 ctxs = pycompat.byteskwargs(ctxs)
202 assert all(k in {'repo', 'ctx', 'fctx'} for k in ctxs)
202 assert all(k in {'repo', 'ctx', 'fctx'} for k in ctxs)
203 if self._converter.storecontext:
203 if self._converter.storecontext:
204 # populate missing resources in fctx -> ctx -> repo order
204 # populate missing resources in fctx -> ctx -> repo order
205 if 'fctx' in ctxs and 'ctx' not in ctxs:
205 if 'fctx' in ctxs and 'ctx' not in ctxs:
206 ctxs['ctx'] = ctxs['fctx'].changectx()
206 ctxs['ctx'] = ctxs['fctx'].changectx()
207 if 'ctx' in ctxs and 'repo' not in ctxs:
207 if 'ctx' in ctxs and 'repo' not in ctxs:
208 ctxs['repo'] = ctxs['ctx'].repo()
208 ctxs['repo'] = ctxs['ctx'].repo()
209 self._item.update(ctxs)
209 self._item.update(ctxs)
210 def datahint(self):
210 def datahint(self):
211 '''set of field names to be referenced'''
211 '''set of field names to be referenced'''
212 return set()
212 return set()
213 def data(self, **data):
213 def data(self, **data):
214 '''insert data into item that's not shown in default output'''
214 '''insert data into item that's not shown in default output'''
215 data = pycompat.byteskwargs(data)
215 data = pycompat.byteskwargs(data)
216 self._item.update(data)
216 self._item.update(data)
217 def write(self, fields, deftext, *fielddata, **opts):
217 def write(self, fields, deftext, *fielddata, **opts):
218 '''do default text output while assigning data to item'''
218 '''do default text output while assigning data to item'''
219 fieldkeys = fields.split()
219 fieldkeys = fields.split()
220 assert len(fieldkeys) == len(fielddata)
220 assert len(fieldkeys) == len(fielddata)
221 self._item.update(zip(fieldkeys, fielddata))
221 self._item.update(zip(fieldkeys, fielddata))
222 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
222 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
223 '''do conditional write (primarily for plain formatter)'''
223 '''do conditional write (primarily for plain formatter)'''
224 fieldkeys = fields.split()
224 fieldkeys = fields.split()
225 assert len(fieldkeys) == len(fielddata)
225 assert len(fieldkeys) == len(fielddata)
226 self._item.update(zip(fieldkeys, fielddata))
226 self._item.update(zip(fieldkeys, fielddata))
227 def plain(self, text, **opts):
227 def plain(self, text, **opts):
228 '''show raw text for non-templated mode'''
228 '''show raw text for non-templated mode'''
229 def isplain(self):
229 def isplain(self):
230 '''check for plain formatter usage'''
230 '''check for plain formatter usage'''
231 return False
231 return False
232 def nested(self, field, tmpl=None, sep=''):
232 def nested(self, field, tmpl=None, sep=''):
233 '''sub formatter to store nested data in the specified field'''
233 '''sub formatter to store nested data in the specified field'''
234 data = []
234 data = []
235 self._item[field] = self._converter.wrapnested(data, tmpl, sep)
235 self._item[field] = self._converter.wrapnested(data, tmpl, sep)
236 return _nestedformatter(self._ui, self._converter, data)
236 return _nestedformatter(self._ui, self._converter, data)
237 def end(self):
237 def end(self):
238 '''end output for the formatter'''
238 '''end output for the formatter'''
239 if self._item is not None:
239 if self._item is not None:
240 self._showitem()
240 self._showitem()
241
241
242 def nullformatter(ui, topic, opts):
242 def nullformatter(ui, topic, opts):
243 '''formatter that prints nothing'''
243 '''formatter that prints nothing'''
244 return baseformatter(ui, topic, opts, converter=_nullconverter)
244 return baseformatter(ui, topic, opts, converter=_nullconverter)
245
245
246 class _nestedformatter(baseformatter):
246 class _nestedformatter(baseformatter):
247 '''build sub items and store them in the parent formatter'''
247 '''build sub items and store them in the parent formatter'''
248 def __init__(self, ui, converter, data):
248 def __init__(self, ui, converter, data):
249 baseformatter.__init__(self, ui, topic='', opts={}, converter=converter)
249 baseformatter.__init__(self, ui, topic='', opts={}, converter=converter)
250 self._data = data
250 self._data = data
251 def _showitem(self):
251 def _showitem(self):
252 self._data.append(self._item)
252 self._data.append(self._item)
253
253
254 def _iteritems(data):
254 def _iteritems(data):
255 '''iterate key-value pairs in stable order'''
255 '''iterate key-value pairs in stable order'''
256 if isinstance(data, dict):
256 if isinstance(data, dict):
257 return sorted(data.iteritems())
257 return sorted(data.iteritems())
258 return data
258 return data
259
259
260 class _plainconverter(object):
260 class _plainconverter(object):
261 '''convert non-primitive data types to text'''
261 '''convert non-primitive data types to text'''
262
262
263 storecontext = False
263 storecontext = False
264
264
265 @staticmethod
265 @staticmethod
266 def wrapnested(data, tmpl, sep):
266 def wrapnested(data, tmpl, sep):
267 raise error.ProgrammingError('plainformatter should never be nested')
267 raise error.ProgrammingError('plainformatter should never be nested')
268 @staticmethod
268 @staticmethod
269 def formatdate(date, fmt):
269 def formatdate(date, fmt):
270 '''stringify date tuple in the given format'''
270 '''stringify date tuple in the given format'''
271 return dateutil.datestr(date, fmt)
271 return dateutil.datestr(date, fmt)
272 @staticmethod
272 @staticmethod
273 def formatdict(data, key, value, fmt, sep):
273 def formatdict(data, key, value, fmt, sep):
274 '''stringify key-value pairs separated by sep'''
274 '''stringify key-value pairs separated by sep'''
275 prefmt = pycompat.identity
275 prefmt = pycompat.identity
276 if fmt is None:
276 if fmt is None:
277 fmt = '%s=%s'
277 fmt = '%s=%s'
278 prefmt = pycompat.bytestr
278 prefmt = pycompat.bytestr
279 return sep.join(fmt % (prefmt(k), prefmt(v))
279 return sep.join(fmt % (prefmt(k), prefmt(v))
280 for k, v in _iteritems(data))
280 for k, v in _iteritems(data))
281 @staticmethod
281 @staticmethod
282 def formatlist(data, name, fmt, sep):
282 def formatlist(data, name, fmt, sep):
283 '''stringify iterable separated by sep'''
283 '''stringify iterable separated by sep'''
284 prefmt = pycompat.identity
284 prefmt = pycompat.identity
285 if fmt is None:
285 if fmt is None:
286 fmt = '%s'
286 fmt = '%s'
287 prefmt = pycompat.bytestr
287 prefmt = pycompat.bytestr
288 return sep.join(fmt % prefmt(e) for e in data)
288 return sep.join(fmt % prefmt(e) for e in data)
289
289
290 class plainformatter(baseformatter):
290 class plainformatter(baseformatter):
291 '''the default text output scheme'''
291 '''the default text output scheme'''
292 def __init__(self, ui, out, topic, opts):
292 def __init__(self, ui, out, topic, opts):
293 baseformatter.__init__(self, ui, topic, opts, _plainconverter)
293 baseformatter.__init__(self, ui, topic, opts, _plainconverter)
294 if ui.debugflag:
294 if ui.debugflag:
295 self.hexfunc = hex
295 self.hexfunc = hex
296 else:
296 else:
297 self.hexfunc = short
297 self.hexfunc = short
298 if ui is out:
298 if ui is out:
299 self._write = ui.write
299 self._write = ui.write
300 else:
300 else:
301 self._write = lambda s, **opts: out.write(s)
301 self._write = lambda s, **opts: out.write(s)
302 def startitem(self):
302 def startitem(self):
303 pass
303 pass
304 def data(self, **data):
304 def data(self, **data):
305 pass
305 pass
306 def write(self, fields, deftext, *fielddata, **opts):
306 def write(self, fields, deftext, *fielddata, **opts):
307 self._write(deftext % fielddata, **opts)
307 self._write(deftext % fielddata, **opts)
308 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
308 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
309 '''do conditional write'''
309 '''do conditional write'''
310 if cond:
310 if cond:
311 self._write(deftext % fielddata, **opts)
311 self._write(deftext % fielddata, **opts)
312 def plain(self, text, **opts):
312 def plain(self, text, **opts):
313 self._write(text, **opts)
313 self._write(text, **opts)
314 def isplain(self):
314 def isplain(self):
315 return True
315 return True
316 def nested(self, field, tmpl=None, sep=''):
316 def nested(self, field, tmpl=None, sep=''):
317 # nested data will be directly written to ui
317 # nested data will be directly written to ui
318 return self
318 return self
319 def end(self):
319 def end(self):
320 pass
320 pass
321
321
322 class debugformatter(baseformatter):
322 class debugformatter(baseformatter):
323 def __init__(self, ui, out, topic, opts):
323 def __init__(self, ui, out, topic, opts):
324 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
324 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
325 self._out = out
325 self._out = out
326 self._out.write("%s = [\n" % self._topic)
326 self._out.write("%s = [\n" % self._topic)
327 def _showitem(self):
327 def _showitem(self):
328 self._out.write(' %s,\n' % pycompat.byterepr(self._item))
328 self._out.write(' %s,\n' % pycompat.byterepr(self._item))
329 def end(self):
329 def end(self):
330 baseformatter.end(self)
330 baseformatter.end(self)
331 self._out.write("]\n")
331 self._out.write("]\n")
332
332
333 class pickleformatter(baseformatter):
333 class pickleformatter(baseformatter):
334 def __init__(self, ui, out, topic, opts):
334 def __init__(self, ui, out, topic, opts):
335 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
335 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
336 self._out = out
336 self._out = out
337 self._data = []
337 self._data = []
338 def _showitem(self):
338 def _showitem(self):
339 self._data.append(self._item)
339 self._data.append(self._item)
340 def end(self):
340 def end(self):
341 baseformatter.end(self)
341 baseformatter.end(self)
342 self._out.write(pickle.dumps(self._data))
342 self._out.write(pickle.dumps(self._data))
343
343
344 class jsonformatter(baseformatter):
344 class jsonformatter(baseformatter):
345 def __init__(self, ui, out, topic, opts):
345 def __init__(self, ui, out, topic, opts):
346 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
346 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
347 self._out = out
347 self._out = out
348 self._out.write("[")
348 self._out.write("[")
349 self._first = True
349 self._first = True
350 def _showitem(self):
350 def _showitem(self):
351 if self._first:
351 if self._first:
352 self._first = False
352 self._first = False
353 else:
353 else:
354 self._out.write(",")
354 self._out.write(",")
355
355
356 self._out.write("\n {\n")
356 self._out.write("\n {\n")
357 first = True
357 first = True
358 for k, v in sorted(self._item.items()):
358 for k, v in sorted(self._item.items()):
359 if first:
359 if first:
360 first = False
360 first = False
361 else:
361 else:
362 self._out.write(",\n")
362 self._out.write(",\n")
363 u = templatefilters.json(v, paranoid=False)
363 u = templatefilters.json(v, paranoid=False)
364 self._out.write(' "%s": %s' % (k, u))
364 self._out.write(' "%s": %s' % (k, u))
365 self._out.write("\n }")
365 self._out.write("\n }")
366 def end(self):
366 def end(self):
367 baseformatter.end(self)
367 baseformatter.end(self)
368 self._out.write("\n]\n")
368 self._out.write("\n]\n")
369
369
370 class _templateconverter(object):
370 class _templateconverter(object):
371 '''convert non-primitive data types to be processed by templater'''
371 '''convert non-primitive data types to be processed by templater'''
372
372
373 storecontext = True
373 storecontext = True
374
374
375 @staticmethod
375 @staticmethod
376 def wrapnested(data, tmpl, sep):
376 def wrapnested(data, tmpl, sep):
377 '''wrap nested data by templatable type'''
377 '''wrap nested data by templatable type'''
378 return templateutil.mappinglist(data, tmpl=tmpl, sep=sep)
378 return templateutil.mappinglist(data, tmpl=tmpl, sep=sep)
379 @staticmethod
379 @staticmethod
380 def formatdate(date, fmt):
380 def formatdate(date, fmt):
381 '''return date tuple'''
381 '''return date tuple'''
382 return templateutil.date(date)
382 return templateutil.date(date)
383 @staticmethod
383 @staticmethod
384 def formatdict(data, key, value, fmt, sep):
384 def formatdict(data, key, value, fmt, sep):
385 '''build object that can be evaluated as either plain string or dict'''
385 '''build object that can be evaluated as either plain string or dict'''
386 data = util.sortdict(_iteritems(data))
386 data = util.sortdict(_iteritems(data))
387 def f():
387 def f():
388 yield _plainconverter.formatdict(data, key, value, fmt, sep)
388 yield _plainconverter.formatdict(data, key, value, fmt, sep)
389 return templateutil.hybriddict(data, key=key, value=value, fmt=fmt,
389 return templateutil.hybriddict(data, key=key, value=value, fmt=fmt,
390 gen=f)
390 gen=f)
391 @staticmethod
391 @staticmethod
392 def formatlist(data, name, fmt, sep):
392 def formatlist(data, name, fmt, sep):
393 '''build object that can be evaluated as either plain string or list'''
393 '''build object that can be evaluated as either plain string or list'''
394 data = list(data)
394 data = list(data)
395 def f():
395 def f():
396 yield _plainconverter.formatlist(data, name, fmt, sep)
396 yield _plainconverter.formatlist(data, name, fmt, sep)
397 return templateutil.hybridlist(data, name=name, fmt=fmt, gen=f)
397 return templateutil.hybridlist(data, name=name, fmt=fmt, gen=f)
398
398
399 class templateformatter(baseformatter):
399 class templateformatter(baseformatter):
400 def __init__(self, ui, out, topic, opts):
400 def __init__(self, ui, out, topic, opts):
401 baseformatter.__init__(self, ui, topic, opts, _templateconverter)
401 baseformatter.__init__(self, ui, topic, opts, _templateconverter)
402 self._out = out
402 self._out = out
403 spec = lookuptemplate(ui, topic, opts.get('template', ''))
403 spec = lookuptemplate(ui, topic, opts.get('template', ''))
404 self._tref = spec.ref
404 self._tref = spec.ref
405 self._t = loadtemplater(ui, spec, defaults=templatekw.keywords,
405 self._t = loadtemplater(ui, spec, defaults=templatekw.keywords,
406 resources=templateresources(ui),
406 resources=templateresources(ui),
407 cache=templatekw.defaulttempl)
407 cache=templatekw.defaulttempl)
408 self._parts = templatepartsmap(spec, self._t,
408 self._parts = templatepartsmap(spec, self._t,
409 ['docheader', 'docfooter', 'separator'])
409 ['docheader', 'docfooter', 'separator'])
410 self._counter = itertools.count()
410 self._counter = itertools.count()
411 self._renderitem('docheader', {})
411 self._renderitem('docheader', {})
412
412
413 def _showitem(self):
413 def _showitem(self):
414 item = self._item.copy()
414 item = self._item.copy()
415 item['index'] = index = next(self._counter)
415 item['index'] = index = next(self._counter)
416 if index > 0:
416 if index > 0:
417 self._renderitem('separator', {})
417 self._renderitem('separator', {})
418 self._renderitem(self._tref, item)
418 self._renderitem(self._tref, item)
419
419
420 def _renderitem(self, part, item):
420 def _renderitem(self, part, item):
421 if part not in self._parts:
421 if part not in self._parts:
422 return
422 return
423 ref = self._parts[part]
423 ref = self._parts[part]
424 self._out.write(self._t.render(ref, item))
424 self._out.write(self._t.render(ref, item))
425
425
426 @util.propertycache
426 @util.propertycache
427 def _symbolsused(self):
427 def _symbolsused(self):
428 return self._t.symbolsused(self._tref)
428 return self._t.symbolsused(self._tref)
429
429
430 def contexthint(self, datafields):
430 def contexthint(self, datafields):
431 '''set of context object keys to be required by the template, given
431 '''set of context object keys to be required by the template, given
432 datafields overridden by immediate values'''
432 datafields overridden by immediate values'''
433 requires = set()
433 requires = set()
434 ksyms, fsyms = self._symbolsused
434 ksyms, fsyms = self._symbolsused
435 ksyms = ksyms - set(datafields.split()) # exclude immediate fields
435 ksyms = ksyms - set(datafields.split()) # exclude immediate fields
436 symtables = [(ksyms, templatekw.keywords),
436 symtables = [(ksyms, templatekw.keywords),
437 (fsyms, templatefuncs.funcs)]
437 (fsyms, templatefuncs.funcs)]
438 for syms, table in symtables:
438 for syms, table in symtables:
439 for k in syms:
439 for k in syms:
440 f = table.get(k)
440 f = table.get(k)
441 if not f:
441 if not f:
442 continue
442 continue
443 requires.update(getattr(f, '_requires', ()))
443 requires.update(getattr(f, '_requires', ()))
444 if 'repo' in requires:
444 if 'repo' in requires:
445 requires.add('ctx') # there's no API to pass repo to formatter
445 requires.add('ctx') # there's no API to pass repo to formatter
446 return requires & {'ctx', 'fctx'}
446 return requires & {'ctx', 'fctx'}
447
447
448 def datahint(self):
448 def datahint(self):
449 '''set of field names to be referenced from the template'''
449 '''set of field names to be referenced from the template'''
450 return self._symbolsused[0]
450 return self._symbolsused[0]
451
451
452 def end(self):
452 def end(self):
453 baseformatter.end(self)
453 baseformatter.end(self)
454 self._renderitem('docfooter', {})
454 self._renderitem('docfooter', {})
455
455
456 @attr.s(frozen=True)
456 @attr.s(frozen=True)
457 class templatespec(object):
457 class templatespec(object):
458 ref = attr.ib()
458 ref = attr.ib()
459 tmpl = attr.ib()
459 tmpl = attr.ib()
460 mapfile = attr.ib()
460 mapfile = attr.ib()
461
461
462 def lookuptemplate(ui, topic, tmpl):
462 def lookuptemplate(ui, topic, tmpl):
463 """Find the template matching the given -T/--template spec 'tmpl'
463 """Find the template matching the given -T/--template spec 'tmpl'
464
464
465 'tmpl' can be any of the following:
465 'tmpl' can be any of the following:
466
466
467 - a literal template (e.g. '{rev}')
467 - a literal template (e.g. '{rev}')
468 - a map-file name or path (e.g. 'changelog')
468 - a map-file name or path (e.g. 'changelog')
469 - a reference to [templates] in config file
469 - a reference to [templates] in config file
470 - a path to raw template file
470 - a path to raw template file
471
471
472 A map file defines a stand-alone template environment. If a map file
472 A map file defines a stand-alone template environment. If a map file
473 selected, all templates defined in the file will be loaded, and the
473 selected, all templates defined in the file will be loaded, and the
474 template matching the given topic will be rendered. Aliases won't be
474 template matching the given topic will be rendered. Aliases won't be
475 loaded from user config, but from the map file.
475 loaded from user config, but from the map file.
476
476
477 If no map file selected, all templates in [templates] section will be
477 If no map file selected, all templates in [templates] section will be
478 available as well as aliases in [templatealias].
478 available as well as aliases in [templatealias].
479 """
479 """
480
480
481 # looks like a literal template?
481 # looks like a literal template?
482 if '{' in tmpl:
482 if '{' in tmpl:
483 return templatespec('', tmpl, None)
483 return templatespec('', tmpl, None)
484
484
485 # perhaps a stock style?
485 # perhaps a stock style?
486 if not os.path.split(tmpl)[0]:
486 if not os.path.split(tmpl)[0]:
487 mapname = (templater.templatepath('map-cmdline.' + tmpl)
487 mapname = (templater.templatepath('map-cmdline.' + tmpl)
488 or templater.templatepath(tmpl))
488 or templater.templatepath(tmpl))
489 if mapname and os.path.isfile(mapname):
489 if mapname and os.path.isfile(mapname):
490 return templatespec(topic, None, mapname)
490 return templatespec(topic, None, mapname)
491
491
492 # perhaps it's a reference to [templates]
492 # perhaps it's a reference to [templates]
493 if ui.config('templates', tmpl):
493 if ui.config('templates', tmpl):
494 return templatespec(tmpl, None, None)
494 return templatespec(tmpl, None, None)
495
495
496 if tmpl == 'list':
496 if tmpl == 'list':
497 ui.write(_("available styles: %s\n") % templater.stylelist())
497 ui.write(_("available styles: %s\n") % templater.stylelist())
498 raise error.Abort(_("specify a template"))
498 raise error.Abort(_("specify a template"))
499
499
500 # perhaps it's a path to a map or a template
500 # perhaps it's a path to a map or a template
501 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
501 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
502 # is it a mapfile for a style?
502 # is it a mapfile for a style?
503 if os.path.basename(tmpl).startswith("map-"):
503 if os.path.basename(tmpl).startswith("map-"):
504 return templatespec(topic, None, os.path.realpath(tmpl))
504 return templatespec(topic, None, os.path.realpath(tmpl))
505 with util.posixfile(tmpl, 'rb') as f:
505 with util.posixfile(tmpl, 'rb') as f:
506 tmpl = f.read()
506 tmpl = f.read()
507 return templatespec('', tmpl, None)
507 return templatespec('', tmpl, None)
508
508
509 # constant string?
509 # constant string?
510 return templatespec('', tmpl, None)
510 return templatespec('', tmpl, None)
511
511
512 def templatepartsmap(spec, t, partnames):
512 def templatepartsmap(spec, t, partnames):
513 """Create a mapping of {part: ref}"""
513 """Create a mapping of {part: ref}"""
514 partsmap = {spec.ref: spec.ref} # initial ref must exist in t
514 partsmap = {spec.ref: spec.ref} # initial ref must exist in t
515 if spec.mapfile:
515 if spec.mapfile:
516 partsmap.update((p, p) for p in partnames if p in t)
516 partsmap.update((p, p) for p in partnames if p in t)
517 elif spec.ref:
517 elif spec.ref:
518 for part in partnames:
518 for part in partnames:
519 ref = '%s:%s' % (spec.ref, part) # select config sub-section
519 ref = '%s:%s' % (spec.ref, part) # select config sub-section
520 if ref in t:
520 if ref in t:
521 partsmap[part] = ref
521 partsmap[part] = ref
522 return partsmap
522 return partsmap
523
523
524 def loadtemplater(ui, spec, defaults=None, resources=None, cache=None):
524 def loadtemplater(ui, spec, defaults=None, resources=None, cache=None):
525 """Create a templater from either a literal template or loading from
525 """Create a templater from either a literal template or loading from
526 a map file"""
526 a map file"""
527 assert not (spec.tmpl and spec.mapfile)
527 assert not (spec.tmpl and spec.mapfile)
528 if spec.mapfile:
528 if spec.mapfile:
529 frommapfile = templater.templater.frommapfile
529 frommapfile = templater.templater.frommapfile
530 return frommapfile(spec.mapfile, defaults=defaults, resources=resources,
530 return frommapfile(spec.mapfile, defaults=defaults, resources=resources,
531 cache=cache)
531 cache=cache)
532 return maketemplater(ui, spec.tmpl, defaults=defaults, resources=resources,
532 return maketemplater(ui, spec.tmpl, defaults=defaults, resources=resources,
533 cache=cache)
533 cache=cache)
534
534
535 def maketemplater(ui, tmpl, defaults=None, resources=None, cache=None):
535 def maketemplater(ui, tmpl, defaults=None, resources=None, cache=None):
536 """Create a templater from a string template 'tmpl'"""
536 """Create a templater from a string template 'tmpl'"""
537 aliases = ui.configitems('templatealias')
537 aliases = ui.configitems('templatealias')
538 t = templater.templater(defaults=defaults, resources=resources,
538 t = templater.templater(defaults=defaults, resources=resources,
539 cache=cache, aliases=aliases)
539 cache=cache, aliases=aliases)
540 t.cache.update((k, templater.unquotestring(v))
540 t.cache.update((k, templater.unquotestring(v))
541 for k, v in ui.configitems('templates'))
541 for k, v in ui.configitems('templates'))
542 if tmpl:
542 if tmpl:
543 t.cache[''] = tmpl
543 t.cache[''] = tmpl
544 return t
544 return t
545
545
546 # marker to denote a resource to be loaded on demand based on mapping values
546 # marker to denote a resource to be loaded on demand based on mapping values
547 # (e.g. (ctx, path) -> fctx)
547 # (e.g. (ctx, path) -> fctx)
548 _placeholder = object()
548 _placeholder = object()
549
549
550 class templateresources(templater.resourcemapper):
550 class templateresources(templater.resourcemapper):
551 """Resource mapper designed for the default templatekw and function"""
551 """Resource mapper designed for the default templatekw and function"""
552
552
553 def __init__(self, ui, repo=None):
553 def __init__(self, ui, repo=None):
554 self._resmap = {
554 self._resmap = {
555 'cache': {}, # for templatekw/funcs to store reusable data
555 'cache': {}, # for templatekw/funcs to store reusable data
556 'repo': repo,
556 'repo': repo,
557 'ui': ui,
557 'ui': ui,
558 }
558 }
559
559
560 def availablekeys(self, mapping):
560 def availablekeys(self, mapping):
561 return {k for k in self.knownkeys()
561 return {k for k in self.knownkeys()
562 if self._getsome(mapping, k) is not None}
562 if self._getsome(mapping, k) is not None}
563
563
564 def knownkeys(self):
564 def knownkeys(self):
565 return {'cache', 'ctx', 'fctx', 'repo', 'revcache', 'ui'}
565 return {'cache', 'ctx', 'fctx', 'repo', 'revcache', 'ui'}
566
566
567 def lookup(self, mapping, key):
567 def lookup(self, mapping, key):
568 if key not in self.knownkeys():
568 if key not in self.knownkeys():
569 return None
569 return None
570 v = self._getsome(mapping, key)
570 v = self._getsome(mapping, key)
571 if v is _placeholder:
571 if v is _placeholder:
572 v = mapping[key] = self._loadermap[key](self, mapping)
572 v = mapping[key] = self._loadermap[key](self, mapping)
573 return v
573 return v
574
574
575 def populatemap(self, context, origmapping, newmapping):
575 def populatemap(self, context, origmapping, newmapping):
576 mapping = {}
576 mapping = {}
577 if self._hasnodespec(newmapping):
577 if self._hasnodespec(newmapping):
578 mapping['revcache'] = {} # per-ctx cache
578 mapping['revcache'] = {} # per-ctx cache
579 if self._hasnodespec(origmapping) and self._hasnodespec(newmapping):
579 if self._hasnodespec(origmapping) and self._hasnodespec(newmapping):
580 orignode = templateutil.runsymbol(context, origmapping, 'node')
580 orignode = templateutil.runsymbol(context, origmapping, 'node')
581 mapping['originalnode'] = orignode
581 mapping['originalnode'] = orignode
582 # put marker to override 'fctx' in mapping if any, and flag
582 # put marker to override 'ctx'/'fctx' in mapping if any, and flag
583 # its existence to be reported by availablekeys()
583 # its existence to be reported by availablekeys()
584 if 'ctx' not in newmapping and self._hasliteral(newmapping, 'node'):
585 mapping['ctx'] = _placeholder
584 if 'fctx' not in newmapping and self._hasliteral(newmapping, 'path'):
586 if 'fctx' not in newmapping and self._hasliteral(newmapping, 'path'):
585 mapping['fctx'] = _placeholder
587 mapping['fctx'] = _placeholder
586 return mapping
588 return mapping
587
589
588 def _getsome(self, mapping, key):
590 def _getsome(self, mapping, key):
589 v = mapping.get(key)
591 v = mapping.get(key)
590 if v is not None:
592 if v is not None:
591 return v
593 return v
592 return self._resmap.get(key)
594 return self._resmap.get(key)
593
595
594 def _hasliteral(self, mapping, key):
596 def _hasliteral(self, mapping, key):
595 """Test if a literal value is set or unset in the given mapping"""
597 """Test if a literal value is set or unset in the given mapping"""
596 return key in mapping and not callable(mapping[key])
598 return key in mapping and not callable(mapping[key])
597
599
598 def _getliteral(self, mapping, key):
600 def _getliteral(self, mapping, key):
599 """Return value of the given name if it is a literal"""
601 """Return value of the given name if it is a literal"""
600 v = mapping.get(key)
602 v = mapping.get(key)
601 if callable(v):
603 if callable(v):
602 return None
604 return None
603 return v
605 return v
604
606
605 def _hasnodespec(self, mapping):
607 def _hasnodespec(self, mapping):
606 """Test if context revision is set or unset in the given mapping"""
608 """Test if context revision is set or unset in the given mapping"""
607 return 'node' in mapping or 'ctx' in mapping
609 return 'node' in mapping or 'ctx' in mapping
608
610
611 def _loadctx(self, mapping):
612 repo = self._getsome(mapping, 'repo')
613 node = self._getliteral(mapping, 'node')
614 if repo is None or node is None:
615 return
616 try:
617 return repo[node]
618 except error.RepoLookupError:
619 return None # maybe hidden/non-existent node
620
609 def _loadfctx(self, mapping):
621 def _loadfctx(self, mapping):
610 ctx = self._getsome(mapping, 'ctx')
622 ctx = self._getsome(mapping, 'ctx')
611 path = self._getliteral(mapping, 'path')
623 path = self._getliteral(mapping, 'path')
612 if ctx is None or path is None:
624 if ctx is None or path is None:
613 return None
625 return None
614 try:
626 try:
615 return ctx[path]
627 return ctx[path]
616 except error.LookupError:
628 except error.LookupError:
617 return None # maybe removed file?
629 return None # maybe removed file?
618
630
619 _loadermap = {
631 _loadermap = {
632 'ctx': _loadctx,
620 'fctx': _loadfctx,
633 'fctx': _loadfctx,
621 }
634 }
622
635
623 def formatter(ui, out, topic, opts):
636 def formatter(ui, out, topic, opts):
624 template = opts.get("template", "")
637 template = opts.get("template", "")
625 if template == "json":
638 if template == "json":
626 return jsonformatter(ui, out, topic, opts)
639 return jsonformatter(ui, out, topic, opts)
627 elif template == "pickle":
640 elif template == "pickle":
628 return pickleformatter(ui, out, topic, opts)
641 return pickleformatter(ui, out, topic, opts)
629 elif template == "debug":
642 elif template == "debug":
630 return debugformatter(ui, out, topic, opts)
643 return debugformatter(ui, out, topic, opts)
631 elif template != "":
644 elif template != "":
632 return templateformatter(ui, out, topic, opts)
645 return templateformatter(ui, out, topic, opts)
633 # developer config: ui.formatdebug
646 # developer config: ui.formatdebug
634 elif ui.configbool('ui', 'formatdebug'):
647 elif ui.configbool('ui', 'formatdebug'):
635 return debugformatter(ui, out, topic, opts)
648 return debugformatter(ui, out, topic, opts)
636 # deprecated config: ui.formatjson
649 # deprecated config: ui.formatjson
637 elif ui.configbool('ui', 'formatjson'):
650 elif ui.configbool('ui', 'formatjson'):
638 return jsonformatter(ui, out, topic, opts)
651 return jsonformatter(ui, out, topic, opts)
639 return plainformatter(ui, out, topic, opts)
652 return plainformatter(ui, out, topic, opts)
640
653
641 @contextlib.contextmanager
654 @contextlib.contextmanager
642 def openformatter(ui, filename, topic, opts):
655 def openformatter(ui, filename, topic, opts):
643 """Create a formatter that writes outputs to the specified file
656 """Create a formatter that writes outputs to the specified file
644
657
645 Must be invoked using the 'with' statement.
658 Must be invoked using the 'with' statement.
646 """
659 """
647 with util.posixfile(filename, 'wb') as out:
660 with util.posixfile(filename, 'wb') as out:
648 with formatter(ui, out, topic, opts) as fm:
661 with formatter(ui, out, topic, opts) as fm:
649 yield fm
662 yield fm
650
663
651 @contextlib.contextmanager
664 @contextlib.contextmanager
652 def _neverending(fm):
665 def _neverending(fm):
653 yield fm
666 yield fm
654
667
655 def maybereopen(fm, filename):
668 def maybereopen(fm, filename):
656 """Create a formatter backed by file if filename specified, else return
669 """Create a formatter backed by file if filename specified, else return
657 the given formatter
670 the given formatter
658
671
659 Must be invoked using the 'with' statement. This will never call fm.end()
672 Must be invoked using the 'with' statement. This will never call fm.end()
660 of the given formatter.
673 of the given formatter.
661 """
674 """
662 if filename:
675 if filename:
663 return openformatter(fm._ui, filename, fm._topic, fm._opts)
676 return openformatter(fm._ui, filename, fm._topic, fm._opts)
664 else:
677 else:
665 return _neverending(fm)
678 return _neverending(fm)
@@ -1,856 +1,854 b''
1 # templatekw.py - common changeset template keywords
1 # templatekw.py - common changeset template keywords
2 #
2 #
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2009 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 from .i18n import _
10 from .i18n import _
11 from .node import (
11 from .node import (
12 hex,
12 hex,
13 nullid,
13 nullid,
14 )
14 )
15
15
16 from . import (
16 from . import (
17 diffutil,
17 diffutil,
18 encoding,
18 encoding,
19 error,
19 error,
20 hbisect,
20 hbisect,
21 i18n,
21 i18n,
22 obsutil,
22 obsutil,
23 patch,
23 patch,
24 pycompat,
24 pycompat,
25 registrar,
25 registrar,
26 scmutil,
26 scmutil,
27 templateutil,
27 templateutil,
28 util,
28 util,
29 )
29 )
30 from .utils import (
30 from .utils import (
31 stringutil,
31 stringutil,
32 )
32 )
33
33
34 _hybrid = templateutil.hybrid
34 _hybrid = templateutil.hybrid
35 hybriddict = templateutil.hybriddict
35 hybriddict = templateutil.hybriddict
36 hybridlist = templateutil.hybridlist
36 hybridlist = templateutil.hybridlist
37 compatdict = templateutil.compatdict
37 compatdict = templateutil.compatdict
38 compatlist = templateutil.compatlist
38 compatlist = templateutil.compatlist
39 _showcompatlist = templateutil._showcompatlist
39 _showcompatlist = templateutil._showcompatlist
40
40
41 def getlatesttags(context, mapping, pattern=None):
41 def getlatesttags(context, mapping, pattern=None):
42 '''return date, distance and name for the latest tag of rev'''
42 '''return date, distance and name for the latest tag of rev'''
43 repo = context.resource(mapping, 'repo')
43 repo = context.resource(mapping, 'repo')
44 ctx = context.resource(mapping, 'ctx')
44 ctx = context.resource(mapping, 'ctx')
45 cache = context.resource(mapping, 'cache')
45 cache = context.resource(mapping, 'cache')
46
46
47 cachename = 'latesttags'
47 cachename = 'latesttags'
48 if pattern is not None:
48 if pattern is not None:
49 cachename += '-' + pattern
49 cachename += '-' + pattern
50 match = stringutil.stringmatcher(pattern)[2]
50 match = stringutil.stringmatcher(pattern)[2]
51 else:
51 else:
52 match = util.always
52 match = util.always
53
53
54 if cachename not in cache:
54 if cachename not in cache:
55 # Cache mapping from rev to a tuple with tag date, tag
55 # Cache mapping from rev to a tuple with tag date, tag
56 # distance and tag name
56 # distance and tag name
57 cache[cachename] = {-1: (0, 0, ['null'])}
57 cache[cachename] = {-1: (0, 0, ['null'])}
58 latesttags = cache[cachename]
58 latesttags = cache[cachename]
59
59
60 rev = ctx.rev()
60 rev = ctx.rev()
61 todo = [rev]
61 todo = [rev]
62 while todo:
62 while todo:
63 rev = todo.pop()
63 rev = todo.pop()
64 if rev in latesttags:
64 if rev in latesttags:
65 continue
65 continue
66 ctx = repo[rev]
66 ctx = repo[rev]
67 tags = [t for t in ctx.tags()
67 tags = [t for t in ctx.tags()
68 if (repo.tagtype(t) and repo.tagtype(t) != 'local'
68 if (repo.tagtype(t) and repo.tagtype(t) != 'local'
69 and match(t))]
69 and match(t))]
70 if tags:
70 if tags:
71 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
71 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
72 continue
72 continue
73 try:
73 try:
74 ptags = [latesttags[p.rev()] for p in ctx.parents()]
74 ptags = [latesttags[p.rev()] for p in ctx.parents()]
75 if len(ptags) > 1:
75 if len(ptags) > 1:
76 if ptags[0][2] == ptags[1][2]:
76 if ptags[0][2] == ptags[1][2]:
77 # The tuples are laid out so the right one can be found by
77 # The tuples are laid out so the right one can be found by
78 # comparison in this case.
78 # comparison in this case.
79 pdate, pdist, ptag = max(ptags)
79 pdate, pdist, ptag = max(ptags)
80 else:
80 else:
81 def key(x):
81 def key(x):
82 changessincetag = len(repo.revs('only(%d, %s)',
82 changessincetag = len(repo.revs('only(%d, %s)',
83 ctx.rev(), x[2][0]))
83 ctx.rev(), x[2][0]))
84 # Smallest number of changes since tag wins. Date is
84 # Smallest number of changes since tag wins. Date is
85 # used as tiebreaker.
85 # used as tiebreaker.
86 return [-changessincetag, x[0]]
86 return [-changessincetag, x[0]]
87 pdate, pdist, ptag = max(ptags, key=key)
87 pdate, pdist, ptag = max(ptags, key=key)
88 else:
88 else:
89 pdate, pdist, ptag = ptags[0]
89 pdate, pdist, ptag = ptags[0]
90 except KeyError:
90 except KeyError:
91 # Cache miss - recurse
91 # Cache miss - recurse
92 todo.append(rev)
92 todo.append(rev)
93 todo.extend(p.rev() for p in ctx.parents())
93 todo.extend(p.rev() for p in ctx.parents())
94 continue
94 continue
95 latesttags[rev] = pdate, pdist + 1, ptag
95 latesttags[rev] = pdate, pdist + 1, ptag
96 return latesttags[rev]
96 return latesttags[rev]
97
97
98 def getrenamedfn(repo, endrev=None):
98 def getrenamedfn(repo, endrev=None):
99 rcache = {}
99 rcache = {}
100 if endrev is None:
100 if endrev is None:
101 endrev = len(repo)
101 endrev = len(repo)
102
102
103 def getrenamed(fn, rev):
103 def getrenamed(fn, rev):
104 '''looks up all renames for a file (up to endrev) the first
104 '''looks up all renames for a file (up to endrev) the first
105 time the file is given. It indexes on the changerev and only
105 time the file is given. It indexes on the changerev and only
106 parses the manifest if linkrev != changerev.
106 parses the manifest if linkrev != changerev.
107 Returns rename info for fn at changerev rev.'''
107 Returns rename info for fn at changerev rev.'''
108 if fn not in rcache:
108 if fn not in rcache:
109 rcache[fn] = {}
109 rcache[fn] = {}
110 fl = repo.file(fn)
110 fl = repo.file(fn)
111 for i in fl:
111 for i in fl:
112 lr = fl.linkrev(i)
112 lr = fl.linkrev(i)
113 renamed = fl.renamed(fl.node(i))
113 renamed = fl.renamed(fl.node(i))
114 rcache[fn][lr] = renamed and renamed[0]
114 rcache[fn][lr] = renamed and renamed[0]
115 if lr >= endrev:
115 if lr >= endrev:
116 break
116 break
117 if rev in rcache[fn]:
117 if rev in rcache[fn]:
118 return rcache[fn][rev]
118 return rcache[fn][rev]
119
119
120 # If linkrev != rev (i.e. rev not found in rcache) fallback to
120 # If linkrev != rev (i.e. rev not found in rcache) fallback to
121 # filectx logic.
121 # filectx logic.
122 try:
122 try:
123 renamed = repo[rev][fn].renamed()
123 renamed = repo[rev][fn].renamed()
124 return renamed and renamed[0]
124 return renamed and renamed[0]
125 except error.LookupError:
125 except error.LookupError:
126 return None
126 return None
127
127
128 return getrenamed
128 return getrenamed
129
129
130 def getlogcolumns():
130 def getlogcolumns():
131 """Return a dict of log column labels"""
131 """Return a dict of log column labels"""
132 _ = pycompat.identity # temporarily disable gettext
132 _ = pycompat.identity # temporarily disable gettext
133 # i18n: column positioning for "hg log"
133 # i18n: column positioning for "hg log"
134 columns = _('bookmark: %s\n'
134 columns = _('bookmark: %s\n'
135 'branch: %s\n'
135 'branch: %s\n'
136 'changeset: %s\n'
136 'changeset: %s\n'
137 'copies: %s\n'
137 'copies: %s\n'
138 'date: %s\n'
138 'date: %s\n'
139 'extra: %s=%s\n'
139 'extra: %s=%s\n'
140 'files+: %s\n'
140 'files+: %s\n'
141 'files-: %s\n'
141 'files-: %s\n'
142 'files: %s\n'
142 'files: %s\n'
143 'instability: %s\n'
143 'instability: %s\n'
144 'manifest: %s\n'
144 'manifest: %s\n'
145 'obsolete: %s\n'
145 'obsolete: %s\n'
146 'parent: %s\n'
146 'parent: %s\n'
147 'phase: %s\n'
147 'phase: %s\n'
148 'summary: %s\n'
148 'summary: %s\n'
149 'tag: %s\n'
149 'tag: %s\n'
150 'user: %s\n')
150 'user: %s\n')
151 return dict(zip([s.split(':', 1)[0] for s in columns.splitlines()],
151 return dict(zip([s.split(':', 1)[0] for s in columns.splitlines()],
152 i18n._(columns).splitlines(True)))
152 i18n._(columns).splitlines(True)))
153
153
154 # default templates internally used for rendering of lists
154 # default templates internally used for rendering of lists
155 defaulttempl = {
155 defaulttempl = {
156 'parent': '{rev}:{node|formatnode} ',
156 'parent': '{rev}:{node|formatnode} ',
157 'manifest': '{rev}:{node|formatnode}',
157 'manifest': '{rev}:{node|formatnode}',
158 'file_copy': '{name} ({source})',
158 'file_copy': '{name} ({source})',
159 'envvar': '{key}={value}',
159 'envvar': '{key}={value}',
160 'extra': '{key}={value|stringescape}'
160 'extra': '{key}={value|stringescape}'
161 }
161 }
162 # filecopy is preserved for compatibility reasons
162 # filecopy is preserved for compatibility reasons
163 defaulttempl['filecopy'] = defaulttempl['file_copy']
163 defaulttempl['filecopy'] = defaulttempl['file_copy']
164
164
165 # keywords are callables (see registrar.templatekeyword for details)
165 # keywords are callables (see registrar.templatekeyword for details)
166 keywords = {}
166 keywords = {}
167 templatekeyword = registrar.templatekeyword(keywords)
167 templatekeyword = registrar.templatekeyword(keywords)
168
168
169 @templatekeyword('author', requires={'ctx'})
169 @templatekeyword('author', requires={'ctx'})
170 def showauthor(context, mapping):
170 def showauthor(context, mapping):
171 """Alias for ``{user}``"""
171 """Alias for ``{user}``"""
172 return showuser(context, mapping)
172 return showuser(context, mapping)
173
173
174 @templatekeyword('bisect', requires={'repo', 'ctx'})
174 @templatekeyword('bisect', requires={'repo', 'ctx'})
175 def showbisect(context, mapping):
175 def showbisect(context, mapping):
176 """String. The changeset bisection status."""
176 """String. The changeset bisection status."""
177 repo = context.resource(mapping, 'repo')
177 repo = context.resource(mapping, 'repo')
178 ctx = context.resource(mapping, 'ctx')
178 ctx = context.resource(mapping, 'ctx')
179 return hbisect.label(repo, ctx.node())
179 return hbisect.label(repo, ctx.node())
180
180
181 @templatekeyword('branch', requires={'ctx'})
181 @templatekeyword('branch', requires={'ctx'})
182 def showbranch(context, mapping):
182 def showbranch(context, mapping):
183 """String. The name of the branch on which the changeset was
183 """String. The name of the branch on which the changeset was
184 committed.
184 committed.
185 """
185 """
186 ctx = context.resource(mapping, 'ctx')
186 ctx = context.resource(mapping, 'ctx')
187 return ctx.branch()
187 return ctx.branch()
188
188
189 @templatekeyword('branches', requires={'ctx'})
189 @templatekeyword('branches', requires={'ctx'})
190 def showbranches(context, mapping):
190 def showbranches(context, mapping):
191 """List of strings. The name of the branch on which the
191 """List of strings. The name of the branch on which the
192 changeset was committed. Will be empty if the branch name was
192 changeset was committed. Will be empty if the branch name was
193 default. (DEPRECATED)
193 default. (DEPRECATED)
194 """
194 """
195 ctx = context.resource(mapping, 'ctx')
195 ctx = context.resource(mapping, 'ctx')
196 branch = ctx.branch()
196 branch = ctx.branch()
197 if branch != 'default':
197 if branch != 'default':
198 return compatlist(context, mapping, 'branch', [branch],
198 return compatlist(context, mapping, 'branch', [branch],
199 plural='branches')
199 plural='branches')
200 return compatlist(context, mapping, 'branch', [], plural='branches')
200 return compatlist(context, mapping, 'branch', [], plural='branches')
201
201
202 @templatekeyword('bookmarks', requires={'repo', 'ctx'})
202 @templatekeyword('bookmarks', requires={'repo', 'ctx'})
203 def showbookmarks(context, mapping):
203 def showbookmarks(context, mapping):
204 """List of strings. Any bookmarks associated with the
204 """List of strings. Any bookmarks associated with the
205 changeset. Also sets 'active', the name of the active bookmark.
205 changeset. Also sets 'active', the name of the active bookmark.
206 """
206 """
207 repo = context.resource(mapping, 'repo')
207 repo = context.resource(mapping, 'repo')
208 ctx = context.resource(mapping, 'ctx')
208 ctx = context.resource(mapping, 'ctx')
209 bookmarks = ctx.bookmarks()
209 bookmarks = ctx.bookmarks()
210 active = repo._activebookmark
210 active = repo._activebookmark
211 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active}
211 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active}
212 f = _showcompatlist(context, mapping, 'bookmark', bookmarks)
212 f = _showcompatlist(context, mapping, 'bookmark', bookmarks)
213 return _hybrid(f, bookmarks, makemap, pycompat.identity)
213 return _hybrid(f, bookmarks, makemap, pycompat.identity)
214
214
215 @templatekeyword('children', requires={'ctx'})
215 @templatekeyword('children', requires={'ctx'})
216 def showchildren(context, mapping):
216 def showchildren(context, mapping):
217 """List of strings. The children of the changeset."""
217 """List of strings. The children of the changeset."""
218 ctx = context.resource(mapping, 'ctx')
218 ctx = context.resource(mapping, 'ctx')
219 childrevs = ['%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()]
219 childrevs = ['%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()]
220 return compatlist(context, mapping, 'children', childrevs, element='child')
220 return compatlist(context, mapping, 'children', childrevs, element='child')
221
221
222 # Deprecated, but kept alive for help generation a purpose.
222 # Deprecated, but kept alive for help generation a purpose.
223 @templatekeyword('currentbookmark', requires={'repo', 'ctx'})
223 @templatekeyword('currentbookmark', requires={'repo', 'ctx'})
224 def showcurrentbookmark(context, mapping):
224 def showcurrentbookmark(context, mapping):
225 """String. The active bookmark, if it is associated with the changeset.
225 """String. The active bookmark, if it is associated with the changeset.
226 (DEPRECATED)"""
226 (DEPRECATED)"""
227 return showactivebookmark(context, mapping)
227 return showactivebookmark(context, mapping)
228
228
229 @templatekeyword('activebookmark', requires={'repo', 'ctx'})
229 @templatekeyword('activebookmark', requires={'repo', 'ctx'})
230 def showactivebookmark(context, mapping):
230 def showactivebookmark(context, mapping):
231 """String. The active bookmark, if it is associated with the changeset."""
231 """String. The active bookmark, if it is associated with the changeset."""
232 repo = context.resource(mapping, 'repo')
232 repo = context.resource(mapping, 'repo')
233 ctx = context.resource(mapping, 'ctx')
233 ctx = context.resource(mapping, 'ctx')
234 active = repo._activebookmark
234 active = repo._activebookmark
235 if active and active in ctx.bookmarks():
235 if active and active in ctx.bookmarks():
236 return active
236 return active
237 return ''
237 return ''
238
238
239 @templatekeyword('date', requires={'ctx'})
239 @templatekeyword('date', requires={'ctx'})
240 def showdate(context, mapping):
240 def showdate(context, mapping):
241 """Date information. The date when the changeset was committed."""
241 """Date information. The date when the changeset was committed."""
242 ctx = context.resource(mapping, 'ctx')
242 ctx = context.resource(mapping, 'ctx')
243 # the default string format is '<float(unixtime)><tzoffset>' because
243 # the default string format is '<float(unixtime)><tzoffset>' because
244 # python-hglib splits date at decimal separator.
244 # python-hglib splits date at decimal separator.
245 return templateutil.date(ctx.date(), showfmt='%d.0%d')
245 return templateutil.date(ctx.date(), showfmt='%d.0%d')
246
246
247 @templatekeyword('desc', requires={'ctx'})
247 @templatekeyword('desc', requires={'ctx'})
248 def showdescription(context, mapping):
248 def showdescription(context, mapping):
249 """String. The text of the changeset description."""
249 """String. The text of the changeset description."""
250 ctx = context.resource(mapping, 'ctx')
250 ctx = context.resource(mapping, 'ctx')
251 s = ctx.description()
251 s = ctx.description()
252 if isinstance(s, encoding.localstr):
252 if isinstance(s, encoding.localstr):
253 # try hard to preserve utf-8 bytes
253 # try hard to preserve utf-8 bytes
254 return encoding.tolocal(encoding.fromlocal(s).strip())
254 return encoding.tolocal(encoding.fromlocal(s).strip())
255 elif isinstance(s, encoding.safelocalstr):
255 elif isinstance(s, encoding.safelocalstr):
256 return encoding.safelocalstr(s.strip())
256 return encoding.safelocalstr(s.strip())
257 else:
257 else:
258 return s.strip()
258 return s.strip()
259
259
260 @templatekeyword('diffstat', requires={'ui', 'ctx'})
260 @templatekeyword('diffstat', requires={'ui', 'ctx'})
261 def showdiffstat(context, mapping):
261 def showdiffstat(context, mapping):
262 """String. Statistics of changes with the following format:
262 """String. Statistics of changes with the following format:
263 "modified files: +added/-removed lines"
263 "modified files: +added/-removed lines"
264 """
264 """
265 ui = context.resource(mapping, 'ui')
265 ui = context.resource(mapping, 'ui')
266 ctx = context.resource(mapping, 'ctx')
266 ctx = context.resource(mapping, 'ctx')
267 diffopts = diffutil.diffallopts(ui, {'noprefix': False})
267 diffopts = diffutil.diffallopts(ui, {'noprefix': False})
268 diff = ctx.diff(opts=diffopts)
268 diff = ctx.diff(opts=diffopts)
269 stats = patch.diffstatdata(util.iterlines(diff))
269 stats = patch.diffstatdata(util.iterlines(diff))
270 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
270 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
271 return '%d: +%d/-%d' % (len(stats), adds, removes)
271 return '%d: +%d/-%d' % (len(stats), adds, removes)
272
272
273 @templatekeyword('envvars', requires={'ui'})
273 @templatekeyword('envvars', requires={'ui'})
274 def showenvvars(context, mapping):
274 def showenvvars(context, mapping):
275 """A dictionary of environment variables. (EXPERIMENTAL)"""
275 """A dictionary of environment variables. (EXPERIMENTAL)"""
276 ui = context.resource(mapping, 'ui')
276 ui = context.resource(mapping, 'ui')
277 env = ui.exportableenviron()
277 env = ui.exportableenviron()
278 env = util.sortdict((k, env[k]) for k in sorted(env))
278 env = util.sortdict((k, env[k]) for k in sorted(env))
279 return compatdict(context, mapping, 'envvar', env, plural='envvars')
279 return compatdict(context, mapping, 'envvar', env, plural='envvars')
280
280
281 @templatekeyword('extras', requires={'ctx'})
281 @templatekeyword('extras', requires={'ctx'})
282 def showextras(context, mapping):
282 def showextras(context, mapping):
283 """List of dicts with key, value entries of the 'extras'
283 """List of dicts with key, value entries of the 'extras'
284 field of this changeset."""
284 field of this changeset."""
285 ctx = context.resource(mapping, 'ctx')
285 ctx = context.resource(mapping, 'ctx')
286 extras = ctx.extra()
286 extras = ctx.extra()
287 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
287 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
288 makemap = lambda k: {'key': k, 'value': extras[k]}
288 makemap = lambda k: {'key': k, 'value': extras[k]}
289 c = [makemap(k) for k in extras]
289 c = [makemap(k) for k in extras]
290 f = _showcompatlist(context, mapping, 'extra', c, plural='extras')
290 f = _showcompatlist(context, mapping, 'extra', c, plural='extras')
291 return _hybrid(f, extras, makemap,
291 return _hybrid(f, extras, makemap,
292 lambda k: '%s=%s' % (k, stringutil.escapestr(extras[k])))
292 lambda k: '%s=%s' % (k, stringutil.escapestr(extras[k])))
293
293
294 def _getfilestatus(context, mapping, listall=False):
294 def _getfilestatus(context, mapping, listall=False):
295 ctx = context.resource(mapping, 'ctx')
295 ctx = context.resource(mapping, 'ctx')
296 revcache = context.resource(mapping, 'revcache')
296 revcache = context.resource(mapping, 'revcache')
297 if 'filestatus' not in revcache or revcache['filestatusall'] < listall:
297 if 'filestatus' not in revcache or revcache['filestatusall'] < listall:
298 stat = ctx.p1().status(ctx, listignored=listall, listclean=listall,
298 stat = ctx.p1().status(ctx, listignored=listall, listclean=listall,
299 listunknown=listall)
299 listunknown=listall)
300 revcache['filestatus'] = stat
300 revcache['filestatus'] = stat
301 revcache['filestatusall'] = listall
301 revcache['filestatusall'] = listall
302 return revcache['filestatus']
302 return revcache['filestatus']
303
303
304 def _getfilestatusmap(context, mapping, listall=False):
304 def _getfilestatusmap(context, mapping, listall=False):
305 revcache = context.resource(mapping, 'revcache')
305 revcache = context.resource(mapping, 'revcache')
306 if 'filestatusmap' not in revcache or revcache['filestatusall'] < listall:
306 if 'filestatusmap' not in revcache or revcache['filestatusall'] < listall:
307 stat = _getfilestatus(context, mapping, listall=listall)
307 stat = _getfilestatus(context, mapping, listall=listall)
308 revcache['filestatusmap'] = statmap = {}
308 revcache['filestatusmap'] = statmap = {}
309 for char, files in zip(pycompat.iterbytestr('MAR!?IC'), stat):
309 for char, files in zip(pycompat.iterbytestr('MAR!?IC'), stat):
310 statmap.update((f, char) for f in files)
310 statmap.update((f, char) for f in files)
311 return revcache['filestatusmap'] # {path: statchar}
311 return revcache['filestatusmap'] # {path: statchar}
312
312
313 def _showfilesbystat(context, mapping, name, index):
313 def _showfilesbystat(context, mapping, name, index):
314 stat = _getfilestatus(context, mapping)
314 stat = _getfilestatus(context, mapping)
315 files = stat[index]
315 files = stat[index]
316 return templateutil.compatfileslist(context, mapping, name, files)
316 return templateutil.compatfileslist(context, mapping, name, files)
317
317
318 @templatekeyword('file_adds', requires={'ctx', 'revcache'})
318 @templatekeyword('file_adds', requires={'ctx', 'revcache'})
319 def showfileadds(context, mapping):
319 def showfileadds(context, mapping):
320 """List of strings. Files added by this changeset."""
320 """List of strings. Files added by this changeset."""
321 return _showfilesbystat(context, mapping, 'file_add', 1)
321 return _showfilesbystat(context, mapping, 'file_add', 1)
322
322
323 @templatekeyword('file_copies',
323 @templatekeyword('file_copies',
324 requires={'repo', 'ctx', 'cache', 'revcache'})
324 requires={'repo', 'ctx', 'cache', 'revcache'})
325 def showfilecopies(context, mapping):
325 def showfilecopies(context, mapping):
326 """List of strings. Files copied in this changeset with
326 """List of strings. Files copied in this changeset with
327 their sources.
327 their sources.
328 """
328 """
329 repo = context.resource(mapping, 'repo')
329 repo = context.resource(mapping, 'repo')
330 ctx = context.resource(mapping, 'ctx')
330 ctx = context.resource(mapping, 'ctx')
331 cache = context.resource(mapping, 'cache')
331 cache = context.resource(mapping, 'cache')
332 copies = context.resource(mapping, 'revcache').get('copies')
332 copies = context.resource(mapping, 'revcache').get('copies')
333 if copies is None:
333 if copies is None:
334 if 'getrenamed' not in cache:
334 if 'getrenamed' not in cache:
335 cache['getrenamed'] = getrenamedfn(repo)
335 cache['getrenamed'] = getrenamedfn(repo)
336 copies = []
336 copies = []
337 getrenamed = cache['getrenamed']
337 getrenamed = cache['getrenamed']
338 for fn in ctx.files():
338 for fn in ctx.files():
339 rename = getrenamed(fn, ctx.rev())
339 rename = getrenamed(fn, ctx.rev())
340 if rename:
340 if rename:
341 copies.append((fn, rename))
341 copies.append((fn, rename))
342 return templateutil.compatfilecopiesdict(context, mapping, 'file_copy',
342 return templateutil.compatfilecopiesdict(context, mapping, 'file_copy',
343 copies)
343 copies)
344
344
345 # showfilecopiesswitch() displays file copies only if copy records are
345 # showfilecopiesswitch() displays file copies only if copy records are
346 # provided before calling the templater, usually with a --copies
346 # provided before calling the templater, usually with a --copies
347 # command line switch.
347 # command line switch.
348 @templatekeyword('file_copies_switch', requires={'revcache'})
348 @templatekeyword('file_copies_switch', requires={'revcache'})
349 def showfilecopiesswitch(context, mapping):
349 def showfilecopiesswitch(context, mapping):
350 """List of strings. Like "file_copies" but displayed
350 """List of strings. Like "file_copies" but displayed
351 only if the --copied switch is set.
351 only if the --copied switch is set.
352 """
352 """
353 copies = context.resource(mapping, 'revcache').get('copies') or []
353 copies = context.resource(mapping, 'revcache').get('copies') or []
354 return templateutil.compatfilecopiesdict(context, mapping, 'file_copy',
354 return templateutil.compatfilecopiesdict(context, mapping, 'file_copy',
355 copies)
355 copies)
356
356
357 @templatekeyword('file_dels', requires={'ctx', 'revcache'})
357 @templatekeyword('file_dels', requires={'ctx', 'revcache'})
358 def showfiledels(context, mapping):
358 def showfiledels(context, mapping):
359 """List of strings. Files removed by this changeset."""
359 """List of strings. Files removed by this changeset."""
360 return _showfilesbystat(context, mapping, 'file_del', 2)
360 return _showfilesbystat(context, mapping, 'file_del', 2)
361
361
362 @templatekeyword('file_mods', requires={'ctx', 'revcache'})
362 @templatekeyword('file_mods', requires={'ctx', 'revcache'})
363 def showfilemods(context, mapping):
363 def showfilemods(context, mapping):
364 """List of strings. Files modified by this changeset."""
364 """List of strings. Files modified by this changeset."""
365 return _showfilesbystat(context, mapping, 'file_mod', 0)
365 return _showfilesbystat(context, mapping, 'file_mod', 0)
366
366
367 @templatekeyword('files', requires={'ctx'})
367 @templatekeyword('files', requires={'ctx'})
368 def showfiles(context, mapping):
368 def showfiles(context, mapping):
369 """List of strings. All files modified, added, or removed by this
369 """List of strings. All files modified, added, or removed by this
370 changeset.
370 changeset.
371 """
371 """
372 ctx = context.resource(mapping, 'ctx')
372 ctx = context.resource(mapping, 'ctx')
373 return templateutil.compatfileslist(context, mapping, 'file', ctx.files())
373 return templateutil.compatfileslist(context, mapping, 'file', ctx.files())
374
374
375 @templatekeyword('graphnode', requires={'repo', 'ctx'})
375 @templatekeyword('graphnode', requires={'repo', 'ctx'})
376 def showgraphnode(context, mapping):
376 def showgraphnode(context, mapping):
377 """String. The character representing the changeset node in an ASCII
377 """String. The character representing the changeset node in an ASCII
378 revision graph."""
378 revision graph."""
379 repo = context.resource(mapping, 'repo')
379 repo = context.resource(mapping, 'repo')
380 ctx = context.resource(mapping, 'ctx')
380 ctx = context.resource(mapping, 'ctx')
381 return getgraphnode(repo, ctx)
381 return getgraphnode(repo, ctx)
382
382
383 def getgraphnode(repo, ctx):
383 def getgraphnode(repo, ctx):
384 return getgraphnodecurrent(repo, ctx) or getgraphnodesymbol(ctx)
384 return getgraphnodecurrent(repo, ctx) or getgraphnodesymbol(ctx)
385
385
386 def getgraphnodecurrent(repo, ctx):
386 def getgraphnodecurrent(repo, ctx):
387 wpnodes = repo.dirstate.parents()
387 wpnodes = repo.dirstate.parents()
388 if wpnodes[1] == nullid:
388 if wpnodes[1] == nullid:
389 wpnodes = wpnodes[:1]
389 wpnodes = wpnodes[:1]
390 if ctx.node() in wpnodes:
390 if ctx.node() in wpnodes:
391 return '@'
391 return '@'
392 else:
392 else:
393 return ''
393 return ''
394
394
395 def getgraphnodesymbol(ctx):
395 def getgraphnodesymbol(ctx):
396 if ctx.obsolete():
396 if ctx.obsolete():
397 return 'x'
397 return 'x'
398 elif ctx.isunstable():
398 elif ctx.isunstable():
399 return '*'
399 return '*'
400 elif ctx.closesbranch():
400 elif ctx.closesbranch():
401 return '_'
401 return '_'
402 else:
402 else:
403 return 'o'
403 return 'o'
404
404
405 @templatekeyword('graphwidth', requires=())
405 @templatekeyword('graphwidth', requires=())
406 def showgraphwidth(context, mapping):
406 def showgraphwidth(context, mapping):
407 """Integer. The width of the graph drawn by 'log --graph' or zero."""
407 """Integer. The width of the graph drawn by 'log --graph' or zero."""
408 # just hosts documentation; should be overridden by template mapping
408 # just hosts documentation; should be overridden by template mapping
409 return 0
409 return 0
410
410
411 @templatekeyword('index', requires=())
411 @templatekeyword('index', requires=())
412 def showindex(context, mapping):
412 def showindex(context, mapping):
413 """Integer. The current iteration of the loop. (0 indexed)"""
413 """Integer. The current iteration of the loop. (0 indexed)"""
414 # just hosts documentation; should be overridden by template mapping
414 # just hosts documentation; should be overridden by template mapping
415 raise error.Abort(_("can't use index in this context"))
415 raise error.Abort(_("can't use index in this context"))
416
416
417 @templatekeyword('latesttag', requires={'repo', 'ctx', 'cache'})
417 @templatekeyword('latesttag', requires={'repo', 'ctx', 'cache'})
418 def showlatesttag(context, mapping):
418 def showlatesttag(context, mapping):
419 """List of strings. The global tags on the most recent globally
419 """List of strings. The global tags on the most recent globally
420 tagged ancestor of this changeset. If no such tags exist, the list
420 tagged ancestor of this changeset. If no such tags exist, the list
421 consists of the single string "null".
421 consists of the single string "null".
422 """
422 """
423 return showlatesttags(context, mapping, None)
423 return showlatesttags(context, mapping, None)
424
424
425 def showlatesttags(context, mapping, pattern):
425 def showlatesttags(context, mapping, pattern):
426 """helper method for the latesttag keyword and function"""
426 """helper method for the latesttag keyword and function"""
427 latesttags = getlatesttags(context, mapping, pattern)
427 latesttags = getlatesttags(context, mapping, pattern)
428
428
429 # latesttag[0] is an implementation detail for sorting csets on different
429 # latesttag[0] is an implementation detail for sorting csets on different
430 # branches in a stable manner- it is the date the tagged cset was created,
430 # branches in a stable manner- it is the date the tagged cset was created,
431 # not the date the tag was created. Therefore it isn't made visible here.
431 # not the date the tag was created. Therefore it isn't made visible here.
432 makemap = lambda v: {
432 makemap = lambda v: {
433 'changes': _showchangessincetag,
433 'changes': _showchangessincetag,
434 'distance': latesttags[1],
434 'distance': latesttags[1],
435 'latesttag': v, # BC with {latesttag % '{latesttag}'}
435 'latesttag': v, # BC with {latesttag % '{latesttag}'}
436 'tag': v
436 'tag': v
437 }
437 }
438
438
439 tags = latesttags[2]
439 tags = latesttags[2]
440 f = _showcompatlist(context, mapping, 'latesttag', tags, separator=':')
440 f = _showcompatlist(context, mapping, 'latesttag', tags, separator=':')
441 return _hybrid(f, tags, makemap, pycompat.identity)
441 return _hybrid(f, tags, makemap, pycompat.identity)
442
442
443 @templatekeyword('latesttagdistance', requires={'repo', 'ctx', 'cache'})
443 @templatekeyword('latesttagdistance', requires={'repo', 'ctx', 'cache'})
444 def showlatesttagdistance(context, mapping):
444 def showlatesttagdistance(context, mapping):
445 """Integer. Longest path to the latest tag."""
445 """Integer. Longest path to the latest tag."""
446 return getlatesttags(context, mapping)[1]
446 return getlatesttags(context, mapping)[1]
447
447
448 @templatekeyword('changessincelatesttag', requires={'repo', 'ctx', 'cache'})
448 @templatekeyword('changessincelatesttag', requires={'repo', 'ctx', 'cache'})
449 def showchangessincelatesttag(context, mapping):
449 def showchangessincelatesttag(context, mapping):
450 """Integer. All ancestors not in the latest tag."""
450 """Integer. All ancestors not in the latest tag."""
451 tag = getlatesttags(context, mapping)[2][0]
451 tag = getlatesttags(context, mapping)[2][0]
452 mapping = context.overlaymap(mapping, {'tag': tag})
452 mapping = context.overlaymap(mapping, {'tag': tag})
453 return _showchangessincetag(context, mapping)
453 return _showchangessincetag(context, mapping)
454
454
455 def _showchangessincetag(context, mapping):
455 def _showchangessincetag(context, mapping):
456 repo = context.resource(mapping, 'repo')
456 repo = context.resource(mapping, 'repo')
457 ctx = context.resource(mapping, 'ctx')
457 ctx = context.resource(mapping, 'ctx')
458 offset = 0
458 offset = 0
459 revs = [ctx.rev()]
459 revs = [ctx.rev()]
460 tag = context.symbol(mapping, 'tag')
460 tag = context.symbol(mapping, 'tag')
461
461
462 # The only() revset doesn't currently support wdir()
462 # The only() revset doesn't currently support wdir()
463 if ctx.rev() is None:
463 if ctx.rev() is None:
464 offset = 1
464 offset = 1
465 revs = [p.rev() for p in ctx.parents()]
465 revs = [p.rev() for p in ctx.parents()]
466
466
467 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset
467 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset
468
468
469 # teach templater latesttags.changes is switched to (context, mapping) API
469 # teach templater latesttags.changes is switched to (context, mapping) API
470 _showchangessincetag._requires = {'repo', 'ctx'}
470 _showchangessincetag._requires = {'repo', 'ctx'}
471
471
472 @templatekeyword('manifest', requires={'repo', 'ctx'})
472 @templatekeyword('manifest', requires={'repo', 'ctx'})
473 def showmanifest(context, mapping):
473 def showmanifest(context, mapping):
474 repo = context.resource(mapping, 'repo')
474 repo = context.resource(mapping, 'repo')
475 ctx = context.resource(mapping, 'ctx')
475 ctx = context.resource(mapping, 'ctx')
476 mnode = ctx.manifestnode()
476 mnode = ctx.manifestnode()
477 if mnode is None:
477 if mnode is None:
478 # just avoid crash, we might want to use the 'ff...' hash in future
478 # just avoid crash, we might want to use the 'ff...' hash in future
479 return
479 return
480 mrev = repo.manifestlog.rev(mnode)
480 mrev = repo.manifestlog.rev(mnode)
481 mhex = hex(mnode)
481 mhex = hex(mnode)
482 mapping = context.overlaymap(mapping, {'rev': mrev, 'node': mhex})
482 mapping = context.overlaymap(mapping, {'rev': mrev, 'node': mhex})
483 f = context.process('manifest', mapping)
483 f = context.process('manifest', mapping)
484 # TODO: perhaps 'ctx' should be dropped from mapping because manifest
485 # rev and node are completely different from changeset's.
486 return templateutil.hybriditem(f, None, f,
484 return templateutil.hybriditem(f, None, f,
487 lambda x: {'rev': mrev, 'node': mhex})
485 lambda x: {'rev': mrev, 'node': mhex})
488
486
489 @templatekeyword('obsfate', requires={'ui', 'repo', 'ctx'})
487 @templatekeyword('obsfate', requires={'ui', 'repo', 'ctx'})
490 def showobsfate(context, mapping):
488 def showobsfate(context, mapping):
491 # this function returns a list containing pre-formatted obsfate strings.
489 # this function returns a list containing pre-formatted obsfate strings.
492 #
490 #
493 # This function will be replaced by templates fragments when we will have
491 # This function will be replaced by templates fragments when we will have
494 # the verbosity templatekw available.
492 # the verbosity templatekw available.
495 succsandmarkers = showsuccsandmarkers(context, mapping)
493 succsandmarkers = showsuccsandmarkers(context, mapping)
496
494
497 ui = context.resource(mapping, 'ui')
495 ui = context.resource(mapping, 'ui')
498 repo = context.resource(mapping, 'repo')
496 repo = context.resource(mapping, 'repo')
499 values = []
497 values = []
500
498
501 for x in succsandmarkers.tovalue(context, mapping):
499 for x in succsandmarkers.tovalue(context, mapping):
502 v = obsutil.obsfateprinter(ui, repo, x['successors'], x['markers'],
500 v = obsutil.obsfateprinter(ui, repo, x['successors'], x['markers'],
503 scmutil.formatchangeid)
501 scmutil.formatchangeid)
504 values.append(v)
502 values.append(v)
505
503
506 return compatlist(context, mapping, "fate", values)
504 return compatlist(context, mapping, "fate", values)
507
505
508 def shownames(context, mapping, namespace):
506 def shownames(context, mapping, namespace):
509 """helper method to generate a template keyword for a namespace"""
507 """helper method to generate a template keyword for a namespace"""
510 repo = context.resource(mapping, 'repo')
508 repo = context.resource(mapping, 'repo')
511 ctx = context.resource(mapping, 'ctx')
509 ctx = context.resource(mapping, 'ctx')
512 ns = repo.names[namespace]
510 ns = repo.names[namespace]
513 names = ns.names(repo, ctx.node())
511 names = ns.names(repo, ctx.node())
514 return compatlist(context, mapping, ns.templatename, names,
512 return compatlist(context, mapping, ns.templatename, names,
515 plural=namespace)
513 plural=namespace)
516
514
517 @templatekeyword('namespaces', requires={'repo', 'ctx'})
515 @templatekeyword('namespaces', requires={'repo', 'ctx'})
518 def shownamespaces(context, mapping):
516 def shownamespaces(context, mapping):
519 """Dict of lists. Names attached to this changeset per
517 """Dict of lists. Names attached to this changeset per
520 namespace."""
518 namespace."""
521 repo = context.resource(mapping, 'repo')
519 repo = context.resource(mapping, 'repo')
522 ctx = context.resource(mapping, 'ctx')
520 ctx = context.resource(mapping, 'ctx')
523
521
524 namespaces = util.sortdict()
522 namespaces = util.sortdict()
525 def makensmapfn(ns):
523 def makensmapfn(ns):
526 # 'name' for iterating over namespaces, templatename for local reference
524 # 'name' for iterating over namespaces, templatename for local reference
527 return lambda v: {'name': v, ns.templatename: v}
525 return lambda v: {'name': v, ns.templatename: v}
528
526
529 for k, ns in repo.names.iteritems():
527 for k, ns in repo.names.iteritems():
530 names = ns.names(repo, ctx.node())
528 names = ns.names(repo, ctx.node())
531 f = _showcompatlist(context, mapping, 'name', names)
529 f = _showcompatlist(context, mapping, 'name', names)
532 namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
530 namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
533
531
534 f = _showcompatlist(context, mapping, 'namespace', list(namespaces))
532 f = _showcompatlist(context, mapping, 'namespace', list(namespaces))
535
533
536 def makemap(ns):
534 def makemap(ns):
537 return {
535 return {
538 'namespace': ns,
536 'namespace': ns,
539 'names': namespaces[ns],
537 'names': namespaces[ns],
540 'builtin': repo.names[ns].builtin,
538 'builtin': repo.names[ns].builtin,
541 'colorname': repo.names[ns].colorname,
539 'colorname': repo.names[ns].colorname,
542 }
540 }
543
541
544 return _hybrid(f, namespaces, makemap, pycompat.identity)
542 return _hybrid(f, namespaces, makemap, pycompat.identity)
545
543
546 @templatekeyword('node', requires={'ctx'})
544 @templatekeyword('node', requires={'ctx'})
547 def shownode(context, mapping):
545 def shownode(context, mapping):
548 """String. The changeset identification hash, as a 40 hexadecimal
546 """String. The changeset identification hash, as a 40 hexadecimal
549 digit string.
547 digit string.
550 """
548 """
551 ctx = context.resource(mapping, 'ctx')
549 ctx = context.resource(mapping, 'ctx')
552 return ctx.hex()
550 return ctx.hex()
553
551
554 @templatekeyword('obsolete', requires={'ctx'})
552 @templatekeyword('obsolete', requires={'ctx'})
555 def showobsolete(context, mapping):
553 def showobsolete(context, mapping):
556 """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
554 """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
557 ctx = context.resource(mapping, 'ctx')
555 ctx = context.resource(mapping, 'ctx')
558 if ctx.obsolete():
556 if ctx.obsolete():
559 return 'obsolete'
557 return 'obsolete'
560 return ''
558 return ''
561
559
562 @templatekeyword('path', requires={'fctx'})
560 @templatekeyword('path', requires={'fctx'})
563 def showpath(context, mapping):
561 def showpath(context, mapping):
564 """String. Repository-absolute path of the current file. (EXPERIMENTAL)"""
562 """String. Repository-absolute path of the current file. (EXPERIMENTAL)"""
565 fctx = context.resource(mapping, 'fctx')
563 fctx = context.resource(mapping, 'fctx')
566 return fctx.path()
564 return fctx.path()
567
565
568 @templatekeyword('peerurls', requires={'repo'})
566 @templatekeyword('peerurls', requires={'repo'})
569 def showpeerurls(context, mapping):
567 def showpeerurls(context, mapping):
570 """A dictionary of repository locations defined in the [paths] section
568 """A dictionary of repository locations defined in the [paths] section
571 of your configuration file."""
569 of your configuration file."""
572 repo = context.resource(mapping, 'repo')
570 repo = context.resource(mapping, 'repo')
573 # see commands.paths() for naming of dictionary keys
571 # see commands.paths() for naming of dictionary keys
574 paths = repo.ui.paths
572 paths = repo.ui.paths
575 urls = util.sortdict((k, p.rawloc) for k, p in sorted(paths.iteritems()))
573 urls = util.sortdict((k, p.rawloc) for k, p in sorted(paths.iteritems()))
576 def makemap(k):
574 def makemap(k):
577 p = paths[k]
575 p = paths[k]
578 d = {'name': k, 'url': p.rawloc}
576 d = {'name': k, 'url': p.rawloc}
579 d.update((o, v) for o, v in sorted(p.suboptions.iteritems()))
577 d.update((o, v) for o, v in sorted(p.suboptions.iteritems()))
580 return d
578 return d
581 return _hybrid(None, urls, makemap, lambda k: '%s=%s' % (k, urls[k]))
579 return _hybrid(None, urls, makemap, lambda k: '%s=%s' % (k, urls[k]))
582
580
583 @templatekeyword("predecessors", requires={'repo', 'ctx'})
581 @templatekeyword("predecessors", requires={'repo', 'ctx'})
584 def showpredecessors(context, mapping):
582 def showpredecessors(context, mapping):
585 """Returns the list if the closest visible successors. (EXPERIMENTAL)"""
583 """Returns the list if the closest visible successors. (EXPERIMENTAL)"""
586 repo = context.resource(mapping, 'repo')
584 repo = context.resource(mapping, 'repo')
587 ctx = context.resource(mapping, 'ctx')
585 ctx = context.resource(mapping, 'ctx')
588 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
586 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
589 predecessors = pycompat.maplist(hex, predecessors)
587 predecessors = pycompat.maplist(hex, predecessors)
590
588
591 return _hybrid(None, predecessors,
589 return _hybrid(None, predecessors,
592 lambda x: {'ctx': repo[x]},
590 lambda x: {'ctx': repo[x]},
593 lambda x: scmutil.formatchangeid(repo[x]))
591 lambda x: scmutil.formatchangeid(repo[x]))
594
592
595 @templatekeyword('reporoot', requires={'repo'})
593 @templatekeyword('reporoot', requires={'repo'})
596 def showreporoot(context, mapping):
594 def showreporoot(context, mapping):
597 """String. The root directory of the current repository."""
595 """String. The root directory of the current repository."""
598 repo = context.resource(mapping, 'repo')
596 repo = context.resource(mapping, 'repo')
599 return repo.root
597 return repo.root
600
598
601 @templatekeyword('size', requires={'fctx'})
599 @templatekeyword('size', requires={'fctx'})
602 def showsize(context, mapping):
600 def showsize(context, mapping):
603 """Integer. Size of the current file in bytes. (EXPERIMENTAL)"""
601 """Integer. Size of the current file in bytes. (EXPERIMENTAL)"""
604 fctx = context.resource(mapping, 'fctx')
602 fctx = context.resource(mapping, 'fctx')
605 return fctx.size()
603 return fctx.size()
606
604
607 # requires 'fctx' to denote {status} depends on (ctx, path) pair
605 # requires 'fctx' to denote {status} depends on (ctx, path) pair
608 @templatekeyword('status', requires={'ctx', 'fctx', 'revcache'})
606 @templatekeyword('status', requires={'ctx', 'fctx', 'revcache'})
609 def showstatus(context, mapping):
607 def showstatus(context, mapping):
610 """String. Status code of the current file. (EXPERIMENTAL)"""
608 """String. Status code of the current file. (EXPERIMENTAL)"""
611 path = templateutil.runsymbol(context, mapping, 'path')
609 path = templateutil.runsymbol(context, mapping, 'path')
612 path = templateutil.stringify(context, mapping, path)
610 path = templateutil.stringify(context, mapping, path)
613 if not path:
611 if not path:
614 return
612 return
615 statmap = _getfilestatusmap(context, mapping)
613 statmap = _getfilestatusmap(context, mapping)
616 if path not in statmap:
614 if path not in statmap:
617 statmap = _getfilestatusmap(context, mapping, listall=True)
615 statmap = _getfilestatusmap(context, mapping, listall=True)
618 return statmap.get(path)
616 return statmap.get(path)
619
617
620 @templatekeyword("successorssets", requires={'repo', 'ctx'})
618 @templatekeyword("successorssets", requires={'repo', 'ctx'})
621 def showsuccessorssets(context, mapping):
619 def showsuccessorssets(context, mapping):
622 """Returns a string of sets of successors for a changectx. Format used
620 """Returns a string of sets of successors for a changectx. Format used
623 is: [ctx1, ctx2], [ctx3] if ctx has been splitted into ctx1 and ctx2
621 is: [ctx1, ctx2], [ctx3] if ctx has been splitted into ctx1 and ctx2
624 while also diverged into ctx3. (EXPERIMENTAL)"""
622 while also diverged into ctx3. (EXPERIMENTAL)"""
625 repo = context.resource(mapping, 'repo')
623 repo = context.resource(mapping, 'repo')
626 ctx = context.resource(mapping, 'ctx')
624 ctx = context.resource(mapping, 'ctx')
627 if not ctx.obsolete():
625 if not ctx.obsolete():
628 return ''
626 return ''
629
627
630 ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
628 ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
631 ssets = [[hex(n) for n in ss] for ss in ssets]
629 ssets = [[hex(n) for n in ss] for ss in ssets]
632
630
633 data = []
631 data = []
634 for ss in ssets:
632 for ss in ssets:
635 h = _hybrid(None, ss, lambda x: {'ctx': repo[x]},
633 h = _hybrid(None, ss, lambda x: {'ctx': repo[x]},
636 lambda x: scmutil.formatchangeid(repo[x]))
634 lambda x: scmutil.formatchangeid(repo[x]))
637 data.append(h)
635 data.append(h)
638
636
639 # Format the successorssets
637 # Format the successorssets
640 def render(d):
638 def render(d):
641 return templateutil.stringify(context, mapping, d)
639 return templateutil.stringify(context, mapping, d)
642
640
643 def gen(data):
641 def gen(data):
644 yield "; ".join(render(d) for d in data)
642 yield "; ".join(render(d) for d in data)
645
643
646 return _hybrid(gen(data), data, lambda x: {'successorset': x},
644 return _hybrid(gen(data), data, lambda x: {'successorset': x},
647 pycompat.identity)
645 pycompat.identity)
648
646
649 @templatekeyword("succsandmarkers", requires={'repo', 'ctx'})
647 @templatekeyword("succsandmarkers", requires={'repo', 'ctx'})
650 def showsuccsandmarkers(context, mapping):
648 def showsuccsandmarkers(context, mapping):
651 """Returns a list of dict for each final successor of ctx. The dict
649 """Returns a list of dict for each final successor of ctx. The dict
652 contains successors node id in "successors" keys and the list of
650 contains successors node id in "successors" keys and the list of
653 obs-markers from ctx to the set of successors in "markers".
651 obs-markers from ctx to the set of successors in "markers".
654 (EXPERIMENTAL)
652 (EXPERIMENTAL)
655 """
653 """
656 repo = context.resource(mapping, 'repo')
654 repo = context.resource(mapping, 'repo')
657 ctx = context.resource(mapping, 'ctx')
655 ctx = context.resource(mapping, 'ctx')
658
656
659 values = obsutil.successorsandmarkers(repo, ctx)
657 values = obsutil.successorsandmarkers(repo, ctx)
660
658
661 if values is None:
659 if values is None:
662 values = []
660 values = []
663
661
664 # Format successors and markers to avoid exposing binary to templates
662 # Format successors and markers to avoid exposing binary to templates
665 data = []
663 data = []
666 for i in values:
664 for i in values:
667 # Format successors
665 # Format successors
668 successors = i['successors']
666 successors = i['successors']
669
667
670 successors = [hex(n) for n in successors]
668 successors = [hex(n) for n in successors]
671 successors = _hybrid(None, successors,
669 successors = _hybrid(None, successors,
672 lambda x: {'ctx': repo[x]},
670 lambda x: {'ctx': repo[x]},
673 lambda x: scmutil.formatchangeid(repo[x]))
671 lambda x: scmutil.formatchangeid(repo[x]))
674
672
675 # Format markers
673 # Format markers
676 finalmarkers = []
674 finalmarkers = []
677 for m in i['markers']:
675 for m in i['markers']:
678 hexprec = hex(m[0])
676 hexprec = hex(m[0])
679 hexsucs = tuple(hex(n) for n in m[1])
677 hexsucs = tuple(hex(n) for n in m[1])
680 hexparents = None
678 hexparents = None
681 if m[5] is not None:
679 if m[5] is not None:
682 hexparents = tuple(hex(n) for n in m[5])
680 hexparents = tuple(hex(n) for n in m[5])
683 newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
681 newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
684 finalmarkers.append(newmarker)
682 finalmarkers.append(newmarker)
685
683
686 data.append({'successors': successors, 'markers': finalmarkers})
684 data.append({'successors': successors, 'markers': finalmarkers})
687
685
688 return templateutil.mappinglist(data)
686 return templateutil.mappinglist(data)
689
687
690 @templatekeyword('p1rev', requires={'ctx'})
688 @templatekeyword('p1rev', requires={'ctx'})
691 def showp1rev(context, mapping):
689 def showp1rev(context, mapping):
692 """Integer. The repository-local revision number of the changeset's
690 """Integer. The repository-local revision number of the changeset's
693 first parent, or -1 if the changeset has no parents."""
691 first parent, or -1 if the changeset has no parents."""
694 ctx = context.resource(mapping, 'ctx')
692 ctx = context.resource(mapping, 'ctx')
695 return ctx.p1().rev()
693 return ctx.p1().rev()
696
694
697 @templatekeyword('p2rev', requires={'ctx'})
695 @templatekeyword('p2rev', requires={'ctx'})
698 def showp2rev(context, mapping):
696 def showp2rev(context, mapping):
699 """Integer. The repository-local revision number of the changeset's
697 """Integer. The repository-local revision number of the changeset's
700 second parent, or -1 if the changeset has no second parent."""
698 second parent, or -1 if the changeset has no second parent."""
701 ctx = context.resource(mapping, 'ctx')
699 ctx = context.resource(mapping, 'ctx')
702 return ctx.p2().rev()
700 return ctx.p2().rev()
703
701
704 @templatekeyword('p1node', requires={'ctx'})
702 @templatekeyword('p1node', requires={'ctx'})
705 def showp1node(context, mapping):
703 def showp1node(context, mapping):
706 """String. The identification hash of the changeset's first parent,
704 """String. The identification hash of the changeset's first parent,
707 as a 40 digit hexadecimal string. If the changeset has no parents, all
705 as a 40 digit hexadecimal string. If the changeset has no parents, all
708 digits are 0."""
706 digits are 0."""
709 ctx = context.resource(mapping, 'ctx')
707 ctx = context.resource(mapping, 'ctx')
710 return ctx.p1().hex()
708 return ctx.p1().hex()
711
709
712 @templatekeyword('p2node', requires={'ctx'})
710 @templatekeyword('p2node', requires={'ctx'})
713 def showp2node(context, mapping):
711 def showp2node(context, mapping):
714 """String. The identification hash of the changeset's second
712 """String. The identification hash of the changeset's second
715 parent, as a 40 digit hexadecimal string. If the changeset has no second
713 parent, as a 40 digit hexadecimal string. If the changeset has no second
716 parent, all digits are 0."""
714 parent, all digits are 0."""
717 ctx = context.resource(mapping, 'ctx')
715 ctx = context.resource(mapping, 'ctx')
718 return ctx.p2().hex()
716 return ctx.p2().hex()
719
717
720 @templatekeyword('parents', requires={'repo', 'ctx'})
718 @templatekeyword('parents', requires={'repo', 'ctx'})
721 def showparents(context, mapping):
719 def showparents(context, mapping):
722 """List of strings. The parents of the changeset in "rev:node"
720 """List of strings. The parents of the changeset in "rev:node"
723 format. If the changeset has only one "natural" parent (the predecessor
721 format. If the changeset has only one "natural" parent (the predecessor
724 revision) nothing is shown."""
722 revision) nothing is shown."""
725 repo = context.resource(mapping, 'repo')
723 repo = context.resource(mapping, 'repo')
726 ctx = context.resource(mapping, 'ctx')
724 ctx = context.resource(mapping, 'ctx')
727 pctxs = scmutil.meaningfulparents(repo, ctx)
725 pctxs = scmutil.meaningfulparents(repo, ctx)
728 prevs = [p.rev() for p in pctxs]
726 prevs = [p.rev() for p in pctxs]
729 parents = [[('rev', p.rev()),
727 parents = [[('rev', p.rev()),
730 ('node', p.hex()),
728 ('node', p.hex()),
731 ('phase', p.phasestr())]
729 ('phase', p.phasestr())]
732 for p in pctxs]
730 for p in pctxs]
733 f = _showcompatlist(context, mapping, 'parent', parents)
731 f = _showcompatlist(context, mapping, 'parent', parents)
734 return _hybrid(f, prevs, lambda x: {'ctx': repo[x]},
732 return _hybrid(f, prevs, lambda x: {'ctx': repo[x]},
735 lambda x: scmutil.formatchangeid(repo[x]), keytype=int)
733 lambda x: scmutil.formatchangeid(repo[x]), keytype=int)
736
734
737 @templatekeyword('phase', requires={'ctx'})
735 @templatekeyword('phase', requires={'ctx'})
738 def showphase(context, mapping):
736 def showphase(context, mapping):
739 """String. The changeset phase name."""
737 """String. The changeset phase name."""
740 ctx = context.resource(mapping, 'ctx')
738 ctx = context.resource(mapping, 'ctx')
741 return ctx.phasestr()
739 return ctx.phasestr()
742
740
743 @templatekeyword('phaseidx', requires={'ctx'})
741 @templatekeyword('phaseidx', requires={'ctx'})
744 def showphaseidx(context, mapping):
742 def showphaseidx(context, mapping):
745 """Integer. The changeset phase index. (ADVANCED)"""
743 """Integer. The changeset phase index. (ADVANCED)"""
746 ctx = context.resource(mapping, 'ctx')
744 ctx = context.resource(mapping, 'ctx')
747 return ctx.phase()
745 return ctx.phase()
748
746
749 @templatekeyword('rev', requires={'ctx'})
747 @templatekeyword('rev', requires={'ctx'})
750 def showrev(context, mapping):
748 def showrev(context, mapping):
751 """Integer. The repository-local changeset revision number."""
749 """Integer. The repository-local changeset revision number."""
752 ctx = context.resource(mapping, 'ctx')
750 ctx = context.resource(mapping, 'ctx')
753 return scmutil.intrev(ctx)
751 return scmutil.intrev(ctx)
754
752
755 def showrevslist(context, mapping, name, revs):
753 def showrevslist(context, mapping, name, revs):
756 """helper to generate a list of revisions in which a mapped template will
754 """helper to generate a list of revisions in which a mapped template will
757 be evaluated"""
755 be evaluated"""
758 repo = context.resource(mapping, 'repo')
756 repo = context.resource(mapping, 'repo')
759 f = _showcompatlist(context, mapping, name, ['%d' % r for r in revs])
757 f = _showcompatlist(context, mapping, name, ['%d' % r for r in revs])
760 return _hybrid(f, revs,
758 return _hybrid(f, revs,
761 lambda x: {name: x, 'ctx': repo[x]},
759 lambda x: {name: x, 'ctx': repo[x]},
762 pycompat.identity, keytype=int)
760 pycompat.identity, keytype=int)
763
761
764 @templatekeyword('subrepos', requires={'ctx'})
762 @templatekeyword('subrepos', requires={'ctx'})
765 def showsubrepos(context, mapping):
763 def showsubrepos(context, mapping):
766 """List of strings. Updated subrepositories in the changeset."""
764 """List of strings. Updated subrepositories in the changeset."""
767 ctx = context.resource(mapping, 'ctx')
765 ctx = context.resource(mapping, 'ctx')
768 substate = ctx.substate
766 substate = ctx.substate
769 if not substate:
767 if not substate:
770 return compatlist(context, mapping, 'subrepo', [])
768 return compatlist(context, mapping, 'subrepo', [])
771 psubstate = ctx.parents()[0].substate or {}
769 psubstate = ctx.parents()[0].substate or {}
772 subrepos = []
770 subrepos = []
773 for sub in substate:
771 for sub in substate:
774 if sub not in psubstate or substate[sub] != psubstate[sub]:
772 if sub not in psubstate or substate[sub] != psubstate[sub]:
775 subrepos.append(sub) # modified or newly added in ctx
773 subrepos.append(sub) # modified or newly added in ctx
776 for sub in psubstate:
774 for sub in psubstate:
777 if sub not in substate:
775 if sub not in substate:
778 subrepos.append(sub) # removed in ctx
776 subrepos.append(sub) # removed in ctx
779 return compatlist(context, mapping, 'subrepo', sorted(subrepos))
777 return compatlist(context, mapping, 'subrepo', sorted(subrepos))
780
778
781 # don't remove "showtags" definition, even though namespaces will put
779 # don't remove "showtags" definition, even though namespaces will put
782 # a helper function for "tags" keyword into "keywords" map automatically,
780 # a helper function for "tags" keyword into "keywords" map automatically,
783 # because online help text is built without namespaces initialization
781 # because online help text is built without namespaces initialization
784 @templatekeyword('tags', requires={'repo', 'ctx'})
782 @templatekeyword('tags', requires={'repo', 'ctx'})
785 def showtags(context, mapping):
783 def showtags(context, mapping):
786 """List of strings. Any tags associated with the changeset."""
784 """List of strings. Any tags associated with the changeset."""
787 return shownames(context, mapping, 'tags')
785 return shownames(context, mapping, 'tags')
788
786
789 @templatekeyword('termwidth', requires={'ui'})
787 @templatekeyword('termwidth', requires={'ui'})
790 def showtermwidth(context, mapping):
788 def showtermwidth(context, mapping):
791 """Integer. The width of the current terminal."""
789 """Integer. The width of the current terminal."""
792 ui = context.resource(mapping, 'ui')
790 ui = context.resource(mapping, 'ui')
793 return ui.termwidth()
791 return ui.termwidth()
794
792
795 @templatekeyword('user', requires={'ctx'})
793 @templatekeyword('user', requires={'ctx'})
796 def showuser(context, mapping):
794 def showuser(context, mapping):
797 """String. The unmodified author of the changeset."""
795 """String. The unmodified author of the changeset."""
798 ctx = context.resource(mapping, 'ctx')
796 ctx = context.resource(mapping, 'ctx')
799 return ctx.user()
797 return ctx.user()
800
798
801 @templatekeyword('instabilities', requires={'ctx'})
799 @templatekeyword('instabilities', requires={'ctx'})
802 def showinstabilities(context, mapping):
800 def showinstabilities(context, mapping):
803 """List of strings. Evolution instabilities affecting the changeset.
801 """List of strings. Evolution instabilities affecting the changeset.
804 (EXPERIMENTAL)
802 (EXPERIMENTAL)
805 """
803 """
806 ctx = context.resource(mapping, 'ctx')
804 ctx = context.resource(mapping, 'ctx')
807 return compatlist(context, mapping, 'instability', ctx.instabilities(),
805 return compatlist(context, mapping, 'instability', ctx.instabilities(),
808 plural='instabilities')
806 plural='instabilities')
809
807
810 @templatekeyword('verbosity', requires={'ui'})
808 @templatekeyword('verbosity', requires={'ui'})
811 def showverbosity(context, mapping):
809 def showverbosity(context, mapping):
812 """String. The current output verbosity in 'debug', 'quiet', 'verbose',
810 """String. The current output verbosity in 'debug', 'quiet', 'verbose',
813 or ''."""
811 or ''."""
814 ui = context.resource(mapping, 'ui')
812 ui = context.resource(mapping, 'ui')
815 # see logcmdutil.changesettemplater for priority of these flags
813 # see logcmdutil.changesettemplater for priority of these flags
816 if ui.debugflag:
814 if ui.debugflag:
817 return 'debug'
815 return 'debug'
818 elif ui.quiet:
816 elif ui.quiet:
819 return 'quiet'
817 return 'quiet'
820 elif ui.verbose:
818 elif ui.verbose:
821 return 'verbose'
819 return 'verbose'
822 return ''
820 return ''
823
821
824 @templatekeyword('whyunstable', requires={'repo', 'ctx'})
822 @templatekeyword('whyunstable', requires={'repo', 'ctx'})
825 def showwhyunstable(context, mapping):
823 def showwhyunstable(context, mapping):
826 """List of dicts explaining all instabilities of a changeset.
824 """List of dicts explaining all instabilities of a changeset.
827 (EXPERIMENTAL)
825 (EXPERIMENTAL)
828 """
826 """
829 repo = context.resource(mapping, 'repo')
827 repo = context.resource(mapping, 'repo')
830 ctx = context.resource(mapping, 'ctx')
828 ctx = context.resource(mapping, 'ctx')
831
829
832 def formatnode(ctx):
830 def formatnode(ctx):
833 return '%s (%s)' % (scmutil.formatchangeid(ctx), ctx.phasestr())
831 return '%s (%s)' % (scmutil.formatchangeid(ctx), ctx.phasestr())
834
832
835 entries = obsutil.whyunstable(repo, ctx)
833 entries = obsutil.whyunstable(repo, ctx)
836
834
837 for entry in entries:
835 for entry in entries:
838 if entry.get('divergentnodes'):
836 if entry.get('divergentnodes'):
839 dnodes = entry['divergentnodes']
837 dnodes = entry['divergentnodes']
840 dnhybrid = _hybrid(None, [dnode.hex() for dnode in dnodes],
838 dnhybrid = _hybrid(None, [dnode.hex() for dnode in dnodes],
841 lambda x: {'ctx': repo[x]},
839 lambda x: {'ctx': repo[x]},
842 lambda x: formatnode(repo[x]))
840 lambda x: formatnode(repo[x]))
843 entry['divergentnodes'] = dnhybrid
841 entry['divergentnodes'] = dnhybrid
844
842
845 tmpl = ('{instability}:{if(divergentnodes, " ")}{divergentnodes} '
843 tmpl = ('{instability}:{if(divergentnodes, " ")}{divergentnodes} '
846 '{reason} {node|short}')
844 '{reason} {node|short}')
847 return templateutil.mappinglist(entries, tmpl=tmpl, sep='\n')
845 return templateutil.mappinglist(entries, tmpl=tmpl, sep='\n')
848
846
849 def loadkeyword(ui, extname, registrarobj):
847 def loadkeyword(ui, extname, registrarobj):
850 """Load template keyword from specified registrarobj
848 """Load template keyword from specified registrarobj
851 """
849 """
852 for name, func in registrarobj._table.iteritems():
850 for name, func in registrarobj._table.iteritems():
853 keywords[name] = func
851 keywords[name] = func
854
852
855 # tell hggettext to extract docstrings from these functions:
853 # tell hggettext to extract docstrings from these functions:
856 i18nfunctions = keywords.values()
854 i18nfunctions = keywords.values()
@@ -1,1280 +1,1285 b''
1 Test template keywords
1 Test template keywords
2 ======================
2 ======================
3
3
4 $ hg init a
4 $ hg init a
5 $ cd a
5 $ cd a
6 $ echo a > a
6 $ echo a > a
7 $ hg add a
7 $ hg add a
8 $ echo line 1 > b
8 $ echo line 1 > b
9 $ echo line 2 >> b
9 $ echo line 2 >> b
10 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
10 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
11
11
12 $ hg add b
12 $ hg add b
13 $ echo other 1 > c
13 $ echo other 1 > c
14 $ echo other 2 >> c
14 $ echo other 2 >> c
15 $ echo >> c
15 $ echo >> c
16 $ echo other 3 >> c
16 $ echo other 3 >> c
17 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
17 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
18
18
19 $ hg add c
19 $ hg add c
20 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
20 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
21 $ echo c >> c
21 $ echo c >> c
22 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
22 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
23
23
24 $ echo foo > .hg/branch
24 $ echo foo > .hg/branch
25 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
25 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
26
26
27 $ hg co -q 3
27 $ hg co -q 3
28 $ echo other 4 >> d
28 $ echo other 4 >> d
29 $ hg add d
29 $ hg add d
30 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
30 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
31
31
32 $ hg merge -q foo
32 $ hg merge -q foo
33 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
33 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
34
34
35 Second branch starting at nullrev:
35 Second branch starting at nullrev:
36
36
37 $ hg update null
37 $ hg update null
38 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
38 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
39 $ echo second > second
39 $ echo second > second
40 $ hg add second
40 $ hg add second
41 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
41 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
42 created new head
42 created new head
43
43
44 $ echo third > third
44 $ echo third > third
45 $ hg add third
45 $ hg add third
46 $ hg mv second fourth
46 $ hg mv second fourth
47 $ hg commit -m third -d "2020-01-01 10:01"
47 $ hg commit -m third -d "2020-01-01 10:01"
48
48
49 Working-directory revision has special identifiers, though they are still
49 Working-directory revision has special identifiers, though they are still
50 experimental:
50 experimental:
51
51
52 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
52 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
53 2147483647:ffffffffffffffffffffffffffffffffffffffff
53 2147483647:ffffffffffffffffffffffffffffffffffffffff
54
54
55 Some keywords are invalid for working-directory revision, but they should
55 Some keywords are invalid for working-directory revision, but they should
56 never cause crash:
56 never cause crash:
57
57
58 $ hg log -r 'wdir()' -T '{manifest}\n'
58 $ hg log -r 'wdir()' -T '{manifest}\n'
59
59
60
60
61 Changectx-derived keywords are disabled within {manifest} as {node} changes:
62
63 $ hg log -r0 -T 'outer:{p1node} {manifest % "inner:{p1node}"}\n'
64 outer:0000000000000000000000000000000000000000 inner:
65
61 Check that {phase} works correctly on parents:
66 Check that {phase} works correctly on parents:
62
67
63 $ cat << EOF > parentphase
68 $ cat << EOF > parentphase
64 > changeset_debug = '{rev} ({phase}):{parents}\n'
69 > changeset_debug = '{rev} ({phase}):{parents}\n'
65 > parent = ' {rev} ({phase})'
70 > parent = ' {rev} ({phase})'
66 > EOF
71 > EOF
67 $ hg phase -r 5 --public
72 $ hg phase -r 5 --public
68 $ hg phase -r 7 --secret --force
73 $ hg phase -r 7 --secret --force
69 $ hg log --debug -G --style ./parentphase
74 $ hg log --debug -G --style ./parentphase
70 @ 8 (secret): 7 (secret) -1 (public)
75 @ 8 (secret): 7 (secret) -1 (public)
71 |
76 |
72 o 7 (secret): -1 (public) -1 (public)
77 o 7 (secret): -1 (public) -1 (public)
73
78
74 o 6 (draft): 5 (public) 4 (draft)
79 o 6 (draft): 5 (public) 4 (draft)
75 |\
80 |\
76 | o 5 (public): 3 (public) -1 (public)
81 | o 5 (public): 3 (public) -1 (public)
77 | |
82 | |
78 o | 4 (draft): 3 (public) -1 (public)
83 o | 4 (draft): 3 (public) -1 (public)
79 |/
84 |/
80 o 3 (public): 2 (public) -1 (public)
85 o 3 (public): 2 (public) -1 (public)
81 |
86 |
82 o 2 (public): 1 (public) -1 (public)
87 o 2 (public): 1 (public) -1 (public)
83 |
88 |
84 o 1 (public): 0 (public) -1 (public)
89 o 1 (public): 0 (public) -1 (public)
85 |
90 |
86 o 0 (public): -1 (public) -1 (public)
91 o 0 (public): -1 (public) -1 (public)
87
92
88
93
89 Keys work:
94 Keys work:
90
95
91 $ for key in author branch branches date desc file_adds file_dels file_mods \
96 $ for key in author branch branches date desc file_adds file_dels file_mods \
92 > file_copies file_copies_switch files \
97 > file_copies file_copies_switch files \
93 > manifest node parents rev tags diffstat extras \
98 > manifest node parents rev tags diffstat extras \
94 > p1rev p2rev p1node p2node user; do
99 > p1rev p2rev p1node p2node user; do
95 > for mode in '' --verbose --debug; do
100 > for mode in '' --verbose --debug; do
96 > hg log $mode --template "$key$mode: {$key}\n"
101 > hg log $mode --template "$key$mode: {$key}\n"
97 > done
102 > done
98 > done
103 > done
99 author: test
104 author: test
100 author: User Name <user@hostname>
105 author: User Name <user@hostname>
101 author: person
106 author: person
102 author: person
107 author: person
103 author: person
108 author: person
104 author: person
109 author: person
105 author: other@place
110 author: other@place
106 author: A. N. Other <other@place>
111 author: A. N. Other <other@place>
107 author: User Name <user@hostname>
112 author: User Name <user@hostname>
108 author--verbose: test
113 author--verbose: test
109 author--verbose: User Name <user@hostname>
114 author--verbose: User Name <user@hostname>
110 author--verbose: person
115 author--verbose: person
111 author--verbose: person
116 author--verbose: person
112 author--verbose: person
117 author--verbose: person
113 author--verbose: person
118 author--verbose: person
114 author--verbose: other@place
119 author--verbose: other@place
115 author--verbose: A. N. Other <other@place>
120 author--verbose: A. N. Other <other@place>
116 author--verbose: User Name <user@hostname>
121 author--verbose: User Name <user@hostname>
117 author--debug: test
122 author--debug: test
118 author--debug: User Name <user@hostname>
123 author--debug: User Name <user@hostname>
119 author--debug: person
124 author--debug: person
120 author--debug: person
125 author--debug: person
121 author--debug: person
126 author--debug: person
122 author--debug: person
127 author--debug: person
123 author--debug: other@place
128 author--debug: other@place
124 author--debug: A. N. Other <other@place>
129 author--debug: A. N. Other <other@place>
125 author--debug: User Name <user@hostname>
130 author--debug: User Name <user@hostname>
126 branch: default
131 branch: default
127 branch: default
132 branch: default
128 branch: default
133 branch: default
129 branch: default
134 branch: default
130 branch: foo
135 branch: foo
131 branch: default
136 branch: default
132 branch: default
137 branch: default
133 branch: default
138 branch: default
134 branch: default
139 branch: default
135 branch--verbose: default
140 branch--verbose: default
136 branch--verbose: default
141 branch--verbose: default
137 branch--verbose: default
142 branch--verbose: default
138 branch--verbose: default
143 branch--verbose: default
139 branch--verbose: foo
144 branch--verbose: foo
140 branch--verbose: default
145 branch--verbose: default
141 branch--verbose: default
146 branch--verbose: default
142 branch--verbose: default
147 branch--verbose: default
143 branch--verbose: default
148 branch--verbose: default
144 branch--debug: default
149 branch--debug: default
145 branch--debug: default
150 branch--debug: default
146 branch--debug: default
151 branch--debug: default
147 branch--debug: default
152 branch--debug: default
148 branch--debug: foo
153 branch--debug: foo
149 branch--debug: default
154 branch--debug: default
150 branch--debug: default
155 branch--debug: default
151 branch--debug: default
156 branch--debug: default
152 branch--debug: default
157 branch--debug: default
153 branches:
158 branches:
154 branches:
159 branches:
155 branches:
160 branches:
156 branches:
161 branches:
157 branches: foo
162 branches: foo
158 branches:
163 branches:
159 branches:
164 branches:
160 branches:
165 branches:
161 branches:
166 branches:
162 branches--verbose:
167 branches--verbose:
163 branches--verbose:
168 branches--verbose:
164 branches--verbose:
169 branches--verbose:
165 branches--verbose:
170 branches--verbose:
166 branches--verbose: foo
171 branches--verbose: foo
167 branches--verbose:
172 branches--verbose:
168 branches--verbose:
173 branches--verbose:
169 branches--verbose:
174 branches--verbose:
170 branches--verbose:
175 branches--verbose:
171 branches--debug:
176 branches--debug:
172 branches--debug:
177 branches--debug:
173 branches--debug:
178 branches--debug:
174 branches--debug:
179 branches--debug:
175 branches--debug: foo
180 branches--debug: foo
176 branches--debug:
181 branches--debug:
177 branches--debug:
182 branches--debug:
178 branches--debug:
183 branches--debug:
179 branches--debug:
184 branches--debug:
180 date: 1577872860.00
185 date: 1577872860.00
181 date: 1000000.00
186 date: 1000000.00
182 date: 1500001.00
187 date: 1500001.00
183 date: 1500000.00
188 date: 1500000.00
184 date: 1400000.00
189 date: 1400000.00
185 date: 1300000.00
190 date: 1300000.00
186 date: 1200000.00
191 date: 1200000.00
187 date: 1100000.00
192 date: 1100000.00
188 date: 1000000.00
193 date: 1000000.00
189 date--verbose: 1577872860.00
194 date--verbose: 1577872860.00
190 date--verbose: 1000000.00
195 date--verbose: 1000000.00
191 date--verbose: 1500001.00
196 date--verbose: 1500001.00
192 date--verbose: 1500000.00
197 date--verbose: 1500000.00
193 date--verbose: 1400000.00
198 date--verbose: 1400000.00
194 date--verbose: 1300000.00
199 date--verbose: 1300000.00
195 date--verbose: 1200000.00
200 date--verbose: 1200000.00
196 date--verbose: 1100000.00
201 date--verbose: 1100000.00
197 date--verbose: 1000000.00
202 date--verbose: 1000000.00
198 date--debug: 1577872860.00
203 date--debug: 1577872860.00
199 date--debug: 1000000.00
204 date--debug: 1000000.00
200 date--debug: 1500001.00
205 date--debug: 1500001.00
201 date--debug: 1500000.00
206 date--debug: 1500000.00
202 date--debug: 1400000.00
207 date--debug: 1400000.00
203 date--debug: 1300000.00
208 date--debug: 1300000.00
204 date--debug: 1200000.00
209 date--debug: 1200000.00
205 date--debug: 1100000.00
210 date--debug: 1100000.00
206 date--debug: 1000000.00
211 date--debug: 1000000.00
207 desc: third
212 desc: third
208 desc: second
213 desc: second
209 desc: merge
214 desc: merge
210 desc: new head
215 desc: new head
211 desc: new branch
216 desc: new branch
212 desc: no user, no domain
217 desc: no user, no domain
213 desc: no person
218 desc: no person
214 desc: other 1
219 desc: other 1
215 other 2
220 other 2
216
221
217 other 3
222 other 3
218 desc: line 1
223 desc: line 1
219 line 2
224 line 2
220 desc--verbose: third
225 desc--verbose: third
221 desc--verbose: second
226 desc--verbose: second
222 desc--verbose: merge
227 desc--verbose: merge
223 desc--verbose: new head
228 desc--verbose: new head
224 desc--verbose: new branch
229 desc--verbose: new branch
225 desc--verbose: no user, no domain
230 desc--verbose: no user, no domain
226 desc--verbose: no person
231 desc--verbose: no person
227 desc--verbose: other 1
232 desc--verbose: other 1
228 other 2
233 other 2
229
234
230 other 3
235 other 3
231 desc--verbose: line 1
236 desc--verbose: line 1
232 line 2
237 line 2
233 desc--debug: third
238 desc--debug: third
234 desc--debug: second
239 desc--debug: second
235 desc--debug: merge
240 desc--debug: merge
236 desc--debug: new head
241 desc--debug: new head
237 desc--debug: new branch
242 desc--debug: new branch
238 desc--debug: no user, no domain
243 desc--debug: no user, no domain
239 desc--debug: no person
244 desc--debug: no person
240 desc--debug: other 1
245 desc--debug: other 1
241 other 2
246 other 2
242
247
243 other 3
248 other 3
244 desc--debug: line 1
249 desc--debug: line 1
245 line 2
250 line 2
246 file_adds: fourth third
251 file_adds: fourth third
247 file_adds: second
252 file_adds: second
248 file_adds:
253 file_adds:
249 file_adds: d
254 file_adds: d
250 file_adds:
255 file_adds:
251 file_adds:
256 file_adds:
252 file_adds: c
257 file_adds: c
253 file_adds: b
258 file_adds: b
254 file_adds: a
259 file_adds: a
255 file_adds--verbose: fourth third
260 file_adds--verbose: fourth third
256 file_adds--verbose: second
261 file_adds--verbose: second
257 file_adds--verbose:
262 file_adds--verbose:
258 file_adds--verbose: d
263 file_adds--verbose: d
259 file_adds--verbose:
264 file_adds--verbose:
260 file_adds--verbose:
265 file_adds--verbose:
261 file_adds--verbose: c
266 file_adds--verbose: c
262 file_adds--verbose: b
267 file_adds--verbose: b
263 file_adds--verbose: a
268 file_adds--verbose: a
264 file_adds--debug: fourth third
269 file_adds--debug: fourth third
265 file_adds--debug: second
270 file_adds--debug: second
266 file_adds--debug:
271 file_adds--debug:
267 file_adds--debug: d
272 file_adds--debug: d
268 file_adds--debug:
273 file_adds--debug:
269 file_adds--debug:
274 file_adds--debug:
270 file_adds--debug: c
275 file_adds--debug: c
271 file_adds--debug: b
276 file_adds--debug: b
272 file_adds--debug: a
277 file_adds--debug: a
273 file_dels: second
278 file_dels: second
274 file_dels:
279 file_dels:
275 file_dels:
280 file_dels:
276 file_dels:
281 file_dels:
277 file_dels:
282 file_dels:
278 file_dels:
283 file_dels:
279 file_dels:
284 file_dels:
280 file_dels:
285 file_dels:
281 file_dels:
286 file_dels:
282 file_dels--verbose: second
287 file_dels--verbose: second
283 file_dels--verbose:
288 file_dels--verbose:
284 file_dels--verbose:
289 file_dels--verbose:
285 file_dels--verbose:
290 file_dels--verbose:
286 file_dels--verbose:
291 file_dels--verbose:
287 file_dels--verbose:
292 file_dels--verbose:
288 file_dels--verbose:
293 file_dels--verbose:
289 file_dels--verbose:
294 file_dels--verbose:
290 file_dels--verbose:
295 file_dels--verbose:
291 file_dels--debug: second
296 file_dels--debug: second
292 file_dels--debug:
297 file_dels--debug:
293 file_dels--debug:
298 file_dels--debug:
294 file_dels--debug:
299 file_dels--debug:
295 file_dels--debug:
300 file_dels--debug:
296 file_dels--debug:
301 file_dels--debug:
297 file_dels--debug:
302 file_dels--debug:
298 file_dels--debug:
303 file_dels--debug:
299 file_dels--debug:
304 file_dels--debug:
300 file_mods:
305 file_mods:
301 file_mods:
306 file_mods:
302 file_mods:
307 file_mods:
303 file_mods:
308 file_mods:
304 file_mods:
309 file_mods:
305 file_mods: c
310 file_mods: c
306 file_mods:
311 file_mods:
307 file_mods:
312 file_mods:
308 file_mods:
313 file_mods:
309 file_mods--verbose:
314 file_mods--verbose:
310 file_mods--verbose:
315 file_mods--verbose:
311 file_mods--verbose:
316 file_mods--verbose:
312 file_mods--verbose:
317 file_mods--verbose:
313 file_mods--verbose:
318 file_mods--verbose:
314 file_mods--verbose: c
319 file_mods--verbose: c
315 file_mods--verbose:
320 file_mods--verbose:
316 file_mods--verbose:
321 file_mods--verbose:
317 file_mods--verbose:
322 file_mods--verbose:
318 file_mods--debug:
323 file_mods--debug:
319 file_mods--debug:
324 file_mods--debug:
320 file_mods--debug:
325 file_mods--debug:
321 file_mods--debug:
326 file_mods--debug:
322 file_mods--debug:
327 file_mods--debug:
323 file_mods--debug: c
328 file_mods--debug: c
324 file_mods--debug:
329 file_mods--debug:
325 file_mods--debug:
330 file_mods--debug:
326 file_mods--debug:
331 file_mods--debug:
327 file_copies: fourth (second)
332 file_copies: fourth (second)
328 file_copies:
333 file_copies:
329 file_copies:
334 file_copies:
330 file_copies:
335 file_copies:
331 file_copies:
336 file_copies:
332 file_copies:
337 file_copies:
333 file_copies:
338 file_copies:
334 file_copies:
339 file_copies:
335 file_copies:
340 file_copies:
336 file_copies--verbose: fourth (second)
341 file_copies--verbose: fourth (second)
337 file_copies--verbose:
342 file_copies--verbose:
338 file_copies--verbose:
343 file_copies--verbose:
339 file_copies--verbose:
344 file_copies--verbose:
340 file_copies--verbose:
345 file_copies--verbose:
341 file_copies--verbose:
346 file_copies--verbose:
342 file_copies--verbose:
347 file_copies--verbose:
343 file_copies--verbose:
348 file_copies--verbose:
344 file_copies--verbose:
349 file_copies--verbose:
345 file_copies--debug: fourth (second)
350 file_copies--debug: fourth (second)
346 file_copies--debug:
351 file_copies--debug:
347 file_copies--debug:
352 file_copies--debug:
348 file_copies--debug:
353 file_copies--debug:
349 file_copies--debug:
354 file_copies--debug:
350 file_copies--debug:
355 file_copies--debug:
351 file_copies--debug:
356 file_copies--debug:
352 file_copies--debug:
357 file_copies--debug:
353 file_copies--debug:
358 file_copies--debug:
354 file_copies_switch:
359 file_copies_switch:
355 file_copies_switch:
360 file_copies_switch:
356 file_copies_switch:
361 file_copies_switch:
357 file_copies_switch:
362 file_copies_switch:
358 file_copies_switch:
363 file_copies_switch:
359 file_copies_switch:
364 file_copies_switch:
360 file_copies_switch:
365 file_copies_switch:
361 file_copies_switch:
366 file_copies_switch:
362 file_copies_switch:
367 file_copies_switch:
363 file_copies_switch--verbose:
368 file_copies_switch--verbose:
364 file_copies_switch--verbose:
369 file_copies_switch--verbose:
365 file_copies_switch--verbose:
370 file_copies_switch--verbose:
366 file_copies_switch--verbose:
371 file_copies_switch--verbose:
367 file_copies_switch--verbose:
372 file_copies_switch--verbose:
368 file_copies_switch--verbose:
373 file_copies_switch--verbose:
369 file_copies_switch--verbose:
374 file_copies_switch--verbose:
370 file_copies_switch--verbose:
375 file_copies_switch--verbose:
371 file_copies_switch--verbose:
376 file_copies_switch--verbose:
372 file_copies_switch--debug:
377 file_copies_switch--debug:
373 file_copies_switch--debug:
378 file_copies_switch--debug:
374 file_copies_switch--debug:
379 file_copies_switch--debug:
375 file_copies_switch--debug:
380 file_copies_switch--debug:
376 file_copies_switch--debug:
381 file_copies_switch--debug:
377 file_copies_switch--debug:
382 file_copies_switch--debug:
378 file_copies_switch--debug:
383 file_copies_switch--debug:
379 file_copies_switch--debug:
384 file_copies_switch--debug:
380 file_copies_switch--debug:
385 file_copies_switch--debug:
381 files: fourth second third
386 files: fourth second third
382 files: second
387 files: second
383 files:
388 files:
384 files: d
389 files: d
385 files:
390 files:
386 files: c
391 files: c
387 files: c
392 files: c
388 files: b
393 files: b
389 files: a
394 files: a
390 files--verbose: fourth second third
395 files--verbose: fourth second third
391 files--verbose: second
396 files--verbose: second
392 files--verbose:
397 files--verbose:
393 files--verbose: d
398 files--verbose: d
394 files--verbose:
399 files--verbose:
395 files--verbose: c
400 files--verbose: c
396 files--verbose: c
401 files--verbose: c
397 files--verbose: b
402 files--verbose: b
398 files--verbose: a
403 files--verbose: a
399 files--debug: fourth second third
404 files--debug: fourth second third
400 files--debug: second
405 files--debug: second
401 files--debug:
406 files--debug:
402 files--debug: d
407 files--debug: d
403 files--debug:
408 files--debug:
404 files--debug: c
409 files--debug: c
405 files--debug: c
410 files--debug: c
406 files--debug: b
411 files--debug: b
407 files--debug: a
412 files--debug: a
408 manifest: 6:94961b75a2da
413 manifest: 6:94961b75a2da
409 manifest: 5:f2dbc354b94e
414 manifest: 5:f2dbc354b94e
410 manifest: 4:4dc3def4f9b4
415 manifest: 4:4dc3def4f9b4
411 manifest: 4:4dc3def4f9b4
416 manifest: 4:4dc3def4f9b4
412 manifest: 3:cb5a1327723b
417 manifest: 3:cb5a1327723b
413 manifest: 3:cb5a1327723b
418 manifest: 3:cb5a1327723b
414 manifest: 2:6e0e82995c35
419 manifest: 2:6e0e82995c35
415 manifest: 1:4e8d705b1e53
420 manifest: 1:4e8d705b1e53
416 manifest: 0:a0c8bcbbb45c
421 manifest: 0:a0c8bcbbb45c
417 manifest--verbose: 6:94961b75a2da
422 manifest--verbose: 6:94961b75a2da
418 manifest--verbose: 5:f2dbc354b94e
423 manifest--verbose: 5:f2dbc354b94e
419 manifest--verbose: 4:4dc3def4f9b4
424 manifest--verbose: 4:4dc3def4f9b4
420 manifest--verbose: 4:4dc3def4f9b4
425 manifest--verbose: 4:4dc3def4f9b4
421 manifest--verbose: 3:cb5a1327723b
426 manifest--verbose: 3:cb5a1327723b
422 manifest--verbose: 3:cb5a1327723b
427 manifest--verbose: 3:cb5a1327723b
423 manifest--verbose: 2:6e0e82995c35
428 manifest--verbose: 2:6e0e82995c35
424 manifest--verbose: 1:4e8d705b1e53
429 manifest--verbose: 1:4e8d705b1e53
425 manifest--verbose: 0:a0c8bcbbb45c
430 manifest--verbose: 0:a0c8bcbbb45c
426 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
431 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
427 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
432 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
428 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
433 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
429 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
434 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
430 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
435 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
431 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
436 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
432 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
437 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
433 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
438 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
434 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
439 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
435 node: 95c24699272ef57d062b8bccc32c878bf841784a
440 node: 95c24699272ef57d062b8bccc32c878bf841784a
436 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
441 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
437 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
442 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
438 node: 13207e5a10d9fd28ec424934298e176197f2c67f
443 node: 13207e5a10d9fd28ec424934298e176197f2c67f
439 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
444 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
440 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
445 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
441 node: 97054abb4ab824450e9164180baf491ae0078465
446 node: 97054abb4ab824450e9164180baf491ae0078465
442 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
447 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
443 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
448 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
444 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
449 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
445 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
450 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
446 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
451 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
447 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
452 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
448 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
453 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
449 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
454 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
450 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
455 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
451 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
456 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
452 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
457 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
453 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
458 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
454 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
459 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
455 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
460 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
456 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
461 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
457 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
462 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
458 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
463 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
459 node--debug: 97054abb4ab824450e9164180baf491ae0078465
464 node--debug: 97054abb4ab824450e9164180baf491ae0078465
460 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
465 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
461 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
466 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
462 parents:
467 parents:
463 parents: -1:000000000000
468 parents: -1:000000000000
464 parents: 5:13207e5a10d9 4:bbe44766e73d
469 parents: 5:13207e5a10d9 4:bbe44766e73d
465 parents: 3:10e46f2dcbf4
470 parents: 3:10e46f2dcbf4
466 parents:
471 parents:
467 parents:
472 parents:
468 parents:
473 parents:
469 parents:
474 parents:
470 parents:
475 parents:
471 parents--verbose:
476 parents--verbose:
472 parents--verbose: -1:000000000000
477 parents--verbose: -1:000000000000
473 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
478 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
474 parents--verbose: 3:10e46f2dcbf4
479 parents--verbose: 3:10e46f2dcbf4
475 parents--verbose:
480 parents--verbose:
476 parents--verbose:
481 parents--verbose:
477 parents--verbose:
482 parents--verbose:
478 parents--verbose:
483 parents--verbose:
479 parents--verbose:
484 parents--verbose:
480 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
485 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
481 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
486 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
482 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
487 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
483 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
488 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
484 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
489 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
485 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
490 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
486 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
491 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
487 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
492 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
488 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
493 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
489 rev: 8
494 rev: 8
490 rev: 7
495 rev: 7
491 rev: 6
496 rev: 6
492 rev: 5
497 rev: 5
493 rev: 4
498 rev: 4
494 rev: 3
499 rev: 3
495 rev: 2
500 rev: 2
496 rev: 1
501 rev: 1
497 rev: 0
502 rev: 0
498 rev--verbose: 8
503 rev--verbose: 8
499 rev--verbose: 7
504 rev--verbose: 7
500 rev--verbose: 6
505 rev--verbose: 6
501 rev--verbose: 5
506 rev--verbose: 5
502 rev--verbose: 4
507 rev--verbose: 4
503 rev--verbose: 3
508 rev--verbose: 3
504 rev--verbose: 2
509 rev--verbose: 2
505 rev--verbose: 1
510 rev--verbose: 1
506 rev--verbose: 0
511 rev--verbose: 0
507 rev--debug: 8
512 rev--debug: 8
508 rev--debug: 7
513 rev--debug: 7
509 rev--debug: 6
514 rev--debug: 6
510 rev--debug: 5
515 rev--debug: 5
511 rev--debug: 4
516 rev--debug: 4
512 rev--debug: 3
517 rev--debug: 3
513 rev--debug: 2
518 rev--debug: 2
514 rev--debug: 1
519 rev--debug: 1
515 rev--debug: 0
520 rev--debug: 0
516 tags: tip
521 tags: tip
517 tags:
522 tags:
518 tags:
523 tags:
519 tags:
524 tags:
520 tags:
525 tags:
521 tags:
526 tags:
522 tags:
527 tags:
523 tags:
528 tags:
524 tags:
529 tags:
525 tags--verbose: tip
530 tags--verbose: tip
526 tags--verbose:
531 tags--verbose:
527 tags--verbose:
532 tags--verbose:
528 tags--verbose:
533 tags--verbose:
529 tags--verbose:
534 tags--verbose:
530 tags--verbose:
535 tags--verbose:
531 tags--verbose:
536 tags--verbose:
532 tags--verbose:
537 tags--verbose:
533 tags--verbose:
538 tags--verbose:
534 tags--debug: tip
539 tags--debug: tip
535 tags--debug:
540 tags--debug:
536 tags--debug:
541 tags--debug:
537 tags--debug:
542 tags--debug:
538 tags--debug:
543 tags--debug:
539 tags--debug:
544 tags--debug:
540 tags--debug:
545 tags--debug:
541 tags--debug:
546 tags--debug:
542 tags--debug:
547 tags--debug:
543 diffstat: 3: +2/-1
548 diffstat: 3: +2/-1
544 diffstat: 1: +1/-0
549 diffstat: 1: +1/-0
545 diffstat: 0: +0/-0
550 diffstat: 0: +0/-0
546 diffstat: 1: +1/-0
551 diffstat: 1: +1/-0
547 diffstat: 0: +0/-0
552 diffstat: 0: +0/-0
548 diffstat: 1: +1/-0
553 diffstat: 1: +1/-0
549 diffstat: 1: +4/-0
554 diffstat: 1: +4/-0
550 diffstat: 1: +2/-0
555 diffstat: 1: +2/-0
551 diffstat: 1: +1/-0
556 diffstat: 1: +1/-0
552 diffstat--verbose: 3: +2/-1
557 diffstat--verbose: 3: +2/-1
553 diffstat--verbose: 1: +1/-0
558 diffstat--verbose: 1: +1/-0
554 diffstat--verbose: 0: +0/-0
559 diffstat--verbose: 0: +0/-0
555 diffstat--verbose: 1: +1/-0
560 diffstat--verbose: 1: +1/-0
556 diffstat--verbose: 0: +0/-0
561 diffstat--verbose: 0: +0/-0
557 diffstat--verbose: 1: +1/-0
562 diffstat--verbose: 1: +1/-0
558 diffstat--verbose: 1: +4/-0
563 diffstat--verbose: 1: +4/-0
559 diffstat--verbose: 1: +2/-0
564 diffstat--verbose: 1: +2/-0
560 diffstat--verbose: 1: +1/-0
565 diffstat--verbose: 1: +1/-0
561 diffstat--debug: 3: +2/-1
566 diffstat--debug: 3: +2/-1
562 diffstat--debug: 1: +1/-0
567 diffstat--debug: 1: +1/-0
563 diffstat--debug: 0: +0/-0
568 diffstat--debug: 0: +0/-0
564 diffstat--debug: 1: +1/-0
569 diffstat--debug: 1: +1/-0
565 diffstat--debug: 0: +0/-0
570 diffstat--debug: 0: +0/-0
566 diffstat--debug: 1: +1/-0
571 diffstat--debug: 1: +1/-0
567 diffstat--debug: 1: +4/-0
572 diffstat--debug: 1: +4/-0
568 diffstat--debug: 1: +2/-0
573 diffstat--debug: 1: +2/-0
569 diffstat--debug: 1: +1/-0
574 diffstat--debug: 1: +1/-0
570 extras: branch=default
575 extras: branch=default
571 extras: branch=default
576 extras: branch=default
572 extras: branch=default
577 extras: branch=default
573 extras: branch=default
578 extras: branch=default
574 extras: branch=foo
579 extras: branch=foo
575 extras: branch=default
580 extras: branch=default
576 extras: branch=default
581 extras: branch=default
577 extras: branch=default
582 extras: branch=default
578 extras: branch=default
583 extras: branch=default
579 extras--verbose: branch=default
584 extras--verbose: branch=default
580 extras--verbose: branch=default
585 extras--verbose: branch=default
581 extras--verbose: branch=default
586 extras--verbose: branch=default
582 extras--verbose: branch=default
587 extras--verbose: branch=default
583 extras--verbose: branch=foo
588 extras--verbose: branch=foo
584 extras--verbose: branch=default
589 extras--verbose: branch=default
585 extras--verbose: branch=default
590 extras--verbose: branch=default
586 extras--verbose: branch=default
591 extras--verbose: branch=default
587 extras--verbose: branch=default
592 extras--verbose: branch=default
588 extras--debug: branch=default
593 extras--debug: branch=default
589 extras--debug: branch=default
594 extras--debug: branch=default
590 extras--debug: branch=default
595 extras--debug: branch=default
591 extras--debug: branch=default
596 extras--debug: branch=default
592 extras--debug: branch=foo
597 extras--debug: branch=foo
593 extras--debug: branch=default
598 extras--debug: branch=default
594 extras--debug: branch=default
599 extras--debug: branch=default
595 extras--debug: branch=default
600 extras--debug: branch=default
596 extras--debug: branch=default
601 extras--debug: branch=default
597 p1rev: 7
602 p1rev: 7
598 p1rev: -1
603 p1rev: -1
599 p1rev: 5
604 p1rev: 5
600 p1rev: 3
605 p1rev: 3
601 p1rev: 3
606 p1rev: 3
602 p1rev: 2
607 p1rev: 2
603 p1rev: 1
608 p1rev: 1
604 p1rev: 0
609 p1rev: 0
605 p1rev: -1
610 p1rev: -1
606 p1rev--verbose: 7
611 p1rev--verbose: 7
607 p1rev--verbose: -1
612 p1rev--verbose: -1
608 p1rev--verbose: 5
613 p1rev--verbose: 5
609 p1rev--verbose: 3
614 p1rev--verbose: 3
610 p1rev--verbose: 3
615 p1rev--verbose: 3
611 p1rev--verbose: 2
616 p1rev--verbose: 2
612 p1rev--verbose: 1
617 p1rev--verbose: 1
613 p1rev--verbose: 0
618 p1rev--verbose: 0
614 p1rev--verbose: -1
619 p1rev--verbose: -1
615 p1rev--debug: 7
620 p1rev--debug: 7
616 p1rev--debug: -1
621 p1rev--debug: -1
617 p1rev--debug: 5
622 p1rev--debug: 5
618 p1rev--debug: 3
623 p1rev--debug: 3
619 p1rev--debug: 3
624 p1rev--debug: 3
620 p1rev--debug: 2
625 p1rev--debug: 2
621 p1rev--debug: 1
626 p1rev--debug: 1
622 p1rev--debug: 0
627 p1rev--debug: 0
623 p1rev--debug: -1
628 p1rev--debug: -1
624 p2rev: -1
629 p2rev: -1
625 p2rev: -1
630 p2rev: -1
626 p2rev: 4
631 p2rev: 4
627 p2rev: -1
632 p2rev: -1
628 p2rev: -1
633 p2rev: -1
629 p2rev: -1
634 p2rev: -1
630 p2rev: -1
635 p2rev: -1
631 p2rev: -1
636 p2rev: -1
632 p2rev: -1
637 p2rev: -1
633 p2rev--verbose: -1
638 p2rev--verbose: -1
634 p2rev--verbose: -1
639 p2rev--verbose: -1
635 p2rev--verbose: 4
640 p2rev--verbose: 4
636 p2rev--verbose: -1
641 p2rev--verbose: -1
637 p2rev--verbose: -1
642 p2rev--verbose: -1
638 p2rev--verbose: -1
643 p2rev--verbose: -1
639 p2rev--verbose: -1
644 p2rev--verbose: -1
640 p2rev--verbose: -1
645 p2rev--verbose: -1
641 p2rev--verbose: -1
646 p2rev--verbose: -1
642 p2rev--debug: -1
647 p2rev--debug: -1
643 p2rev--debug: -1
648 p2rev--debug: -1
644 p2rev--debug: 4
649 p2rev--debug: 4
645 p2rev--debug: -1
650 p2rev--debug: -1
646 p2rev--debug: -1
651 p2rev--debug: -1
647 p2rev--debug: -1
652 p2rev--debug: -1
648 p2rev--debug: -1
653 p2rev--debug: -1
649 p2rev--debug: -1
654 p2rev--debug: -1
650 p2rev--debug: -1
655 p2rev--debug: -1
651 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
656 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
652 p1node: 0000000000000000000000000000000000000000
657 p1node: 0000000000000000000000000000000000000000
653 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
658 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
654 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
659 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
655 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
660 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
656 p1node: 97054abb4ab824450e9164180baf491ae0078465
661 p1node: 97054abb4ab824450e9164180baf491ae0078465
657 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
662 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
658 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
663 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
659 p1node: 0000000000000000000000000000000000000000
664 p1node: 0000000000000000000000000000000000000000
660 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
665 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
661 p1node--verbose: 0000000000000000000000000000000000000000
666 p1node--verbose: 0000000000000000000000000000000000000000
662 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
667 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
663 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
668 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
664 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
669 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
665 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
670 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
666 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
671 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
667 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
672 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
668 p1node--verbose: 0000000000000000000000000000000000000000
673 p1node--verbose: 0000000000000000000000000000000000000000
669 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
674 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
670 p1node--debug: 0000000000000000000000000000000000000000
675 p1node--debug: 0000000000000000000000000000000000000000
671 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
676 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
672 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
677 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
673 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
678 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
674 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
679 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
675 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
680 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
676 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
681 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
677 p1node--debug: 0000000000000000000000000000000000000000
682 p1node--debug: 0000000000000000000000000000000000000000
678 p2node: 0000000000000000000000000000000000000000
683 p2node: 0000000000000000000000000000000000000000
679 p2node: 0000000000000000000000000000000000000000
684 p2node: 0000000000000000000000000000000000000000
680 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
685 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
681 p2node: 0000000000000000000000000000000000000000
686 p2node: 0000000000000000000000000000000000000000
682 p2node: 0000000000000000000000000000000000000000
687 p2node: 0000000000000000000000000000000000000000
683 p2node: 0000000000000000000000000000000000000000
688 p2node: 0000000000000000000000000000000000000000
684 p2node: 0000000000000000000000000000000000000000
689 p2node: 0000000000000000000000000000000000000000
685 p2node: 0000000000000000000000000000000000000000
690 p2node: 0000000000000000000000000000000000000000
686 p2node: 0000000000000000000000000000000000000000
691 p2node: 0000000000000000000000000000000000000000
687 p2node--verbose: 0000000000000000000000000000000000000000
692 p2node--verbose: 0000000000000000000000000000000000000000
688 p2node--verbose: 0000000000000000000000000000000000000000
693 p2node--verbose: 0000000000000000000000000000000000000000
689 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
694 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
690 p2node--verbose: 0000000000000000000000000000000000000000
695 p2node--verbose: 0000000000000000000000000000000000000000
691 p2node--verbose: 0000000000000000000000000000000000000000
696 p2node--verbose: 0000000000000000000000000000000000000000
692 p2node--verbose: 0000000000000000000000000000000000000000
697 p2node--verbose: 0000000000000000000000000000000000000000
693 p2node--verbose: 0000000000000000000000000000000000000000
698 p2node--verbose: 0000000000000000000000000000000000000000
694 p2node--verbose: 0000000000000000000000000000000000000000
699 p2node--verbose: 0000000000000000000000000000000000000000
695 p2node--verbose: 0000000000000000000000000000000000000000
700 p2node--verbose: 0000000000000000000000000000000000000000
696 p2node--debug: 0000000000000000000000000000000000000000
701 p2node--debug: 0000000000000000000000000000000000000000
697 p2node--debug: 0000000000000000000000000000000000000000
702 p2node--debug: 0000000000000000000000000000000000000000
698 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
703 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
699 p2node--debug: 0000000000000000000000000000000000000000
704 p2node--debug: 0000000000000000000000000000000000000000
700 p2node--debug: 0000000000000000000000000000000000000000
705 p2node--debug: 0000000000000000000000000000000000000000
701 p2node--debug: 0000000000000000000000000000000000000000
706 p2node--debug: 0000000000000000000000000000000000000000
702 p2node--debug: 0000000000000000000000000000000000000000
707 p2node--debug: 0000000000000000000000000000000000000000
703 p2node--debug: 0000000000000000000000000000000000000000
708 p2node--debug: 0000000000000000000000000000000000000000
704 p2node--debug: 0000000000000000000000000000000000000000
709 p2node--debug: 0000000000000000000000000000000000000000
705 user: test
710 user: test
706 user: User Name <user@hostname>
711 user: User Name <user@hostname>
707 user: person
712 user: person
708 user: person
713 user: person
709 user: person
714 user: person
710 user: person
715 user: person
711 user: other@place
716 user: other@place
712 user: A. N. Other <other@place>
717 user: A. N. Other <other@place>
713 user: User Name <user@hostname>
718 user: User Name <user@hostname>
714 user--verbose: test
719 user--verbose: test
715 user--verbose: User Name <user@hostname>
720 user--verbose: User Name <user@hostname>
716 user--verbose: person
721 user--verbose: person
717 user--verbose: person
722 user--verbose: person
718 user--verbose: person
723 user--verbose: person
719 user--verbose: person
724 user--verbose: person
720 user--verbose: other@place
725 user--verbose: other@place
721 user--verbose: A. N. Other <other@place>
726 user--verbose: A. N. Other <other@place>
722 user--verbose: User Name <user@hostname>
727 user--verbose: User Name <user@hostname>
723 user--debug: test
728 user--debug: test
724 user--debug: User Name <user@hostname>
729 user--debug: User Name <user@hostname>
725 user--debug: person
730 user--debug: person
726 user--debug: person
731 user--debug: person
727 user--debug: person
732 user--debug: person
728 user--debug: person
733 user--debug: person
729 user--debug: other@place
734 user--debug: other@place
730 user--debug: A. N. Other <other@place>
735 user--debug: A. N. Other <other@place>
731 user--debug: User Name <user@hostname>
736 user--debug: User Name <user@hostname>
732
737
733 Add a dummy commit to make up for the instability of the above:
738 Add a dummy commit to make up for the instability of the above:
734
739
735 $ echo a > a
740 $ echo a > a
736 $ hg add a
741 $ hg add a
737 $ hg ci -m future
742 $ hg ci -m future
738
743
739 Add a commit that does all possible modifications at once
744 Add a commit that does all possible modifications at once
740
745
741 $ echo modify >> third
746 $ echo modify >> third
742 $ touch b
747 $ touch b
743 $ hg add b
748 $ hg add b
744 $ hg mv fourth fifth
749 $ hg mv fourth fifth
745 $ hg rm a
750 $ hg rm a
746 $ hg ci -m "Modify, add, remove, rename"
751 $ hg ci -m "Modify, add, remove, rename"
747
752
748 Test files list:
753 Test files list:
749
754
750 $ hg log -l1 -T '{join(file_mods, " ")}\n'
755 $ hg log -l1 -T '{join(file_mods, " ")}\n'
751 third
756 third
752 $ hg log -l1 -T '{file_mods % "{file}\n"}'
757 $ hg log -l1 -T '{file_mods % "{file}\n"}'
753 third
758 third
754 $ hg log -l1 -T '{file_mods % "{path}\n"}'
759 $ hg log -l1 -T '{file_mods % "{path}\n"}'
755 third
760 third
756
761
757 $ hg log -l1 -T '{join(files, " ")}\n'
762 $ hg log -l1 -T '{join(files, " ")}\n'
758 a b fifth fourth third
763 a b fifth fourth third
759 $ hg log -l1 -T '{files % "{file}\n"}'
764 $ hg log -l1 -T '{files % "{file}\n"}'
760 a
765 a
761 b
766 b
762 fifth
767 fifth
763 fourth
768 fourth
764 third
769 third
765 $ hg log -l1 -T '{files % "{path}\n"}'
770 $ hg log -l1 -T '{files % "{path}\n"}'
766 a
771 a
767 b
772 b
768 fifth
773 fifth
769 fourth
774 fourth
770 third
775 third
771
776
772 Test file copies dict:
777 Test file copies dict:
773
778
774 $ hg log -r8 -T '{join(file_copies, " ")}\n'
779 $ hg log -r8 -T '{join(file_copies, " ")}\n'
775 fourth (second)
780 fourth (second)
776 $ hg log -r8 -T '{file_copies % "{name} <- {source}\n"}'
781 $ hg log -r8 -T '{file_copies % "{name} <- {source}\n"}'
777 fourth <- second
782 fourth <- second
778 $ hg log -r8 -T '{file_copies % "{path} <- {source}\n"}'
783 $ hg log -r8 -T '{file_copies % "{path} <- {source}\n"}'
779 fourth <- second
784 fourth <- second
780
785
781 $ hg log -r8 -T '{join(file_copies_switch, " ")}\n'
786 $ hg log -r8 -T '{join(file_copies_switch, " ")}\n'
782
787
783 $ hg log -r8 -C -T '{join(file_copies_switch, " ")}\n'
788 $ hg log -r8 -C -T '{join(file_copies_switch, " ")}\n'
784 fourth (second)
789 fourth (second)
785 $ hg log -r8 -C -T '{file_copies_switch % "{name} <- {source}\n"}'
790 $ hg log -r8 -C -T '{file_copies_switch % "{name} <- {source}\n"}'
786 fourth <- second
791 fourth <- second
787 $ hg log -r8 -C -T '{file_copies_switch % "{path} <- {source}\n"}'
792 $ hg log -r8 -C -T '{file_copies_switch % "{path} <- {source}\n"}'
788 fourth <- second
793 fourth <- second
789
794
790 Test file attributes:
795 Test file attributes:
791
796
792 $ hg log -l1 -T '{files % "{status} {pad(size, 3, left=True)} {path}\n"}'
797 $ hg log -l1 -T '{files % "{status} {pad(size, 3, left=True)} {path}\n"}'
793 R a
798 R a
794 A 0 b
799 A 0 b
795 A 7 fifth
800 A 7 fifth
796 R fourth
801 R fourth
797 M 13 third
802 M 13 third
798
803
799 Test file status including clean ones:
804 Test file status including clean ones:
800
805
801 $ hg log -r9 -T '{files("**") % "{status} {path}\n"}'
806 $ hg log -r9 -T '{files("**") % "{status} {path}\n"}'
802 A a
807 A a
803 C fourth
808 C fourth
804 C third
809 C third
805
810
806 Test index keyword:
811 Test index keyword:
807
812
808 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
813 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
809 10 0:a 1:b 2:fifth 3:fourth 4:third
814 10 0:a 1:b 2:fifth 3:fourth 4:third
810 11 0:a
815 11 0:a
811
816
812 $ hg branches -T '{index} {branch}\n'
817 $ hg branches -T '{index} {branch}\n'
813 0 default
818 0 default
814 1 foo
819 1 foo
815
820
816 ui verbosity:
821 ui verbosity:
817
822
818 $ hg log -l1 -T '{verbosity}\n'
823 $ hg log -l1 -T '{verbosity}\n'
819
824
820 $ hg log -l1 -T '{verbosity}\n' --debug
825 $ hg log -l1 -T '{verbosity}\n' --debug
821 debug
826 debug
822 $ hg log -l1 -T '{verbosity}\n' --quiet
827 $ hg log -l1 -T '{verbosity}\n' --quiet
823 quiet
828 quiet
824 $ hg log -l1 -T '{verbosity}\n' --verbose
829 $ hg log -l1 -T '{verbosity}\n' --verbose
825 verbose
830 verbose
826
831
827 $ cd ..
832 $ cd ..
828
833
829 latesttag:
834 latesttag:
830
835
831 $ hg init latesttag
836 $ hg init latesttag
832 $ cd latesttag
837 $ cd latesttag
833
838
834 $ echo a > file
839 $ echo a > file
835 $ hg ci -Am a -d '0 0'
840 $ hg ci -Am a -d '0 0'
836 adding file
841 adding file
837
842
838 $ echo b >> file
843 $ echo b >> file
839 $ hg ci -m b -d '1 0'
844 $ hg ci -m b -d '1 0'
840
845
841 $ echo c >> head1
846 $ echo c >> head1
842 $ hg ci -Am h1c -d '2 0'
847 $ hg ci -Am h1c -d '2 0'
843 adding head1
848 adding head1
844
849
845 $ hg update -q 1
850 $ hg update -q 1
846 $ echo d >> head2
851 $ echo d >> head2
847 $ hg ci -Am h2d -d '3 0'
852 $ hg ci -Am h2d -d '3 0'
848 adding head2
853 adding head2
849 created new head
854 created new head
850
855
851 $ echo e >> head2
856 $ echo e >> head2
852 $ hg ci -m h2e -d '4 0'
857 $ hg ci -m h2e -d '4 0'
853
858
854 $ hg merge -q
859 $ hg merge -q
855 $ hg ci -m merge -d '5 -3600'
860 $ hg ci -m merge -d '5 -3600'
856
861
857 No tag set:
862 No tag set:
858
863
859 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
864 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
860 @ 5: null+5
865 @ 5: null+5
861 |\
866 |\
862 | o 4: null+4
867 | o 4: null+4
863 | |
868 | |
864 | o 3: null+3
869 | o 3: null+3
865 | |
870 | |
866 o | 2: null+3
871 o | 2: null+3
867 |/
872 |/
868 o 1: null+2
873 o 1: null+2
869 |
874 |
870 o 0: null+1
875 o 0: null+1
871
876
872
877
873 One common tag: longest path wins for {latesttagdistance}:
878 One common tag: longest path wins for {latesttagdistance}:
874
879
875 $ hg tag -r 1 -m t1 -d '6 0' t1
880 $ hg tag -r 1 -m t1 -d '6 0' t1
876 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
881 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
877 @ 6: t1+4
882 @ 6: t1+4
878 |
883 |
879 o 5: t1+3
884 o 5: t1+3
880 |\
885 |\
881 | o 4: t1+2
886 | o 4: t1+2
882 | |
887 | |
883 | o 3: t1+1
888 | o 3: t1+1
884 | |
889 | |
885 o | 2: t1+1
890 o | 2: t1+1
886 |/
891 |/
887 o 1: t1+0
892 o 1: t1+0
888 |
893 |
889 o 0: null+1
894 o 0: null+1
890
895
891
896
892 One ancestor tag: closest wins:
897 One ancestor tag: closest wins:
893
898
894 $ hg tag -r 2 -m t2 -d '7 0' t2
899 $ hg tag -r 2 -m t2 -d '7 0' t2
895 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
900 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
896 @ 7: t2+3
901 @ 7: t2+3
897 |
902 |
898 o 6: t2+2
903 o 6: t2+2
899 |
904 |
900 o 5: t2+1
905 o 5: t2+1
901 |\
906 |\
902 | o 4: t1+2
907 | o 4: t1+2
903 | |
908 | |
904 | o 3: t1+1
909 | o 3: t1+1
905 | |
910 | |
906 o | 2: t2+0
911 o | 2: t2+0
907 |/
912 |/
908 o 1: t1+0
913 o 1: t1+0
909 |
914 |
910 o 0: null+1
915 o 0: null+1
911
916
912
917
913 Two branch tags: more recent wins if same number of changes:
918 Two branch tags: more recent wins if same number of changes:
914
919
915 $ hg tag -r 3 -m t3 -d '8 0' t3
920 $ hg tag -r 3 -m t3 -d '8 0' t3
916 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
921 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
917 @ 8: t3+5
922 @ 8: t3+5
918 |
923 |
919 o 7: t3+4
924 o 7: t3+4
920 |
925 |
921 o 6: t3+3
926 o 6: t3+3
922 |
927 |
923 o 5: t3+2
928 o 5: t3+2
924 |\
929 |\
925 | o 4: t3+1
930 | o 4: t3+1
926 | |
931 | |
927 | o 3: t3+0
932 | o 3: t3+0
928 | |
933 | |
929 o | 2: t2+0
934 o | 2: t2+0
930 |/
935 |/
931 o 1: t1+0
936 o 1: t1+0
932 |
937 |
933 o 0: null+1
938 o 0: null+1
934
939
935
940
936 Two branch tags: fewest changes wins:
941 Two branch tags: fewest changes wins:
937
942
938 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
943 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
939 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
944 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
940 @ 9: t4+5,6
945 @ 9: t4+5,6
941 |
946 |
942 o 8: t4+4,5
947 o 8: t4+4,5
943 |
948 |
944 o 7: t4+3,4
949 o 7: t4+3,4
945 |
950 |
946 o 6: t4+2,3
951 o 6: t4+2,3
947 |
952 |
948 o 5: t4+1,2
953 o 5: t4+1,2
949 |\
954 |\
950 | o 4: t4+0,0
955 | o 4: t4+0,0
951 | |
956 | |
952 | o 3: t3+0,0
957 | o 3: t3+0,0
953 | |
958 | |
954 o | 2: t2+0,0
959 o | 2: t2+0,0
955 |/
960 |/
956 o 1: t1+0,0
961 o 1: t1+0,0
957 |
962 |
958 o 0: null+1,1
963 o 0: null+1,1
959
964
960
965
961 Merged tag overrides:
966 Merged tag overrides:
962
967
963 $ hg tag -r 5 -m t5 -d '9 0' t5
968 $ hg tag -r 5 -m t5 -d '9 0' t5
964 $ hg tag -r 3 -m at3 -d '10 0' at3
969 $ hg tag -r 3 -m at3 -d '10 0' at3
965 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
970 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
966 @ 11: t5+6
971 @ 11: t5+6
967 |
972 |
968 o 10: t5+5
973 o 10: t5+5
969 |
974 |
970 o 9: t5+4
975 o 9: t5+4
971 |
976 |
972 o 8: t5+3
977 o 8: t5+3
973 |
978 |
974 o 7: t5+2
979 o 7: t5+2
975 |
980 |
976 o 6: t5+1
981 o 6: t5+1
977 |
982 |
978 o 5: t5+0
983 o 5: t5+0
979 |\
984 |\
980 | o 4: t4+0
985 | o 4: t4+0
981 | |
986 | |
982 | o 3: at3:t3+0
987 | o 3: at3:t3+0
983 | |
988 | |
984 o | 2: t2+0
989 o | 2: t2+0
985 |/
990 |/
986 o 1: t1+0
991 o 1: t1+0
987 |
992 |
988 o 0: null+1
993 o 0: null+1
989
994
990
995
991 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
996 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
992 @ 11: t5+6,6
997 @ 11: t5+6,6
993 |
998 |
994 o 10: t5+5,5
999 o 10: t5+5,5
995 |
1000 |
996 o 9: t5+4,4
1001 o 9: t5+4,4
997 |
1002 |
998 o 8: t5+3,3
1003 o 8: t5+3,3
999 |
1004 |
1000 o 7: t5+2,2
1005 o 7: t5+2,2
1001 |
1006 |
1002 o 6: t5+1,1
1007 o 6: t5+1,1
1003 |
1008 |
1004 o 5: t5+0,0
1009 o 5: t5+0,0
1005 |\
1010 |\
1006 | o 4: t4+0,0
1011 | o 4: t4+0,0
1007 | |
1012 | |
1008 | o 3: at3+0,0 t3+0,0
1013 | o 3: at3+0,0 t3+0,0
1009 | |
1014 | |
1010 o | 2: t2+0,0
1015 o | 2: t2+0,0
1011 |/
1016 |/
1012 o 1: t1+0,0
1017 o 1: t1+0,0
1013 |
1018 |
1014 o 0: null+1,1
1019 o 0: null+1,1
1015
1020
1016
1021
1017 $ cd ..
1022 $ cd ..
1018
1023
1019 Set up repository containing template fragments in commit metadata:
1024 Set up repository containing template fragments in commit metadata:
1020
1025
1021 $ hg init r
1026 $ hg init r
1022 $ cd r
1027 $ cd r
1023 $ echo a > a
1028 $ echo a > a
1024 $ hg ci -Am '{rev}'
1029 $ hg ci -Am '{rev}'
1025 adding a
1030 adding a
1026
1031
1027 $ hg branch -q 'text.{rev}'
1032 $ hg branch -q 'text.{rev}'
1028 $ echo aa >> aa
1033 $ echo aa >> aa
1029 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
1034 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
1030
1035
1031 Test termwidth:
1036 Test termwidth:
1032
1037
1033 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
1038 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
1034 bcc7ff960b8e:desc to be
1039 bcc7ff960b8e:desc to be
1035 termwidth.1:wrapped desc
1040 termwidth.1:wrapped desc
1036 termwidth.1:to be wrapped (no-eol)
1041 termwidth.1:to be wrapped (no-eol)
1037
1042
1038 Just one more commit:
1043 Just one more commit:
1039
1044
1040 $ echo b > b
1045 $ echo b > b
1041 $ hg ci -qAm b
1046 $ hg ci -qAm b
1042
1047
1043 Test 'originalnode'
1048 Test 'originalnode'
1044
1049
1045 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
1050 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
1046 000000000000 bcc7ff960b8e
1051 000000000000 bcc7ff960b8e
1047 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
1052 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
1048 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
1053 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
1049
1054
1050 Test active bookmark templating
1055 Test active bookmark templating
1051
1056
1052 $ hg book foo
1057 $ hg book foo
1053 $ hg book bar
1058 $ hg book bar
1054 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
1059 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
1055 2 bar* foo
1060 2 bar* foo
1056 1
1061 1
1057 0
1062 0
1058 $ hg log --template "{rev} {activebookmark}\n"
1063 $ hg log --template "{rev} {activebookmark}\n"
1059 2 bar
1064 2 bar
1060 1
1065 1
1061 0
1066 0
1062 $ hg bookmarks --inactive bar
1067 $ hg bookmarks --inactive bar
1063 $ hg log --template "{rev} {activebookmark}\n"
1068 $ hg log --template "{rev} {activebookmark}\n"
1064 2
1069 2
1065 1
1070 1
1066 0
1071 0
1067 $ hg book -r1 baz
1072 $ hg book -r1 baz
1068 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
1073 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
1069 2 bar foo
1074 2 bar foo
1070 1 baz
1075 1 baz
1071 0
1076 0
1072 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
1077 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
1073 2 t
1078 2 t
1074 1 f
1079 1 f
1075 0 f
1080 0 f
1076
1081
1077 Test namespaces dict
1082 Test namespaces dict
1078
1083
1079 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
1084 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
1080 2
1085 2
1081 bookmarks color=bookmark builtin=True
1086 bookmarks color=bookmark builtin=True
1082 bar,foo
1087 bar,foo
1083 tags color=tag builtin=True
1088 tags color=tag builtin=True
1084 tip
1089 tip
1085 branches color=branch builtin=True
1090 branches color=branch builtin=True
1086 text.{rev}
1091 text.{rev}
1087 revnames color=revname builtin=False
1092 revnames color=revname builtin=False
1088 r2
1093 r2
1089
1094
1090 1
1095 1
1091 bookmarks color=bookmark builtin=True
1096 bookmarks color=bookmark builtin=True
1092 baz
1097 baz
1093 tags color=tag builtin=True
1098 tags color=tag builtin=True
1094
1099
1095 branches color=branch builtin=True
1100 branches color=branch builtin=True
1096 text.{rev}
1101 text.{rev}
1097 revnames color=revname builtin=False
1102 revnames color=revname builtin=False
1098 r1
1103 r1
1099
1104
1100 0
1105 0
1101 bookmarks color=bookmark builtin=True
1106 bookmarks color=bookmark builtin=True
1102
1107
1103 tags color=tag builtin=True
1108 tags color=tag builtin=True
1104
1109
1105 branches color=branch builtin=True
1110 branches color=branch builtin=True
1106 default
1111 default
1107 revnames color=revname builtin=False
1112 revnames color=revname builtin=False
1108 r0
1113 r0
1109
1114
1110 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
1115 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
1111 bookmarks: bar foo
1116 bookmarks: bar foo
1112 tags: tip
1117 tags: tip
1113 branches: text.{rev}
1118 branches: text.{rev}
1114 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
1119 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
1115 bookmarks:
1120 bookmarks:
1116 bar
1121 bar
1117 foo
1122 foo
1118 tags:
1123 tags:
1119 tip
1124 tip
1120 branches:
1125 branches:
1121 text.{rev}
1126 text.{rev}
1122 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
1127 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
1123 bar
1128 bar
1124 foo
1129 foo
1125 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
1130 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
1126 bar
1131 bar
1127 foo
1132 foo
1128
1133
1129 $ cd ..
1134 $ cd ..
1130
1135
1131 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
1136 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
1132 printed graphwidths 3, 5, 7, etc. should all line up in their respective
1137 printed graphwidths 3, 5, 7, etc. should all line up in their respective
1133 columns. We don't care about other aspects of the graph rendering here.
1138 columns. We don't care about other aspects of the graph rendering here.
1134
1139
1135 $ hg init graphwidth
1140 $ hg init graphwidth
1136 $ cd graphwidth
1141 $ cd graphwidth
1137
1142
1138 $ wrappabletext="a a a a a a a a a a a a"
1143 $ wrappabletext="a a a a a a a a a a a a"
1139
1144
1140 $ printf "first\n" > file
1145 $ printf "first\n" > file
1141 $ hg add file
1146 $ hg add file
1142 $ hg commit -m "$wrappabletext"
1147 $ hg commit -m "$wrappabletext"
1143
1148
1144 $ printf "first\nsecond\n" > file
1149 $ printf "first\nsecond\n" > file
1145 $ hg commit -m "$wrappabletext"
1150 $ hg commit -m "$wrappabletext"
1146
1151
1147 $ hg checkout 0
1152 $ hg checkout 0
1148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1153 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1149 $ printf "third\nfirst\n" > file
1154 $ printf "third\nfirst\n" > file
1150 $ hg commit -m "$wrappabletext"
1155 $ hg commit -m "$wrappabletext"
1151 created new head
1156 created new head
1152
1157
1153 $ hg merge
1158 $ hg merge
1154 merging file
1159 merging file
1155 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1160 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1156 (branch merge, don't forget to commit)
1161 (branch merge, don't forget to commit)
1157
1162
1158 $ hg log --graph -T "{graphwidth}"
1163 $ hg log --graph -T "{graphwidth}"
1159 @ 3
1164 @ 3
1160 |
1165 |
1161 | @ 5
1166 | @ 5
1162 |/
1167 |/
1163 o 3
1168 o 3
1164
1169
1165 $ hg commit -m "$wrappabletext"
1170 $ hg commit -m "$wrappabletext"
1166
1171
1167 $ hg log --graph -T "{graphwidth}"
1172 $ hg log --graph -T "{graphwidth}"
1168 @ 5
1173 @ 5
1169 |\
1174 |\
1170 | o 5
1175 | o 5
1171 | |
1176 | |
1172 o | 5
1177 o | 5
1173 |/
1178 |/
1174 o 3
1179 o 3
1175
1180
1176
1181
1177 $ hg checkout 0
1182 $ hg checkout 0
1178 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1183 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1179 $ printf "third\nfirst\nsecond\n" > file
1184 $ printf "third\nfirst\nsecond\n" > file
1180 $ hg commit -m "$wrappabletext"
1185 $ hg commit -m "$wrappabletext"
1181 created new head
1186 created new head
1182
1187
1183 $ hg log --graph -T "{graphwidth}"
1188 $ hg log --graph -T "{graphwidth}"
1184 @ 3
1189 @ 3
1185 |
1190 |
1186 | o 7
1191 | o 7
1187 | |\
1192 | |\
1188 +---o 7
1193 +---o 7
1189 | |
1194 | |
1190 | o 5
1195 | o 5
1191 |/
1196 |/
1192 o 3
1197 o 3
1193
1198
1194
1199
1195 $ hg log --graph -T "{graphwidth}" -r 3
1200 $ hg log --graph -T "{graphwidth}" -r 3
1196 o 5
1201 o 5
1197 |\
1202 |\
1198 ~ ~
1203 ~ ~
1199
1204
1200 $ hg log --graph -T "{graphwidth}" -r 1
1205 $ hg log --graph -T "{graphwidth}" -r 1
1201 o 3
1206 o 3
1202 |
1207 |
1203 ~
1208 ~
1204
1209
1205 $ hg merge
1210 $ hg merge
1206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1211 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1207 (branch merge, don't forget to commit)
1212 (branch merge, don't forget to commit)
1208 $ hg commit -m "$wrappabletext"
1213 $ hg commit -m "$wrappabletext"
1209
1214
1210 $ printf "seventh\n" >> file
1215 $ printf "seventh\n" >> file
1211 $ hg commit -m "$wrappabletext"
1216 $ hg commit -m "$wrappabletext"
1212
1217
1213 $ hg log --graph -T "{graphwidth}"
1218 $ hg log --graph -T "{graphwidth}"
1214 @ 3
1219 @ 3
1215 |
1220 |
1216 o 5
1221 o 5
1217 |\
1222 |\
1218 | o 5
1223 | o 5
1219 | |
1224 | |
1220 o | 7
1225 o | 7
1221 |\ \
1226 |\ \
1222 | o | 7
1227 | o | 7
1223 | |/
1228 | |/
1224 o / 5
1229 o / 5
1225 |/
1230 |/
1226 o 3
1231 o 3
1227
1232
1228
1233
1229 The point of graphwidth is to allow wrapping that accounts for the space taken
1234 The point of graphwidth is to allow wrapping that accounts for the space taken
1230 by the graph.
1235 by the graph.
1231
1236
1232 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
1237 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
1233 @ a a a a
1238 @ a a a a
1234 | a a a a
1239 | a a a a
1235 | a a a a
1240 | a a a a
1236 o a a a
1241 o a a a
1237 |\ a a a
1242 |\ a a a
1238 | | a a a
1243 | | a a a
1239 | | a a a
1244 | | a a a
1240 | o a a a
1245 | o a a a
1241 | | a a a
1246 | | a a a
1242 | | a a a
1247 | | a a a
1243 | | a a a
1248 | | a a a
1244 o | a a
1249 o | a a
1245 |\ \ a a
1250 |\ \ a a
1246 | | | a a
1251 | | | a a
1247 | | | a a
1252 | | | a a
1248 | | | a a
1253 | | | a a
1249 | | | a a
1254 | | | a a
1250 | o | a a
1255 | o | a a
1251 | |/ a a
1256 | |/ a a
1252 | | a a
1257 | | a a
1253 | | a a
1258 | | a a
1254 | | a a
1259 | | a a
1255 | | a a
1260 | | a a
1256 o | a a a
1261 o | a a a
1257 |/ a a a
1262 |/ a a a
1258 | a a a
1263 | a a a
1259 | a a a
1264 | a a a
1260 o a a a a
1265 o a a a a
1261 a a a a
1266 a a a a
1262 a a a a
1267 a a a a
1263
1268
1264 Something tricky happens when there are elided nodes; the next drawn row of
1269 Something tricky happens when there are elided nodes; the next drawn row of
1265 edges can be more than one column wider, but the graph width only increases by
1270 edges can be more than one column wider, but the graph width only increases by
1266 one column. The remaining columns are added in between the nodes.
1271 one column. The remaining columns are added in between the nodes.
1267
1272
1268 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
1273 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
1269 o 5
1274 o 5
1270 |\
1275 |\
1271 | \
1276 | \
1272 | :\
1277 | :\
1273 o : : 7
1278 o : : 7
1274 :/ /
1279 :/ /
1275 : o 5
1280 : o 5
1276 :/
1281 :/
1277 o 3
1282 o 3
1278
1283
1279
1284
1280 $ cd ..
1285 $ cd ..
@@ -1,1760 +1,1760 b''
1 Test template map files and styles
1 Test template map files and styles
2 ==================================
2 ==================================
3
3
4 $ hg init a
4 $ hg init a
5 $ cd a
5 $ cd a
6 $ echo a > a
6 $ echo a > a
7 $ hg add a
7 $ hg add a
8 $ echo line 1 > b
8 $ echo line 1 > b
9 $ echo line 2 >> b
9 $ echo line 2 >> b
10 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
10 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
11
11
12 $ hg add b
12 $ hg add b
13 $ echo other 1 > c
13 $ echo other 1 > c
14 $ echo other 2 >> c
14 $ echo other 2 >> c
15 $ echo >> c
15 $ echo >> c
16 $ echo other 3 >> c
16 $ echo other 3 >> c
17 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
17 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
18
18
19 $ hg add c
19 $ hg add c
20 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
20 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
21 $ echo c >> c
21 $ echo c >> c
22 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
22 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
23
23
24 $ echo foo > .hg/branch
24 $ echo foo > .hg/branch
25 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
25 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
26
26
27 $ hg co -q 3
27 $ hg co -q 3
28 $ echo other 4 >> d
28 $ echo other 4 >> d
29 $ hg add d
29 $ hg add d
30 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
30 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
31
31
32 $ hg merge -q foo
32 $ hg merge -q foo
33 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
33 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
34
34
35 Second branch starting at nullrev:
35 Second branch starting at nullrev:
36
36
37 $ hg update null
37 $ hg update null
38 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
38 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
39 $ echo second > second
39 $ echo second > second
40 $ hg add second
40 $ hg add second
41 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
41 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
42 created new head
42 created new head
43
43
44 $ echo third > third
44 $ echo third > third
45 $ hg add third
45 $ hg add third
46 $ hg mv second fourth
46 $ hg mv second fourth
47 $ hg commit -m third -d "2020-01-01 10:01"
47 $ hg commit -m third -d "2020-01-01 10:01"
48
48
49 Make sure user/global hgrc does not affect tests
49 Make sure user/global hgrc does not affect tests
50
50
51 $ echo '[ui]' > .hg/hgrc
51 $ echo '[ui]' > .hg/hgrc
52 $ echo 'logtemplate =' >> .hg/hgrc
52 $ echo 'logtemplate =' >> .hg/hgrc
53 $ echo 'style =' >> .hg/hgrc
53 $ echo 'style =' >> .hg/hgrc
54
54
55 Add some simple styles to settings
55 Add some simple styles to settings
56
56
57 $ cat <<'EOF' >> .hg/hgrc
57 $ cat <<'EOF' >> .hg/hgrc
58 > [templates]
58 > [templates]
59 > simple = "{rev}\n"
59 > simple = "{rev}\n"
60 > simple2 = {rev}\n
60 > simple2 = {rev}\n
61 > rev = "should not precede {rev} keyword\n"
61 > rev = "should not precede {rev} keyword\n"
62 > EOF
62 > EOF
63
63
64 $ hg log -l1 -Tsimple
64 $ hg log -l1 -Tsimple
65 8
65 8
66 $ hg log -l1 -Tsimple2
66 $ hg log -l1 -Tsimple2
67 8
67 8
68 $ hg log -l1 -Trev
68 $ hg log -l1 -Trev
69 should not precede 8 keyword
69 should not precede 8 keyword
70 $ hg log -l1 -T '{simple}'
70 $ hg log -l1 -T '{simple}'
71 8
71 8
72
72
73 Map file shouldn't see user templates:
73 Map file shouldn't see user templates:
74
74
75 $ cat <<EOF > tmpl
75 $ cat <<EOF > tmpl
76 > changeset = 'nothing expanded:{simple}\n'
76 > changeset = 'nothing expanded:{simple}\n'
77 > EOF
77 > EOF
78 $ hg log -l1 --style ./tmpl
78 $ hg log -l1 --style ./tmpl
79 nothing expanded:
79 nothing expanded:
80
80
81 Test templates and style maps in files:
81 Test templates and style maps in files:
82
82
83 $ echo "{rev}" > tmpl
83 $ echo "{rev}" > tmpl
84 $ hg log -l1 -T./tmpl
84 $ hg log -l1 -T./tmpl
85 8
85 8
86 $ hg log -l1 -Tblah/blah
86 $ hg log -l1 -Tblah/blah
87 blah/blah (no-eol)
87 blah/blah (no-eol)
88
88
89 $ printf 'changeset = "{rev}\\n"\n' > map-simple
89 $ printf 'changeset = "{rev}\\n"\n' > map-simple
90 $ hg log -l1 -T./map-simple
90 $ hg log -l1 -T./map-simple
91 8
91 8
92
92
93 a map file may have [templates] and [templatealias] sections:
93 a map file may have [templates] and [templatealias] sections:
94
94
95 $ cat <<'EOF' > map-simple
95 $ cat <<'EOF' > map-simple
96 > [templates]
96 > [templates]
97 > changeset = "{a}\n"
97 > changeset = "{a}\n"
98 > [templatealias]
98 > [templatealias]
99 > a = rev
99 > a = rev
100 > EOF
100 > EOF
101 $ hg log -l1 -T./map-simple
101 $ hg log -l1 -T./map-simple
102 8
102 8
103
103
104 so it can be included in hgrc
104 so it can be included in hgrc
105
105
106 $ cat <<EOF > myhgrc
106 $ cat <<EOF > myhgrc
107 > %include $HGRCPATH
107 > %include $HGRCPATH
108 > %include map-simple
108 > %include map-simple
109 > [templates]
109 > [templates]
110 > foo = "{changeset}"
110 > foo = "{changeset}"
111 > EOF
111 > EOF
112 $ HGRCPATH=./myhgrc hg log -l1 -Tfoo
112 $ HGRCPATH=./myhgrc hg log -l1 -Tfoo
113 8
113 8
114 $ HGRCPATH=./myhgrc hg log -l1 -T'{a}\n'
114 $ HGRCPATH=./myhgrc hg log -l1 -T'{a}\n'
115 8
115 8
116
116
117 Test template map inheritance
117 Test template map inheritance
118
118
119 $ echo "__base__ = map-cmdline.default" > map-simple
119 $ echo "__base__ = map-cmdline.default" > map-simple
120 $ printf 'cset = "changeset: ***{rev}***\\n"\n' >> map-simple
120 $ printf 'cset = "changeset: ***{rev}***\\n"\n' >> map-simple
121 $ hg log -l1 -T./map-simple
121 $ hg log -l1 -T./map-simple
122 changeset: ***8***
122 changeset: ***8***
123 tag: tip
123 tag: tip
124 user: test
124 user: test
125 date: Wed Jan 01 10:01:00 2020 +0000
125 date: Wed Jan 01 10:01:00 2020 +0000
126 summary: third
126 summary: third
127
127
128
128
129 Test docheader, docfooter and separator in template map
129 Test docheader, docfooter and separator in template map
130
130
131 $ cat <<'EOF' > map-myjson
131 $ cat <<'EOF' > map-myjson
132 > docheader = '\{\n'
132 > docheader = '\{\n'
133 > docfooter = '\n}\n'
133 > docfooter = '\n}\n'
134 > separator = ',\n'
134 > separator = ',\n'
135 > changeset = ' {dict(rev, node|short)|json}'
135 > changeset = ' {dict(rev, node|short)|json}'
136 > EOF
136 > EOF
137 $ hg log -l2 -T./map-myjson
137 $ hg log -l2 -T./map-myjson
138 {
138 {
139 {"node": "95c24699272e", "rev": 8},
139 {"node": "95c24699272e", "rev": 8},
140 {"node": "29114dbae42b", "rev": 7}
140 {"node": "29114dbae42b", "rev": 7}
141 }
141 }
142
142
143 Test docheader, docfooter and separator in [templates] section
143 Test docheader, docfooter and separator in [templates] section
144
144
145 $ cat <<'EOF' >> .hg/hgrc
145 $ cat <<'EOF' >> .hg/hgrc
146 > [templates]
146 > [templates]
147 > myjson = ' {dict(rev, node|short)|json}'
147 > myjson = ' {dict(rev, node|short)|json}'
148 > myjson:docheader = '\{\n'
148 > myjson:docheader = '\{\n'
149 > myjson:docfooter = '\n}\n'
149 > myjson:docfooter = '\n}\n'
150 > myjson:separator = ',\n'
150 > myjson:separator = ',\n'
151 > :docheader = 'should not be selected as a docheader for literal templates\n'
151 > :docheader = 'should not be selected as a docheader for literal templates\n'
152 > EOF
152 > EOF
153 $ hg log -l2 -Tmyjson
153 $ hg log -l2 -Tmyjson
154 {
154 {
155 {"node": "95c24699272e", "rev": 8},
155 {"node": "95c24699272e", "rev": 8},
156 {"node": "29114dbae42b", "rev": 7}
156 {"node": "29114dbae42b", "rev": 7}
157 }
157 }
158 $ hg log -l1 -T'{rev}\n'
158 $ hg log -l1 -T'{rev}\n'
159 8
159 8
160
160
161 Template should precede style option
161 Template should precede style option
162
162
163 $ hg log -l1 --style default -T '{rev}\n'
163 $ hg log -l1 --style default -T '{rev}\n'
164 8
164 8
165
165
166 Add a commit with empty description, to ensure that the templates
166 Add a commit with empty description, to ensure that the templates
167 below will omit the description line.
167 below will omit the description line.
168
168
169 $ echo c >> c
169 $ echo c >> c
170 $ hg add c
170 $ hg add c
171 $ hg commit -qm ' '
171 $ hg commit -qm ' '
172
172
173 Default style is like normal output. Phases style should be the same
173 Default style is like normal output. Phases style should be the same
174 as default style, except for extra phase lines.
174 as default style, except for extra phase lines.
175
175
176 $ hg log > log.out
176 $ hg log > log.out
177 $ hg log --style default > style.out
177 $ hg log --style default > style.out
178 $ cmp log.out style.out || diff -u log.out style.out
178 $ cmp log.out style.out || diff -u log.out style.out
179 $ hg log -T phases > phases.out
179 $ hg log -T phases > phases.out
180 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
180 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
181 +phase: draft
181 +phase: draft
182 +phase: draft
182 +phase: draft
183 +phase: draft
183 +phase: draft
184 +phase: draft
184 +phase: draft
185 +phase: draft
185 +phase: draft
186 +phase: draft
186 +phase: draft
187 +phase: draft
187 +phase: draft
188 +phase: draft
188 +phase: draft
189 +phase: draft
189 +phase: draft
190 +phase: draft
190 +phase: draft
191
191
192 $ hg log -v > log.out
192 $ hg log -v > log.out
193 $ hg log -v --style default > style.out
193 $ hg log -v --style default > style.out
194 $ cmp log.out style.out || diff -u log.out style.out
194 $ cmp log.out style.out || diff -u log.out style.out
195 $ hg log -v -T phases > phases.out
195 $ hg log -v -T phases > phases.out
196 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
196 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
197 +phase: draft
197 +phase: draft
198 +phase: draft
198 +phase: draft
199 +phase: draft
199 +phase: draft
200 +phase: draft
200 +phase: draft
201 +phase: draft
201 +phase: draft
202 +phase: draft
202 +phase: draft
203 +phase: draft
203 +phase: draft
204 +phase: draft
204 +phase: draft
205 +phase: draft
205 +phase: draft
206 +phase: draft
206 +phase: draft
207
207
208 $ hg log -q > log.out
208 $ hg log -q > log.out
209 $ hg log -q --style default > style.out
209 $ hg log -q --style default > style.out
210 $ cmp log.out style.out || diff -u log.out style.out
210 $ cmp log.out style.out || diff -u log.out style.out
211 $ hg log -q -T phases > phases.out
211 $ hg log -q -T phases > phases.out
212 $ cmp log.out phases.out || diff -u log.out phases.out
212 $ cmp log.out phases.out || diff -u log.out phases.out
213
213
214 $ hg log --debug > log.out
214 $ hg log --debug > log.out
215 $ hg log --debug --style default > style.out
215 $ hg log --debug --style default > style.out
216 $ cmp log.out style.out || diff -u log.out style.out
216 $ cmp log.out style.out || diff -u log.out style.out
217 $ hg log --debug -T phases > phases.out
217 $ hg log --debug -T phases > phases.out
218 $ cmp log.out phases.out || diff -u log.out phases.out
218 $ cmp log.out phases.out || diff -u log.out phases.out
219
219
220 Default style of working-directory revision should also be the same (but
220 Default style of working-directory revision should also be the same (but
221 date may change while running tests):
221 date may change while running tests):
222
222
223 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
223 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
224 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
224 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
225 $ cmp log.out style.out || diff -u log.out style.out
225 $ cmp log.out style.out || diff -u log.out style.out
226
226
227 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
227 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
228 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
228 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
229 $ cmp log.out style.out || diff -u log.out style.out
229 $ cmp log.out style.out || diff -u log.out style.out
230
230
231 $ hg log -r 'wdir()' -q > log.out
231 $ hg log -r 'wdir()' -q > log.out
232 $ hg log -r 'wdir()' -q --style default > style.out
232 $ hg log -r 'wdir()' -q --style default > style.out
233 $ cmp log.out style.out || diff -u log.out style.out
233 $ cmp log.out style.out || diff -u log.out style.out
234
234
235 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
235 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
236 $ hg log -r 'wdir()' --debug --style default \
236 $ hg log -r 'wdir()' --debug --style default \
237 > | sed 's|^date:.*|date:|' > style.out
237 > | sed 's|^date:.*|date:|' > style.out
238 $ cmp log.out style.out || diff -u log.out style.out
238 $ cmp log.out style.out || diff -u log.out style.out
239
239
240 Default style should also preserve color information (issue2866):
240 Default style should also preserve color information (issue2866):
241
241
242 $ cp $HGRCPATH $HGRCPATH-bak
242 $ cp $HGRCPATH $HGRCPATH-bak
243 $ cat <<EOF >> $HGRCPATH
243 $ cat <<EOF >> $HGRCPATH
244 > [extensions]
244 > [extensions]
245 > color=
245 > color=
246 > EOF
246 > EOF
247
247
248 $ hg --color=debug log > log.out
248 $ hg --color=debug log > log.out
249 $ hg --color=debug log --style default > style.out
249 $ hg --color=debug log --style default > style.out
250 $ cmp log.out style.out || diff -u log.out style.out
250 $ cmp log.out style.out || diff -u log.out style.out
251 $ hg --color=debug log -T phases > phases.out
251 $ hg --color=debug log -T phases > phases.out
252 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
252 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
253 +[log.phase|phase: draft]
253 +[log.phase|phase: draft]
254 +[log.phase|phase: draft]
254 +[log.phase|phase: draft]
255 +[log.phase|phase: draft]
255 +[log.phase|phase: draft]
256 +[log.phase|phase: draft]
256 +[log.phase|phase: draft]
257 +[log.phase|phase: draft]
257 +[log.phase|phase: draft]
258 +[log.phase|phase: draft]
258 +[log.phase|phase: draft]
259 +[log.phase|phase: draft]
259 +[log.phase|phase: draft]
260 +[log.phase|phase: draft]
260 +[log.phase|phase: draft]
261 +[log.phase|phase: draft]
261 +[log.phase|phase: draft]
262 +[log.phase|phase: draft]
262 +[log.phase|phase: draft]
263
263
264 $ hg --color=debug -v log > log.out
264 $ hg --color=debug -v log > log.out
265 $ hg --color=debug -v log --style default > style.out
265 $ hg --color=debug -v log --style default > style.out
266 $ cmp log.out style.out || diff -u log.out style.out
266 $ cmp log.out style.out || diff -u log.out style.out
267 $ hg --color=debug -v log -T phases > phases.out
267 $ hg --color=debug -v log -T phases > phases.out
268 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
268 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
269 +[log.phase|phase: draft]
269 +[log.phase|phase: draft]
270 +[log.phase|phase: draft]
270 +[log.phase|phase: draft]
271 +[log.phase|phase: draft]
271 +[log.phase|phase: draft]
272 +[log.phase|phase: draft]
272 +[log.phase|phase: draft]
273 +[log.phase|phase: draft]
273 +[log.phase|phase: draft]
274 +[log.phase|phase: draft]
274 +[log.phase|phase: draft]
275 +[log.phase|phase: draft]
275 +[log.phase|phase: draft]
276 +[log.phase|phase: draft]
276 +[log.phase|phase: draft]
277 +[log.phase|phase: draft]
277 +[log.phase|phase: draft]
278 +[log.phase|phase: draft]
278 +[log.phase|phase: draft]
279
279
280 $ hg --color=debug -q log > log.out
280 $ hg --color=debug -q log > log.out
281 $ hg --color=debug -q log --style default > style.out
281 $ hg --color=debug -q log --style default > style.out
282 $ cmp log.out style.out || diff -u log.out style.out
282 $ cmp log.out style.out || diff -u log.out style.out
283 $ hg --color=debug -q log -T phases > phases.out
283 $ hg --color=debug -q log -T phases > phases.out
284 $ cmp log.out phases.out || diff -u log.out phases.out
284 $ cmp log.out phases.out || diff -u log.out phases.out
285
285
286 $ hg --color=debug --debug log > log.out
286 $ hg --color=debug --debug log > log.out
287 $ hg --color=debug --debug log --style default > style.out
287 $ hg --color=debug --debug log --style default > style.out
288 $ cmp log.out style.out || diff -u log.out style.out
288 $ cmp log.out style.out || diff -u log.out style.out
289 $ hg --color=debug --debug log -T phases > phases.out
289 $ hg --color=debug --debug log -T phases > phases.out
290 $ cmp log.out phases.out || diff -u log.out phases.out
290 $ cmp log.out phases.out || diff -u log.out phases.out
291
291
292 $ mv $HGRCPATH-bak $HGRCPATH
292 $ mv $HGRCPATH-bak $HGRCPATH
293
293
294 Remove commit with empty commit message, so as to not pollute further
294 Remove commit with empty commit message, so as to not pollute further
295 tests.
295 tests.
296
296
297 $ hg --config extensions.strip= strip -q .
297 $ hg --config extensions.strip= strip -q .
298
298
299 Revision with no copies (used to print a traceback):
299 Revision with no copies (used to print a traceback):
300
300
301 $ hg tip -v --template '\n'
301 $ hg tip -v --template '\n'
302
302
303
303
304 Compact style works:
304 Compact style works:
305
305
306 $ hg log -Tcompact
306 $ hg log -Tcompact
307 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
307 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
308 third
308 third
309
309
310 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
310 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
311 second
311 second
312
312
313 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
313 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
314 merge
314 merge
315
315
316 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
316 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
317 new head
317 new head
318
318
319 4 bbe44766e73d 1970-01-17 04:53 +0000 person
319 4 bbe44766e73d 1970-01-17 04:53 +0000 person
320 new branch
320 new branch
321
321
322 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
322 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
323 no user, no domain
323 no user, no domain
324
324
325 2 97054abb4ab8 1970-01-14 21:20 +0000 other
325 2 97054abb4ab8 1970-01-14 21:20 +0000 other
326 no person
326 no person
327
327
328 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
328 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
329 other 1
329 other 1
330
330
331 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
331 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
332 line 1
332 line 1
333
333
334
334
335 $ hg log -v --style compact
335 $ hg log -v --style compact
336 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
336 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
337 third
337 third
338
338
339 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
339 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
340 second
340 second
341
341
342 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
342 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
343 merge
343 merge
344
344
345 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
345 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
346 new head
346 new head
347
347
348 4 bbe44766e73d 1970-01-17 04:53 +0000 person
348 4 bbe44766e73d 1970-01-17 04:53 +0000 person
349 new branch
349 new branch
350
350
351 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
351 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
352 no user, no domain
352 no user, no domain
353
353
354 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
354 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
355 no person
355 no person
356
356
357 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
357 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
358 other 1
358 other 1
359 other 2
359 other 2
360
360
361 other 3
361 other 3
362
362
363 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
363 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
364 line 1
364 line 1
365 line 2
365 line 2
366
366
367
367
368 $ hg log --debug --style compact
368 $ hg log --debug --style compact
369 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
369 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
370 third
370 third
371
371
372 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
372 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
373 second
373 second
374
374
375 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
375 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
376 merge
376 merge
377
377
378 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
378 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
379 new head
379 new head
380
380
381 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
381 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
382 new branch
382 new branch
383
383
384 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
384 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
385 no user, no domain
385 no user, no domain
386
386
387 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
387 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
388 no person
388 no person
389
389
390 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
390 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
391 other 1
391 other 1
392 other 2
392 other 2
393
393
394 other 3
394 other 3
395
395
396 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
396 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
397 line 1
397 line 1
398 line 2
398 line 2
399
399
400
400
401 Test xml styles:
401 Test xml styles:
402
402
403 $ hg log --style xml -r 'not all()'
403 $ hg log --style xml -r 'not all()'
404 <?xml version="1.0"?>
404 <?xml version="1.0"?>
405 <log>
405 <log>
406 </log>
406 </log>
407
407
408 $ hg log --style xml
408 $ hg log --style xml
409 <?xml version="1.0"?>
409 <?xml version="1.0"?>
410 <log>
410 <log>
411 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
411 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
412 <tag>tip</tag>
412 <tag>tip</tag>
413 <author email="test">test</author>
413 <author email="test">test</author>
414 <date>2020-01-01T10:01:00+00:00</date>
414 <date>2020-01-01T10:01:00+00:00</date>
415 <msg xml:space="preserve">third</msg>
415 <msg xml:space="preserve">third</msg>
416 </logentry>
416 </logentry>
417 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
417 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
418 <parent revision="-1" node="0000000000000000000000000000000000000000" />
418 <parent revision="-1" node="0000000000000000000000000000000000000000" />
419 <author email="user@hostname">User Name</author>
419 <author email="user@hostname">User Name</author>
420 <date>1970-01-12T13:46:40+00:00</date>
420 <date>1970-01-12T13:46:40+00:00</date>
421 <msg xml:space="preserve">second</msg>
421 <msg xml:space="preserve">second</msg>
422 </logentry>
422 </logentry>
423 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
423 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
424 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
424 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
425 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
425 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
426 <author email="person">person</author>
426 <author email="person">person</author>
427 <date>1970-01-18T08:40:01+00:00</date>
427 <date>1970-01-18T08:40:01+00:00</date>
428 <msg xml:space="preserve">merge</msg>
428 <msg xml:space="preserve">merge</msg>
429 </logentry>
429 </logentry>
430 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
430 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
431 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
431 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
432 <author email="person">person</author>
432 <author email="person">person</author>
433 <date>1970-01-18T08:40:00+00:00</date>
433 <date>1970-01-18T08:40:00+00:00</date>
434 <msg xml:space="preserve">new head</msg>
434 <msg xml:space="preserve">new head</msg>
435 </logentry>
435 </logentry>
436 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
436 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
437 <branch>foo</branch>
437 <branch>foo</branch>
438 <author email="person">person</author>
438 <author email="person">person</author>
439 <date>1970-01-17T04:53:20+00:00</date>
439 <date>1970-01-17T04:53:20+00:00</date>
440 <msg xml:space="preserve">new branch</msg>
440 <msg xml:space="preserve">new branch</msg>
441 </logentry>
441 </logentry>
442 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
442 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
443 <author email="person">person</author>
443 <author email="person">person</author>
444 <date>1970-01-16T01:06:40+00:00</date>
444 <date>1970-01-16T01:06:40+00:00</date>
445 <msg xml:space="preserve">no user, no domain</msg>
445 <msg xml:space="preserve">no user, no domain</msg>
446 </logentry>
446 </logentry>
447 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
447 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
448 <author email="other@place">other</author>
448 <author email="other@place">other</author>
449 <date>1970-01-14T21:20:00+00:00</date>
449 <date>1970-01-14T21:20:00+00:00</date>
450 <msg xml:space="preserve">no person</msg>
450 <msg xml:space="preserve">no person</msg>
451 </logentry>
451 </logentry>
452 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
452 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
453 <author email="other@place">A. N. Other</author>
453 <author email="other@place">A. N. Other</author>
454 <date>1970-01-13T17:33:20+00:00</date>
454 <date>1970-01-13T17:33:20+00:00</date>
455 <msg xml:space="preserve">other 1
455 <msg xml:space="preserve">other 1
456 other 2
456 other 2
457
457
458 other 3</msg>
458 other 3</msg>
459 </logentry>
459 </logentry>
460 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
460 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
461 <author email="user@hostname">User Name</author>
461 <author email="user@hostname">User Name</author>
462 <date>1970-01-12T13:46:40+00:00</date>
462 <date>1970-01-12T13:46:40+00:00</date>
463 <msg xml:space="preserve">line 1
463 <msg xml:space="preserve">line 1
464 line 2</msg>
464 line 2</msg>
465 </logentry>
465 </logentry>
466 </log>
466 </log>
467
467
468 $ hg log -v --style xml
468 $ hg log -v --style xml
469 <?xml version="1.0"?>
469 <?xml version="1.0"?>
470 <log>
470 <log>
471 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
471 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
472 <tag>tip</tag>
472 <tag>tip</tag>
473 <author email="test">test</author>
473 <author email="test">test</author>
474 <date>2020-01-01T10:01:00+00:00</date>
474 <date>2020-01-01T10:01:00+00:00</date>
475 <msg xml:space="preserve">third</msg>
475 <msg xml:space="preserve">third</msg>
476 <paths>
476 <paths>
477 <path action="A">fourth</path>
477 <path action="A">fourth</path>
478 <path action="A">third</path>
478 <path action="A">third</path>
479 <path action="R">second</path>
479 <path action="R">second</path>
480 </paths>
480 </paths>
481 <copies>
481 <copies>
482 <copy source="second">fourth</copy>
482 <copy source="second">fourth</copy>
483 </copies>
483 </copies>
484 </logentry>
484 </logentry>
485 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
485 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
486 <parent revision="-1" node="0000000000000000000000000000000000000000" />
486 <parent revision="-1" node="0000000000000000000000000000000000000000" />
487 <author email="user@hostname">User Name</author>
487 <author email="user@hostname">User Name</author>
488 <date>1970-01-12T13:46:40+00:00</date>
488 <date>1970-01-12T13:46:40+00:00</date>
489 <msg xml:space="preserve">second</msg>
489 <msg xml:space="preserve">second</msg>
490 <paths>
490 <paths>
491 <path action="A">second</path>
491 <path action="A">second</path>
492 </paths>
492 </paths>
493 </logentry>
493 </logentry>
494 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
494 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
495 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
495 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
496 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
496 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
497 <author email="person">person</author>
497 <author email="person">person</author>
498 <date>1970-01-18T08:40:01+00:00</date>
498 <date>1970-01-18T08:40:01+00:00</date>
499 <msg xml:space="preserve">merge</msg>
499 <msg xml:space="preserve">merge</msg>
500 <paths>
500 <paths>
501 </paths>
501 </paths>
502 </logentry>
502 </logentry>
503 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
503 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
504 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
504 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
505 <author email="person">person</author>
505 <author email="person">person</author>
506 <date>1970-01-18T08:40:00+00:00</date>
506 <date>1970-01-18T08:40:00+00:00</date>
507 <msg xml:space="preserve">new head</msg>
507 <msg xml:space="preserve">new head</msg>
508 <paths>
508 <paths>
509 <path action="A">d</path>
509 <path action="A">d</path>
510 </paths>
510 </paths>
511 </logentry>
511 </logentry>
512 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
512 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
513 <branch>foo</branch>
513 <branch>foo</branch>
514 <author email="person">person</author>
514 <author email="person">person</author>
515 <date>1970-01-17T04:53:20+00:00</date>
515 <date>1970-01-17T04:53:20+00:00</date>
516 <msg xml:space="preserve">new branch</msg>
516 <msg xml:space="preserve">new branch</msg>
517 <paths>
517 <paths>
518 </paths>
518 </paths>
519 </logentry>
519 </logentry>
520 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
520 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
521 <author email="person">person</author>
521 <author email="person">person</author>
522 <date>1970-01-16T01:06:40+00:00</date>
522 <date>1970-01-16T01:06:40+00:00</date>
523 <msg xml:space="preserve">no user, no domain</msg>
523 <msg xml:space="preserve">no user, no domain</msg>
524 <paths>
524 <paths>
525 <path action="M">c</path>
525 <path action="M">c</path>
526 </paths>
526 </paths>
527 </logentry>
527 </logentry>
528 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
528 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
529 <author email="other@place">other</author>
529 <author email="other@place">other</author>
530 <date>1970-01-14T21:20:00+00:00</date>
530 <date>1970-01-14T21:20:00+00:00</date>
531 <msg xml:space="preserve">no person</msg>
531 <msg xml:space="preserve">no person</msg>
532 <paths>
532 <paths>
533 <path action="A">c</path>
533 <path action="A">c</path>
534 </paths>
534 </paths>
535 </logentry>
535 </logentry>
536 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
536 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
537 <author email="other@place">A. N. Other</author>
537 <author email="other@place">A. N. Other</author>
538 <date>1970-01-13T17:33:20+00:00</date>
538 <date>1970-01-13T17:33:20+00:00</date>
539 <msg xml:space="preserve">other 1
539 <msg xml:space="preserve">other 1
540 other 2
540 other 2
541
541
542 other 3</msg>
542 other 3</msg>
543 <paths>
543 <paths>
544 <path action="A">b</path>
544 <path action="A">b</path>
545 </paths>
545 </paths>
546 </logentry>
546 </logentry>
547 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
547 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
548 <author email="user@hostname">User Name</author>
548 <author email="user@hostname">User Name</author>
549 <date>1970-01-12T13:46:40+00:00</date>
549 <date>1970-01-12T13:46:40+00:00</date>
550 <msg xml:space="preserve">line 1
550 <msg xml:space="preserve">line 1
551 line 2</msg>
551 line 2</msg>
552 <paths>
552 <paths>
553 <path action="A">a</path>
553 <path action="A">a</path>
554 </paths>
554 </paths>
555 </logentry>
555 </logentry>
556 </log>
556 </log>
557
557
558 $ hg log --debug --style xml
558 $ hg log --debug --style xml
559 <?xml version="1.0"?>
559 <?xml version="1.0"?>
560 <log>
560 <log>
561 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
561 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
562 <tag>tip</tag>
562 <tag>tip</tag>
563 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
563 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
564 <parent revision="-1" node="0000000000000000000000000000000000000000" />
564 <parent revision="-1" node="0000000000000000000000000000000000000000" />
565 <author email="test">test</author>
565 <author email="test">test</author>
566 <date>2020-01-01T10:01:00+00:00</date>
566 <date>2020-01-01T10:01:00+00:00</date>
567 <msg xml:space="preserve">third</msg>
567 <msg xml:space="preserve">third</msg>
568 <paths>
568 <paths>
569 <path action="A">fourth</path>
569 <path action="A">fourth</path>
570 <path action="A">third</path>
570 <path action="A">third</path>
571 <path action="R">second</path>
571 <path action="R">second</path>
572 </paths>
572 </paths>
573 <copies>
573 <copies>
574 <copy source="second">fourth</copy>
574 <copy source="second">fourth</copy>
575 </copies>
575 </copies>
576 <extra key="branch">default</extra>
576 <extra key="branch">default</extra>
577 </logentry>
577 </logentry>
578 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
578 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
579 <parent revision="-1" node="0000000000000000000000000000000000000000" />
579 <parent revision="-1" node="0000000000000000000000000000000000000000" />
580 <parent revision="-1" node="0000000000000000000000000000000000000000" />
580 <parent revision="-1" node="0000000000000000000000000000000000000000" />
581 <author email="user@hostname">User Name</author>
581 <author email="user@hostname">User Name</author>
582 <date>1970-01-12T13:46:40+00:00</date>
582 <date>1970-01-12T13:46:40+00:00</date>
583 <msg xml:space="preserve">second</msg>
583 <msg xml:space="preserve">second</msg>
584 <paths>
584 <paths>
585 <path action="A">second</path>
585 <path action="A">second</path>
586 </paths>
586 </paths>
587 <extra key="branch">default</extra>
587 <extra key="branch">default</extra>
588 </logentry>
588 </logentry>
589 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
589 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
590 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
590 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
591 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
591 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
592 <author email="person">person</author>
592 <author email="person">person</author>
593 <date>1970-01-18T08:40:01+00:00</date>
593 <date>1970-01-18T08:40:01+00:00</date>
594 <msg xml:space="preserve">merge</msg>
594 <msg xml:space="preserve">merge</msg>
595 <paths>
595 <paths>
596 </paths>
596 </paths>
597 <extra key="branch">default</extra>
597 <extra key="branch">default</extra>
598 </logentry>
598 </logentry>
599 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
599 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
600 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
600 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
601 <parent revision="-1" node="0000000000000000000000000000000000000000" />
601 <parent revision="-1" node="0000000000000000000000000000000000000000" />
602 <author email="person">person</author>
602 <author email="person">person</author>
603 <date>1970-01-18T08:40:00+00:00</date>
603 <date>1970-01-18T08:40:00+00:00</date>
604 <msg xml:space="preserve">new head</msg>
604 <msg xml:space="preserve">new head</msg>
605 <paths>
605 <paths>
606 <path action="A">d</path>
606 <path action="A">d</path>
607 </paths>
607 </paths>
608 <extra key="branch">default</extra>
608 <extra key="branch">default</extra>
609 </logentry>
609 </logentry>
610 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
610 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
611 <branch>foo</branch>
611 <branch>foo</branch>
612 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
612 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
613 <parent revision="-1" node="0000000000000000000000000000000000000000" />
613 <parent revision="-1" node="0000000000000000000000000000000000000000" />
614 <author email="person">person</author>
614 <author email="person">person</author>
615 <date>1970-01-17T04:53:20+00:00</date>
615 <date>1970-01-17T04:53:20+00:00</date>
616 <msg xml:space="preserve">new branch</msg>
616 <msg xml:space="preserve">new branch</msg>
617 <paths>
617 <paths>
618 </paths>
618 </paths>
619 <extra key="branch">foo</extra>
619 <extra key="branch">foo</extra>
620 </logentry>
620 </logentry>
621 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
621 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
622 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
622 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
623 <parent revision="-1" node="0000000000000000000000000000000000000000" />
623 <parent revision="-1" node="0000000000000000000000000000000000000000" />
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 <paths>
627 <paths>
628 <path action="M">c</path>
628 <path action="M">c</path>
629 </paths>
629 </paths>
630 <extra key="branch">default</extra>
630 <extra key="branch">default</extra>
631 </logentry>
631 </logentry>
632 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
632 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
633 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
633 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
634 <parent revision="-1" node="0000000000000000000000000000000000000000" />
634 <parent revision="-1" node="0000000000000000000000000000000000000000" />
635 <author email="other@place">other</author>
635 <author email="other@place">other</author>
636 <date>1970-01-14T21:20:00+00:00</date>
636 <date>1970-01-14T21:20:00+00:00</date>
637 <msg xml:space="preserve">no person</msg>
637 <msg xml:space="preserve">no person</msg>
638 <paths>
638 <paths>
639 <path action="A">c</path>
639 <path action="A">c</path>
640 </paths>
640 </paths>
641 <extra key="branch">default</extra>
641 <extra key="branch">default</extra>
642 </logentry>
642 </logentry>
643 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
643 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
644 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
644 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
645 <parent revision="-1" node="0000000000000000000000000000000000000000" />
645 <parent revision="-1" node="0000000000000000000000000000000000000000" />
646 <author email="other@place">A. N. Other</author>
646 <author email="other@place">A. N. Other</author>
647 <date>1970-01-13T17:33:20+00:00</date>
647 <date>1970-01-13T17:33:20+00:00</date>
648 <msg xml:space="preserve">other 1
648 <msg xml:space="preserve">other 1
649 other 2
649 other 2
650
650
651 other 3</msg>
651 other 3</msg>
652 <paths>
652 <paths>
653 <path action="A">b</path>
653 <path action="A">b</path>
654 </paths>
654 </paths>
655 <extra key="branch">default</extra>
655 <extra key="branch">default</extra>
656 </logentry>
656 </logentry>
657 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
657 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
658 <parent revision="-1" node="0000000000000000000000000000000000000000" />
658 <parent revision="-1" node="0000000000000000000000000000000000000000" />
659 <parent revision="-1" node="0000000000000000000000000000000000000000" />
659 <parent revision="-1" node="0000000000000000000000000000000000000000" />
660 <author email="user@hostname">User Name</author>
660 <author email="user@hostname">User Name</author>
661 <date>1970-01-12T13:46:40+00:00</date>
661 <date>1970-01-12T13:46:40+00:00</date>
662 <msg xml:space="preserve">line 1
662 <msg xml:space="preserve">line 1
663 line 2</msg>
663 line 2</msg>
664 <paths>
664 <paths>
665 <path action="A">a</path>
665 <path action="A">a</path>
666 </paths>
666 </paths>
667 <extra key="branch">default</extra>
667 <extra key="branch">default</extra>
668 </logentry>
668 </logentry>
669 </log>
669 </log>
670
670
671
671
672 Test JSON style:
672 Test JSON style:
673
673
674 $ hg log -k nosuch -Tjson
674 $ hg log -k nosuch -Tjson
675 [
675 [
676 ]
676 ]
677
677
678 $ hg log -qr . -Tjson
678 $ hg log -qr . -Tjson
679 [
679 [
680 {
680 {
681 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
681 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
682 "rev": 8
682 "rev": 8
683 }
683 }
684 ]
684 ]
685
685
686 $ hg log -vpr . -Tjson --stat
686 $ hg log -vpr . -Tjson --stat
687 [
687 [
688 {
688 {
689 "bookmarks": [],
689 "bookmarks": [],
690 "branch": "default",
690 "branch": "default",
691 "date": [1577872860, 0],
691 "date": [1577872860, 0],
692 "desc": "third",
692 "desc": "third",
693 "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",
693 "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",
694 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
694 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
695 "files": ["fourth", "second", "third"],
695 "files": ["fourth", "second", "third"],
696 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
696 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
697 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
697 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
698 "phase": "draft",
698 "phase": "draft",
699 "rev": 8,
699 "rev": 8,
700 "tags": ["tip"],
700 "tags": ["tip"],
701 "user": "test"
701 "user": "test"
702 }
702 }
703 ]
703 ]
704
704
705 honor --git but not format-breaking diffopts
705 honor --git but not format-breaking diffopts
706 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
706 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
707 [
707 [
708 {
708 {
709 "bookmarks": [],
709 "bookmarks": [],
710 "branch": "default",
710 "branch": "default",
711 "date": [1577872860, 0],
711 "date": [1577872860, 0],
712 "desc": "third",
712 "desc": "third",
713 "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",
713 "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",
714 "files": ["fourth", "second", "third"],
714 "files": ["fourth", "second", "third"],
715 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
715 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
716 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
716 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
717 "phase": "draft",
717 "phase": "draft",
718 "rev": 8,
718 "rev": 8,
719 "tags": ["tip"],
719 "tags": ["tip"],
720 "user": "test"
720 "user": "test"
721 }
721 }
722 ]
722 ]
723
723
724 $ hg log -T json
724 $ hg log -T json
725 [
725 [
726 {
726 {
727 "bookmarks": [],
727 "bookmarks": [],
728 "branch": "default",
728 "branch": "default",
729 "date": [1577872860, 0],
729 "date": [1577872860, 0],
730 "desc": "third",
730 "desc": "third",
731 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
731 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
732 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
732 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
733 "phase": "draft",
733 "phase": "draft",
734 "rev": 8,
734 "rev": 8,
735 "tags": ["tip"],
735 "tags": ["tip"],
736 "user": "test"
736 "user": "test"
737 },
737 },
738 {
738 {
739 "bookmarks": [],
739 "bookmarks": [],
740 "branch": "default",
740 "branch": "default",
741 "date": [1000000, 0],
741 "date": [1000000, 0],
742 "desc": "second",
742 "desc": "second",
743 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
743 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
744 "parents": ["0000000000000000000000000000000000000000"],
744 "parents": ["0000000000000000000000000000000000000000"],
745 "phase": "draft",
745 "phase": "draft",
746 "rev": 7,
746 "rev": 7,
747 "tags": [],
747 "tags": [],
748 "user": "User Name <user@hostname>"
748 "user": "User Name <user@hostname>"
749 },
749 },
750 {
750 {
751 "bookmarks": [],
751 "bookmarks": [],
752 "branch": "default",
752 "branch": "default",
753 "date": [1500001, 0],
753 "date": [1500001, 0],
754 "desc": "merge",
754 "desc": "merge",
755 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
755 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
756 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
756 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
757 "phase": "draft",
757 "phase": "draft",
758 "rev": 6,
758 "rev": 6,
759 "tags": [],
759 "tags": [],
760 "user": "person"
760 "user": "person"
761 },
761 },
762 {
762 {
763 "bookmarks": [],
763 "bookmarks": [],
764 "branch": "default",
764 "branch": "default",
765 "date": [1500000, 0],
765 "date": [1500000, 0],
766 "desc": "new head",
766 "desc": "new head",
767 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
767 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
768 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
768 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
769 "phase": "draft",
769 "phase": "draft",
770 "rev": 5,
770 "rev": 5,
771 "tags": [],
771 "tags": [],
772 "user": "person"
772 "user": "person"
773 },
773 },
774 {
774 {
775 "bookmarks": [],
775 "bookmarks": [],
776 "branch": "foo",
776 "branch": "foo",
777 "date": [1400000, 0],
777 "date": [1400000, 0],
778 "desc": "new branch",
778 "desc": "new branch",
779 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
779 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
780 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
780 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
781 "phase": "draft",
781 "phase": "draft",
782 "rev": 4,
782 "rev": 4,
783 "tags": [],
783 "tags": [],
784 "user": "person"
784 "user": "person"
785 },
785 },
786 {
786 {
787 "bookmarks": [],
787 "bookmarks": [],
788 "branch": "default",
788 "branch": "default",
789 "date": [1300000, 0],
789 "date": [1300000, 0],
790 "desc": "no user, no domain",
790 "desc": "no user, no domain",
791 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
791 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
792 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
792 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
793 "phase": "draft",
793 "phase": "draft",
794 "rev": 3,
794 "rev": 3,
795 "tags": [],
795 "tags": [],
796 "user": "person"
796 "user": "person"
797 },
797 },
798 {
798 {
799 "bookmarks": [],
799 "bookmarks": [],
800 "branch": "default",
800 "branch": "default",
801 "date": [1200000, 0],
801 "date": [1200000, 0],
802 "desc": "no person",
802 "desc": "no person",
803 "node": "97054abb4ab824450e9164180baf491ae0078465",
803 "node": "97054abb4ab824450e9164180baf491ae0078465",
804 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
804 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
805 "phase": "draft",
805 "phase": "draft",
806 "rev": 2,
806 "rev": 2,
807 "tags": [],
807 "tags": [],
808 "user": "other@place"
808 "user": "other@place"
809 },
809 },
810 {
810 {
811 "bookmarks": [],
811 "bookmarks": [],
812 "branch": "default",
812 "branch": "default",
813 "date": [1100000, 0],
813 "date": [1100000, 0],
814 "desc": "other 1\nother 2\n\nother 3",
814 "desc": "other 1\nother 2\n\nother 3",
815 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
815 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
816 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
816 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
817 "phase": "draft",
817 "phase": "draft",
818 "rev": 1,
818 "rev": 1,
819 "tags": [],
819 "tags": [],
820 "user": "A. N. Other <other@place>"
820 "user": "A. N. Other <other@place>"
821 },
821 },
822 {
822 {
823 "bookmarks": [],
823 "bookmarks": [],
824 "branch": "default",
824 "branch": "default",
825 "date": [1000000, 0],
825 "date": [1000000, 0],
826 "desc": "line 1\nline 2",
826 "desc": "line 1\nline 2",
827 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
827 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
828 "parents": ["0000000000000000000000000000000000000000"],
828 "parents": ["0000000000000000000000000000000000000000"],
829 "phase": "draft",
829 "phase": "draft",
830 "rev": 0,
830 "rev": 0,
831 "tags": [],
831 "tags": [],
832 "user": "User Name <user@hostname>"
832 "user": "User Name <user@hostname>"
833 }
833 }
834 ]
834 ]
835
835
836 $ hg heads -v -Tjson
836 $ hg heads -v -Tjson
837 [
837 [
838 {
838 {
839 "bookmarks": [],
839 "bookmarks": [],
840 "branch": "default",
840 "branch": "default",
841 "date": [1577872860, 0],
841 "date": [1577872860, 0],
842 "desc": "third",
842 "desc": "third",
843 "files": ["fourth", "second", "third"],
843 "files": ["fourth", "second", "third"],
844 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
844 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
845 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
845 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
846 "phase": "draft",
846 "phase": "draft",
847 "rev": 8,
847 "rev": 8,
848 "tags": ["tip"],
848 "tags": ["tip"],
849 "user": "test"
849 "user": "test"
850 },
850 },
851 {
851 {
852 "bookmarks": [],
852 "bookmarks": [],
853 "branch": "default",
853 "branch": "default",
854 "date": [1500001, 0],
854 "date": [1500001, 0],
855 "desc": "merge",
855 "desc": "merge",
856 "files": [],
856 "files": [],
857 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
857 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
858 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
858 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
859 "phase": "draft",
859 "phase": "draft",
860 "rev": 6,
860 "rev": 6,
861 "tags": [],
861 "tags": [],
862 "user": "person"
862 "user": "person"
863 },
863 },
864 {
864 {
865 "bookmarks": [],
865 "bookmarks": [],
866 "branch": "foo",
866 "branch": "foo",
867 "date": [1400000, 0],
867 "date": [1400000, 0],
868 "desc": "new branch",
868 "desc": "new branch",
869 "files": [],
869 "files": [],
870 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
870 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
871 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
871 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
872 "phase": "draft",
872 "phase": "draft",
873 "rev": 4,
873 "rev": 4,
874 "tags": [],
874 "tags": [],
875 "user": "person"
875 "user": "person"
876 }
876 }
877 ]
877 ]
878
878
879 $ hg log --debug -Tjson
879 $ hg log --debug -Tjson
880 [
880 [
881 {
881 {
882 "added": ["fourth", "third"],
882 "added": ["fourth", "third"],
883 "bookmarks": [],
883 "bookmarks": [],
884 "branch": "default",
884 "branch": "default",
885 "date": [1577872860, 0],
885 "date": [1577872860, 0],
886 "desc": "third",
886 "desc": "third",
887 "extra": {"branch": "default"},
887 "extra": {"branch": "default"},
888 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
888 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
889 "modified": [],
889 "modified": [],
890 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
890 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
891 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
891 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
892 "phase": "draft",
892 "phase": "draft",
893 "removed": ["second"],
893 "removed": ["second"],
894 "rev": 8,
894 "rev": 8,
895 "tags": ["tip"],
895 "tags": ["tip"],
896 "user": "test"
896 "user": "test"
897 },
897 },
898 {
898 {
899 "added": ["second"],
899 "added": ["second"],
900 "bookmarks": [],
900 "bookmarks": [],
901 "branch": "default",
901 "branch": "default",
902 "date": [1000000, 0],
902 "date": [1000000, 0],
903 "desc": "second",
903 "desc": "second",
904 "extra": {"branch": "default"},
904 "extra": {"branch": "default"},
905 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
905 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
906 "modified": [],
906 "modified": [],
907 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
907 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
908 "parents": ["0000000000000000000000000000000000000000"],
908 "parents": ["0000000000000000000000000000000000000000"],
909 "phase": "draft",
909 "phase": "draft",
910 "removed": [],
910 "removed": [],
911 "rev": 7,
911 "rev": 7,
912 "tags": [],
912 "tags": [],
913 "user": "User Name <user@hostname>"
913 "user": "User Name <user@hostname>"
914 },
914 },
915 {
915 {
916 "added": [],
916 "added": [],
917 "bookmarks": [],
917 "bookmarks": [],
918 "branch": "default",
918 "branch": "default",
919 "date": [1500001, 0],
919 "date": [1500001, 0],
920 "desc": "merge",
920 "desc": "merge",
921 "extra": {"branch": "default"},
921 "extra": {"branch": "default"},
922 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
922 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
923 "modified": [],
923 "modified": [],
924 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
924 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
925 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
925 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
926 "phase": "draft",
926 "phase": "draft",
927 "removed": [],
927 "removed": [],
928 "rev": 6,
928 "rev": 6,
929 "tags": [],
929 "tags": [],
930 "user": "person"
930 "user": "person"
931 },
931 },
932 {
932 {
933 "added": ["d"],
933 "added": ["d"],
934 "bookmarks": [],
934 "bookmarks": [],
935 "branch": "default",
935 "branch": "default",
936 "date": [1500000, 0],
936 "date": [1500000, 0],
937 "desc": "new head",
937 "desc": "new head",
938 "extra": {"branch": "default"},
938 "extra": {"branch": "default"},
939 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
939 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
940 "modified": [],
940 "modified": [],
941 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
941 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
942 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
942 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
943 "phase": "draft",
943 "phase": "draft",
944 "removed": [],
944 "removed": [],
945 "rev": 5,
945 "rev": 5,
946 "tags": [],
946 "tags": [],
947 "user": "person"
947 "user": "person"
948 },
948 },
949 {
949 {
950 "added": [],
950 "added": [],
951 "bookmarks": [],
951 "bookmarks": [],
952 "branch": "foo",
952 "branch": "foo",
953 "date": [1400000, 0],
953 "date": [1400000, 0],
954 "desc": "new branch",
954 "desc": "new branch",
955 "extra": {"branch": "foo"},
955 "extra": {"branch": "foo"},
956 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
956 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
957 "modified": [],
957 "modified": [],
958 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
958 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
959 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
959 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
960 "phase": "draft",
960 "phase": "draft",
961 "removed": [],
961 "removed": [],
962 "rev": 4,
962 "rev": 4,
963 "tags": [],
963 "tags": [],
964 "user": "person"
964 "user": "person"
965 },
965 },
966 {
966 {
967 "added": [],
967 "added": [],
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 "extra": {"branch": "default"},
972 "extra": {"branch": "default"},
973 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
973 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
974 "modified": ["c"],
974 "modified": ["c"],
975 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
975 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
976 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
976 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
977 "phase": "draft",
977 "phase": "draft",
978 "removed": [],
978 "removed": [],
979 "rev": 3,
979 "rev": 3,
980 "tags": [],
980 "tags": [],
981 "user": "person"
981 "user": "person"
982 },
982 },
983 {
983 {
984 "added": ["c"],
984 "added": ["c"],
985 "bookmarks": [],
985 "bookmarks": [],
986 "branch": "default",
986 "branch": "default",
987 "date": [1200000, 0],
987 "date": [1200000, 0],
988 "desc": "no person",
988 "desc": "no person",
989 "extra": {"branch": "default"},
989 "extra": {"branch": "default"},
990 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
990 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
991 "modified": [],
991 "modified": [],
992 "node": "97054abb4ab824450e9164180baf491ae0078465",
992 "node": "97054abb4ab824450e9164180baf491ae0078465",
993 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
993 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
994 "phase": "draft",
994 "phase": "draft",
995 "removed": [],
995 "removed": [],
996 "rev": 2,
996 "rev": 2,
997 "tags": [],
997 "tags": [],
998 "user": "other@place"
998 "user": "other@place"
999 },
999 },
1000 {
1000 {
1001 "added": ["b"],
1001 "added": ["b"],
1002 "bookmarks": [],
1002 "bookmarks": [],
1003 "branch": "default",
1003 "branch": "default",
1004 "date": [1100000, 0],
1004 "date": [1100000, 0],
1005 "desc": "other 1\nother 2\n\nother 3",
1005 "desc": "other 1\nother 2\n\nother 3",
1006 "extra": {"branch": "default"},
1006 "extra": {"branch": "default"},
1007 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
1007 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
1008 "modified": [],
1008 "modified": [],
1009 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
1009 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
1010 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
1010 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
1011 "phase": "draft",
1011 "phase": "draft",
1012 "removed": [],
1012 "removed": [],
1013 "rev": 1,
1013 "rev": 1,
1014 "tags": [],
1014 "tags": [],
1015 "user": "A. N. Other <other@place>"
1015 "user": "A. N. Other <other@place>"
1016 },
1016 },
1017 {
1017 {
1018 "added": ["a"],
1018 "added": ["a"],
1019 "bookmarks": [],
1019 "bookmarks": [],
1020 "branch": "default",
1020 "branch": "default",
1021 "date": [1000000, 0],
1021 "date": [1000000, 0],
1022 "desc": "line 1\nline 2",
1022 "desc": "line 1\nline 2",
1023 "extra": {"branch": "default"},
1023 "extra": {"branch": "default"},
1024 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
1024 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
1025 "modified": [],
1025 "modified": [],
1026 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1026 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1027 "parents": ["0000000000000000000000000000000000000000"],
1027 "parents": ["0000000000000000000000000000000000000000"],
1028 "phase": "draft",
1028 "phase": "draft",
1029 "removed": [],
1029 "removed": [],
1030 "rev": 0,
1030 "rev": 0,
1031 "tags": [],
1031 "tags": [],
1032 "user": "User Name <user@hostname>"
1032 "user": "User Name <user@hostname>"
1033 }
1033 }
1034 ]
1034 ]
1035
1035
1036 Error if style not readable:
1036 Error if style not readable:
1037
1037
1038 #if unix-permissions no-root
1038 #if unix-permissions no-root
1039 $ touch q
1039 $ touch q
1040 $ chmod 0 q
1040 $ chmod 0 q
1041 $ hg log --style ./q
1041 $ hg log --style ./q
1042 abort: Permission denied: ./q
1042 abort: Permission denied: ./q
1043 [255]
1043 [255]
1044 #endif
1044 #endif
1045
1045
1046 Error if no style:
1046 Error if no style:
1047
1047
1048 $ hg log --style notexist
1048 $ hg log --style notexist
1049 abort: style 'notexist' not found
1049 abort: style 'notexist' not found
1050 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
1050 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
1051 [255]
1051 [255]
1052
1052
1053 $ hg log -T list
1053 $ hg log -T list
1054 available styles: bisect, changelog, compact, default, phases, show, status, xml
1054 available styles: bisect, changelog, compact, default, phases, show, status, xml
1055 abort: specify a template
1055 abort: specify a template
1056 [255]
1056 [255]
1057
1057
1058 Error if style missing key:
1058 Error if style missing key:
1059
1059
1060 $ echo 'q = q' > t
1060 $ echo 'q = q' > t
1061 $ hg log --style ./t
1061 $ hg log --style ./t
1062 abort: "changeset" not in template map
1062 abort: "changeset" not in template map
1063 [255]
1063 [255]
1064
1064
1065 Error if style missing value:
1065 Error if style missing value:
1066
1066
1067 $ echo 'changeset =' > t
1067 $ echo 'changeset =' > t
1068 $ hg log --style t
1068 $ hg log --style t
1069 hg: parse error at t:1: missing value
1069 hg: parse error at t:1: missing value
1070 [255]
1070 [255]
1071
1071
1072 Error if include fails:
1072 Error if include fails:
1073
1073
1074 $ echo 'changeset = q' >> t
1074 $ echo 'changeset = q' >> t
1075 #if unix-permissions no-root
1075 #if unix-permissions no-root
1076 $ hg log --style ./t
1076 $ hg log --style ./t
1077 abort: template file ./q: Permission denied
1077 abort: template file ./q: Permission denied
1078 [255]
1078 [255]
1079 $ rm -f q
1079 $ rm -f q
1080 #endif
1080 #endif
1081
1081
1082 Include works:
1082 Include works:
1083
1083
1084 $ echo '{rev}' > q
1084 $ echo '{rev}' > q
1085 $ hg log --style ./t
1085 $ hg log --style ./t
1086 8
1086 8
1087 7
1087 7
1088 6
1088 6
1089 5
1089 5
1090 4
1090 4
1091 3
1091 3
1092 2
1092 2
1093 1
1093 1
1094 0
1094 0
1095
1095
1096 $ hg phase -r 5 --public
1096 $ hg phase -r 5 --public
1097 $ hg phase -r 7 --secret --force
1097 $ hg phase -r 7 --secret --force
1098
1098
1099 Missing non-standard names give no error (backward compatibility):
1099 Missing non-standard names give no error (backward compatibility):
1100
1100
1101 $ echo "changeset = '{c}'" > t
1101 $ echo "changeset = '{c}'" > t
1102 $ hg log --style ./t
1102 $ hg log --style ./t
1103
1103
1104 Defining non-standard name works:
1104 Defining non-standard name works:
1105
1105
1106 $ cat <<EOF > t
1106 $ cat <<EOF > t
1107 > changeset = '{c}'
1107 > changeset = '{c}'
1108 > c = q
1108 > c = q
1109 > EOF
1109 > EOF
1110 $ hg log --style ./t
1110 $ hg log --style ./t
1111 8
1111 8
1112 7
1112 7
1113 6
1113 6
1114 5
1114 5
1115 4
1115 4
1116 3
1116 3
1117 2
1117 2
1118 1
1118 1
1119 0
1119 0
1120
1120
1121 ui.style works:
1121 ui.style works:
1122
1122
1123 $ echo '[ui]' > .hg/hgrc
1123 $ echo '[ui]' > .hg/hgrc
1124 $ echo 'style = t' >> .hg/hgrc
1124 $ echo 'style = t' >> .hg/hgrc
1125 $ hg log
1125 $ hg log
1126 8
1126 8
1127 7
1127 7
1128 6
1128 6
1129 5
1129 5
1130 4
1130 4
1131 3
1131 3
1132 2
1132 2
1133 1
1133 1
1134 0
1134 0
1135
1135
1136 Issue338:
1136 Issue338:
1137
1137
1138 $ hg log --style=changelog > changelog
1138 $ hg log --style=changelog > changelog
1139
1139
1140 $ cat changelog
1140 $ cat changelog
1141 2020-01-01 test <test>
1141 2020-01-01 test <test>
1142
1142
1143 * fourth, second, third:
1143 * fourth, second, third:
1144 third
1144 third
1145 [95c24699272e] [tip]
1145 [95c24699272e] [tip]
1146
1146
1147 1970-01-12 User Name <user@hostname>
1147 1970-01-12 User Name <user@hostname>
1148
1148
1149 * second:
1149 * second:
1150 second
1150 second
1151 [29114dbae42b]
1151 [29114dbae42b]
1152
1152
1153 1970-01-18 person <person>
1153 1970-01-18 person <person>
1154
1154
1155 * merge
1155 * merge
1156 [d41e714fe50d]
1156 [d41e714fe50d]
1157
1157
1158 * d:
1158 * d:
1159 new head
1159 new head
1160 [13207e5a10d9]
1160 [13207e5a10d9]
1161
1161
1162 1970-01-17 person <person>
1162 1970-01-17 person <person>
1163
1163
1164 * new branch
1164 * new branch
1165 [bbe44766e73d] <foo>
1165 [bbe44766e73d] <foo>
1166
1166
1167 1970-01-16 person <person>
1167 1970-01-16 person <person>
1168
1168
1169 * c:
1169 * c:
1170 no user, no domain
1170 no user, no domain
1171 [10e46f2dcbf4]
1171 [10e46f2dcbf4]
1172
1172
1173 1970-01-14 other <other@place>
1173 1970-01-14 other <other@place>
1174
1174
1175 * c:
1175 * c:
1176 no person
1176 no person
1177 [97054abb4ab8]
1177 [97054abb4ab8]
1178
1178
1179 1970-01-13 A. N. Other <other@place>
1179 1970-01-13 A. N. Other <other@place>
1180
1180
1181 * b:
1181 * b:
1182 other 1 other 2
1182 other 1 other 2
1183
1183
1184 other 3
1184 other 3
1185 [b608e9d1a3f0]
1185 [b608e9d1a3f0]
1186
1186
1187 1970-01-12 User Name <user@hostname>
1187 1970-01-12 User Name <user@hostname>
1188
1188
1189 * a:
1189 * a:
1190 line 1 line 2
1190 line 1 line 2
1191 [1e4e1b8f71e0]
1191 [1e4e1b8f71e0]
1192
1192
1193
1193
1194 Issue2130: xml output for 'hg heads' is malformed
1194 Issue2130: xml output for 'hg heads' is malformed
1195
1195
1196 $ hg heads --style changelog
1196 $ hg heads --style changelog
1197 2020-01-01 test <test>
1197 2020-01-01 test <test>
1198
1198
1199 * fourth, second, third:
1199 * fourth, second, third:
1200 third
1200 third
1201 [95c24699272e] [tip]
1201 [95c24699272e] [tip]
1202
1202
1203 1970-01-18 person <person>
1203 1970-01-18 person <person>
1204
1204
1205 * merge
1205 * merge
1206 [d41e714fe50d]
1206 [d41e714fe50d]
1207
1207
1208 1970-01-17 person <person>
1208 1970-01-17 person <person>
1209
1209
1210 * new branch
1210 * new branch
1211 [bbe44766e73d] <foo>
1211 [bbe44766e73d] <foo>
1212
1212
1213
1213
1214 Add a dummy commit to make up for the instability of the above:
1214 Add a dummy commit to make up for the instability of the above:
1215
1215
1216 $ echo a > a
1216 $ echo a > a
1217 $ hg add a
1217 $ hg add a
1218 $ hg ci -m future
1218 $ hg ci -m future
1219
1219
1220 Add a commit that does all possible modifications at once
1220 Add a commit that does all possible modifications at once
1221
1221
1222 $ echo modify >> third
1222 $ echo modify >> third
1223 $ touch b
1223 $ touch b
1224 $ hg add b
1224 $ hg add b
1225 $ hg mv fourth fifth
1225 $ hg mv fourth fifth
1226 $ hg rm a
1226 $ hg rm a
1227 $ hg ci -m "Modify, add, remove, rename"
1227 $ hg ci -m "Modify, add, remove, rename"
1228
1228
1229 Check the status template
1229 Check the status template
1230
1230
1231 $ cat <<EOF >> $HGRCPATH
1231 $ cat <<EOF >> $HGRCPATH
1232 > [extensions]
1232 > [extensions]
1233 > color=
1233 > color=
1234 > EOF
1234 > EOF
1235
1235
1236 $ hg log -T status -r 10
1236 $ hg log -T status -r 10
1237 changeset: 10:0f9759ec227a
1237 changeset: 10:0f9759ec227a
1238 tag: tip
1238 tag: tip
1239 user: test
1239 user: test
1240 date: Thu Jan 01 00:00:00 1970 +0000
1240 date: Thu Jan 01 00:00:00 1970 +0000
1241 summary: Modify, add, remove, rename
1241 summary: Modify, add, remove, rename
1242 files:
1242 files:
1243 M third
1243 M third
1244 A b
1244 A b
1245 A fifth
1245 A fifth
1246 R a
1246 R a
1247 R fourth
1247 R fourth
1248
1248
1249 $ hg log -T status -C -r 10
1249 $ hg log -T status -C -r 10
1250 changeset: 10:0f9759ec227a
1250 changeset: 10:0f9759ec227a
1251 tag: tip
1251 tag: tip
1252 user: test
1252 user: test
1253 date: Thu Jan 01 00:00:00 1970 +0000
1253 date: Thu Jan 01 00:00:00 1970 +0000
1254 summary: Modify, add, remove, rename
1254 summary: Modify, add, remove, rename
1255 files:
1255 files:
1256 M third
1256 M third
1257 A b
1257 A b
1258 A fifth
1258 A fifth
1259 fourth
1259 fourth
1260 R a
1260 R a
1261 R fourth
1261 R fourth
1262
1262
1263 $ hg log -T status -C -r 10 -v
1263 $ hg log -T status -C -r 10 -v
1264 changeset: 10:0f9759ec227a
1264 changeset: 10:0f9759ec227a
1265 tag: tip
1265 tag: tip
1266 user: test
1266 user: test
1267 date: Thu Jan 01 00:00:00 1970 +0000
1267 date: Thu Jan 01 00:00:00 1970 +0000
1268 description:
1268 description:
1269 Modify, add, remove, rename
1269 Modify, add, remove, rename
1270
1270
1271 files:
1271 files:
1272 M third
1272 M third
1273 A b
1273 A b
1274 A fifth
1274 A fifth
1275 fourth
1275 fourth
1276 R a
1276 R a
1277 R fourth
1277 R fourth
1278
1278
1279 $ hg log -T status -C -r 10 --debug
1279 $ hg log -T status -C -r 10 --debug
1280 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
1280 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
1281 tag: tip
1281 tag: tip
1282 phase: secret
1282 phase: secret
1283 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
1283 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
1284 parent: -1:0000000000000000000000000000000000000000
1284 parent: -1:0000000000000000000000000000000000000000
1285 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
1285 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
1286 user: test
1286 user: test
1287 date: Thu Jan 01 00:00:00 1970 +0000
1287 date: Thu Jan 01 00:00:00 1970 +0000
1288 extra: branch=default
1288 extra: branch=default
1289 description:
1289 description:
1290 Modify, add, remove, rename
1290 Modify, add, remove, rename
1291
1291
1292 files:
1292 files:
1293 M third
1293 M third
1294 A b
1294 A b
1295 A fifth
1295 A fifth
1296 fourth
1296 fourth
1297 R a
1297 R a
1298 R fourth
1298 R fourth
1299
1299
1300 $ hg log -T status -C -r 10 --quiet
1300 $ hg log -T status -C -r 10 --quiet
1301 10:0f9759ec227a
1301 10:0f9759ec227a
1302 $ hg --color=debug log -T status -r 10
1302 $ hg --color=debug log -T status -r 10
1303 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
1303 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
1304 [log.tag|tag: tip]
1304 [log.tag|tag: tip]
1305 [log.user|user: test]
1305 [log.user|user: test]
1306 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1306 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1307 [log.summary|summary: Modify, add, remove, rename]
1307 [log.summary|summary: Modify, add, remove, rename]
1308 [ui.note log.files|files:]
1308 [ui.note log.files|files:]
1309 [status.modified|M third]
1309 [status.modified|M third]
1310 [status.added|A b]
1310 [status.added|A b]
1311 [status.added|A fifth]
1311 [status.added|A fifth]
1312 [status.removed|R a]
1312 [status.removed|R a]
1313 [status.removed|R fourth]
1313 [status.removed|R fourth]
1314
1314
1315 $ hg --color=debug log -T status -C -r 10
1315 $ hg --color=debug log -T status -C -r 10
1316 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
1316 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
1317 [log.tag|tag: tip]
1317 [log.tag|tag: tip]
1318 [log.user|user: test]
1318 [log.user|user: test]
1319 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1319 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1320 [log.summary|summary: Modify, add, remove, rename]
1320 [log.summary|summary: Modify, add, remove, rename]
1321 [ui.note log.files|files:]
1321 [ui.note log.files|files:]
1322 [status.modified|M third]
1322 [status.modified|M third]
1323 [status.added|A b]
1323 [status.added|A b]
1324 [status.added|A fifth]
1324 [status.added|A fifth]
1325 [status.copied| fourth]
1325 [status.copied| fourth]
1326 [status.removed|R a]
1326 [status.removed|R a]
1327 [status.removed|R fourth]
1327 [status.removed|R fourth]
1328
1328
1329 $ hg --color=debug log -T status -C -r 10 -v
1329 $ hg --color=debug log -T status -C -r 10 -v
1330 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
1330 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
1331 [log.tag|tag: tip]
1331 [log.tag|tag: tip]
1332 [log.user|user: test]
1332 [log.user|user: test]
1333 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1333 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1334 [ui.note log.description|description:]
1334 [ui.note log.description|description:]
1335 [ui.note log.description|Modify, add, remove, rename]
1335 [ui.note log.description|Modify, add, remove, rename]
1336
1336
1337 [ui.note log.files|files:]
1337 [ui.note log.files|files:]
1338 [status.modified|M third]
1338 [status.modified|M third]
1339 [status.added|A b]
1339 [status.added|A b]
1340 [status.added|A fifth]
1340 [status.added|A fifth]
1341 [status.copied| fourth]
1341 [status.copied| fourth]
1342 [status.removed|R a]
1342 [status.removed|R a]
1343 [status.removed|R fourth]
1343 [status.removed|R fourth]
1344
1344
1345 $ hg --color=debug log -T status -C -r 10 --debug
1345 $ hg --color=debug log -T status -C -r 10 --debug
1346 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
1346 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
1347 [log.tag|tag: tip]
1347 [log.tag|tag: tip]
1348 [log.phase|phase: secret]
1348 [log.phase|phase: secret]
1349 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
1349 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
1350 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1350 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1351 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
1351 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
1352 [log.user|user: test]
1352 [log.user|user: test]
1353 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1353 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1354 [ui.debug log.extra|extra: branch=default]
1354 [ui.debug log.extra|extra: branch=default]
1355 [ui.note log.description|description:]
1355 [ui.note log.description|description:]
1356 [ui.note log.description|Modify, add, remove, rename]
1356 [ui.note log.description|Modify, add, remove, rename]
1357
1357
1358 [ui.note log.files|files:]
1358 [ui.note log.files|files:]
1359 [status.modified|M third]
1359 [status.modified|M third]
1360 [status.added|A b]
1360 [status.added|A b]
1361 [status.added|A fifth]
1361 [status.added|A fifth]
1362 [status.copied| fourth]
1362 [status.copied| fourth]
1363 [status.removed|R a]
1363 [status.removed|R a]
1364 [status.removed|R fourth]
1364 [status.removed|R fourth]
1365
1365
1366 $ hg --color=debug log -T status -C -r 10 --quiet
1366 $ hg --color=debug log -T status -C -r 10 --quiet
1367 [log.node|10:0f9759ec227a]
1367 [log.node|10:0f9759ec227a]
1368
1368
1369 Check the bisect template
1369 Check the bisect template
1370
1370
1371 $ hg bisect -g 1
1371 $ hg bisect -g 1
1372 $ hg bisect -b 3 --noupdate
1372 $ hg bisect -b 3 --noupdate
1373 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
1373 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
1374 $ hg log -T bisect -r 0:4
1374 $ hg log -T bisect -r 0:4
1375 changeset: 0:1e4e1b8f71e0
1375 changeset: 0:1e4e1b8f71e0
1376 bisect: good (implicit)
1376 bisect: good (implicit)
1377 user: User Name <user@hostname>
1377 user: User Name <user@hostname>
1378 date: Mon Jan 12 13:46:40 1970 +0000
1378 date: Mon Jan 12 13:46:40 1970 +0000
1379 summary: line 1
1379 summary: line 1
1380
1380
1381 changeset: 1:b608e9d1a3f0
1381 changeset: 1:b608e9d1a3f0
1382 bisect: good
1382 bisect: good
1383 user: A. N. Other <other@place>
1383 user: A. N. Other <other@place>
1384 date: Tue Jan 13 17:33:20 1970 +0000
1384 date: Tue Jan 13 17:33:20 1970 +0000
1385 summary: other 1
1385 summary: other 1
1386
1386
1387 changeset: 2:97054abb4ab8
1387 changeset: 2:97054abb4ab8
1388 bisect: untested
1388 bisect: untested
1389 user: other@place
1389 user: other@place
1390 date: Wed Jan 14 21:20:00 1970 +0000
1390 date: Wed Jan 14 21:20:00 1970 +0000
1391 summary: no person
1391 summary: no person
1392
1392
1393 changeset: 3:10e46f2dcbf4
1393 changeset: 3:10e46f2dcbf4
1394 bisect: bad
1394 bisect: bad
1395 user: person
1395 user: person
1396 date: Fri Jan 16 01:06:40 1970 +0000
1396 date: Fri Jan 16 01:06:40 1970 +0000
1397 summary: no user, no domain
1397 summary: no user, no domain
1398
1398
1399 changeset: 4:bbe44766e73d
1399 changeset: 4:bbe44766e73d
1400 bisect: bad (implicit)
1400 bisect: bad (implicit)
1401 branch: foo
1401 branch: foo
1402 user: person
1402 user: person
1403 date: Sat Jan 17 04:53:20 1970 +0000
1403 date: Sat Jan 17 04:53:20 1970 +0000
1404 summary: new branch
1404 summary: new branch
1405
1405
1406 $ hg log --debug -T bisect -r 0:4
1406 $ hg log --debug -T bisect -r 0:4
1407 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
1407 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
1408 bisect: good (implicit)
1408 bisect: good (implicit)
1409 phase: public
1409 phase: public
1410 parent: -1:0000000000000000000000000000000000000000
1410 parent: -1:0000000000000000000000000000000000000000
1411 parent: -1:0000000000000000000000000000000000000000
1411 parent: -1:0000000000000000000000000000000000000000
1412 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1412 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1413 user: User Name <user@hostname>
1413 user: User Name <user@hostname>
1414 date: Mon Jan 12 13:46:40 1970 +0000
1414 date: Mon Jan 12 13:46:40 1970 +0000
1415 files+: a
1415 files+: a
1416 extra: branch=default
1416 extra: branch=default
1417 description:
1417 description:
1418 line 1
1418 line 1
1419 line 2
1419 line 2
1420
1420
1421
1421
1422 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1422 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1423 bisect: good
1423 bisect: good
1424 phase: public
1424 phase: public
1425 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
1425 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
1426 parent: -1:0000000000000000000000000000000000000000
1426 parent: -1:0000000000000000000000000000000000000000
1427 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1427 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1428 user: A. N. Other <other@place>
1428 user: A. N. Other <other@place>
1429 date: Tue Jan 13 17:33:20 1970 +0000
1429 date: Tue Jan 13 17:33:20 1970 +0000
1430 files+: b
1430 files+: b
1431 extra: branch=default
1431 extra: branch=default
1432 description:
1432 description:
1433 other 1
1433 other 1
1434 other 2
1434 other 2
1435
1435
1436 other 3
1436 other 3
1437
1437
1438
1438
1439 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
1439 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
1440 bisect: untested
1440 bisect: untested
1441 phase: public
1441 phase: public
1442 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1442 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1443 parent: -1:0000000000000000000000000000000000000000
1443 parent: -1:0000000000000000000000000000000000000000
1444 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1444 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1445 user: other@place
1445 user: other@place
1446 date: Wed Jan 14 21:20:00 1970 +0000
1446 date: Wed Jan 14 21:20:00 1970 +0000
1447 files+: c
1447 files+: c
1448 extra: branch=default
1448 extra: branch=default
1449 description:
1449 description:
1450 no person
1450 no person
1451
1451
1452
1452
1453 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
1453 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
1454 bisect: bad
1454 bisect: bad
1455 phase: public
1455 phase: public
1456 parent: 2:97054abb4ab824450e9164180baf491ae0078465
1456 parent: 2:97054abb4ab824450e9164180baf491ae0078465
1457 parent: -1:0000000000000000000000000000000000000000
1457 parent: -1:0000000000000000000000000000000000000000
1458 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1458 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1459 user: person
1459 user: person
1460 date: Fri Jan 16 01:06:40 1970 +0000
1460 date: Fri Jan 16 01:06:40 1970 +0000
1461 files: c
1461 files: c
1462 extra: branch=default
1462 extra: branch=default
1463 description:
1463 description:
1464 no user, no domain
1464 no user, no domain
1465
1465
1466
1466
1467 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1467 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1468 bisect: bad (implicit)
1468 bisect: bad (implicit)
1469 branch: foo
1469 branch: foo
1470 phase: draft
1470 phase: draft
1471 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
1471 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
1472 parent: -1:0000000000000000000000000000000000000000
1472 parent: -1:0000000000000000000000000000000000000000
1473 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1473 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1474 user: person
1474 user: person
1475 date: Sat Jan 17 04:53:20 1970 +0000
1475 date: Sat Jan 17 04:53:20 1970 +0000
1476 extra: branch=foo
1476 extra: branch=foo
1477 description:
1477 description:
1478 new branch
1478 new branch
1479
1479
1480
1480
1481 $ hg log -v -T bisect -r 0:4
1481 $ hg log -v -T bisect -r 0:4
1482 changeset: 0:1e4e1b8f71e0
1482 changeset: 0:1e4e1b8f71e0
1483 bisect: good (implicit)
1483 bisect: good (implicit)
1484 user: User Name <user@hostname>
1484 user: User Name <user@hostname>
1485 date: Mon Jan 12 13:46:40 1970 +0000
1485 date: Mon Jan 12 13:46:40 1970 +0000
1486 files: a
1486 files: a
1487 description:
1487 description:
1488 line 1
1488 line 1
1489 line 2
1489 line 2
1490
1490
1491
1491
1492 changeset: 1:b608e9d1a3f0
1492 changeset: 1:b608e9d1a3f0
1493 bisect: good
1493 bisect: good
1494 user: A. N. Other <other@place>
1494 user: A. N. Other <other@place>
1495 date: Tue Jan 13 17:33:20 1970 +0000
1495 date: Tue Jan 13 17:33:20 1970 +0000
1496 files: b
1496 files: b
1497 description:
1497 description:
1498 other 1
1498 other 1
1499 other 2
1499 other 2
1500
1500
1501 other 3
1501 other 3
1502
1502
1503
1503
1504 changeset: 2:97054abb4ab8
1504 changeset: 2:97054abb4ab8
1505 bisect: untested
1505 bisect: untested
1506 user: other@place
1506 user: other@place
1507 date: Wed Jan 14 21:20:00 1970 +0000
1507 date: Wed Jan 14 21:20:00 1970 +0000
1508 files: c
1508 files: c
1509 description:
1509 description:
1510 no person
1510 no person
1511
1511
1512
1512
1513 changeset: 3:10e46f2dcbf4
1513 changeset: 3:10e46f2dcbf4
1514 bisect: bad
1514 bisect: bad
1515 user: person
1515 user: person
1516 date: Fri Jan 16 01:06:40 1970 +0000
1516 date: Fri Jan 16 01:06:40 1970 +0000
1517 files: c
1517 files: c
1518 description:
1518 description:
1519 no user, no domain
1519 no user, no domain
1520
1520
1521
1521
1522 changeset: 4:bbe44766e73d
1522 changeset: 4:bbe44766e73d
1523 bisect: bad (implicit)
1523 bisect: bad (implicit)
1524 branch: foo
1524 branch: foo
1525 user: person
1525 user: person
1526 date: Sat Jan 17 04:53:20 1970 +0000
1526 date: Sat Jan 17 04:53:20 1970 +0000
1527 description:
1527 description:
1528 new branch
1528 new branch
1529
1529
1530
1530
1531 $ hg --color=debug log -T bisect -r 0:4
1531 $ hg --color=debug log -T bisect -r 0:4
1532 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
1532 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
1533 [log.bisect bisect.good|bisect: good (implicit)]
1533 [log.bisect bisect.good|bisect: good (implicit)]
1534 [log.user|user: User Name <user@hostname>]
1534 [log.user|user: User Name <user@hostname>]
1535 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
1535 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
1536 [log.summary|summary: line 1]
1536 [log.summary|summary: line 1]
1537
1537
1538 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
1538 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
1539 [log.bisect bisect.good|bisect: good]
1539 [log.bisect bisect.good|bisect: good]
1540 [log.user|user: A. N. Other <other@place>]
1540 [log.user|user: A. N. Other <other@place>]
1541 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
1541 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
1542 [log.summary|summary: other 1]
1542 [log.summary|summary: other 1]
1543
1543
1544 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
1544 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
1545 [log.bisect bisect.untested|bisect: untested]
1545 [log.bisect bisect.untested|bisect: untested]
1546 [log.user|user: other@place]
1546 [log.user|user: other@place]
1547 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
1547 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
1548 [log.summary|summary: no person]
1548 [log.summary|summary: no person]
1549
1549
1550 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
1550 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
1551 [log.bisect bisect.bad|bisect: bad]
1551 [log.bisect bisect.bad|bisect: bad]
1552 [log.user|user: person]
1552 [log.user|user: person]
1553 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
1553 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
1554 [log.summary|summary: no user, no domain]
1554 [log.summary|summary: no user, no domain]
1555
1555
1556 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
1556 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
1557 [log.bisect bisect.bad|bisect: bad (implicit)]
1557 [log.bisect bisect.bad|bisect: bad (implicit)]
1558 [log.branch|branch: foo]
1558 [log.branch|branch: foo]
1559 [log.user|user: person]
1559 [log.user|user: person]
1560 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
1560 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
1561 [log.summary|summary: new branch]
1561 [log.summary|summary: new branch]
1562
1562
1563 $ hg --color=debug log --debug -T bisect -r 0:4
1563 $ hg --color=debug log --debug -T bisect -r 0:4
1564 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
1564 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
1565 [log.bisect bisect.good|bisect: good (implicit)]
1565 [log.bisect bisect.good|bisect: good (implicit)]
1566 [log.phase|phase: public]
1566 [log.phase|phase: public]
1567 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1567 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1568 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1568 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1569 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
1569 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
1570 [log.user|user: User Name <user@hostname>]
1570 [log.user|user: User Name <user@hostname>]
1571 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
1571 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
1572 [ui.debug log.files|files+: a]
1572 [ui.debug log.files|files+: a]
1573 [ui.debug log.extra|extra: branch=default]
1573 [ui.debug log.extra|extra: branch=default]
1574 [ui.note log.description|description:]
1574 [ui.note log.description|description:]
1575 [ui.note log.description|line 1
1575 [ui.note log.description|line 1
1576 line 2]
1576 line 2]
1577
1577
1578
1578
1579 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
1579 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
1580 [log.bisect bisect.good|bisect: good]
1580 [log.bisect bisect.good|bisect: good]
1581 [log.phase|phase: public]
1581 [log.phase|phase: public]
1582 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
1582 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
1583 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1583 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1584 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
1584 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
1585 [log.user|user: A. N. Other <other@place>]
1585 [log.user|user: A. N. Other <other@place>]
1586 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
1586 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
1587 [ui.debug log.files|files+: b]
1587 [ui.debug log.files|files+: b]
1588 [ui.debug log.extra|extra: branch=default]
1588 [ui.debug log.extra|extra: branch=default]
1589 [ui.note log.description|description:]
1589 [ui.note log.description|description:]
1590 [ui.note log.description|other 1
1590 [ui.note log.description|other 1
1591 other 2
1591 other 2
1592
1592
1593 other 3]
1593 other 3]
1594
1594
1595
1595
1596 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
1596 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
1597 [log.bisect bisect.untested|bisect: untested]
1597 [log.bisect bisect.untested|bisect: untested]
1598 [log.phase|phase: public]
1598 [log.phase|phase: public]
1599 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
1599 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
1600 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1600 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1601 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
1601 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
1602 [log.user|user: other@place]
1602 [log.user|user: other@place]
1603 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
1603 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
1604 [ui.debug log.files|files+: c]
1604 [ui.debug log.files|files+: c]
1605 [ui.debug log.extra|extra: branch=default]
1605 [ui.debug log.extra|extra: branch=default]
1606 [ui.note log.description|description:]
1606 [ui.note log.description|description:]
1607 [ui.note log.description|no person]
1607 [ui.note log.description|no person]
1608
1608
1609
1609
1610 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
1610 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
1611 [log.bisect bisect.bad|bisect: bad]
1611 [log.bisect bisect.bad|bisect: bad]
1612 [log.phase|phase: public]
1612 [log.phase|phase: public]
1613 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
1613 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
1614 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1614 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1615 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
1615 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
1616 [log.user|user: person]
1616 [log.user|user: person]
1617 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
1617 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
1618 [ui.debug log.files|files: c]
1618 [ui.debug log.files|files: c]
1619 [ui.debug log.extra|extra: branch=default]
1619 [ui.debug log.extra|extra: branch=default]
1620 [ui.note log.description|description:]
1620 [ui.note log.description|description:]
1621 [ui.note log.description|no user, no domain]
1621 [ui.note log.description|no user, no domain]
1622
1622
1623
1623
1624 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
1624 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
1625 [log.bisect bisect.bad|bisect: bad (implicit)]
1625 [log.bisect bisect.bad|bisect: bad (implicit)]
1626 [log.branch|branch: foo]
1626 [log.branch|branch: foo]
1627 [log.phase|phase: draft]
1627 [log.phase|phase: draft]
1628 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
1628 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
1629 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1629 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
1630 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
1630 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
1631 [log.user|user: person]
1631 [log.user|user: person]
1632 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
1632 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
1633 [ui.debug log.extra|extra: branch=foo]
1633 [ui.debug log.extra|extra: branch=foo]
1634 [ui.note log.description|description:]
1634 [ui.note log.description|description:]
1635 [ui.note log.description|new branch]
1635 [ui.note log.description|new branch]
1636
1636
1637
1637
1638 $ hg --color=debug log -v -T bisect -r 0:4
1638 $ hg --color=debug log -v -T bisect -r 0:4
1639 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
1639 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
1640 [log.bisect bisect.good|bisect: good (implicit)]
1640 [log.bisect bisect.good|bisect: good (implicit)]
1641 [log.user|user: User Name <user@hostname>]
1641 [log.user|user: User Name <user@hostname>]
1642 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
1642 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
1643 [ui.note log.files|files: a]
1643 [ui.note log.files|files: a]
1644 [ui.note log.description|description:]
1644 [ui.note log.description|description:]
1645 [ui.note log.description|line 1
1645 [ui.note log.description|line 1
1646 line 2]
1646 line 2]
1647
1647
1648
1648
1649 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
1649 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
1650 [log.bisect bisect.good|bisect: good]
1650 [log.bisect bisect.good|bisect: good]
1651 [log.user|user: A. N. Other <other@place>]
1651 [log.user|user: A. N. Other <other@place>]
1652 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
1652 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
1653 [ui.note log.files|files: b]
1653 [ui.note log.files|files: b]
1654 [ui.note log.description|description:]
1654 [ui.note log.description|description:]
1655 [ui.note log.description|other 1
1655 [ui.note log.description|other 1
1656 other 2
1656 other 2
1657
1657
1658 other 3]
1658 other 3]
1659
1659
1660
1660
1661 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
1661 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
1662 [log.bisect bisect.untested|bisect: untested]
1662 [log.bisect bisect.untested|bisect: untested]
1663 [log.user|user: other@place]
1663 [log.user|user: other@place]
1664 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
1664 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
1665 [ui.note log.files|files: c]
1665 [ui.note log.files|files: c]
1666 [ui.note log.description|description:]
1666 [ui.note log.description|description:]
1667 [ui.note log.description|no person]
1667 [ui.note log.description|no person]
1668
1668
1669
1669
1670 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
1670 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
1671 [log.bisect bisect.bad|bisect: bad]
1671 [log.bisect bisect.bad|bisect: bad]
1672 [log.user|user: person]
1672 [log.user|user: person]
1673 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
1673 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
1674 [ui.note log.files|files: c]
1674 [ui.note log.files|files: c]
1675 [ui.note log.description|description:]
1675 [ui.note log.description|description:]
1676 [ui.note log.description|no user, no domain]
1676 [ui.note log.description|no user, no domain]
1677
1677
1678
1678
1679 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
1679 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
1680 [log.bisect bisect.bad|bisect: bad (implicit)]
1680 [log.bisect bisect.bad|bisect: bad (implicit)]
1681 [log.branch|branch: foo]
1681 [log.branch|branch: foo]
1682 [log.user|user: person]
1682 [log.user|user: person]
1683 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
1683 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
1684 [ui.note log.description|description:]
1684 [ui.note log.description|description:]
1685 [ui.note log.description|new branch]
1685 [ui.note log.description|new branch]
1686
1686
1687
1687
1688 $ hg bisect --reset
1688 $ hg bisect --reset
1689
1689
1690 $ cd ..
1690 $ cd ..
1691
1691
1692 Set up latesttag repository:
1692 Set up latesttag repository:
1693
1693
1694 $ hg init latesttag
1694 $ hg init latesttag
1695 $ cd latesttag
1695 $ cd latesttag
1696
1696
1697 $ echo a > file
1697 $ echo a > file
1698 $ hg ci -Am a -d '0 0'
1698 $ hg ci -Am a -d '0 0'
1699 adding file
1699 adding file
1700
1700
1701 $ echo b >> file
1701 $ echo b >> file
1702 $ hg ci -m b -d '1 0'
1702 $ hg ci -m b -d '1 0'
1703
1703
1704 $ echo c >> head1
1704 $ echo c >> head1
1705 $ hg ci -Am h1c -d '2 0'
1705 $ hg ci -Am h1c -d '2 0'
1706 adding head1
1706 adding head1
1707
1707
1708 $ hg update -q 1
1708 $ hg update -q 1
1709 $ echo d >> head2
1709 $ echo d >> head2
1710 $ hg ci -Am h2d -d '3 0'
1710 $ hg ci -Am h2d -d '3 0'
1711 adding head2
1711 adding head2
1712 created new head
1712 created new head
1713
1713
1714 $ echo e >> head2
1714 $ echo e >> head2
1715 $ hg ci -m h2e -d '4 0'
1715 $ hg ci -m h2e -d '4 0'
1716
1716
1717 $ hg merge -q
1717 $ hg merge -q
1718 $ hg ci -m merge -d '5 -3600'
1718 $ hg ci -m merge -d '5 -3600'
1719
1719
1720 $ hg tag -r 1 -m t1 -d '6 0' t1
1720 $ hg tag -r 1 -m t1 -d '6 0' t1
1721 $ hg tag -r 2 -m t2 -d '7 0' t2
1721 $ hg tag -r 2 -m t2 -d '7 0' t2
1722 $ hg tag -r 3 -m t3 -d '8 0' t3
1722 $ hg tag -r 3 -m t3 -d '8 0' t3
1723 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
1723 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
1724 $ hg tag -r 5 -m t5 -d '9 0' t5
1724 $ hg tag -r 5 -m t5 -d '9 0' t5
1725 $ hg tag -r 3 -m at3 -d '10 0' at3
1725 $ hg tag -r 3 -m at3 -d '10 0' at3
1726
1726
1727 $ cd ..
1727 $ cd ..
1728
1728
1729 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1729 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1730 if it is a relative path
1730 if it is a relative path
1731
1731
1732 $ mkdir -p home/styles
1732 $ mkdir -p home/styles
1733
1733
1734 $ cat > home/styles/teststyle <<EOF
1734 $ cat > home/styles/teststyle <<EOF
1735 > changeset = 'test {rev}:{node|short}\n'
1735 > changeset = 'test {rev}:{node|short}\n'
1736 > EOF
1736 > EOF
1737
1737
1738 $ HOME=`pwd`/home; export HOME
1738 $ HOME=`pwd`/home; export HOME
1739
1739
1740 $ cat > latesttag/.hg/hgrc <<EOF
1740 $ cat > latesttag/.hg/hgrc <<EOF
1741 > [ui]
1741 > [ui]
1742 > style = ~/styles/teststyle
1742 > style = ~/styles/teststyle
1743 > EOF
1743 > EOF
1744
1744
1745 $ hg -R latesttag tip
1745 $ hg -R latesttag tip
1746 test 11:97e5943b523a
1746 test 11:97e5943b523a
1747
1747
1748 Test recursive showlist template (issue1989):
1748 Test recursive showlist template (issue1989):
1749
1749
1750 $ cat > style1989 <<EOF
1750 $ cat > style1989 <<EOF
1751 > changeset = '{file_mods}{manifest}{extras}'
1751 > changeset = '{file_mods}{manifest}{extras}'
1752 > file_mod = 'M|{author|person}\n'
1752 > file_mod = 'M|{author|person}\n'
1753 > manifest = '{rev},{author}\n'
1753 > manifest = '{rev},{author}\n'
1754 > extra = '{key}: {author}\n'
1754 > extra = '{key}: {author}\n'
1755 > EOF
1755 > EOF
1756
1756
1757 $ hg -R latesttag log -r tip --style=style1989
1757 $ hg -R latesttag log -r tip --style=style1989
1758 M|test
1758 M|test
1759 11,test
1759 11,
1760 branch: test
1760 branch: test
General Comments 0
You need to be logged in to leave comments. Login now