##// END OF EJS Templates
templates: define a {onelinesummary} keyword...
Martin von Zweigbergk -
r46472:dbc57472 default draft
parent child Browse files
Show More
@@ -1,991 +1,1004 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 wdirid,
14 wdirid,
15 wdirrev,
15 wdirrev,
16 )
16 )
17
17
18 from . import (
18 from . import (
19 diffutil,
19 diffutil,
20 encoding,
20 encoding,
21 error,
21 error,
22 hbisect,
22 hbisect,
23 i18n,
23 i18n,
24 obsutil,
24 obsutil,
25 patch,
25 patch,
26 pycompat,
26 pycompat,
27 registrar,
27 registrar,
28 scmutil,
28 scmutil,
29 templateutil,
29 templateutil,
30 util,
30 util,
31 )
31 )
32 from .utils import stringutil
32 from .utils import stringutil
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
41
42 def getlatesttags(context, mapping, pattern=None):
42 def getlatesttags(context, mapping, pattern=None):
43 '''return date, distance and name for the latest tag of rev'''
43 '''return date, distance and name for the latest tag of rev'''
44 repo = context.resource(mapping, b'repo')
44 repo = context.resource(mapping, b'repo')
45 ctx = context.resource(mapping, b'ctx')
45 ctx = context.resource(mapping, b'ctx')
46 cache = context.resource(mapping, b'cache')
46 cache = context.resource(mapping, b'cache')
47
47
48 cachename = b'latesttags'
48 cachename = b'latesttags'
49 if pattern is not None:
49 if pattern is not None:
50 cachename += b'-' + pattern
50 cachename += b'-' + pattern
51 match = stringutil.stringmatcher(pattern)[2]
51 match = stringutil.stringmatcher(pattern)[2]
52 else:
52 else:
53 match = util.always
53 match = util.always
54
54
55 if cachename not in cache:
55 if cachename not in cache:
56 # Cache mapping from rev to a tuple with tag date, tag
56 # Cache mapping from rev to a tuple with tag date, tag
57 # distance and tag name
57 # distance and tag name
58 cache[cachename] = {-1: (0, 0, [b'null'])}
58 cache[cachename] = {-1: (0, 0, [b'null'])}
59 latesttags = cache[cachename]
59 latesttags = cache[cachename]
60
60
61 rev = ctx.rev()
61 rev = ctx.rev()
62 todo = [rev]
62 todo = [rev]
63 while todo:
63 while todo:
64 rev = todo.pop()
64 rev = todo.pop()
65 if rev in latesttags:
65 if rev in latesttags:
66 continue
66 continue
67 ctx = repo[rev]
67 ctx = repo[rev]
68 tags = [
68 tags = [
69 t
69 t
70 for t in ctx.tags()
70 for t in ctx.tags()
71 if (repo.tagtype(t) and repo.tagtype(t) != b'local' and match(t))
71 if (repo.tagtype(t) and repo.tagtype(t) != b'local' and match(t))
72 ]
72 ]
73 if tags:
73 if tags:
74 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
74 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
75 continue
75 continue
76 try:
76 try:
77 ptags = [latesttags[p.rev()] for p in ctx.parents()]
77 ptags = [latesttags[p.rev()] for p in ctx.parents()]
78 if len(ptags) > 1:
78 if len(ptags) > 1:
79 if ptags[0][2] == ptags[1][2]:
79 if ptags[0][2] == ptags[1][2]:
80 # The tuples are laid out so the right one can be found by
80 # The tuples are laid out so the right one can be found by
81 # comparison in this case.
81 # comparison in this case.
82 pdate, pdist, ptag = max(ptags)
82 pdate, pdist, ptag = max(ptags)
83 else:
83 else:
84
84
85 def key(x):
85 def key(x):
86 tag = x[2][0]
86 tag = x[2][0]
87 if ctx.rev() is None:
87 if ctx.rev() is None:
88 # only() doesn't support wdir
88 # only() doesn't support wdir
89 prevs = [c.rev() for c in ctx.parents()]
89 prevs = [c.rev() for c in ctx.parents()]
90 changes = repo.revs(b'only(%ld, %s)', prevs, tag)
90 changes = repo.revs(b'only(%ld, %s)', prevs, tag)
91 changessincetag = len(changes) + 1
91 changessincetag = len(changes) + 1
92 else:
92 else:
93 changes = repo.revs(b'only(%d, %s)', ctx.rev(), tag)
93 changes = repo.revs(b'only(%d, %s)', ctx.rev(), tag)
94 changessincetag = len(changes)
94 changessincetag = len(changes)
95 # Smallest number of changes since tag wins. Date is
95 # Smallest number of changes since tag wins. Date is
96 # used as tiebreaker.
96 # used as tiebreaker.
97 return [-changessincetag, x[0]]
97 return [-changessincetag, x[0]]
98
98
99 pdate, pdist, ptag = max(ptags, key=key)
99 pdate, pdist, ptag = max(ptags, key=key)
100 else:
100 else:
101 pdate, pdist, ptag = ptags[0]
101 pdate, pdist, ptag = ptags[0]
102 except KeyError:
102 except KeyError:
103 # Cache miss - recurse
103 # Cache miss - recurse
104 todo.append(rev)
104 todo.append(rev)
105 todo.extend(p.rev() for p in ctx.parents())
105 todo.extend(p.rev() for p in ctx.parents())
106 continue
106 continue
107 latesttags[rev] = pdate, pdist + 1, ptag
107 latesttags[rev] = pdate, pdist + 1, ptag
108 return latesttags[rev]
108 return latesttags[rev]
109
109
110
110
111 def getlogcolumns():
111 def getlogcolumns():
112 """Return a dict of log column labels"""
112 """Return a dict of log column labels"""
113 _ = pycompat.identity # temporarily disable gettext
113 _ = pycompat.identity # temporarily disable gettext
114 # i18n: column positioning for "hg log"
114 # i18n: column positioning for "hg log"
115 columns = _(
115 columns = _(
116 b'bookmark: %s\n'
116 b'bookmark: %s\n'
117 b'branch: %s\n'
117 b'branch: %s\n'
118 b'changeset: %s\n'
118 b'changeset: %s\n'
119 b'copies: %s\n'
119 b'copies: %s\n'
120 b'date: %s\n'
120 b'date: %s\n'
121 b'extra: %s=%s\n'
121 b'extra: %s=%s\n'
122 b'files+: %s\n'
122 b'files+: %s\n'
123 b'files-: %s\n'
123 b'files-: %s\n'
124 b'files: %s\n'
124 b'files: %s\n'
125 b'instability: %s\n'
125 b'instability: %s\n'
126 b'manifest: %s\n'
126 b'manifest: %s\n'
127 b'obsolete: %s\n'
127 b'obsolete: %s\n'
128 b'parent: %s\n'
128 b'parent: %s\n'
129 b'phase: %s\n'
129 b'phase: %s\n'
130 b'summary: %s\n'
130 b'summary: %s\n'
131 b'tag: %s\n'
131 b'tag: %s\n'
132 b'user: %s\n'
132 b'user: %s\n'
133 )
133 )
134 return dict(
134 return dict(
135 zip(
135 zip(
136 [s.split(b':', 1)[0] for s in columns.splitlines()],
136 [s.split(b':', 1)[0] for s in columns.splitlines()],
137 i18n._(columns).splitlines(True),
137 i18n._(columns).splitlines(True),
138 )
138 )
139 )
139 )
140
140
141
141
142 # basic internal templates
142 # basic internal templates
143 _changeidtmpl = b'{rev}:{node|formatnode}'
143 _changeidtmpl = b'{rev}:{node|formatnode}'
144
144
145 # default templates internally used for rendering of lists
145 # default templates internally used for rendering of lists
146 defaulttempl = {
146 defaulttempl = {
147 b'parent': _changeidtmpl + b' ',
147 b'parent': _changeidtmpl + b' ',
148 b'manifest': _changeidtmpl,
148 b'manifest': _changeidtmpl,
149 b'file_copy': b'{name} ({source})',
149 b'file_copy': b'{name} ({source})',
150 b'envvar': b'{key}={value}',
150 b'envvar': b'{key}={value}',
151 b'extra': b'{key}={value|stringescape}',
151 b'extra': b'{key}={value|stringescape}',
152 }
152 }
153 # filecopy is preserved for compatibility reasons
153 # filecopy is preserved for compatibility reasons
154 defaulttempl[b'filecopy'] = defaulttempl[b'file_copy']
154 defaulttempl[b'filecopy'] = defaulttempl[b'file_copy']
155
155
156 # keywords are callables (see registrar.templatekeyword for details)
156 # keywords are callables (see registrar.templatekeyword for details)
157 keywords = {}
157 keywords = {}
158 templatekeyword = registrar.templatekeyword(keywords)
158 templatekeyword = registrar.templatekeyword(keywords)
159
159
160
160
161 @templatekeyword(b'author', requires={b'ctx'})
161 @templatekeyword(b'author', requires={b'ctx'})
162 def showauthor(context, mapping):
162 def showauthor(context, mapping):
163 """Alias for ``{user}``"""
163 """Alias for ``{user}``"""
164 return showuser(context, mapping)
164 return showuser(context, mapping)
165
165
166
166
167 @templatekeyword(b'bisect', requires={b'repo', b'ctx'})
167 @templatekeyword(b'bisect', requires={b'repo', b'ctx'})
168 def showbisect(context, mapping):
168 def showbisect(context, mapping):
169 """String. The changeset bisection status."""
169 """String. The changeset bisection status."""
170 repo = context.resource(mapping, b'repo')
170 repo = context.resource(mapping, b'repo')
171 ctx = context.resource(mapping, b'ctx')
171 ctx = context.resource(mapping, b'ctx')
172 return hbisect.label(repo, ctx.node())
172 return hbisect.label(repo, ctx.node())
173
173
174
174
175 @templatekeyword(b'branch', requires={b'ctx'})
175 @templatekeyword(b'branch', requires={b'ctx'})
176 def showbranch(context, mapping):
176 def showbranch(context, mapping):
177 """String. The name of the branch on which the changeset was
177 """String. The name of the branch on which the changeset was
178 committed.
178 committed.
179 """
179 """
180 ctx = context.resource(mapping, b'ctx')
180 ctx = context.resource(mapping, b'ctx')
181 return ctx.branch()
181 return ctx.branch()
182
182
183
183
184 @templatekeyword(b'branches', requires={b'ctx'})
184 @templatekeyword(b'branches', requires={b'ctx'})
185 def showbranches(context, mapping):
185 def showbranches(context, mapping):
186 """List of strings. The name of the branch on which the
186 """List of strings. The name of the branch on which the
187 changeset was committed. Will be empty if the branch name was
187 changeset was committed. Will be empty if the branch name was
188 default. (DEPRECATED)
188 default. (DEPRECATED)
189 """
189 """
190 ctx = context.resource(mapping, b'ctx')
190 ctx = context.resource(mapping, b'ctx')
191 branch = ctx.branch()
191 branch = ctx.branch()
192 if branch != b'default':
192 if branch != b'default':
193 return compatlist(
193 return compatlist(
194 context, mapping, b'branch', [branch], plural=b'branches'
194 context, mapping, b'branch', [branch], plural=b'branches'
195 )
195 )
196 return compatlist(context, mapping, b'branch', [], plural=b'branches')
196 return compatlist(context, mapping, b'branch', [], plural=b'branches')
197
197
198
198
199 @templatekeyword(b'bookmarks', requires={b'repo', b'ctx'})
199 @templatekeyword(b'bookmarks', requires={b'repo', b'ctx'})
200 def showbookmarks(context, mapping):
200 def showbookmarks(context, mapping):
201 """List of strings. Any bookmarks associated with the
201 """List of strings. Any bookmarks associated with the
202 changeset. Also sets 'active', the name of the active bookmark.
202 changeset. Also sets 'active', the name of the active bookmark.
203 """
203 """
204 repo = context.resource(mapping, b'repo')
204 repo = context.resource(mapping, b'repo')
205 ctx = context.resource(mapping, b'ctx')
205 ctx = context.resource(mapping, b'ctx')
206 bookmarks = ctx.bookmarks()
206 bookmarks = ctx.bookmarks()
207 active = repo._activebookmark
207 active = repo._activebookmark
208 makemap = lambda v: {b'bookmark': v, b'active': active, b'current': active}
208 makemap = lambda v: {b'bookmark': v, b'active': active, b'current': active}
209 f = _showcompatlist(context, mapping, b'bookmark', bookmarks)
209 f = _showcompatlist(context, mapping, b'bookmark', bookmarks)
210 return _hybrid(f, bookmarks, makemap, pycompat.identity)
210 return _hybrid(f, bookmarks, makemap, pycompat.identity)
211
211
212
212
213 @templatekeyword(b'children', requires={b'ctx'})
213 @templatekeyword(b'children', requires={b'ctx'})
214 def showchildren(context, mapping):
214 def showchildren(context, mapping):
215 """List of strings. The children of the changeset."""
215 """List of strings. The children of the changeset."""
216 ctx = context.resource(mapping, b'ctx')
216 ctx = context.resource(mapping, b'ctx')
217 childrevs = [b'%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()]
217 childrevs = [b'%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()]
218 return compatlist(
218 return compatlist(
219 context, mapping, b'children', childrevs, element=b'child'
219 context, mapping, b'children', childrevs, element=b'child'
220 )
220 )
221
221
222
222
223 # Deprecated, but kept alive for help generation a purpose.
223 # Deprecated, but kept alive for help generation a purpose.
224 @templatekeyword(b'currentbookmark', requires={b'repo', b'ctx'})
224 @templatekeyword(b'currentbookmark', requires={b'repo', b'ctx'})
225 def showcurrentbookmark(context, mapping):
225 def showcurrentbookmark(context, mapping):
226 """String. The active bookmark, if it is associated with the changeset.
226 """String. The active bookmark, if it is associated with the changeset.
227 (DEPRECATED)"""
227 (DEPRECATED)"""
228 return showactivebookmark(context, mapping)
228 return showactivebookmark(context, mapping)
229
229
230
230
231 @templatekeyword(b'activebookmark', requires={b'repo', b'ctx'})
231 @templatekeyword(b'activebookmark', requires={b'repo', b'ctx'})
232 def showactivebookmark(context, mapping):
232 def showactivebookmark(context, mapping):
233 """String. The active bookmark, if it is associated with the changeset."""
233 """String. The active bookmark, if it is associated with the changeset."""
234 repo = context.resource(mapping, b'repo')
234 repo = context.resource(mapping, b'repo')
235 ctx = context.resource(mapping, b'ctx')
235 ctx = context.resource(mapping, b'ctx')
236 active = repo._activebookmark
236 active = repo._activebookmark
237 if active and active in ctx.bookmarks():
237 if active and active in ctx.bookmarks():
238 return active
238 return active
239 return b''
239 return b''
240
240
241
241
242 @templatekeyword(b'date', requires={b'ctx'})
242 @templatekeyword(b'date', requires={b'ctx'})
243 def showdate(context, mapping):
243 def showdate(context, mapping):
244 """Date information. The date when the changeset was committed."""
244 """Date information. The date when the changeset was committed."""
245 ctx = context.resource(mapping, b'ctx')
245 ctx = context.resource(mapping, b'ctx')
246 # the default string format is '<float(unixtime)><tzoffset>' because
246 # the default string format is '<float(unixtime)><tzoffset>' because
247 # python-hglib splits date at decimal separator.
247 # python-hglib splits date at decimal separator.
248 return templateutil.date(ctx.date(), showfmt=b'%d.0%d')
248 return templateutil.date(ctx.date(), showfmt=b'%d.0%d')
249
249
250
250
251 @templatekeyword(b'desc', requires={b'ctx'})
251 @templatekeyword(b'desc', requires={b'ctx'})
252 def showdescription(context, mapping):
252 def showdescription(context, mapping):
253 """String. The text of the changeset description."""
253 """String. The text of the changeset description."""
254 ctx = context.resource(mapping, b'ctx')
254 ctx = context.resource(mapping, b'ctx')
255 s = ctx.description()
255 s = ctx.description()
256 if isinstance(s, encoding.localstr):
256 if isinstance(s, encoding.localstr):
257 # try hard to preserve utf-8 bytes
257 # try hard to preserve utf-8 bytes
258 return encoding.tolocal(encoding.fromlocal(s).strip())
258 return encoding.tolocal(encoding.fromlocal(s).strip())
259 elif isinstance(s, encoding.safelocalstr):
259 elif isinstance(s, encoding.safelocalstr):
260 return encoding.safelocalstr(s.strip())
260 return encoding.safelocalstr(s.strip())
261 else:
261 else:
262 return s.strip()
262 return s.strip()
263
263
264
264
265 @templatekeyword(b'diffstat', requires={b'ui', b'ctx'})
265 @templatekeyword(b'diffstat', requires={b'ui', b'ctx'})
266 def showdiffstat(context, mapping):
266 def showdiffstat(context, mapping):
267 """String. Statistics of changes with the following format:
267 """String. Statistics of changes with the following format:
268 "modified files: +added/-removed lines"
268 "modified files: +added/-removed lines"
269 """
269 """
270 ui = context.resource(mapping, b'ui')
270 ui = context.resource(mapping, b'ui')
271 ctx = context.resource(mapping, b'ctx')
271 ctx = context.resource(mapping, b'ctx')
272 diffopts = diffutil.diffallopts(ui, {b'noprefix': False})
272 diffopts = diffutil.diffallopts(ui, {b'noprefix': False})
273 diff = ctx.diff(opts=diffopts)
273 diff = ctx.diff(opts=diffopts)
274 stats = patch.diffstatdata(util.iterlines(diff))
274 stats = patch.diffstatdata(util.iterlines(diff))
275 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
275 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
276 return b'%d: +%d/-%d' % (len(stats), adds, removes)
276 return b'%d: +%d/-%d' % (len(stats), adds, removes)
277
277
278
278
279 @templatekeyword(b'envvars', requires={b'ui'})
279 @templatekeyword(b'envvars', requires={b'ui'})
280 def showenvvars(context, mapping):
280 def showenvvars(context, mapping):
281 """A dictionary of environment variables. (EXPERIMENTAL)"""
281 """A dictionary of environment variables. (EXPERIMENTAL)"""
282 ui = context.resource(mapping, b'ui')
282 ui = context.resource(mapping, b'ui')
283 env = ui.exportableenviron()
283 env = ui.exportableenviron()
284 env = util.sortdict((k, env[k]) for k in sorted(env))
284 env = util.sortdict((k, env[k]) for k in sorted(env))
285 return compatdict(context, mapping, b'envvar', env, plural=b'envvars')
285 return compatdict(context, mapping, b'envvar', env, plural=b'envvars')
286
286
287
287
288 @templatekeyword(b'extras', requires={b'ctx'})
288 @templatekeyword(b'extras', requires={b'ctx'})
289 def showextras(context, mapping):
289 def showextras(context, mapping):
290 """List of dicts with key, value entries of the 'extras'
290 """List of dicts with key, value entries of the 'extras'
291 field of this changeset."""
291 field of this changeset."""
292 ctx = context.resource(mapping, b'ctx')
292 ctx = context.resource(mapping, b'ctx')
293 extras = ctx.extra()
293 extras = ctx.extra()
294 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
294 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
295 makemap = lambda k: {b'key': k, b'value': extras[k]}
295 makemap = lambda k: {b'key': k, b'value': extras[k]}
296 c = [makemap(k) for k in extras]
296 c = [makemap(k) for k in extras]
297 f = _showcompatlist(context, mapping, b'extra', c, plural=b'extras')
297 f = _showcompatlist(context, mapping, b'extra', c, plural=b'extras')
298 return _hybrid(
298 return _hybrid(
299 f,
299 f,
300 extras,
300 extras,
301 makemap,
301 makemap,
302 lambda k: b'%s=%s' % (k, stringutil.escapestr(extras[k])),
302 lambda k: b'%s=%s' % (k, stringutil.escapestr(extras[k])),
303 )
303 )
304
304
305
305
306 def _getfilestatus(context, mapping, listall=False):
306 def _getfilestatus(context, mapping, listall=False):
307 ctx = context.resource(mapping, b'ctx')
307 ctx = context.resource(mapping, b'ctx')
308 revcache = context.resource(mapping, b'revcache')
308 revcache = context.resource(mapping, b'revcache')
309 if b'filestatus' not in revcache or revcache[b'filestatusall'] < listall:
309 if b'filestatus' not in revcache or revcache[b'filestatusall'] < listall:
310 stat = ctx.p1().status(
310 stat = ctx.p1().status(
311 ctx, listignored=listall, listclean=listall, listunknown=listall
311 ctx, listignored=listall, listclean=listall, listunknown=listall
312 )
312 )
313 revcache[b'filestatus'] = stat
313 revcache[b'filestatus'] = stat
314 revcache[b'filestatusall'] = listall
314 revcache[b'filestatusall'] = listall
315 return revcache[b'filestatus']
315 return revcache[b'filestatus']
316
316
317
317
318 def _getfilestatusmap(context, mapping, listall=False):
318 def _getfilestatusmap(context, mapping, listall=False):
319 revcache = context.resource(mapping, b'revcache')
319 revcache = context.resource(mapping, b'revcache')
320 if b'filestatusmap' not in revcache or revcache[b'filestatusall'] < listall:
320 if b'filestatusmap' not in revcache or revcache[b'filestatusall'] < listall:
321 stat = _getfilestatus(context, mapping, listall=listall)
321 stat = _getfilestatus(context, mapping, listall=listall)
322 revcache[b'filestatusmap'] = statmap = {}
322 revcache[b'filestatusmap'] = statmap = {}
323 for char, files in zip(pycompat.iterbytestr(b'MAR!?IC'), stat):
323 for char, files in zip(pycompat.iterbytestr(b'MAR!?IC'), stat):
324 statmap.update((f, char) for f in files)
324 statmap.update((f, char) for f in files)
325 return revcache[b'filestatusmap'] # {path: statchar}
325 return revcache[b'filestatusmap'] # {path: statchar}
326
326
327
327
328 @templatekeyword(
328 @templatekeyword(
329 b'file_copies', requires={b'repo', b'ctx', b'cache', b'revcache'}
329 b'file_copies', requires={b'repo', b'ctx', b'cache', b'revcache'}
330 )
330 )
331 def showfilecopies(context, mapping):
331 def showfilecopies(context, mapping):
332 """List of strings. Files copied in this changeset with
332 """List of strings. Files copied in this changeset with
333 their sources.
333 their sources.
334 """
334 """
335 repo = context.resource(mapping, b'repo')
335 repo = context.resource(mapping, b'repo')
336 ctx = context.resource(mapping, b'ctx')
336 ctx = context.resource(mapping, b'ctx')
337 cache = context.resource(mapping, b'cache')
337 cache = context.resource(mapping, b'cache')
338 copies = context.resource(mapping, b'revcache').get(b'copies')
338 copies = context.resource(mapping, b'revcache').get(b'copies')
339 if copies is None:
339 if copies is None:
340 if b'getcopies' not in cache:
340 if b'getcopies' not in cache:
341 cache[b'getcopies'] = scmutil.getcopiesfn(repo)
341 cache[b'getcopies'] = scmutil.getcopiesfn(repo)
342 getcopies = cache[b'getcopies']
342 getcopies = cache[b'getcopies']
343 copies = getcopies(ctx)
343 copies = getcopies(ctx)
344 return templateutil.compatfilecopiesdict(
344 return templateutil.compatfilecopiesdict(
345 context, mapping, b'file_copy', copies
345 context, mapping, b'file_copy', copies
346 )
346 )
347
347
348
348
349 # showfilecopiesswitch() displays file copies only if copy records are
349 # showfilecopiesswitch() displays file copies only if copy records are
350 # provided before calling the templater, usually with a --copies
350 # provided before calling the templater, usually with a --copies
351 # command line switch.
351 # command line switch.
352 @templatekeyword(b'file_copies_switch', requires={b'revcache'})
352 @templatekeyword(b'file_copies_switch', requires={b'revcache'})
353 def showfilecopiesswitch(context, mapping):
353 def showfilecopiesswitch(context, mapping):
354 """List of strings. Like "file_copies" but displayed
354 """List of strings. Like "file_copies" but displayed
355 only if the --copied switch is set.
355 only if the --copied switch is set.
356 """
356 """
357 copies = context.resource(mapping, b'revcache').get(b'copies') or []
357 copies = context.resource(mapping, b'revcache').get(b'copies') or []
358 return templateutil.compatfilecopiesdict(
358 return templateutil.compatfilecopiesdict(
359 context, mapping, b'file_copy', copies
359 context, mapping, b'file_copy', copies
360 )
360 )
361
361
362
362
363 @templatekeyword(b'file_adds', requires={b'ctx', b'revcache'})
363 @templatekeyword(b'file_adds', requires={b'ctx', b'revcache'})
364 def showfileadds(context, mapping):
364 def showfileadds(context, mapping):
365 """List of strings. Files added by this changeset."""
365 """List of strings. Files added by this changeset."""
366 ctx = context.resource(mapping, b'ctx')
366 ctx = context.resource(mapping, b'ctx')
367 return templateutil.compatfileslist(
367 return templateutil.compatfileslist(
368 context, mapping, b'file_add', ctx.filesadded()
368 context, mapping, b'file_add', ctx.filesadded()
369 )
369 )
370
370
371
371
372 @templatekeyword(b'file_dels', requires={b'ctx', b'revcache'})
372 @templatekeyword(b'file_dels', requires={b'ctx', b'revcache'})
373 def showfiledels(context, mapping):
373 def showfiledels(context, mapping):
374 """List of strings. Files removed by this changeset."""
374 """List of strings. Files removed by this changeset."""
375 ctx = context.resource(mapping, b'ctx')
375 ctx = context.resource(mapping, b'ctx')
376 return templateutil.compatfileslist(
376 return templateutil.compatfileslist(
377 context, mapping, b'file_del', ctx.filesremoved()
377 context, mapping, b'file_del', ctx.filesremoved()
378 )
378 )
379
379
380
380
381 @templatekeyword(b'file_mods', requires={b'ctx', b'revcache'})
381 @templatekeyword(b'file_mods', requires={b'ctx', b'revcache'})
382 def showfilemods(context, mapping):
382 def showfilemods(context, mapping):
383 """List of strings. Files modified by this changeset."""
383 """List of strings. Files modified by this changeset."""
384 ctx = context.resource(mapping, b'ctx')
384 ctx = context.resource(mapping, b'ctx')
385 return templateutil.compatfileslist(
385 return templateutil.compatfileslist(
386 context, mapping, b'file_mod', ctx.filesmodified()
386 context, mapping, b'file_mod', ctx.filesmodified()
387 )
387 )
388
388
389
389
390 @templatekeyword(b'files', requires={b'ctx'})
390 @templatekeyword(b'files', requires={b'ctx'})
391 def showfiles(context, mapping):
391 def showfiles(context, mapping):
392 """List of strings. All files modified, added, or removed by this
392 """List of strings. All files modified, added, or removed by this
393 changeset.
393 changeset.
394 """
394 """
395 ctx = context.resource(mapping, b'ctx')
395 ctx = context.resource(mapping, b'ctx')
396 return templateutil.compatfileslist(context, mapping, b'file', ctx.files())
396 return templateutil.compatfileslist(context, mapping, b'file', ctx.files())
397
397
398
398
399 @templatekeyword(b'graphnode', requires={b'repo', b'ctx', b'cache'})
399 @templatekeyword(b'graphnode', requires={b'repo', b'ctx', b'cache'})
400 def showgraphnode(context, mapping):
400 def showgraphnode(context, mapping):
401 """String. The character representing the changeset node in an ASCII
401 """String. The character representing the changeset node in an ASCII
402 revision graph."""
402 revision graph."""
403 repo = context.resource(mapping, b'repo')
403 repo = context.resource(mapping, b'repo')
404 ctx = context.resource(mapping, b'ctx')
404 ctx = context.resource(mapping, b'ctx')
405 cache = context.resource(mapping, b'cache')
405 cache = context.resource(mapping, b'cache')
406 return getgraphnode(repo, ctx, cache)
406 return getgraphnode(repo, ctx, cache)
407
407
408
408
409 def getgraphnode(repo, ctx, cache):
409 def getgraphnode(repo, ctx, cache):
410 return getgraphnodecurrent(repo, ctx, cache) or getgraphnodesymbol(ctx)
410 return getgraphnodecurrent(repo, ctx, cache) or getgraphnodesymbol(ctx)
411
411
412
412
413 def getgraphnodecurrent(repo, ctx, cache):
413 def getgraphnodecurrent(repo, ctx, cache):
414 wpnodes = repo.dirstate.parents()
414 wpnodes = repo.dirstate.parents()
415 if wpnodes[1] == nullid:
415 if wpnodes[1] == nullid:
416 wpnodes = wpnodes[:1]
416 wpnodes = wpnodes[:1]
417 if ctx.node() in wpnodes:
417 if ctx.node() in wpnodes:
418 return b'@'
418 return b'@'
419 else:
419 else:
420 merge_nodes = cache.get(b'merge_nodes')
420 merge_nodes = cache.get(b'merge_nodes')
421 if merge_nodes is None:
421 if merge_nodes is None:
422 from . import mergestate as mergestatemod
422 from . import mergestate as mergestatemod
423
423
424 mergestate = mergestatemod.mergestate.read(repo)
424 mergestate = mergestatemod.mergestate.read(repo)
425 if mergestate.unresolvedcount():
425 if mergestate.unresolvedcount():
426 merge_nodes = (mergestate.local, mergestate.other)
426 merge_nodes = (mergestate.local, mergestate.other)
427 else:
427 else:
428 merge_nodes = ()
428 merge_nodes = ()
429 cache[b'merge_nodes'] = merge_nodes
429 cache[b'merge_nodes'] = merge_nodes
430
430
431 if ctx.node() in merge_nodes:
431 if ctx.node() in merge_nodes:
432 return b'%'
432 return b'%'
433 return b''
433 return b''
434
434
435
435
436 def getgraphnodesymbol(ctx):
436 def getgraphnodesymbol(ctx):
437 if ctx.obsolete():
437 if ctx.obsolete():
438 return b'x'
438 return b'x'
439 elif ctx.isunstable():
439 elif ctx.isunstable():
440 return b'*'
440 return b'*'
441 elif ctx.closesbranch():
441 elif ctx.closesbranch():
442 return b'_'
442 return b'_'
443 else:
443 else:
444 return b'o'
444 return b'o'
445
445
446
446
447 @templatekeyword(b'graphwidth', requires=())
447 @templatekeyword(b'graphwidth', requires=())
448 def showgraphwidth(context, mapping):
448 def showgraphwidth(context, mapping):
449 """Integer. The width of the graph drawn by 'log --graph' or zero."""
449 """Integer. The width of the graph drawn by 'log --graph' or zero."""
450 # just hosts documentation; should be overridden by template mapping
450 # just hosts documentation; should be overridden by template mapping
451 return 0
451 return 0
452
452
453
453
454 @templatekeyword(b'index', requires=())
454 @templatekeyword(b'index', requires=())
455 def showindex(context, mapping):
455 def showindex(context, mapping):
456 """Integer. The current iteration of the loop. (0 indexed)"""
456 """Integer. The current iteration of the loop. (0 indexed)"""
457 # just hosts documentation; should be overridden by template mapping
457 # just hosts documentation; should be overridden by template mapping
458 raise error.Abort(_(b"can't use index in this context"))
458 raise error.Abort(_(b"can't use index in this context"))
459
459
460
460
461 @templatekeyword(b'latesttag', requires={b'repo', b'ctx', b'cache'})
461 @templatekeyword(b'latesttag', requires={b'repo', b'ctx', b'cache'})
462 def showlatesttag(context, mapping):
462 def showlatesttag(context, mapping):
463 """List of strings. The global tags on the most recent globally
463 """List of strings. The global tags on the most recent globally
464 tagged ancestor of this changeset. If no such tags exist, the list
464 tagged ancestor of this changeset. If no such tags exist, the list
465 consists of the single string "null".
465 consists of the single string "null".
466 """
466 """
467 return showlatesttags(context, mapping, None)
467 return showlatesttags(context, mapping, None)
468
468
469
469
470 def showlatesttags(context, mapping, pattern):
470 def showlatesttags(context, mapping, pattern):
471 """helper method for the latesttag keyword and function"""
471 """helper method for the latesttag keyword and function"""
472 latesttags = getlatesttags(context, mapping, pattern)
472 latesttags = getlatesttags(context, mapping, pattern)
473
473
474 # latesttag[0] is an implementation detail for sorting csets on different
474 # latesttag[0] is an implementation detail for sorting csets on different
475 # branches in a stable manner- it is the date the tagged cset was created,
475 # branches in a stable manner- it is the date the tagged cset was created,
476 # not the date the tag was created. Therefore it isn't made visible here.
476 # not the date the tag was created. Therefore it isn't made visible here.
477 makemap = lambda v: {
477 makemap = lambda v: {
478 b'changes': _showchangessincetag,
478 b'changes': _showchangessincetag,
479 b'distance': latesttags[1],
479 b'distance': latesttags[1],
480 b'latesttag': v, # BC with {latesttag % '{latesttag}'}
480 b'latesttag': v, # BC with {latesttag % '{latesttag}'}
481 b'tag': v,
481 b'tag': v,
482 }
482 }
483
483
484 tags = latesttags[2]
484 tags = latesttags[2]
485 f = _showcompatlist(context, mapping, b'latesttag', tags, separator=b':')
485 f = _showcompatlist(context, mapping, b'latesttag', tags, separator=b':')
486 return _hybrid(f, tags, makemap, pycompat.identity)
486 return _hybrid(f, tags, makemap, pycompat.identity)
487
487
488
488
489 @templatekeyword(b'latesttagdistance', requires={b'repo', b'ctx', b'cache'})
489 @templatekeyword(b'latesttagdistance', requires={b'repo', b'ctx', b'cache'})
490 def showlatesttagdistance(context, mapping):
490 def showlatesttagdistance(context, mapping):
491 """Integer. Longest path to the latest tag."""
491 """Integer. Longest path to the latest tag."""
492 return getlatesttags(context, mapping)[1]
492 return getlatesttags(context, mapping)[1]
493
493
494
494
495 @templatekeyword(b'changessincelatesttag', requires={b'repo', b'ctx', b'cache'})
495 @templatekeyword(b'changessincelatesttag', requires={b'repo', b'ctx', b'cache'})
496 def showchangessincelatesttag(context, mapping):
496 def showchangessincelatesttag(context, mapping):
497 """Integer. All ancestors not in the latest tag."""
497 """Integer. All ancestors not in the latest tag."""
498 tag = getlatesttags(context, mapping)[2][0]
498 tag = getlatesttags(context, mapping)[2][0]
499 mapping = context.overlaymap(mapping, {b'tag': tag})
499 mapping = context.overlaymap(mapping, {b'tag': tag})
500 return _showchangessincetag(context, mapping)
500 return _showchangessincetag(context, mapping)
501
501
502
502
503 def _showchangessincetag(context, mapping):
503 def _showchangessincetag(context, mapping):
504 repo = context.resource(mapping, b'repo')
504 repo = context.resource(mapping, b'repo')
505 ctx = context.resource(mapping, b'ctx')
505 ctx = context.resource(mapping, b'ctx')
506 offset = 0
506 offset = 0
507 revs = [ctx.rev()]
507 revs = [ctx.rev()]
508 tag = context.symbol(mapping, b'tag')
508 tag = context.symbol(mapping, b'tag')
509
509
510 # The only() revset doesn't currently support wdir()
510 # The only() revset doesn't currently support wdir()
511 if ctx.rev() is None:
511 if ctx.rev() is None:
512 offset = 1
512 offset = 1
513 revs = [p.rev() for p in ctx.parents()]
513 revs = [p.rev() for p in ctx.parents()]
514
514
515 return len(repo.revs(b'only(%ld, %s)', revs, tag)) + offset
515 return len(repo.revs(b'only(%ld, %s)', revs, tag)) + offset
516
516
517
517
518 # teach templater latesttags.changes is switched to (context, mapping) API
518 # teach templater latesttags.changes is switched to (context, mapping) API
519 _showchangessincetag._requires = {b'repo', b'ctx'}
519 _showchangessincetag._requires = {b'repo', b'ctx'}
520
520
521
521
522 @templatekeyword(b'manifest', requires={b'repo', b'ctx'})
522 @templatekeyword(b'manifest', requires={b'repo', b'ctx'})
523 def showmanifest(context, mapping):
523 def showmanifest(context, mapping):
524 repo = context.resource(mapping, b'repo')
524 repo = context.resource(mapping, b'repo')
525 ctx = context.resource(mapping, b'ctx')
525 ctx = context.resource(mapping, b'ctx')
526 mnode = ctx.manifestnode()
526 mnode = ctx.manifestnode()
527 if mnode is None:
527 if mnode is None:
528 mnode = wdirid
528 mnode = wdirid
529 mrev = wdirrev
529 mrev = wdirrev
530 else:
530 else:
531 mrev = repo.manifestlog.rev(mnode)
531 mrev = repo.manifestlog.rev(mnode)
532 mhex = hex(mnode)
532 mhex = hex(mnode)
533 mapping = context.overlaymap(mapping, {b'rev': mrev, b'node': mhex})
533 mapping = context.overlaymap(mapping, {b'rev': mrev, b'node': mhex})
534 f = context.process(b'manifest', mapping)
534 f = context.process(b'manifest', mapping)
535 return templateutil.hybriditem(
535 return templateutil.hybriditem(
536 f, None, f, lambda x: {b'rev': mrev, b'node': mhex}
536 f, None, f, lambda x: {b'rev': mrev, b'node': mhex}
537 )
537 )
538
538
539
539
540 @templatekeyword(b'obsfate', requires={b'ui', b'repo', b'ctx'})
540 @templatekeyword(b'obsfate', requires={b'ui', b'repo', b'ctx'})
541 def showobsfate(context, mapping):
541 def showobsfate(context, mapping):
542 # this function returns a list containing pre-formatted obsfate strings.
542 # this function returns a list containing pre-formatted obsfate strings.
543 #
543 #
544 # This function will be replaced by templates fragments when we will have
544 # This function will be replaced by templates fragments when we will have
545 # the verbosity templatekw available.
545 # the verbosity templatekw available.
546 succsandmarkers = showsuccsandmarkers(context, mapping)
546 succsandmarkers = showsuccsandmarkers(context, mapping)
547
547
548 ui = context.resource(mapping, b'ui')
548 ui = context.resource(mapping, b'ui')
549 repo = context.resource(mapping, b'repo')
549 repo = context.resource(mapping, b'repo')
550 values = []
550 values = []
551
551
552 for x in succsandmarkers.tovalue(context, mapping):
552 for x in succsandmarkers.tovalue(context, mapping):
553 v = obsutil.obsfateprinter(
553 v = obsutil.obsfateprinter(
554 ui, repo, x[b'successors'], x[b'markers'], scmutil.formatchangeid
554 ui, repo, x[b'successors'], x[b'markers'], scmutil.formatchangeid
555 )
555 )
556 values.append(v)
556 values.append(v)
557
557
558 return compatlist(context, mapping, b"fate", values)
558 return compatlist(context, mapping, b"fate", values)
559
559
560
560
561 def shownames(context, mapping, namespace):
561 def shownames(context, mapping, namespace):
562 """helper method to generate a template keyword for a namespace"""
562 """helper method to generate a template keyword for a namespace"""
563 repo = context.resource(mapping, b'repo')
563 repo = context.resource(mapping, b'repo')
564 ctx = context.resource(mapping, b'ctx')
564 ctx = context.resource(mapping, b'ctx')
565 ns = repo.names.get(namespace)
565 ns = repo.names.get(namespace)
566 if ns is None:
566 if ns is None:
567 # namespaces.addnamespace() registers new template keyword, but
567 # namespaces.addnamespace() registers new template keyword, but
568 # the registered namespace might not exist in the current repo.
568 # the registered namespace might not exist in the current repo.
569 return
569 return
570 names = ns.names(repo, ctx.node())
570 names = ns.names(repo, ctx.node())
571 return compatlist(
571 return compatlist(
572 context, mapping, ns.templatename, names, plural=namespace
572 context, mapping, ns.templatename, names, plural=namespace
573 )
573 )
574
574
575
575
576 @templatekeyword(b'namespaces', requires={b'repo', b'ctx'})
576 @templatekeyword(b'namespaces', requires={b'repo', b'ctx'})
577 def shownamespaces(context, mapping):
577 def shownamespaces(context, mapping):
578 """Dict of lists. Names attached to this changeset per
578 """Dict of lists. Names attached to this changeset per
579 namespace."""
579 namespace."""
580 repo = context.resource(mapping, b'repo')
580 repo = context.resource(mapping, b'repo')
581 ctx = context.resource(mapping, b'ctx')
581 ctx = context.resource(mapping, b'ctx')
582
582
583 namespaces = util.sortdict()
583 namespaces = util.sortdict()
584
584
585 def makensmapfn(ns):
585 def makensmapfn(ns):
586 # 'name' for iterating over namespaces, templatename for local reference
586 # 'name' for iterating over namespaces, templatename for local reference
587 return lambda v: {b'name': v, ns.templatename: v}
587 return lambda v: {b'name': v, ns.templatename: v}
588
588
589 for k, ns in pycompat.iteritems(repo.names):
589 for k, ns in pycompat.iteritems(repo.names):
590 names = ns.names(repo, ctx.node())
590 names = ns.names(repo, ctx.node())
591 f = _showcompatlist(context, mapping, b'name', names)
591 f = _showcompatlist(context, mapping, b'name', names)
592 namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
592 namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
593
593
594 f = _showcompatlist(context, mapping, b'namespace', list(namespaces))
594 f = _showcompatlist(context, mapping, b'namespace', list(namespaces))
595
595
596 def makemap(ns):
596 def makemap(ns):
597 return {
597 return {
598 b'namespace': ns,
598 b'namespace': ns,
599 b'names': namespaces[ns],
599 b'names': namespaces[ns],
600 b'builtin': repo.names[ns].builtin,
600 b'builtin': repo.names[ns].builtin,
601 b'colorname': repo.names[ns].colorname,
601 b'colorname': repo.names[ns].colorname,
602 }
602 }
603
603
604 return _hybrid(f, namespaces, makemap, pycompat.identity)
604 return _hybrid(f, namespaces, makemap, pycompat.identity)
605
605
606
606
607 @templatekeyword(b'negrev', requires={b'repo', b'ctx'})
607 @templatekeyword(b'negrev', requires={b'repo', b'ctx'})
608 def shownegrev(context, mapping):
608 def shownegrev(context, mapping):
609 """Integer. The repository-local changeset negative revision number,
609 """Integer. The repository-local changeset negative revision number,
610 which counts in the opposite direction."""
610 which counts in the opposite direction."""
611 ctx = context.resource(mapping, b'ctx')
611 ctx = context.resource(mapping, b'ctx')
612 rev = ctx.rev()
612 rev = ctx.rev()
613 if rev is None or rev < 0: # wdir() or nullrev?
613 if rev is None or rev < 0: # wdir() or nullrev?
614 return None
614 return None
615 repo = context.resource(mapping, b'repo')
615 repo = context.resource(mapping, b'repo')
616 return rev - len(repo)
616 return rev - len(repo)
617
617
618
618
619 @templatekeyword(b'node', requires={b'ctx'})
619 @templatekeyword(b'node', requires={b'ctx'})
620 def shownode(context, mapping):
620 def shownode(context, mapping):
621 """String. The changeset identification hash, as a 40 hexadecimal
621 """String. The changeset identification hash, as a 40 hexadecimal
622 digit string.
622 digit string.
623 """
623 """
624 ctx = context.resource(mapping, b'ctx')
624 ctx = context.resource(mapping, b'ctx')
625 return ctx.hex()
625 return ctx.hex()
626
626
627
627
628 @templatekeyword(b'obsolete', requires={b'ctx'})
628 @templatekeyword(b'obsolete', requires={b'ctx'})
629 def showobsolete(context, mapping):
629 def showobsolete(context, mapping):
630 """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
630 """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
631 ctx = context.resource(mapping, b'ctx')
631 ctx = context.resource(mapping, b'ctx')
632 if ctx.obsolete():
632 if ctx.obsolete():
633 return b'obsolete'
633 return b'obsolete'
634 return b''
634 return b''
635
635
636
636
637 @templatekeyword(b'onelinesummary', requires={b'ui', b'ctx'})
638 def showonelinesummary(context, mapping):
639 """String. A one-line summary for the ctx (not including trailing newline).
640 The default template be overridden in command-templates.oneline-summary."""
641 # Avoid cycle:
642 # mercurial.cmdutil -> mercurial.templatekw -> mercurial.cmdutil
643 from . import cmdutil
644
645 ui = context.resource(mapping, b'ui')
646 ctx = context.resource(mapping, b'ctx')
647 return cmdutil.format_changeset_summary(ui, ctx)
648
649
637 @templatekeyword(b'path', requires={b'fctx'})
650 @templatekeyword(b'path', requires={b'fctx'})
638 def showpath(context, mapping):
651 def showpath(context, mapping):
639 """String. Repository-absolute path of the current file. (EXPERIMENTAL)"""
652 """String. Repository-absolute path of the current file. (EXPERIMENTAL)"""
640 fctx = context.resource(mapping, b'fctx')
653 fctx = context.resource(mapping, b'fctx')
641 return fctx.path()
654 return fctx.path()
642
655
643
656
644 @templatekeyword(b'peerurls', requires={b'repo'})
657 @templatekeyword(b'peerurls', requires={b'repo'})
645 def showpeerurls(context, mapping):
658 def showpeerurls(context, mapping):
646 """A dictionary of repository locations defined in the [paths] section
659 """A dictionary of repository locations defined in the [paths] section
647 of your configuration file."""
660 of your configuration file."""
648 repo = context.resource(mapping, b'repo')
661 repo = context.resource(mapping, b'repo')
649 # see commands.paths() for naming of dictionary keys
662 # see commands.paths() for naming of dictionary keys
650 paths = repo.ui.paths
663 paths = repo.ui.paths
651 urls = util.sortdict(
664 urls = util.sortdict(
652 (k, p.rawloc) for k, p in sorted(pycompat.iteritems(paths))
665 (k, p.rawloc) for k, p in sorted(pycompat.iteritems(paths))
653 )
666 )
654
667
655 def makemap(k):
668 def makemap(k):
656 p = paths[k]
669 p = paths[k]
657 d = {b'name': k, b'url': p.rawloc}
670 d = {b'name': k, b'url': p.rawloc}
658 d.update((o, v) for o, v in sorted(pycompat.iteritems(p.suboptions)))
671 d.update((o, v) for o, v in sorted(pycompat.iteritems(p.suboptions)))
659 return d
672 return d
660
673
661 return _hybrid(None, urls, makemap, lambda k: b'%s=%s' % (k, urls[k]))
674 return _hybrid(None, urls, makemap, lambda k: b'%s=%s' % (k, urls[k]))
662
675
663
676
664 @templatekeyword(b"predecessors", requires={b'repo', b'ctx'})
677 @templatekeyword(b"predecessors", requires={b'repo', b'ctx'})
665 def showpredecessors(context, mapping):
678 def showpredecessors(context, mapping):
666 """Returns the list of the closest visible predecessors. (EXPERIMENTAL)"""
679 """Returns the list of the closest visible predecessors. (EXPERIMENTAL)"""
667 repo = context.resource(mapping, b'repo')
680 repo = context.resource(mapping, b'repo')
668 ctx = context.resource(mapping, b'ctx')
681 ctx = context.resource(mapping, b'ctx')
669 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
682 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
670 predecessors = pycompat.maplist(hex, predecessors)
683 predecessors = pycompat.maplist(hex, predecessors)
671
684
672 return _hybrid(
685 return _hybrid(
673 None,
686 None,
674 predecessors,
687 predecessors,
675 lambda x: {b'ctx': repo[x]},
688 lambda x: {b'ctx': repo[x]},
676 lambda x: scmutil.formatchangeid(repo[x]),
689 lambda x: scmutil.formatchangeid(repo[x]),
677 )
690 )
678
691
679
692
680 @templatekeyword(b'reporoot', requires={b'repo'})
693 @templatekeyword(b'reporoot', requires={b'repo'})
681 def showreporoot(context, mapping):
694 def showreporoot(context, mapping):
682 """String. The root directory of the current repository."""
695 """String. The root directory of the current repository."""
683 repo = context.resource(mapping, b'repo')
696 repo = context.resource(mapping, b'repo')
684 return repo.root
697 return repo.root
685
698
686
699
687 @templatekeyword(b'size', requires={b'fctx'})
700 @templatekeyword(b'size', requires={b'fctx'})
688 def showsize(context, mapping):
701 def showsize(context, mapping):
689 """Integer. Size of the current file in bytes. (EXPERIMENTAL)"""
702 """Integer. Size of the current file in bytes. (EXPERIMENTAL)"""
690 fctx = context.resource(mapping, b'fctx')
703 fctx = context.resource(mapping, b'fctx')
691 return fctx.size()
704 return fctx.size()
692
705
693
706
694 # requires 'fctx' to denote {status} depends on (ctx, path) pair
707 # requires 'fctx' to denote {status} depends on (ctx, path) pair
695 @templatekeyword(b'status', requires={b'ctx', b'fctx', b'revcache'})
708 @templatekeyword(b'status', requires={b'ctx', b'fctx', b'revcache'})
696 def showstatus(context, mapping):
709 def showstatus(context, mapping):
697 """String. Status code of the current file. (EXPERIMENTAL)"""
710 """String. Status code of the current file. (EXPERIMENTAL)"""
698 path = templateutil.runsymbol(context, mapping, b'path')
711 path = templateutil.runsymbol(context, mapping, b'path')
699 path = templateutil.stringify(context, mapping, path)
712 path = templateutil.stringify(context, mapping, path)
700 if not path:
713 if not path:
701 return
714 return
702 statmap = _getfilestatusmap(context, mapping)
715 statmap = _getfilestatusmap(context, mapping)
703 if path not in statmap:
716 if path not in statmap:
704 statmap = _getfilestatusmap(context, mapping, listall=True)
717 statmap = _getfilestatusmap(context, mapping, listall=True)
705 return statmap.get(path)
718 return statmap.get(path)
706
719
707
720
708 @templatekeyword(b"successorssets", requires={b'repo', b'ctx'})
721 @templatekeyword(b"successorssets", requires={b'repo', b'ctx'})
709 def showsuccessorssets(context, mapping):
722 def showsuccessorssets(context, mapping):
710 """Returns a string of sets of successors for a changectx. Format used
723 """Returns a string of sets of successors for a changectx. Format used
711 is: [ctx1, ctx2], [ctx3] if ctx has been split into ctx1 and ctx2
724 is: [ctx1, ctx2], [ctx3] if ctx has been split into ctx1 and ctx2
712 while also diverged into ctx3. (EXPERIMENTAL)"""
725 while also diverged into ctx3. (EXPERIMENTAL)"""
713 repo = context.resource(mapping, b'repo')
726 repo = context.resource(mapping, b'repo')
714 ctx = context.resource(mapping, b'ctx')
727 ctx = context.resource(mapping, b'ctx')
715 data = []
728 data = []
716
729
717 if ctx.obsolete():
730 if ctx.obsolete():
718 ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
731 ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
719 ssets = [[hex(n) for n in ss] for ss in ssets]
732 ssets = [[hex(n) for n in ss] for ss in ssets]
720
733
721 for ss in ssets:
734 for ss in ssets:
722 h = _hybrid(
735 h = _hybrid(
723 None,
736 None,
724 ss,
737 ss,
725 lambda x: {b'ctx': repo[x]},
738 lambda x: {b'ctx': repo[x]},
726 lambda x: scmutil.formatchangeid(repo[x]),
739 lambda x: scmutil.formatchangeid(repo[x]),
727 )
740 )
728 data.append(h)
741 data.append(h)
729
742
730 # Format the successorssets
743 # Format the successorssets
731 def render(d):
744 def render(d):
732 return templateutil.stringify(context, mapping, d)
745 return templateutil.stringify(context, mapping, d)
733
746
734 def gen(data):
747 def gen(data):
735 yield b"; ".join(render(d) for d in data)
748 yield b"; ".join(render(d) for d in data)
736
749
737 return _hybrid(
750 return _hybrid(
738 gen(data), data, lambda x: {b'successorset': x}, pycompat.identity
751 gen(data), data, lambda x: {b'successorset': x}, pycompat.identity
739 )
752 )
740
753
741
754
742 @templatekeyword(b"succsandmarkers", requires={b'repo', b'ctx'})
755 @templatekeyword(b"succsandmarkers", requires={b'repo', b'ctx'})
743 def showsuccsandmarkers(context, mapping):
756 def showsuccsandmarkers(context, mapping):
744 """Returns a list of dict for each final successor of ctx. The dict
757 """Returns a list of dict for each final successor of ctx. The dict
745 contains successors node id in "successors" keys and the list of
758 contains successors node id in "successors" keys and the list of
746 obs-markers from ctx to the set of successors in "markers".
759 obs-markers from ctx to the set of successors in "markers".
747 (EXPERIMENTAL)
760 (EXPERIMENTAL)
748 """
761 """
749 repo = context.resource(mapping, b'repo')
762 repo = context.resource(mapping, b'repo')
750 ctx = context.resource(mapping, b'ctx')
763 ctx = context.resource(mapping, b'ctx')
751
764
752 values = obsutil.successorsandmarkers(repo, ctx)
765 values = obsutil.successorsandmarkers(repo, ctx)
753
766
754 if values is None:
767 if values is None:
755 values = []
768 values = []
756
769
757 # Format successors and markers to avoid exposing binary to templates
770 # Format successors and markers to avoid exposing binary to templates
758 data = []
771 data = []
759 for i in values:
772 for i in values:
760 # Format successors
773 # Format successors
761 successors = i[b'successors']
774 successors = i[b'successors']
762
775
763 successors = [hex(n) for n in successors]
776 successors = [hex(n) for n in successors]
764 successors = _hybrid(
777 successors = _hybrid(
765 None,
778 None,
766 successors,
779 successors,
767 lambda x: {b'ctx': repo[x]},
780 lambda x: {b'ctx': repo[x]},
768 lambda x: scmutil.formatchangeid(repo[x]),
781 lambda x: scmutil.formatchangeid(repo[x]),
769 )
782 )
770
783
771 # Format markers
784 # Format markers
772 finalmarkers = []
785 finalmarkers = []
773 for m in i[b'markers']:
786 for m in i[b'markers']:
774 hexprec = hex(m[0])
787 hexprec = hex(m[0])
775 hexsucs = tuple(hex(n) for n in m[1])
788 hexsucs = tuple(hex(n) for n in m[1])
776 hexparents = None
789 hexparents = None
777 if m[5] is not None:
790 if m[5] is not None:
778 hexparents = tuple(hex(n) for n in m[5])
791 hexparents = tuple(hex(n) for n in m[5])
779 newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
792 newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
780 finalmarkers.append(newmarker)
793 finalmarkers.append(newmarker)
781
794
782 data.append({b'successors': successors, b'markers': finalmarkers})
795 data.append({b'successors': successors, b'markers': finalmarkers})
783
796
784 return templateutil.mappinglist(data)
797 return templateutil.mappinglist(data)
785
798
786
799
787 @templatekeyword(b'p1', requires={b'ctx'})
800 @templatekeyword(b'p1', requires={b'ctx'})
788 def showp1(context, mapping):
801 def showp1(context, mapping):
789 """Changeset. The changeset's first parent. ``{p1.rev}`` for the revision
802 """Changeset. The changeset's first parent. ``{p1.rev}`` for the revision
790 number, and ``{p1.node}`` for the identification hash."""
803 number, and ``{p1.node}`` for the identification hash."""
791 ctx = context.resource(mapping, b'ctx')
804 ctx = context.resource(mapping, b'ctx')
792 return templateutil.mappingdict({b'ctx': ctx.p1()}, tmpl=_changeidtmpl)
805 return templateutil.mappingdict({b'ctx': ctx.p1()}, tmpl=_changeidtmpl)
793
806
794
807
795 @templatekeyword(b'p2', requires={b'ctx'})
808 @templatekeyword(b'p2', requires={b'ctx'})
796 def showp2(context, mapping):
809 def showp2(context, mapping):
797 """Changeset. The changeset's second parent. ``{p2.rev}`` for the revision
810 """Changeset. The changeset's second parent. ``{p2.rev}`` for the revision
798 number, and ``{p2.node}`` for the identification hash."""
811 number, and ``{p2.node}`` for the identification hash."""
799 ctx = context.resource(mapping, b'ctx')
812 ctx = context.resource(mapping, b'ctx')
800 return templateutil.mappingdict({b'ctx': ctx.p2()}, tmpl=_changeidtmpl)
813 return templateutil.mappingdict({b'ctx': ctx.p2()}, tmpl=_changeidtmpl)
801
814
802
815
803 @templatekeyword(b'p1rev', requires={b'ctx'})
816 @templatekeyword(b'p1rev', requires={b'ctx'})
804 def showp1rev(context, mapping):
817 def showp1rev(context, mapping):
805 """Integer. The repository-local revision number of the changeset's
818 """Integer. The repository-local revision number of the changeset's
806 first parent, or -1 if the changeset has no parents. (DEPRECATED)"""
819 first parent, or -1 if the changeset has no parents. (DEPRECATED)"""
807 ctx = context.resource(mapping, b'ctx')
820 ctx = context.resource(mapping, b'ctx')
808 return ctx.p1().rev()
821 return ctx.p1().rev()
809
822
810
823
811 @templatekeyword(b'p2rev', requires={b'ctx'})
824 @templatekeyword(b'p2rev', requires={b'ctx'})
812 def showp2rev(context, mapping):
825 def showp2rev(context, mapping):
813 """Integer. The repository-local revision number of the changeset's
826 """Integer. The repository-local revision number of the changeset's
814 second parent, or -1 if the changeset has no second parent. (DEPRECATED)"""
827 second parent, or -1 if the changeset has no second parent. (DEPRECATED)"""
815 ctx = context.resource(mapping, b'ctx')
828 ctx = context.resource(mapping, b'ctx')
816 return ctx.p2().rev()
829 return ctx.p2().rev()
817
830
818
831
819 @templatekeyword(b'p1node', requires={b'ctx'})
832 @templatekeyword(b'p1node', requires={b'ctx'})
820 def showp1node(context, mapping):
833 def showp1node(context, mapping):
821 """String. The identification hash of the changeset's first parent,
834 """String. The identification hash of the changeset's first parent,
822 as a 40 digit hexadecimal string. If the changeset has no parents, all
835 as a 40 digit hexadecimal string. If the changeset has no parents, all
823 digits are 0. (DEPRECATED)"""
836 digits are 0. (DEPRECATED)"""
824 ctx = context.resource(mapping, b'ctx')
837 ctx = context.resource(mapping, b'ctx')
825 return ctx.p1().hex()
838 return ctx.p1().hex()
826
839
827
840
828 @templatekeyword(b'p2node', requires={b'ctx'})
841 @templatekeyword(b'p2node', requires={b'ctx'})
829 def showp2node(context, mapping):
842 def showp2node(context, mapping):
830 """String. The identification hash of the changeset's second
843 """String. The identification hash of the changeset's second
831 parent, as a 40 digit hexadecimal string. If the changeset has no second
844 parent, as a 40 digit hexadecimal string. If the changeset has no second
832 parent, all digits are 0. (DEPRECATED)"""
845 parent, all digits are 0. (DEPRECATED)"""
833 ctx = context.resource(mapping, b'ctx')
846 ctx = context.resource(mapping, b'ctx')
834 return ctx.p2().hex()
847 return ctx.p2().hex()
835
848
836
849
837 @templatekeyword(b'parents', requires={b'repo', b'ctx'})
850 @templatekeyword(b'parents', requires={b'repo', b'ctx'})
838 def showparents(context, mapping):
851 def showparents(context, mapping):
839 """List of strings. The parents of the changeset in "rev:node"
852 """List of strings. The parents of the changeset in "rev:node"
840 format. If the changeset has only one "natural" parent (the predecessor
853 format. If the changeset has only one "natural" parent (the predecessor
841 revision) nothing is shown."""
854 revision) nothing is shown."""
842 repo = context.resource(mapping, b'repo')
855 repo = context.resource(mapping, b'repo')
843 ctx = context.resource(mapping, b'ctx')
856 ctx = context.resource(mapping, b'ctx')
844 pctxs = scmutil.meaningfulparents(repo, ctx)
857 pctxs = scmutil.meaningfulparents(repo, ctx)
845 prevs = [p.rev() for p in pctxs]
858 prevs = [p.rev() for p in pctxs]
846 parents = [
859 parents = [
847 [(b'rev', p.rev()), (b'node', p.hex()), (b'phase', p.phasestr())]
860 [(b'rev', p.rev()), (b'node', p.hex()), (b'phase', p.phasestr())]
848 for p in pctxs
861 for p in pctxs
849 ]
862 ]
850 f = _showcompatlist(context, mapping, b'parent', parents)
863 f = _showcompatlist(context, mapping, b'parent', parents)
851 return _hybrid(
864 return _hybrid(
852 f,
865 f,
853 prevs,
866 prevs,
854 lambda x: {b'ctx': repo[x]},
867 lambda x: {b'ctx': repo[x]},
855 lambda x: scmutil.formatchangeid(repo[x]),
868 lambda x: scmutil.formatchangeid(repo[x]),
856 keytype=int,
869 keytype=int,
857 )
870 )
858
871
859
872
860 @templatekeyword(b'phase', requires={b'ctx'})
873 @templatekeyword(b'phase', requires={b'ctx'})
861 def showphase(context, mapping):
874 def showphase(context, mapping):
862 """String. The changeset phase name."""
875 """String. The changeset phase name."""
863 ctx = context.resource(mapping, b'ctx')
876 ctx = context.resource(mapping, b'ctx')
864 return ctx.phasestr()
877 return ctx.phasestr()
865
878
866
879
867 @templatekeyword(b'phaseidx', requires={b'ctx'})
880 @templatekeyword(b'phaseidx', requires={b'ctx'})
868 def showphaseidx(context, mapping):
881 def showphaseidx(context, mapping):
869 """Integer. The changeset phase index. (ADVANCED)"""
882 """Integer. The changeset phase index. (ADVANCED)"""
870 ctx = context.resource(mapping, b'ctx')
883 ctx = context.resource(mapping, b'ctx')
871 return ctx.phase()
884 return ctx.phase()
872
885
873
886
874 @templatekeyword(b'rev', requires={b'ctx'})
887 @templatekeyword(b'rev', requires={b'ctx'})
875 def showrev(context, mapping):
888 def showrev(context, mapping):
876 """Integer. The repository-local changeset revision number."""
889 """Integer. The repository-local changeset revision number."""
877 ctx = context.resource(mapping, b'ctx')
890 ctx = context.resource(mapping, b'ctx')
878 return scmutil.intrev(ctx)
891 return scmutil.intrev(ctx)
879
892
880
893
881 @templatekeyword(b'subrepos', requires={b'ctx'})
894 @templatekeyword(b'subrepos', requires={b'ctx'})
882 def showsubrepos(context, mapping):
895 def showsubrepos(context, mapping):
883 """List of strings. Updated subrepositories in the changeset."""
896 """List of strings. Updated subrepositories in the changeset."""
884 ctx = context.resource(mapping, b'ctx')
897 ctx = context.resource(mapping, b'ctx')
885 substate = ctx.substate
898 substate = ctx.substate
886 if not substate:
899 if not substate:
887 return compatlist(context, mapping, b'subrepo', [])
900 return compatlist(context, mapping, b'subrepo', [])
888 psubstate = ctx.p1().substate or {}
901 psubstate = ctx.p1().substate or {}
889 subrepos = []
902 subrepos = []
890 for sub in substate:
903 for sub in substate:
891 if sub not in psubstate or substate[sub] != psubstate[sub]:
904 if sub not in psubstate or substate[sub] != psubstate[sub]:
892 subrepos.append(sub) # modified or newly added in ctx
905 subrepos.append(sub) # modified or newly added in ctx
893 for sub in psubstate:
906 for sub in psubstate:
894 if sub not in substate:
907 if sub not in substate:
895 subrepos.append(sub) # removed in ctx
908 subrepos.append(sub) # removed in ctx
896 return compatlist(context, mapping, b'subrepo', sorted(subrepos))
909 return compatlist(context, mapping, b'subrepo', sorted(subrepos))
897
910
898
911
899 # don't remove "showtags" definition, even though namespaces will put
912 # don't remove "showtags" definition, even though namespaces will put
900 # a helper function for "tags" keyword into "keywords" map automatically,
913 # a helper function for "tags" keyword into "keywords" map automatically,
901 # because online help text is built without namespaces initialization
914 # because online help text is built without namespaces initialization
902 @templatekeyword(b'tags', requires={b'repo', b'ctx'})
915 @templatekeyword(b'tags', requires={b'repo', b'ctx'})
903 def showtags(context, mapping):
916 def showtags(context, mapping):
904 """List of strings. Any tags associated with the changeset."""
917 """List of strings. Any tags associated with the changeset."""
905 return shownames(context, mapping, b'tags')
918 return shownames(context, mapping, b'tags')
906
919
907
920
908 @templatekeyword(b'termwidth', requires={b'ui'})
921 @templatekeyword(b'termwidth', requires={b'ui'})
909 def showtermwidth(context, mapping):
922 def showtermwidth(context, mapping):
910 """Integer. The width of the current terminal."""
923 """Integer. The width of the current terminal."""
911 ui = context.resource(mapping, b'ui')
924 ui = context.resource(mapping, b'ui')
912 return ui.termwidth()
925 return ui.termwidth()
913
926
914
927
915 @templatekeyword(b'user', requires={b'ctx'})
928 @templatekeyword(b'user', requires={b'ctx'})
916 def showuser(context, mapping):
929 def showuser(context, mapping):
917 """String. The unmodified author of the changeset."""
930 """String. The unmodified author of the changeset."""
918 ctx = context.resource(mapping, b'ctx')
931 ctx = context.resource(mapping, b'ctx')
919 return ctx.user()
932 return ctx.user()
920
933
921
934
922 @templatekeyword(b'instabilities', requires={b'ctx'})
935 @templatekeyword(b'instabilities', requires={b'ctx'})
923 def showinstabilities(context, mapping):
936 def showinstabilities(context, mapping):
924 """List of strings. Evolution instabilities affecting the changeset.
937 """List of strings. Evolution instabilities affecting the changeset.
925 (EXPERIMENTAL)
938 (EXPERIMENTAL)
926 """
939 """
927 ctx = context.resource(mapping, b'ctx')
940 ctx = context.resource(mapping, b'ctx')
928 return compatlist(
941 return compatlist(
929 context,
942 context,
930 mapping,
943 mapping,
931 b'instability',
944 b'instability',
932 ctx.instabilities(),
945 ctx.instabilities(),
933 plural=b'instabilities',
946 plural=b'instabilities',
934 )
947 )
935
948
936
949
937 @templatekeyword(b'verbosity', requires={b'ui'})
950 @templatekeyword(b'verbosity', requires={b'ui'})
938 def showverbosity(context, mapping):
951 def showverbosity(context, mapping):
939 """String. The current output verbosity in 'debug', 'quiet', 'verbose',
952 """String. The current output verbosity in 'debug', 'quiet', 'verbose',
940 or ''."""
953 or ''."""
941 ui = context.resource(mapping, b'ui')
954 ui = context.resource(mapping, b'ui')
942 # see logcmdutil.changesettemplater for priority of these flags
955 # see logcmdutil.changesettemplater for priority of these flags
943 if ui.debugflag:
956 if ui.debugflag:
944 return b'debug'
957 return b'debug'
945 elif ui.quiet:
958 elif ui.quiet:
946 return b'quiet'
959 return b'quiet'
947 elif ui.verbose:
960 elif ui.verbose:
948 return b'verbose'
961 return b'verbose'
949 return b''
962 return b''
950
963
951
964
952 @templatekeyword(b'whyunstable', requires={b'repo', b'ctx'})
965 @templatekeyword(b'whyunstable', requires={b'repo', b'ctx'})
953 def showwhyunstable(context, mapping):
966 def showwhyunstable(context, mapping):
954 """List of dicts explaining all instabilities of a changeset.
967 """List of dicts explaining all instabilities of a changeset.
955 (EXPERIMENTAL)
968 (EXPERIMENTAL)
956 """
969 """
957 repo = context.resource(mapping, b'repo')
970 repo = context.resource(mapping, b'repo')
958 ctx = context.resource(mapping, b'ctx')
971 ctx = context.resource(mapping, b'ctx')
959
972
960 def formatnode(ctx):
973 def formatnode(ctx):
961 return b'%s (%s)' % (scmutil.formatchangeid(ctx), ctx.phasestr())
974 return b'%s (%s)' % (scmutil.formatchangeid(ctx), ctx.phasestr())
962
975
963 entries = obsutil.whyunstable(repo, ctx)
976 entries = obsutil.whyunstable(repo, ctx)
964
977
965 for entry in entries:
978 for entry in entries:
966 if entry.get(b'divergentnodes'):
979 if entry.get(b'divergentnodes'):
967 dnodes = entry[b'divergentnodes']
980 dnodes = entry[b'divergentnodes']
968 dnhybrid = _hybrid(
981 dnhybrid = _hybrid(
969 None,
982 None,
970 [dnode.hex() for dnode in dnodes],
983 [dnode.hex() for dnode in dnodes],
971 lambda x: {b'ctx': repo[x]},
984 lambda x: {b'ctx': repo[x]},
972 lambda x: formatnode(repo[x]),
985 lambda x: formatnode(repo[x]),
973 )
986 )
974 entry[b'divergentnodes'] = dnhybrid
987 entry[b'divergentnodes'] = dnhybrid
975
988
976 tmpl = (
989 tmpl = (
977 b'{instability}:{if(divergentnodes, " ")}{divergentnodes} '
990 b'{instability}:{if(divergentnodes, " ")}{divergentnodes} '
978 b'{reason} {node|short}'
991 b'{reason} {node|short}'
979 )
992 )
980 return templateutil.mappinglist(entries, tmpl=tmpl, sep=b'\n')
993 return templateutil.mappinglist(entries, tmpl=tmpl, sep=b'\n')
981
994
982
995
983 def loadkeyword(ui, extname, registrarobj):
996 def loadkeyword(ui, extname, registrarobj):
984 """Load template keyword from specified registrarobj
997 """Load template keyword from specified registrarobj
985 """
998 """
986 for name, func in pycompat.iteritems(registrarobj._table):
999 for name, func in pycompat.iteritems(registrarobj._table):
987 keywords[name] = func
1000 keywords[name] = func
988
1001
989
1002
990 # tell hggettext to extract docstrings from these functions:
1003 # tell hggettext to extract docstrings from these functions:
991 i18nfunctions = keywords.values()
1004 i18nfunctions = keywords.values()
@@ -1,1380 +1,1404 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 $ hg log -r 'wdir()' -Tjson --debug
55 $ hg log -r 'wdir()' -Tjson --debug
56 [
56 [
57 {
57 {
58 "added": [],
58 "added": [],
59 "bookmarks": [],
59 "bookmarks": [],
60 "branch": "default",
60 "branch": "default",
61 "date": [0, 0],
61 "date": [0, 0],
62 "desc": "",
62 "desc": "",
63 "extra": {"branch": "default"},
63 "extra": {"branch": "default"},
64 "manifest": "ffffffffffffffffffffffffffffffffffffffff",
64 "manifest": "ffffffffffffffffffffffffffffffffffffffff",
65 "modified": [],
65 "modified": [],
66 "node": "ffffffffffffffffffffffffffffffffffffffff",
66 "node": "ffffffffffffffffffffffffffffffffffffffff",
67 "parents": ["95c24699272ef57d062b8bccc32c878bf841784a"],
67 "parents": ["95c24699272ef57d062b8bccc32c878bf841784a"],
68 "phase": "draft",
68 "phase": "draft",
69 "removed": [],
69 "removed": [],
70 "rev": 2147483647,
70 "rev": 2147483647,
71 "tags": [],
71 "tags": [],
72 "user": "test"
72 "user": "test"
73 }
73 }
74 ]
74 ]
75
75
76 $ hg log -r 'wdir()' -T '{manifest}\n'
76 $ hg log -r 'wdir()' -T '{manifest}\n'
77 2147483647:ffffffffffff
77 2147483647:ffffffffffff
78
78
79 However, for negrev, we refuse to output anything (as well as for null)
79 However, for negrev, we refuse to output anything (as well as for null)
80
80
81 $ hg log -r 'wdir() + null' -T 'bla{negrev}nk\n'
81 $ hg log -r 'wdir() + null' -T 'bla{negrev}nk\n'
82 blank
82 blank
83 blank
83 blank
84
84
85 Changectx-derived keywords are disabled within {manifest} as {node} changes:
85 Changectx-derived keywords are disabled within {manifest} as {node} changes:
86
86
87 $ hg log -r0 -T 'outer:{p1node} {manifest % "inner:{p1node}"}\n'
87 $ hg log -r0 -T 'outer:{p1node} {manifest % "inner:{p1node}"}\n'
88 outer:0000000000000000000000000000000000000000 inner:
88 outer:0000000000000000000000000000000000000000 inner:
89
89
90 Check that {phase} works correctly on parents:
90 Check that {phase} works correctly on parents:
91
91
92 $ cat << EOF > parentphase
92 $ cat << EOF > parentphase
93 > changeset_debug = '{rev} ({phase}):{parents}\n'
93 > changeset_debug = '{rev} ({phase}):{parents}\n'
94 > parent = ' {rev} ({phase})'
94 > parent = ' {rev} ({phase})'
95 > EOF
95 > EOF
96 $ hg phase -r 5 --public
96 $ hg phase -r 5 --public
97 $ hg phase -r 7 --secret --force
97 $ hg phase -r 7 --secret --force
98 $ hg log --debug -G --style ./parentphase
98 $ hg log --debug -G --style ./parentphase
99 @ 8 (secret): 7 (secret) -1 (public)
99 @ 8 (secret): 7 (secret) -1 (public)
100 |
100 |
101 o 7 (secret): -1 (public) -1 (public)
101 o 7 (secret): -1 (public) -1 (public)
102
102
103 o 6 (draft): 5 (public) 4 (draft)
103 o 6 (draft): 5 (public) 4 (draft)
104 |\
104 |\
105 | o 5 (public): 3 (public) -1 (public)
105 | o 5 (public): 3 (public) -1 (public)
106 | |
106 | |
107 o | 4 (draft): 3 (public) -1 (public)
107 o | 4 (draft): 3 (public) -1 (public)
108 |/
108 |/
109 o 3 (public): 2 (public) -1 (public)
109 o 3 (public): 2 (public) -1 (public)
110 |
110 |
111 o 2 (public): 1 (public) -1 (public)
111 o 2 (public): 1 (public) -1 (public)
112 |
112 |
113 o 1 (public): 0 (public) -1 (public)
113 o 1 (public): 0 (public) -1 (public)
114 |
114 |
115 o 0 (public): -1 (public) -1 (public)
115 o 0 (public): -1 (public) -1 (public)
116
116
117 Test {onelinesummary}
118
119 $ hg log -G -T '{onelinesummary}'
120 @ 8:95c24699272e tip "third"
121 |
122 o 7:29114dbae42b "second"
123
124 o 6:d41e714fe50d "merge"
125 |\
126 | o 5:13207e5a10d9 "new head"
127 | |
128 o | 4:bbe44766e73d "new branch"
129 |/
130 o 3:10e46f2dcbf4 "no user, no domain"
131 |
132 o 2:97054abb4ab8 "no person"
133 |
134 o 1:b608e9d1a3f0 "other 1"
135 |
136 o 0:1e4e1b8f71e0 "line 1"
137
138 $ hg log -T '{onelinesummary}' -r 0 \
139 > --config command-templates.oneline-summary='{rev} - {desc}'
140 0 - line 1 (no-eol)
117
141
118 Keys work:
142 Keys work:
119
143
120 $ for key in author branch branches date desc file_adds file_dels file_mods \
144 $ for key in author branch branches date desc file_adds file_dels file_mods \
121 > file_copies file_copies_switch files \
145 > file_copies file_copies_switch files \
122 > manifest node parents rev tags diffstat extras \
146 > manifest node parents rev tags diffstat extras \
123 > p1rev p2rev p1node p2node user; do
147 > p1rev p2rev p1node p2node user; do
124 > for mode in '' --verbose --debug; do
148 > for mode in '' --verbose --debug; do
125 > hg log $mode --template "$key$mode: {$key}\n"
149 > hg log $mode --template "$key$mode: {$key}\n"
126 > done
150 > done
127 > done
151 > done
128 author: test
152 author: test
129 author: User Name <user@hostname>
153 author: User Name <user@hostname>
130 author: person
154 author: person
131 author: person
155 author: person
132 author: person
156 author: person
133 author: person
157 author: person
134 author: other@place
158 author: other@place
135 author: A. N. Other <other@place>
159 author: A. N. Other <other@place>
136 author: User Name <user@hostname>
160 author: User Name <user@hostname>
137 author--verbose: test
161 author--verbose: test
138 author--verbose: User Name <user@hostname>
162 author--verbose: User Name <user@hostname>
139 author--verbose: person
163 author--verbose: person
140 author--verbose: person
164 author--verbose: person
141 author--verbose: person
165 author--verbose: person
142 author--verbose: person
166 author--verbose: person
143 author--verbose: other@place
167 author--verbose: other@place
144 author--verbose: A. N. Other <other@place>
168 author--verbose: A. N. Other <other@place>
145 author--verbose: User Name <user@hostname>
169 author--verbose: User Name <user@hostname>
146 author--debug: test
170 author--debug: test
147 author--debug: User Name <user@hostname>
171 author--debug: User Name <user@hostname>
148 author--debug: person
172 author--debug: person
149 author--debug: person
173 author--debug: person
150 author--debug: person
174 author--debug: person
151 author--debug: person
175 author--debug: person
152 author--debug: other@place
176 author--debug: other@place
153 author--debug: A. N. Other <other@place>
177 author--debug: A. N. Other <other@place>
154 author--debug: User Name <user@hostname>
178 author--debug: User Name <user@hostname>
155 branch: default
179 branch: default
156 branch: default
180 branch: default
157 branch: default
181 branch: default
158 branch: default
182 branch: default
159 branch: foo
183 branch: foo
160 branch: default
184 branch: default
161 branch: default
185 branch: default
162 branch: default
186 branch: default
163 branch: default
187 branch: default
164 branch--verbose: default
188 branch--verbose: default
165 branch--verbose: default
189 branch--verbose: default
166 branch--verbose: default
190 branch--verbose: default
167 branch--verbose: default
191 branch--verbose: default
168 branch--verbose: foo
192 branch--verbose: foo
169 branch--verbose: default
193 branch--verbose: default
170 branch--verbose: default
194 branch--verbose: default
171 branch--verbose: default
195 branch--verbose: default
172 branch--verbose: default
196 branch--verbose: default
173 branch--debug: default
197 branch--debug: default
174 branch--debug: default
198 branch--debug: default
175 branch--debug: default
199 branch--debug: default
176 branch--debug: default
200 branch--debug: default
177 branch--debug: foo
201 branch--debug: foo
178 branch--debug: default
202 branch--debug: default
179 branch--debug: default
203 branch--debug: default
180 branch--debug: default
204 branch--debug: default
181 branch--debug: default
205 branch--debug: default
182 branches:
206 branches:
183 branches:
207 branches:
184 branches:
208 branches:
185 branches:
209 branches:
186 branches: foo
210 branches: foo
187 branches:
211 branches:
188 branches:
212 branches:
189 branches:
213 branches:
190 branches:
214 branches:
191 branches--verbose:
215 branches--verbose:
192 branches--verbose:
216 branches--verbose:
193 branches--verbose:
217 branches--verbose:
194 branches--verbose:
218 branches--verbose:
195 branches--verbose: foo
219 branches--verbose: foo
196 branches--verbose:
220 branches--verbose:
197 branches--verbose:
221 branches--verbose:
198 branches--verbose:
222 branches--verbose:
199 branches--verbose:
223 branches--verbose:
200 branches--debug:
224 branches--debug:
201 branches--debug:
225 branches--debug:
202 branches--debug:
226 branches--debug:
203 branches--debug:
227 branches--debug:
204 branches--debug: foo
228 branches--debug: foo
205 branches--debug:
229 branches--debug:
206 branches--debug:
230 branches--debug:
207 branches--debug:
231 branches--debug:
208 branches--debug:
232 branches--debug:
209 date: 1577872860.00
233 date: 1577872860.00
210 date: 1000000.00
234 date: 1000000.00
211 date: 1500001.00
235 date: 1500001.00
212 date: 1500000.00
236 date: 1500000.00
213 date: 1400000.00
237 date: 1400000.00
214 date: 1300000.00
238 date: 1300000.00
215 date: 1200000.00
239 date: 1200000.00
216 date: 1100000.00
240 date: 1100000.00
217 date: 1000000.00
241 date: 1000000.00
218 date--verbose: 1577872860.00
242 date--verbose: 1577872860.00
219 date--verbose: 1000000.00
243 date--verbose: 1000000.00
220 date--verbose: 1500001.00
244 date--verbose: 1500001.00
221 date--verbose: 1500000.00
245 date--verbose: 1500000.00
222 date--verbose: 1400000.00
246 date--verbose: 1400000.00
223 date--verbose: 1300000.00
247 date--verbose: 1300000.00
224 date--verbose: 1200000.00
248 date--verbose: 1200000.00
225 date--verbose: 1100000.00
249 date--verbose: 1100000.00
226 date--verbose: 1000000.00
250 date--verbose: 1000000.00
227 date--debug: 1577872860.00
251 date--debug: 1577872860.00
228 date--debug: 1000000.00
252 date--debug: 1000000.00
229 date--debug: 1500001.00
253 date--debug: 1500001.00
230 date--debug: 1500000.00
254 date--debug: 1500000.00
231 date--debug: 1400000.00
255 date--debug: 1400000.00
232 date--debug: 1300000.00
256 date--debug: 1300000.00
233 date--debug: 1200000.00
257 date--debug: 1200000.00
234 date--debug: 1100000.00
258 date--debug: 1100000.00
235 date--debug: 1000000.00
259 date--debug: 1000000.00
236 desc: third
260 desc: third
237 desc: second
261 desc: second
238 desc: merge
262 desc: merge
239 desc: new head
263 desc: new head
240 desc: new branch
264 desc: new branch
241 desc: no user, no domain
265 desc: no user, no domain
242 desc: no person
266 desc: no person
243 desc: other 1
267 desc: other 1
244 other 2
268 other 2
245
269
246 other 3
270 other 3
247 desc: line 1
271 desc: line 1
248 line 2
272 line 2
249 desc--verbose: third
273 desc--verbose: third
250 desc--verbose: second
274 desc--verbose: second
251 desc--verbose: merge
275 desc--verbose: merge
252 desc--verbose: new head
276 desc--verbose: new head
253 desc--verbose: new branch
277 desc--verbose: new branch
254 desc--verbose: no user, no domain
278 desc--verbose: no user, no domain
255 desc--verbose: no person
279 desc--verbose: no person
256 desc--verbose: other 1
280 desc--verbose: other 1
257 other 2
281 other 2
258
282
259 other 3
283 other 3
260 desc--verbose: line 1
284 desc--verbose: line 1
261 line 2
285 line 2
262 desc--debug: third
286 desc--debug: third
263 desc--debug: second
287 desc--debug: second
264 desc--debug: merge
288 desc--debug: merge
265 desc--debug: new head
289 desc--debug: new head
266 desc--debug: new branch
290 desc--debug: new branch
267 desc--debug: no user, no domain
291 desc--debug: no user, no domain
268 desc--debug: no person
292 desc--debug: no person
269 desc--debug: other 1
293 desc--debug: other 1
270 other 2
294 other 2
271
295
272 other 3
296 other 3
273 desc--debug: line 1
297 desc--debug: line 1
274 line 2
298 line 2
275 file_adds: fourth third
299 file_adds: fourth third
276 file_adds: second
300 file_adds: second
277 file_adds:
301 file_adds:
278 file_adds: d
302 file_adds: d
279 file_adds:
303 file_adds:
280 file_adds:
304 file_adds:
281 file_adds: c
305 file_adds: c
282 file_adds: b
306 file_adds: b
283 file_adds: a
307 file_adds: a
284 file_adds--verbose: fourth third
308 file_adds--verbose: fourth third
285 file_adds--verbose: second
309 file_adds--verbose: second
286 file_adds--verbose:
310 file_adds--verbose:
287 file_adds--verbose: d
311 file_adds--verbose: d
288 file_adds--verbose:
312 file_adds--verbose:
289 file_adds--verbose:
313 file_adds--verbose:
290 file_adds--verbose: c
314 file_adds--verbose: c
291 file_adds--verbose: b
315 file_adds--verbose: b
292 file_adds--verbose: a
316 file_adds--verbose: a
293 file_adds--debug: fourth third
317 file_adds--debug: fourth third
294 file_adds--debug: second
318 file_adds--debug: second
295 file_adds--debug:
319 file_adds--debug:
296 file_adds--debug: d
320 file_adds--debug: d
297 file_adds--debug:
321 file_adds--debug:
298 file_adds--debug:
322 file_adds--debug:
299 file_adds--debug: c
323 file_adds--debug: c
300 file_adds--debug: b
324 file_adds--debug: b
301 file_adds--debug: a
325 file_adds--debug: a
302 file_dels: second
326 file_dels: second
303 file_dels:
327 file_dels:
304 file_dels:
328 file_dels:
305 file_dels:
329 file_dels:
306 file_dels:
330 file_dels:
307 file_dels:
331 file_dels:
308 file_dels:
332 file_dels:
309 file_dels:
333 file_dels:
310 file_dels:
334 file_dels:
311 file_dels--verbose: second
335 file_dels--verbose: second
312 file_dels--verbose:
336 file_dels--verbose:
313 file_dels--verbose:
337 file_dels--verbose:
314 file_dels--verbose:
338 file_dels--verbose:
315 file_dels--verbose:
339 file_dels--verbose:
316 file_dels--verbose:
340 file_dels--verbose:
317 file_dels--verbose:
341 file_dels--verbose:
318 file_dels--verbose:
342 file_dels--verbose:
319 file_dels--verbose:
343 file_dels--verbose:
320 file_dels--debug: second
344 file_dels--debug: second
321 file_dels--debug:
345 file_dels--debug:
322 file_dels--debug:
346 file_dels--debug:
323 file_dels--debug:
347 file_dels--debug:
324 file_dels--debug:
348 file_dels--debug:
325 file_dels--debug:
349 file_dels--debug:
326 file_dels--debug:
350 file_dels--debug:
327 file_dels--debug:
351 file_dels--debug:
328 file_dels--debug:
352 file_dels--debug:
329 file_mods:
353 file_mods:
330 file_mods:
354 file_mods:
331 file_mods:
355 file_mods:
332 file_mods:
356 file_mods:
333 file_mods:
357 file_mods:
334 file_mods: c
358 file_mods: c
335 file_mods:
359 file_mods:
336 file_mods:
360 file_mods:
337 file_mods:
361 file_mods:
338 file_mods--verbose:
362 file_mods--verbose:
339 file_mods--verbose:
363 file_mods--verbose:
340 file_mods--verbose:
364 file_mods--verbose:
341 file_mods--verbose:
365 file_mods--verbose:
342 file_mods--verbose:
366 file_mods--verbose:
343 file_mods--verbose: c
367 file_mods--verbose: c
344 file_mods--verbose:
368 file_mods--verbose:
345 file_mods--verbose:
369 file_mods--verbose:
346 file_mods--verbose:
370 file_mods--verbose:
347 file_mods--debug:
371 file_mods--debug:
348 file_mods--debug:
372 file_mods--debug:
349 file_mods--debug:
373 file_mods--debug:
350 file_mods--debug:
374 file_mods--debug:
351 file_mods--debug:
375 file_mods--debug:
352 file_mods--debug: c
376 file_mods--debug: c
353 file_mods--debug:
377 file_mods--debug:
354 file_mods--debug:
378 file_mods--debug:
355 file_mods--debug:
379 file_mods--debug:
356 file_copies: fourth (second)
380 file_copies: fourth (second)
357 file_copies:
381 file_copies:
358 file_copies:
382 file_copies:
359 file_copies:
383 file_copies:
360 file_copies:
384 file_copies:
361 file_copies:
385 file_copies:
362 file_copies:
386 file_copies:
363 file_copies:
387 file_copies:
364 file_copies:
388 file_copies:
365 file_copies--verbose: fourth (second)
389 file_copies--verbose: fourth (second)
366 file_copies--verbose:
390 file_copies--verbose:
367 file_copies--verbose:
391 file_copies--verbose:
368 file_copies--verbose:
392 file_copies--verbose:
369 file_copies--verbose:
393 file_copies--verbose:
370 file_copies--verbose:
394 file_copies--verbose:
371 file_copies--verbose:
395 file_copies--verbose:
372 file_copies--verbose:
396 file_copies--verbose:
373 file_copies--verbose:
397 file_copies--verbose:
374 file_copies--debug: fourth (second)
398 file_copies--debug: fourth (second)
375 file_copies--debug:
399 file_copies--debug:
376 file_copies--debug:
400 file_copies--debug:
377 file_copies--debug:
401 file_copies--debug:
378 file_copies--debug:
402 file_copies--debug:
379 file_copies--debug:
403 file_copies--debug:
380 file_copies--debug:
404 file_copies--debug:
381 file_copies--debug:
405 file_copies--debug:
382 file_copies--debug:
406 file_copies--debug:
383 file_copies_switch:
407 file_copies_switch:
384 file_copies_switch:
408 file_copies_switch:
385 file_copies_switch:
409 file_copies_switch:
386 file_copies_switch:
410 file_copies_switch:
387 file_copies_switch:
411 file_copies_switch:
388 file_copies_switch:
412 file_copies_switch:
389 file_copies_switch:
413 file_copies_switch:
390 file_copies_switch:
414 file_copies_switch:
391 file_copies_switch:
415 file_copies_switch:
392 file_copies_switch--verbose:
416 file_copies_switch--verbose:
393 file_copies_switch--verbose:
417 file_copies_switch--verbose:
394 file_copies_switch--verbose:
418 file_copies_switch--verbose:
395 file_copies_switch--verbose:
419 file_copies_switch--verbose:
396 file_copies_switch--verbose:
420 file_copies_switch--verbose:
397 file_copies_switch--verbose:
421 file_copies_switch--verbose:
398 file_copies_switch--verbose:
422 file_copies_switch--verbose:
399 file_copies_switch--verbose:
423 file_copies_switch--verbose:
400 file_copies_switch--verbose:
424 file_copies_switch--verbose:
401 file_copies_switch--debug:
425 file_copies_switch--debug:
402 file_copies_switch--debug:
426 file_copies_switch--debug:
403 file_copies_switch--debug:
427 file_copies_switch--debug:
404 file_copies_switch--debug:
428 file_copies_switch--debug:
405 file_copies_switch--debug:
429 file_copies_switch--debug:
406 file_copies_switch--debug:
430 file_copies_switch--debug:
407 file_copies_switch--debug:
431 file_copies_switch--debug:
408 file_copies_switch--debug:
432 file_copies_switch--debug:
409 file_copies_switch--debug:
433 file_copies_switch--debug:
410 files: fourth second third
434 files: fourth second third
411 files: second
435 files: second
412 files:
436 files:
413 files: d
437 files: d
414 files:
438 files:
415 files: c
439 files: c
416 files: c
440 files: c
417 files: b
441 files: b
418 files: a
442 files: a
419 files--verbose: fourth second third
443 files--verbose: fourth second third
420 files--verbose: second
444 files--verbose: second
421 files--verbose:
445 files--verbose:
422 files--verbose: d
446 files--verbose: d
423 files--verbose:
447 files--verbose:
424 files--verbose: c
448 files--verbose: c
425 files--verbose: c
449 files--verbose: c
426 files--verbose: b
450 files--verbose: b
427 files--verbose: a
451 files--verbose: a
428 files--debug: fourth second third
452 files--debug: fourth second third
429 files--debug: second
453 files--debug: second
430 files--debug:
454 files--debug:
431 files--debug: d
455 files--debug: d
432 files--debug:
456 files--debug:
433 files--debug: c
457 files--debug: c
434 files--debug: c
458 files--debug: c
435 files--debug: b
459 files--debug: b
436 files--debug: a
460 files--debug: a
437 manifest: 6:94961b75a2da
461 manifest: 6:94961b75a2da
438 manifest: 5:f2dbc354b94e
462 manifest: 5:f2dbc354b94e
439 manifest: 4:4dc3def4f9b4
463 manifest: 4:4dc3def4f9b4
440 manifest: 4:4dc3def4f9b4
464 manifest: 4:4dc3def4f9b4
441 manifest: 3:cb5a1327723b
465 manifest: 3:cb5a1327723b
442 manifest: 3:cb5a1327723b
466 manifest: 3:cb5a1327723b
443 manifest: 2:6e0e82995c35
467 manifest: 2:6e0e82995c35
444 manifest: 1:4e8d705b1e53
468 manifest: 1:4e8d705b1e53
445 manifest: 0:a0c8bcbbb45c
469 manifest: 0:a0c8bcbbb45c
446 manifest--verbose: 6:94961b75a2da
470 manifest--verbose: 6:94961b75a2da
447 manifest--verbose: 5:f2dbc354b94e
471 manifest--verbose: 5:f2dbc354b94e
448 manifest--verbose: 4:4dc3def4f9b4
472 manifest--verbose: 4:4dc3def4f9b4
449 manifest--verbose: 4:4dc3def4f9b4
473 manifest--verbose: 4:4dc3def4f9b4
450 manifest--verbose: 3:cb5a1327723b
474 manifest--verbose: 3:cb5a1327723b
451 manifest--verbose: 3:cb5a1327723b
475 manifest--verbose: 3:cb5a1327723b
452 manifest--verbose: 2:6e0e82995c35
476 manifest--verbose: 2:6e0e82995c35
453 manifest--verbose: 1:4e8d705b1e53
477 manifest--verbose: 1:4e8d705b1e53
454 manifest--verbose: 0:a0c8bcbbb45c
478 manifest--verbose: 0:a0c8bcbbb45c
455 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
479 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
456 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
480 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
457 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
481 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
458 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
482 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
459 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
483 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
460 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
484 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
461 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
485 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
462 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
486 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
463 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
487 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
464 node: 95c24699272ef57d062b8bccc32c878bf841784a
488 node: 95c24699272ef57d062b8bccc32c878bf841784a
465 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
489 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
466 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
490 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
467 node: 13207e5a10d9fd28ec424934298e176197f2c67f
491 node: 13207e5a10d9fd28ec424934298e176197f2c67f
468 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
492 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
469 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
493 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
470 node: 97054abb4ab824450e9164180baf491ae0078465
494 node: 97054abb4ab824450e9164180baf491ae0078465
471 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
495 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
472 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
496 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
473 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
497 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
474 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
498 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
475 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
499 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
476 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
500 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
477 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
501 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
478 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
502 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
479 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
503 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
480 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
504 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
481 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
505 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
482 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
506 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
483 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
507 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
484 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
508 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
485 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
509 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
486 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
510 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
487 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
511 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
488 node--debug: 97054abb4ab824450e9164180baf491ae0078465
512 node--debug: 97054abb4ab824450e9164180baf491ae0078465
489 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
513 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
490 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
514 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
491 parents:
515 parents:
492 parents: -1:000000000000
516 parents: -1:000000000000
493 parents: 5:13207e5a10d9 4:bbe44766e73d
517 parents: 5:13207e5a10d9 4:bbe44766e73d
494 parents: 3:10e46f2dcbf4
518 parents: 3:10e46f2dcbf4
495 parents:
519 parents:
496 parents:
520 parents:
497 parents:
521 parents:
498 parents:
522 parents:
499 parents:
523 parents:
500 parents--verbose:
524 parents--verbose:
501 parents--verbose: -1:000000000000
525 parents--verbose: -1:000000000000
502 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
526 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
503 parents--verbose: 3:10e46f2dcbf4
527 parents--verbose: 3:10e46f2dcbf4
504 parents--verbose:
528 parents--verbose:
505 parents--verbose:
529 parents--verbose:
506 parents--verbose:
530 parents--verbose:
507 parents--verbose:
531 parents--verbose:
508 parents--verbose:
532 parents--verbose:
509 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
533 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
510 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
534 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
511 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
535 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
512 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
536 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
513 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
537 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
514 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
538 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
515 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
539 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
516 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
540 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
517 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
541 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
518 rev: 8
542 rev: 8
519 rev: 7
543 rev: 7
520 rev: 6
544 rev: 6
521 rev: 5
545 rev: 5
522 rev: 4
546 rev: 4
523 rev: 3
547 rev: 3
524 rev: 2
548 rev: 2
525 rev: 1
549 rev: 1
526 rev: 0
550 rev: 0
527 rev--verbose: 8
551 rev--verbose: 8
528 rev--verbose: 7
552 rev--verbose: 7
529 rev--verbose: 6
553 rev--verbose: 6
530 rev--verbose: 5
554 rev--verbose: 5
531 rev--verbose: 4
555 rev--verbose: 4
532 rev--verbose: 3
556 rev--verbose: 3
533 rev--verbose: 2
557 rev--verbose: 2
534 rev--verbose: 1
558 rev--verbose: 1
535 rev--verbose: 0
559 rev--verbose: 0
536 rev--debug: 8
560 rev--debug: 8
537 rev--debug: 7
561 rev--debug: 7
538 rev--debug: 6
562 rev--debug: 6
539 rev--debug: 5
563 rev--debug: 5
540 rev--debug: 4
564 rev--debug: 4
541 rev--debug: 3
565 rev--debug: 3
542 rev--debug: 2
566 rev--debug: 2
543 rev--debug: 1
567 rev--debug: 1
544 rev--debug: 0
568 rev--debug: 0
545 tags: tip
569 tags: tip
546 tags:
570 tags:
547 tags:
571 tags:
548 tags:
572 tags:
549 tags:
573 tags:
550 tags:
574 tags:
551 tags:
575 tags:
552 tags:
576 tags:
553 tags:
577 tags:
554 tags--verbose: tip
578 tags--verbose: tip
555 tags--verbose:
579 tags--verbose:
556 tags--verbose:
580 tags--verbose:
557 tags--verbose:
581 tags--verbose:
558 tags--verbose:
582 tags--verbose:
559 tags--verbose:
583 tags--verbose:
560 tags--verbose:
584 tags--verbose:
561 tags--verbose:
585 tags--verbose:
562 tags--verbose:
586 tags--verbose:
563 tags--debug: tip
587 tags--debug: tip
564 tags--debug:
588 tags--debug:
565 tags--debug:
589 tags--debug:
566 tags--debug:
590 tags--debug:
567 tags--debug:
591 tags--debug:
568 tags--debug:
592 tags--debug:
569 tags--debug:
593 tags--debug:
570 tags--debug:
594 tags--debug:
571 tags--debug:
595 tags--debug:
572 diffstat: 3: +2/-1
596 diffstat: 3: +2/-1
573 diffstat: 1: +1/-0
597 diffstat: 1: +1/-0
574 diffstat: 0: +0/-0
598 diffstat: 0: +0/-0
575 diffstat: 1: +1/-0
599 diffstat: 1: +1/-0
576 diffstat: 0: +0/-0
600 diffstat: 0: +0/-0
577 diffstat: 1: +1/-0
601 diffstat: 1: +1/-0
578 diffstat: 1: +4/-0
602 diffstat: 1: +4/-0
579 diffstat: 1: +2/-0
603 diffstat: 1: +2/-0
580 diffstat: 1: +1/-0
604 diffstat: 1: +1/-0
581 diffstat--verbose: 3: +2/-1
605 diffstat--verbose: 3: +2/-1
582 diffstat--verbose: 1: +1/-0
606 diffstat--verbose: 1: +1/-0
583 diffstat--verbose: 0: +0/-0
607 diffstat--verbose: 0: +0/-0
584 diffstat--verbose: 1: +1/-0
608 diffstat--verbose: 1: +1/-0
585 diffstat--verbose: 0: +0/-0
609 diffstat--verbose: 0: +0/-0
586 diffstat--verbose: 1: +1/-0
610 diffstat--verbose: 1: +1/-0
587 diffstat--verbose: 1: +4/-0
611 diffstat--verbose: 1: +4/-0
588 diffstat--verbose: 1: +2/-0
612 diffstat--verbose: 1: +2/-0
589 diffstat--verbose: 1: +1/-0
613 diffstat--verbose: 1: +1/-0
590 diffstat--debug: 3: +2/-1
614 diffstat--debug: 3: +2/-1
591 diffstat--debug: 1: +1/-0
615 diffstat--debug: 1: +1/-0
592 diffstat--debug: 0: +0/-0
616 diffstat--debug: 0: +0/-0
593 diffstat--debug: 1: +1/-0
617 diffstat--debug: 1: +1/-0
594 diffstat--debug: 0: +0/-0
618 diffstat--debug: 0: +0/-0
595 diffstat--debug: 1: +1/-0
619 diffstat--debug: 1: +1/-0
596 diffstat--debug: 1: +4/-0
620 diffstat--debug: 1: +4/-0
597 diffstat--debug: 1: +2/-0
621 diffstat--debug: 1: +2/-0
598 diffstat--debug: 1: +1/-0
622 diffstat--debug: 1: +1/-0
599 extras: branch=default
623 extras: branch=default
600 extras: branch=default
624 extras: branch=default
601 extras: branch=default
625 extras: branch=default
602 extras: branch=default
626 extras: branch=default
603 extras: branch=foo
627 extras: branch=foo
604 extras: branch=default
628 extras: branch=default
605 extras: branch=default
629 extras: branch=default
606 extras: branch=default
630 extras: branch=default
607 extras: branch=default
631 extras: branch=default
608 extras--verbose: branch=default
632 extras--verbose: branch=default
609 extras--verbose: branch=default
633 extras--verbose: branch=default
610 extras--verbose: branch=default
634 extras--verbose: branch=default
611 extras--verbose: branch=default
635 extras--verbose: branch=default
612 extras--verbose: branch=foo
636 extras--verbose: branch=foo
613 extras--verbose: branch=default
637 extras--verbose: branch=default
614 extras--verbose: branch=default
638 extras--verbose: branch=default
615 extras--verbose: branch=default
639 extras--verbose: branch=default
616 extras--verbose: branch=default
640 extras--verbose: branch=default
617 extras--debug: branch=default
641 extras--debug: branch=default
618 extras--debug: branch=default
642 extras--debug: branch=default
619 extras--debug: branch=default
643 extras--debug: branch=default
620 extras--debug: branch=default
644 extras--debug: branch=default
621 extras--debug: branch=foo
645 extras--debug: branch=foo
622 extras--debug: branch=default
646 extras--debug: branch=default
623 extras--debug: branch=default
647 extras--debug: branch=default
624 extras--debug: branch=default
648 extras--debug: branch=default
625 extras--debug: branch=default
649 extras--debug: branch=default
626 p1rev: 7
650 p1rev: 7
627 p1rev: -1
651 p1rev: -1
628 p1rev: 5
652 p1rev: 5
629 p1rev: 3
653 p1rev: 3
630 p1rev: 3
654 p1rev: 3
631 p1rev: 2
655 p1rev: 2
632 p1rev: 1
656 p1rev: 1
633 p1rev: 0
657 p1rev: 0
634 p1rev: -1
658 p1rev: -1
635 p1rev--verbose: 7
659 p1rev--verbose: 7
636 p1rev--verbose: -1
660 p1rev--verbose: -1
637 p1rev--verbose: 5
661 p1rev--verbose: 5
638 p1rev--verbose: 3
662 p1rev--verbose: 3
639 p1rev--verbose: 3
663 p1rev--verbose: 3
640 p1rev--verbose: 2
664 p1rev--verbose: 2
641 p1rev--verbose: 1
665 p1rev--verbose: 1
642 p1rev--verbose: 0
666 p1rev--verbose: 0
643 p1rev--verbose: -1
667 p1rev--verbose: -1
644 p1rev--debug: 7
668 p1rev--debug: 7
645 p1rev--debug: -1
669 p1rev--debug: -1
646 p1rev--debug: 5
670 p1rev--debug: 5
647 p1rev--debug: 3
671 p1rev--debug: 3
648 p1rev--debug: 3
672 p1rev--debug: 3
649 p1rev--debug: 2
673 p1rev--debug: 2
650 p1rev--debug: 1
674 p1rev--debug: 1
651 p1rev--debug: 0
675 p1rev--debug: 0
652 p1rev--debug: -1
676 p1rev--debug: -1
653 p2rev: -1
677 p2rev: -1
654 p2rev: -1
678 p2rev: -1
655 p2rev: 4
679 p2rev: 4
656 p2rev: -1
680 p2rev: -1
657 p2rev: -1
681 p2rev: -1
658 p2rev: -1
682 p2rev: -1
659 p2rev: -1
683 p2rev: -1
660 p2rev: -1
684 p2rev: -1
661 p2rev: -1
685 p2rev: -1
662 p2rev--verbose: -1
686 p2rev--verbose: -1
663 p2rev--verbose: -1
687 p2rev--verbose: -1
664 p2rev--verbose: 4
688 p2rev--verbose: 4
665 p2rev--verbose: -1
689 p2rev--verbose: -1
666 p2rev--verbose: -1
690 p2rev--verbose: -1
667 p2rev--verbose: -1
691 p2rev--verbose: -1
668 p2rev--verbose: -1
692 p2rev--verbose: -1
669 p2rev--verbose: -1
693 p2rev--verbose: -1
670 p2rev--verbose: -1
694 p2rev--verbose: -1
671 p2rev--debug: -1
695 p2rev--debug: -1
672 p2rev--debug: -1
696 p2rev--debug: -1
673 p2rev--debug: 4
697 p2rev--debug: 4
674 p2rev--debug: -1
698 p2rev--debug: -1
675 p2rev--debug: -1
699 p2rev--debug: -1
676 p2rev--debug: -1
700 p2rev--debug: -1
677 p2rev--debug: -1
701 p2rev--debug: -1
678 p2rev--debug: -1
702 p2rev--debug: -1
679 p2rev--debug: -1
703 p2rev--debug: -1
680 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
704 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
681 p1node: 0000000000000000000000000000000000000000
705 p1node: 0000000000000000000000000000000000000000
682 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
706 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
683 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
707 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
684 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
708 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
685 p1node: 97054abb4ab824450e9164180baf491ae0078465
709 p1node: 97054abb4ab824450e9164180baf491ae0078465
686 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
710 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
687 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
711 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
688 p1node: 0000000000000000000000000000000000000000
712 p1node: 0000000000000000000000000000000000000000
689 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
713 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
690 p1node--verbose: 0000000000000000000000000000000000000000
714 p1node--verbose: 0000000000000000000000000000000000000000
691 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
715 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
692 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
716 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
693 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
717 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
694 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
718 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
695 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
719 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
696 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
720 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
697 p1node--verbose: 0000000000000000000000000000000000000000
721 p1node--verbose: 0000000000000000000000000000000000000000
698 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
722 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
699 p1node--debug: 0000000000000000000000000000000000000000
723 p1node--debug: 0000000000000000000000000000000000000000
700 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
724 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
701 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
725 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
702 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
726 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
703 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
727 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
704 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
728 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
705 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
729 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
706 p1node--debug: 0000000000000000000000000000000000000000
730 p1node--debug: 0000000000000000000000000000000000000000
707 p2node: 0000000000000000000000000000000000000000
731 p2node: 0000000000000000000000000000000000000000
708 p2node: 0000000000000000000000000000000000000000
732 p2node: 0000000000000000000000000000000000000000
709 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
733 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
710 p2node: 0000000000000000000000000000000000000000
734 p2node: 0000000000000000000000000000000000000000
711 p2node: 0000000000000000000000000000000000000000
735 p2node: 0000000000000000000000000000000000000000
712 p2node: 0000000000000000000000000000000000000000
736 p2node: 0000000000000000000000000000000000000000
713 p2node: 0000000000000000000000000000000000000000
737 p2node: 0000000000000000000000000000000000000000
714 p2node: 0000000000000000000000000000000000000000
738 p2node: 0000000000000000000000000000000000000000
715 p2node: 0000000000000000000000000000000000000000
739 p2node: 0000000000000000000000000000000000000000
716 p2node--verbose: 0000000000000000000000000000000000000000
740 p2node--verbose: 0000000000000000000000000000000000000000
717 p2node--verbose: 0000000000000000000000000000000000000000
741 p2node--verbose: 0000000000000000000000000000000000000000
718 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
742 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
719 p2node--verbose: 0000000000000000000000000000000000000000
743 p2node--verbose: 0000000000000000000000000000000000000000
720 p2node--verbose: 0000000000000000000000000000000000000000
744 p2node--verbose: 0000000000000000000000000000000000000000
721 p2node--verbose: 0000000000000000000000000000000000000000
745 p2node--verbose: 0000000000000000000000000000000000000000
722 p2node--verbose: 0000000000000000000000000000000000000000
746 p2node--verbose: 0000000000000000000000000000000000000000
723 p2node--verbose: 0000000000000000000000000000000000000000
747 p2node--verbose: 0000000000000000000000000000000000000000
724 p2node--verbose: 0000000000000000000000000000000000000000
748 p2node--verbose: 0000000000000000000000000000000000000000
725 p2node--debug: 0000000000000000000000000000000000000000
749 p2node--debug: 0000000000000000000000000000000000000000
726 p2node--debug: 0000000000000000000000000000000000000000
750 p2node--debug: 0000000000000000000000000000000000000000
727 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
751 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
728 p2node--debug: 0000000000000000000000000000000000000000
752 p2node--debug: 0000000000000000000000000000000000000000
729 p2node--debug: 0000000000000000000000000000000000000000
753 p2node--debug: 0000000000000000000000000000000000000000
730 p2node--debug: 0000000000000000000000000000000000000000
754 p2node--debug: 0000000000000000000000000000000000000000
731 p2node--debug: 0000000000000000000000000000000000000000
755 p2node--debug: 0000000000000000000000000000000000000000
732 p2node--debug: 0000000000000000000000000000000000000000
756 p2node--debug: 0000000000000000000000000000000000000000
733 p2node--debug: 0000000000000000000000000000000000000000
757 p2node--debug: 0000000000000000000000000000000000000000
734 user: test
758 user: test
735 user: User Name <user@hostname>
759 user: User Name <user@hostname>
736 user: person
760 user: person
737 user: person
761 user: person
738 user: person
762 user: person
739 user: person
763 user: person
740 user: other@place
764 user: other@place
741 user: A. N. Other <other@place>
765 user: A. N. Other <other@place>
742 user: User Name <user@hostname>
766 user: User Name <user@hostname>
743 user--verbose: test
767 user--verbose: test
744 user--verbose: User Name <user@hostname>
768 user--verbose: User Name <user@hostname>
745 user--verbose: person
769 user--verbose: person
746 user--verbose: person
770 user--verbose: person
747 user--verbose: person
771 user--verbose: person
748 user--verbose: person
772 user--verbose: person
749 user--verbose: other@place
773 user--verbose: other@place
750 user--verbose: A. N. Other <other@place>
774 user--verbose: A. N. Other <other@place>
751 user--verbose: User Name <user@hostname>
775 user--verbose: User Name <user@hostname>
752 user--debug: test
776 user--debug: test
753 user--debug: User Name <user@hostname>
777 user--debug: User Name <user@hostname>
754 user--debug: person
778 user--debug: person
755 user--debug: person
779 user--debug: person
756 user--debug: person
780 user--debug: person
757 user--debug: person
781 user--debug: person
758 user--debug: other@place
782 user--debug: other@place
759 user--debug: A. N. Other <other@place>
783 user--debug: A. N. Other <other@place>
760 user--debug: User Name <user@hostname>
784 user--debug: User Name <user@hostname>
761
785
762 Add a dummy commit to make up for the instability of the above:
786 Add a dummy commit to make up for the instability of the above:
763
787
764 $ echo a > a
788 $ echo a > a
765 $ hg add a
789 $ hg add a
766 $ hg ci -m future
790 $ hg ci -m future
767
791
768 Add a commit that does all possible modifications at once
792 Add a commit that does all possible modifications at once
769
793
770 $ echo modify >> third
794 $ echo modify >> third
771 $ touch b
795 $ touch b
772 $ hg add b
796 $ hg add b
773 $ hg mv fourth fifth
797 $ hg mv fourth fifth
774 $ hg rm a
798 $ hg rm a
775 $ hg ci -m "Modify, add, remove, rename"
799 $ hg ci -m "Modify, add, remove, rename"
776
800
777 Test files list:
801 Test files list:
778
802
779 $ hg log -l1 -T '{join(file_mods, " ")}\n'
803 $ hg log -l1 -T '{join(file_mods, " ")}\n'
780 third
804 third
781 $ hg log -l1 -T '{file_mods % "{file}\n"}'
805 $ hg log -l1 -T '{file_mods % "{file}\n"}'
782 third
806 third
783 $ hg log -l1 -T '{file_mods % "{path}\n"}'
807 $ hg log -l1 -T '{file_mods % "{path}\n"}'
784 third
808 third
785
809
786 $ hg log -l1 -T '{join(files, " ")}\n'
810 $ hg log -l1 -T '{join(files, " ")}\n'
787 a b fifth fourth third
811 a b fifth fourth third
788 $ hg log -l1 -T '{files % "{file}\n"}'
812 $ hg log -l1 -T '{files % "{file}\n"}'
789 a
813 a
790 b
814 b
791 fifth
815 fifth
792 fourth
816 fourth
793 third
817 third
794 $ hg log -l1 -T '{files % "{path}\n"}'
818 $ hg log -l1 -T '{files % "{path}\n"}'
795 a
819 a
796 b
820 b
797 fifth
821 fifth
798 fourth
822 fourth
799 third
823 third
800
824
801 Test files lists on merge commit:
825 Test files lists on merge commit:
802
826
803 $ hg co '.^' -q
827 $ hg co '.^' -q
804 $ touch c
828 $ touch c
805 $ hg add c
829 $ hg add c
806 $ hg ci -qm 'add file'
830 $ hg ci -qm 'add file'
807 $ hg merge 10 -q
831 $ hg merge 10 -q
808 $ hg ci -m 'merge'
832 $ hg ci -m 'merge'
809 $ hg log -l1 -T '{files}\n'
833 $ hg log -l1 -T '{files}\n'
810
834
811 $ hg log -l1 -T '{file_mods}\n'
835 $ hg log -l1 -T '{file_mods}\n'
812
836
813 $ hg log -l1 -T '{file_adds}\n'
837 $ hg log -l1 -T '{file_adds}\n'
814
838
815 $ hg log -l1 -T '{file_dels}\n'
839 $ hg log -l1 -T '{file_dels}\n'
816
840
817
841
818 Test file copies dict:
842 Test file copies dict:
819
843
820 $ hg log -r8 -T '{join(file_copies, " ")}\n'
844 $ hg log -r8 -T '{join(file_copies, " ")}\n'
821 fourth (second)
845 fourth (second)
822 $ hg log -r8 -T '{file_copies % "{name} <- {source}\n"}'
846 $ hg log -r8 -T '{file_copies % "{name} <- {source}\n"}'
823 fourth <- second
847 fourth <- second
824 $ hg log -r8 -T '{file_copies % "{path} <- {source}\n"}'
848 $ hg log -r8 -T '{file_copies % "{path} <- {source}\n"}'
825 fourth <- second
849 fourth <- second
826
850
827 $ hg log -r8 -T '{join(file_copies_switch, " ")}\n'
851 $ hg log -r8 -T '{join(file_copies_switch, " ")}\n'
828
852
829 $ hg log -r8 -C -T '{join(file_copies_switch, " ")}\n'
853 $ hg log -r8 -C -T '{join(file_copies_switch, " ")}\n'
830 fourth (second)
854 fourth (second)
831 $ hg log -r8 -C -T '{file_copies_switch % "{name} <- {source}\n"}'
855 $ hg log -r8 -C -T '{file_copies_switch % "{name} <- {source}\n"}'
832 fourth <- second
856 fourth <- second
833 $ hg log -r8 -C -T '{file_copies_switch % "{path} <- {source}\n"}'
857 $ hg log -r8 -C -T '{file_copies_switch % "{path} <- {source}\n"}'
834 fourth <- second
858 fourth <- second
835
859
836 Test file attributes:
860 Test file attributes:
837
861
838 $ hg log -r10 -T '{files % "{status} {pad(size, 3, left=True)} {path}\n"}'
862 $ hg log -r10 -T '{files % "{status} {pad(size, 3, left=True)} {path}\n"}'
839 R a
863 R a
840 A 0 b
864 A 0 b
841 A 7 fifth
865 A 7 fifth
842 R fourth
866 R fourth
843 M 13 third
867 M 13 third
844
868
845 Test file status including clean ones:
869 Test file status including clean ones:
846
870
847 $ hg log -r9 -T '{files("**") % "{status} {path}\n"}'
871 $ hg log -r9 -T '{files("**") % "{status} {path}\n"}'
848 A a
872 A a
849 C fourth
873 C fourth
850 C third
874 C third
851
875
852 Test index keyword:
876 Test index keyword:
853
877
854 $ hg log -r 10:9 -T '{index + 10}{files % " {index}:{file}"}\n'
878 $ hg log -r 10:9 -T '{index + 10}{files % " {index}:{file}"}\n'
855 10 0:a 1:b 2:fifth 3:fourth 4:third
879 10 0:a 1:b 2:fifth 3:fourth 4:third
856 11 0:a
880 11 0:a
857
881
858 $ hg branches -T '{index} {branch}\n'
882 $ hg branches -T '{index} {branch}\n'
859 0 default
883 0 default
860 1 foo
884 1 foo
861
885
862 p1/p2 keywords:
886 p1/p2 keywords:
863
887
864 $ hg log -r4:7 -GT '{rev} p1:{p1} p2:{p2} p1.rev:{p1.rev} p2.node:{p2.node}\n'
888 $ hg log -r4:7 -GT '{rev} p1:{p1} p2:{p2} p1.rev:{p1.rev} p2.node:{p2.node}\n'
865 o 7 p1:-1:000000000000 p2:-1:000000000000 p1.rev:-1 p2.node:0000000000000000000000000000000000000000
889 o 7 p1:-1:000000000000 p2:-1:000000000000 p1.rev:-1 p2.node:0000000000000000000000000000000000000000
866
890
867 o 6 p1:5:13207e5a10d9 p2:4:bbe44766e73d p1.rev:5 p2.node:bbe44766e73d5f11ed2177f1838de10c53ef3e74
891 o 6 p1:5:13207e5a10d9 p2:4:bbe44766e73d p1.rev:5 p2.node:bbe44766e73d5f11ed2177f1838de10c53ef3e74
868 |\
892 |\
869 | o 5 p1:3:10e46f2dcbf4 p2:-1:000000000000 p1.rev:3 p2.node:0000000000000000000000000000000000000000
893 | o 5 p1:3:10e46f2dcbf4 p2:-1:000000000000 p1.rev:3 p2.node:0000000000000000000000000000000000000000
870 | |
894 | |
871 | ~
895 | ~
872 o 4 p1:3:10e46f2dcbf4 p2:-1:000000000000 p1.rev:3 p2.node:0000000000000000000000000000000000000000
896 o 4 p1:3:10e46f2dcbf4 p2:-1:000000000000 p1.rev:3 p2.node:0000000000000000000000000000000000000000
873 |
897 |
874 ~
898 ~
875
899
876 TODO: no idea what should be displayed as a JSON representation
900 TODO: no idea what should be displayed as a JSON representation
877 $ hg log -r6 -T 'p1:{p1|json}\np2:{p2|json}\n'
901 $ hg log -r6 -T 'p1:{p1|json}\np2:{p2|json}\n'
878 p1:{}
902 p1:{}
879 p2:{}
903 p2:{}
880
904
881 ui verbosity:
905 ui verbosity:
882
906
883 $ hg log -l1 -T '{verbosity}\n'
907 $ hg log -l1 -T '{verbosity}\n'
884
908
885 $ hg log -l1 -T '{verbosity}\n' --debug
909 $ hg log -l1 -T '{verbosity}\n' --debug
886 debug
910 debug
887 $ hg log -l1 -T '{verbosity}\n' --quiet
911 $ hg log -l1 -T '{verbosity}\n' --quiet
888 quiet
912 quiet
889 $ hg log -l1 -T '{verbosity}\n' --verbose
913 $ hg log -l1 -T '{verbosity}\n' --verbose
890 verbose
914 verbose
891
915
892 $ cd ..
916 $ cd ..
893
917
894 latesttag:
918 latesttag:
895
919
896 $ hg init latesttag
920 $ hg init latesttag
897 $ cd latesttag
921 $ cd latesttag
898
922
899 $ echo a > file
923 $ echo a > file
900 $ hg ci -Am a -d '0 0'
924 $ hg ci -Am a -d '0 0'
901 adding file
925 adding file
902
926
903 $ echo b >> file
927 $ echo b >> file
904 $ hg ci -m b -d '1 0'
928 $ hg ci -m b -d '1 0'
905
929
906 $ echo c >> head1
930 $ echo c >> head1
907 $ hg ci -Am h1c -d '2 0'
931 $ hg ci -Am h1c -d '2 0'
908 adding head1
932 adding head1
909
933
910 $ hg update -q 1
934 $ hg update -q 1
911 $ echo d >> head2
935 $ echo d >> head2
912 $ hg ci -Am h2d -d '3 0'
936 $ hg ci -Am h2d -d '3 0'
913 adding head2
937 adding head2
914 created new head
938 created new head
915
939
916 $ echo e >> head2
940 $ echo e >> head2
917 $ hg ci -m h2e -d '4 0'
941 $ hg ci -m h2e -d '4 0'
918
942
919 $ hg merge -q
943 $ hg merge -q
920 $ hg ci -m merge -d '5 -3600'
944 $ hg ci -m merge -d '5 -3600'
921
945
922 No tag set:
946 No tag set:
923
947
924 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
948 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
925 @ 5: null+5
949 @ 5: null+5
926 |\
950 |\
927 | o 4: null+4
951 | o 4: null+4
928 | |
952 | |
929 | o 3: null+3
953 | o 3: null+3
930 | |
954 | |
931 o | 2: null+3
955 o | 2: null+3
932 |/
956 |/
933 o 1: null+2
957 o 1: null+2
934 |
958 |
935 o 0: null+1
959 o 0: null+1
936
960
937
961
938 One common tag: longest path wins for {latesttagdistance}:
962 One common tag: longest path wins for {latesttagdistance}:
939
963
940 $ hg tag -r 1 -m t1 -d '6 0' t1
964 $ hg tag -r 1 -m t1 -d '6 0' t1
941 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
965 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
942 @ 6: t1+4
966 @ 6: t1+4
943 |
967 |
944 o 5: t1+3
968 o 5: t1+3
945 |\
969 |\
946 | o 4: t1+2
970 | o 4: t1+2
947 | |
971 | |
948 | o 3: t1+1
972 | o 3: t1+1
949 | |
973 | |
950 o | 2: t1+1
974 o | 2: t1+1
951 |/
975 |/
952 o 1: t1+0
976 o 1: t1+0
953 |
977 |
954 o 0: null+1
978 o 0: null+1
955
979
956
980
957 One ancestor tag: closest wins:
981 One ancestor tag: closest wins:
958
982
959 $ hg tag -r 2 -m t2 -d '7 0' t2
983 $ hg tag -r 2 -m t2 -d '7 0' t2
960 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
984 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
961 @ 7: t2+3
985 @ 7: t2+3
962 |
986 |
963 o 6: t2+2
987 o 6: t2+2
964 |
988 |
965 o 5: t2+1
989 o 5: t2+1
966 |\
990 |\
967 | o 4: t1+2
991 | o 4: t1+2
968 | |
992 | |
969 | o 3: t1+1
993 | o 3: t1+1
970 | |
994 | |
971 o | 2: t2+0
995 o | 2: t2+0
972 |/
996 |/
973 o 1: t1+0
997 o 1: t1+0
974 |
998 |
975 o 0: null+1
999 o 0: null+1
976
1000
977
1001
978 Two branch tags: more recent wins if same number of changes:
1002 Two branch tags: more recent wins if same number of changes:
979
1003
980 $ hg tag -r 3 -m t3 -d '8 0' t3
1004 $ hg tag -r 3 -m t3 -d '8 0' t3
981 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1005 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
982 @ 8: t3+5
1006 @ 8: t3+5
983 |
1007 |
984 o 7: t3+4
1008 o 7: t3+4
985 |
1009 |
986 o 6: t3+3
1010 o 6: t3+3
987 |
1011 |
988 o 5: t3+2
1012 o 5: t3+2
989 |\
1013 |\
990 | o 4: t3+1
1014 | o 4: t3+1
991 | |
1015 | |
992 | o 3: t3+0
1016 | o 3: t3+0
993 | |
1017 | |
994 o | 2: t2+0
1018 o | 2: t2+0
995 |/
1019 |/
996 o 1: t1+0
1020 o 1: t1+0
997 |
1021 |
998 o 0: null+1
1022 o 0: null+1
999
1023
1000
1024
1001 Two branch tags: fewest changes wins:
1025 Two branch tags: fewest changes wins:
1002
1026
1003 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
1027 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
1004 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1028 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1005 @ 9: t4+5,6
1029 @ 9: t4+5,6
1006 |
1030 |
1007 o 8: t4+4,5
1031 o 8: t4+4,5
1008 |
1032 |
1009 o 7: t4+3,4
1033 o 7: t4+3,4
1010 |
1034 |
1011 o 6: t4+2,3
1035 o 6: t4+2,3
1012 |
1036 |
1013 o 5: t4+1,2
1037 o 5: t4+1,2
1014 |\
1038 |\
1015 | o 4: t4+0,0
1039 | o 4: t4+0,0
1016 | |
1040 | |
1017 | o 3: t3+0,0
1041 | o 3: t3+0,0
1018 | |
1042 | |
1019 o | 2: t2+0,0
1043 o | 2: t2+0,0
1020 |/
1044 |/
1021 o 1: t1+0,0
1045 o 1: t1+0,0
1022 |
1046 |
1023 o 0: null+1,1
1047 o 0: null+1,1
1024
1048
1025
1049
1026 Merged tag overrides:
1050 Merged tag overrides:
1027
1051
1028 $ hg tag -r 5 -m t5 -d '9 0' t5
1052 $ hg tag -r 5 -m t5 -d '9 0' t5
1029 $ hg tag -r 3 -m at3 -d '10 0' at3
1053 $ hg tag -r 3 -m at3 -d '10 0' at3
1030 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1054 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1031 @ 11: t5+6
1055 @ 11: t5+6
1032 |
1056 |
1033 o 10: t5+5
1057 o 10: t5+5
1034 |
1058 |
1035 o 9: t5+4
1059 o 9: t5+4
1036 |
1060 |
1037 o 8: t5+3
1061 o 8: t5+3
1038 |
1062 |
1039 o 7: t5+2
1063 o 7: t5+2
1040 |
1064 |
1041 o 6: t5+1
1065 o 6: t5+1
1042 |
1066 |
1043 o 5: t5+0
1067 o 5: t5+0
1044 |\
1068 |\
1045 | o 4: t4+0
1069 | o 4: t4+0
1046 | |
1070 | |
1047 | o 3: at3:t3+0
1071 | o 3: at3:t3+0
1048 | |
1072 | |
1049 o | 2: t2+0
1073 o | 2: t2+0
1050 |/
1074 |/
1051 o 1: t1+0
1075 o 1: t1+0
1052 |
1076 |
1053 o 0: null+1
1077 o 0: null+1
1054
1078
1055
1079
1056 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1080 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1057 @ 11: t5+6,6
1081 @ 11: t5+6,6
1058 |
1082 |
1059 o 10: t5+5,5
1083 o 10: t5+5,5
1060 |
1084 |
1061 o 9: t5+4,4
1085 o 9: t5+4,4
1062 |
1086 |
1063 o 8: t5+3,3
1087 o 8: t5+3,3
1064 |
1088 |
1065 o 7: t5+2,2
1089 o 7: t5+2,2
1066 |
1090 |
1067 o 6: t5+1,1
1091 o 6: t5+1,1
1068 |
1092 |
1069 o 5: t5+0,0
1093 o 5: t5+0,0
1070 |\
1094 |\
1071 | o 4: t4+0,0
1095 | o 4: t4+0,0
1072 | |
1096 | |
1073 | o 3: at3+0,0 t3+0,0
1097 | o 3: at3+0,0 t3+0,0
1074 | |
1098 | |
1075 o | 2: t2+0,0
1099 o | 2: t2+0,0
1076 |/
1100 |/
1077 o 1: t1+0,0
1101 o 1: t1+0,0
1078 |
1102 |
1079 o 0: null+1,1
1103 o 0: null+1,1
1080
1104
1081
1105
1082 Tags of working-directory parents (issue6055):
1106 Tags of working-directory parents (issue6055):
1083
1107
1084 $ hg update -q 3
1108 $ hg update -q 3
1085 $ echo a > head3
1109 $ echo a > head3
1086 $ hg ci -qAm h3a
1110 $ hg ci -qAm h3a
1087 $ hg merge -q 2
1111 $ hg merge -q 2
1088 $ hg log -Gr'::wdir()' -T "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1112 $ hg log -Gr'::wdir()' -T "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1089 o 2147483647: at3+2,3 t3+2,3
1113 o 2147483647: at3+2,3 t3+2,3
1090 |\
1114 |\
1091 | @ 12: at3+1,1 t3+1,1
1115 | @ 12: at3+1,1 t3+1,1
1092 | |
1116 | |
1093 | o 3: at3+0,0 t3+0,0
1117 | o 3: at3+0,0 t3+0,0
1094 | |
1118 | |
1095 @ | 2: t2+0,0
1119 @ | 2: t2+0,0
1096 |/
1120 |/
1097 o 1: t1+0,0
1121 o 1: t1+0,0
1098 |
1122 |
1099 o 0: null+1,1
1123 o 0: null+1,1
1100
1124
1101
1125
1102 $ hg ci -m merge
1126 $ hg ci -m merge
1103 $ hg log -Gr'::.' -T "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1127 $ hg log -Gr'::.' -T "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1104 @ 13: at3+2,3 t3+2,3
1128 @ 13: at3+2,3 t3+2,3
1105 |\
1129 |\
1106 | o 12: at3+1,1 t3+1,1
1130 | o 12: at3+1,1 t3+1,1
1107 | |
1131 | |
1108 | o 3: at3+0,0 t3+0,0
1132 | o 3: at3+0,0 t3+0,0
1109 | |
1133 | |
1110 o | 2: t2+0,0
1134 o | 2: t2+0,0
1111 |/
1135 |/
1112 o 1: t1+0,0
1136 o 1: t1+0,0
1113 |
1137 |
1114 o 0: null+1,1
1138 o 0: null+1,1
1115
1139
1116
1140
1117 $ cd ..
1141 $ cd ..
1118
1142
1119 Set up repository containing template fragments in commit metadata:
1143 Set up repository containing template fragments in commit metadata:
1120
1144
1121 $ hg init r
1145 $ hg init r
1122 $ cd r
1146 $ cd r
1123 $ echo a > a
1147 $ echo a > a
1124 $ hg ci -Am '{rev}'
1148 $ hg ci -Am '{rev}'
1125 adding a
1149 adding a
1126
1150
1127 $ hg branch -q 'text.{rev}'
1151 $ hg branch -q 'text.{rev}'
1128 $ echo aa >> aa
1152 $ echo aa >> aa
1129 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
1153 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
1130
1154
1131 Test termwidth:
1155 Test termwidth:
1132
1156
1133 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
1157 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
1134 bcc7ff960b8e:desc to be
1158 bcc7ff960b8e:desc to be
1135 termwidth.1:wrapped desc
1159 termwidth.1:wrapped desc
1136 termwidth.1:to be wrapped (no-eol)
1160 termwidth.1:to be wrapped (no-eol)
1137
1161
1138 Just one more commit:
1162 Just one more commit:
1139
1163
1140 $ echo b > b
1164 $ echo b > b
1141 $ hg ci -qAm b
1165 $ hg ci -qAm b
1142
1166
1143 Test 'originalnode'
1167 Test 'originalnode'
1144
1168
1145 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
1169 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
1146 000000000000 bcc7ff960b8e
1170 000000000000 bcc7ff960b8e
1147 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
1171 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
1148 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
1172 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
1149
1173
1150 Test active bookmark templating
1174 Test active bookmark templating
1151
1175
1152 $ hg book foo
1176 $ hg book foo
1153 $ hg book bar
1177 $ hg book bar
1154 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
1178 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
1155 2 bar* foo
1179 2 bar* foo
1156 1
1180 1
1157 0
1181 0
1158 $ hg log --template "{rev} {activebookmark}\n"
1182 $ hg log --template "{rev} {activebookmark}\n"
1159 2 bar
1183 2 bar
1160 1
1184 1
1161 0
1185 0
1162 $ hg bookmarks --inactive bar
1186 $ hg bookmarks --inactive bar
1163 $ hg log --template "{rev} {activebookmark}\n"
1187 $ hg log --template "{rev} {activebookmark}\n"
1164 2
1188 2
1165 1
1189 1
1166 0
1190 0
1167 $ hg book -r1 baz
1191 $ hg book -r1 baz
1168 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
1192 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
1169 2 bar foo
1193 2 bar foo
1170 1 baz
1194 1 baz
1171 0
1195 0
1172 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
1196 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
1173 2 t
1197 2 t
1174 1 f
1198 1 f
1175 0 f
1199 0 f
1176
1200
1177 Test namespaces dict
1201 Test namespaces dict
1178
1202
1179 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
1203 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
1180 2
1204 2
1181 bookmarks color=bookmark builtin=True
1205 bookmarks color=bookmark builtin=True
1182 bar,foo
1206 bar,foo
1183 tags color=tag builtin=True
1207 tags color=tag builtin=True
1184 tip
1208 tip
1185 branches color=branch builtin=True
1209 branches color=branch builtin=True
1186 text.{rev}
1210 text.{rev}
1187 revnames color=revname builtin=False
1211 revnames color=revname builtin=False
1188 r2
1212 r2
1189
1213
1190 1
1214 1
1191 bookmarks color=bookmark builtin=True
1215 bookmarks color=bookmark builtin=True
1192 baz
1216 baz
1193 tags color=tag builtin=True
1217 tags color=tag builtin=True
1194
1218
1195 branches color=branch builtin=True
1219 branches color=branch builtin=True
1196 text.{rev}
1220 text.{rev}
1197 revnames color=revname builtin=False
1221 revnames color=revname builtin=False
1198 r1
1222 r1
1199
1223
1200 0
1224 0
1201 bookmarks color=bookmark builtin=True
1225 bookmarks color=bookmark builtin=True
1202
1226
1203 tags color=tag builtin=True
1227 tags color=tag builtin=True
1204
1228
1205 branches color=branch builtin=True
1229 branches color=branch builtin=True
1206 default
1230 default
1207 revnames color=revname builtin=False
1231 revnames color=revname builtin=False
1208 r0
1232 r0
1209
1233
1210 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
1234 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
1211 bookmarks: bar foo
1235 bookmarks: bar foo
1212 tags: tip
1236 tags: tip
1213 branches: text.{rev}
1237 branches: text.{rev}
1214 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
1238 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
1215 bookmarks:
1239 bookmarks:
1216 bar
1240 bar
1217 foo
1241 foo
1218 tags:
1242 tags:
1219 tip
1243 tip
1220 branches:
1244 branches:
1221 text.{rev}
1245 text.{rev}
1222 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
1246 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
1223 bar
1247 bar
1224 foo
1248 foo
1225 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
1249 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
1226 bar
1250 bar
1227 foo
1251 foo
1228
1252
1229 $ cd ..
1253 $ cd ..
1230
1254
1231 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
1255 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
1232 printed graphwidths 3, 5, 7, etc. should all line up in their respective
1256 printed graphwidths 3, 5, 7, etc. should all line up in their respective
1233 columns. We don't care about other aspects of the graph rendering here.
1257 columns. We don't care about other aspects of the graph rendering here.
1234
1258
1235 $ hg init graphwidth
1259 $ hg init graphwidth
1236 $ cd graphwidth
1260 $ cd graphwidth
1237
1261
1238 $ wrappabletext="a a a a a a a a a a a a"
1262 $ wrappabletext="a a a a a a a a a a a a"
1239
1263
1240 $ printf "first\n" > file
1264 $ printf "first\n" > file
1241 $ hg add file
1265 $ hg add file
1242 $ hg commit -m "$wrappabletext"
1266 $ hg commit -m "$wrappabletext"
1243
1267
1244 $ printf "first\nsecond\n" > file
1268 $ printf "first\nsecond\n" > file
1245 $ hg commit -m "$wrappabletext"
1269 $ hg commit -m "$wrappabletext"
1246
1270
1247 $ hg checkout 0
1271 $ hg checkout 0
1248 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1272 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1249 $ printf "third\nfirst\n" > file
1273 $ printf "third\nfirst\n" > file
1250 $ hg commit -m "$wrappabletext"
1274 $ hg commit -m "$wrappabletext"
1251 created new head
1275 created new head
1252
1276
1253 $ hg merge
1277 $ hg merge
1254 merging file
1278 merging file
1255 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1279 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1256 (branch merge, don't forget to commit)
1280 (branch merge, don't forget to commit)
1257
1281
1258 $ hg log --graph -T "{graphwidth}"
1282 $ hg log --graph -T "{graphwidth}"
1259 @ 3
1283 @ 3
1260 |
1284 |
1261 | @ 5
1285 | @ 5
1262 |/
1286 |/
1263 o 3
1287 o 3
1264
1288
1265 $ hg commit -m "$wrappabletext"
1289 $ hg commit -m "$wrappabletext"
1266
1290
1267 $ hg log --graph -T "{graphwidth}"
1291 $ hg log --graph -T "{graphwidth}"
1268 @ 5
1292 @ 5
1269 |\
1293 |\
1270 | o 5
1294 | o 5
1271 | |
1295 | |
1272 o | 5
1296 o | 5
1273 |/
1297 |/
1274 o 3
1298 o 3
1275
1299
1276
1300
1277 $ hg checkout 0
1301 $ hg checkout 0
1278 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1302 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1279 $ printf "third\nfirst\nsecond\n" > file
1303 $ printf "third\nfirst\nsecond\n" > file
1280 $ hg commit -m "$wrappabletext"
1304 $ hg commit -m "$wrappabletext"
1281 created new head
1305 created new head
1282
1306
1283 $ hg log --graph -T "{graphwidth}"
1307 $ hg log --graph -T "{graphwidth}"
1284 @ 3
1308 @ 3
1285 |
1309 |
1286 | o 7
1310 | o 7
1287 | |\
1311 | |\
1288 +---o 7
1312 +---o 7
1289 | |
1313 | |
1290 | o 5
1314 | o 5
1291 |/
1315 |/
1292 o 3
1316 o 3
1293
1317
1294
1318
1295 $ hg log --graph -T "{graphwidth}" -r 3
1319 $ hg log --graph -T "{graphwidth}" -r 3
1296 o 5
1320 o 5
1297 |\
1321 |\
1298 ~ ~
1322 ~ ~
1299
1323
1300 $ hg log --graph -T "{graphwidth}" -r 1
1324 $ hg log --graph -T "{graphwidth}" -r 1
1301 o 3
1325 o 3
1302 |
1326 |
1303 ~
1327 ~
1304
1328
1305 $ hg merge
1329 $ hg merge
1306 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1330 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1307 (branch merge, don't forget to commit)
1331 (branch merge, don't forget to commit)
1308 $ hg commit -m "$wrappabletext"
1332 $ hg commit -m "$wrappabletext"
1309
1333
1310 $ printf "seventh\n" >> file
1334 $ printf "seventh\n" >> file
1311 $ hg commit -m "$wrappabletext"
1335 $ hg commit -m "$wrappabletext"
1312
1336
1313 $ hg log --graph -T "{graphwidth}"
1337 $ hg log --graph -T "{graphwidth}"
1314 @ 3
1338 @ 3
1315 |
1339 |
1316 o 5
1340 o 5
1317 |\
1341 |\
1318 | o 5
1342 | o 5
1319 | |
1343 | |
1320 o | 7
1344 o | 7
1321 |\ \
1345 |\ \
1322 | o | 7
1346 | o | 7
1323 | |/
1347 | |/
1324 o / 5
1348 o / 5
1325 |/
1349 |/
1326 o 3
1350 o 3
1327
1351
1328
1352
1329 The point of graphwidth is to allow wrapping that accounts for the space taken
1353 The point of graphwidth is to allow wrapping that accounts for the space taken
1330 by the graph.
1354 by the graph.
1331
1355
1332 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
1356 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
1333 @ a a a a
1357 @ a a a a
1334 | a a a a
1358 | a a a a
1335 | a a a a
1359 | a a a a
1336 o a a a
1360 o a a a
1337 |\ a a a
1361 |\ a a a
1338 | | a a a
1362 | | a a a
1339 | | a a a
1363 | | a a a
1340 | o a a a
1364 | o a a a
1341 | | a a a
1365 | | a a a
1342 | | a a a
1366 | | a a a
1343 | | a a a
1367 | | a a a
1344 o | a a
1368 o | a a
1345 |\ \ a a
1369 |\ \ a a
1346 | | | a a
1370 | | | a a
1347 | | | a a
1371 | | | a a
1348 | | | a a
1372 | | | a a
1349 | | | a a
1373 | | | a a
1350 | o | a a
1374 | o | a a
1351 | |/ a a
1375 | |/ a a
1352 | | a a
1376 | | a a
1353 | | a a
1377 | | a a
1354 | | a a
1378 | | a a
1355 | | a a
1379 | | a a
1356 o | a a a
1380 o | a a a
1357 |/ a a a
1381 |/ a a a
1358 | a a a
1382 | a a a
1359 | a a a
1383 | a a a
1360 o a a a a
1384 o a a a a
1361 a a a a
1385 a a a a
1362 a a a a
1386 a a a a
1363
1387
1364 Something tricky happens when there are elided nodes; the next drawn row of
1388 Something tricky happens when there are elided nodes; the next drawn row of
1365 edges can be more than one column wider, but the graph width only increases by
1389 edges can be more than one column wider, but the graph width only increases by
1366 one column. The remaining columns are added in between the nodes.
1390 one column. The remaining columns are added in between the nodes.
1367
1391
1368 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
1392 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
1369 o 5
1393 o 5
1370 |\
1394 |\
1371 | \
1395 | \
1372 | :\
1396 | :\
1373 o : : 7
1397 o : : 7
1374 :/ /
1398 :/ /
1375 : o 5
1399 : o 5
1376 :/
1400 :/
1377 o 3
1401 o 3
1378
1402
1379
1403
1380 $ cd ..
1404 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now