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