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