##// END OF EJS Templates
templatekw: correct typo in activebookmark documentation
Matt Harbison -
r25663:edd2d20a default
parent child Browse files
Show More
@@ -1,471 +1,471
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 node import hex
8 from node import hex
9 import patch, util, error
9 import patch, util, error
10 import hbisect
10 import hbisect
11
11
12 # This helper class allows us to handle both:
12 # This helper class allows us to handle both:
13 # "{files}" (legacy command-line-specific list hack) and
13 # "{files}" (legacy command-line-specific list hack) and
14 # "{files % '{file}\n'}" (hgweb-style with inlining and function support)
14 # "{files % '{file}\n'}" (hgweb-style with inlining and function support)
15 # and to access raw values:
15 # and to access raw values:
16 # "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
16 # "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
17 # "{get(extras, key)}"
17 # "{get(extras, key)}"
18
18
19 class _hybrid(object):
19 class _hybrid(object):
20 def __init__(self, gen, values, makemap, joinfmt=None):
20 def __init__(self, gen, values, makemap, joinfmt=None):
21 self.gen = gen
21 self.gen = gen
22 self.values = values
22 self.values = values
23 self._makemap = makemap
23 self._makemap = makemap
24 if joinfmt:
24 if joinfmt:
25 self.joinfmt = joinfmt
25 self.joinfmt = joinfmt
26 else:
26 else:
27 self.joinfmt = lambda x: x.values()[0]
27 self.joinfmt = lambda x: x.values()[0]
28 def __iter__(self):
28 def __iter__(self):
29 return self.gen
29 return self.gen
30 def __call__(self):
30 def __call__(self):
31 makemap = self._makemap
31 makemap = self._makemap
32 for x in self.values:
32 for x in self.values:
33 yield makemap(x)
33 yield makemap(x)
34 def __contains__(self, x):
34 def __contains__(self, x):
35 return x in self.values
35 return x in self.values
36 def __len__(self):
36 def __len__(self):
37 return len(self.values)
37 return len(self.values)
38 def __getattr__(self, name):
38 def __getattr__(self, name):
39 if name != 'get':
39 if name != 'get':
40 raise AttributeError(name)
40 raise AttributeError(name)
41 return getattr(self.values, name)
41 return getattr(self.values, name)
42
42
43 def showlist(name, values, plural=None, element=None, **args):
43 def showlist(name, values, plural=None, element=None, **args):
44 if not element:
44 if not element:
45 element = name
45 element = name
46 f = _showlist(name, values, plural, **args)
46 f = _showlist(name, values, plural, **args)
47 return _hybrid(f, values, lambda x: {element: x})
47 return _hybrid(f, values, lambda x: {element: x})
48
48
49 def _showlist(name, values, plural=None, **args):
49 def _showlist(name, values, plural=None, **args):
50 '''expand set of values.
50 '''expand set of values.
51 name is name of key in template map.
51 name is name of key in template map.
52 values is list of strings or dicts.
52 values is list of strings or dicts.
53 plural is plural of name, if not simply name + 's'.
53 plural is plural of name, if not simply name + 's'.
54
54
55 expansion works like this, given name 'foo'.
55 expansion works like this, given name 'foo'.
56
56
57 if values is empty, expand 'no_foos'.
57 if values is empty, expand 'no_foos'.
58
58
59 if 'foo' not in template map, return values as a string,
59 if 'foo' not in template map, return values as a string,
60 joined by space.
60 joined by space.
61
61
62 expand 'start_foos'.
62 expand 'start_foos'.
63
63
64 for each value, expand 'foo'. if 'last_foo' in template
64 for each value, expand 'foo'. if 'last_foo' in template
65 map, expand it instead of 'foo' for last key.
65 map, expand it instead of 'foo' for last key.
66
66
67 expand 'end_foos'.
67 expand 'end_foos'.
68 '''
68 '''
69 templ = args['templ']
69 templ = args['templ']
70 if plural:
70 if plural:
71 names = plural
71 names = plural
72 else: names = name + 's'
72 else: names = name + 's'
73 if not values:
73 if not values:
74 noname = 'no_' + names
74 noname = 'no_' + names
75 if noname in templ:
75 if noname in templ:
76 yield templ(noname, **args)
76 yield templ(noname, **args)
77 return
77 return
78 if name not in templ:
78 if name not in templ:
79 if isinstance(values[0], str):
79 if isinstance(values[0], str):
80 yield ' '.join(values)
80 yield ' '.join(values)
81 else:
81 else:
82 for v in values:
82 for v in values:
83 yield dict(v, **args)
83 yield dict(v, **args)
84 return
84 return
85 startname = 'start_' + names
85 startname = 'start_' + names
86 if startname in templ:
86 if startname in templ:
87 yield templ(startname, **args)
87 yield templ(startname, **args)
88 vargs = args.copy()
88 vargs = args.copy()
89 def one(v, tag=name):
89 def one(v, tag=name):
90 try:
90 try:
91 vargs.update(v)
91 vargs.update(v)
92 except (AttributeError, ValueError):
92 except (AttributeError, ValueError):
93 try:
93 try:
94 for a, b in v:
94 for a, b in v:
95 vargs[a] = b
95 vargs[a] = b
96 except ValueError:
96 except ValueError:
97 vargs[name] = v
97 vargs[name] = v
98 return templ(tag, **vargs)
98 return templ(tag, **vargs)
99 lastname = 'last_' + name
99 lastname = 'last_' + name
100 if lastname in templ:
100 if lastname in templ:
101 last = values.pop()
101 last = values.pop()
102 else:
102 else:
103 last = None
103 last = None
104 for v in values:
104 for v in values:
105 yield one(v)
105 yield one(v)
106 if last is not None:
106 if last is not None:
107 yield one(last, tag=lastname)
107 yield one(last, tag=lastname)
108 endname = 'end_' + names
108 endname = 'end_' + names
109 if endname in templ:
109 if endname in templ:
110 yield templ(endname, **args)
110 yield templ(endname, **args)
111
111
112 def getfiles(repo, ctx, revcache):
112 def getfiles(repo, ctx, revcache):
113 if 'files' not in revcache:
113 if 'files' not in revcache:
114 revcache['files'] = repo.status(ctx.p1(), ctx)[:3]
114 revcache['files'] = repo.status(ctx.p1(), ctx)[:3]
115 return revcache['files']
115 return revcache['files']
116
116
117 def getlatesttags(repo, ctx, cache):
117 def getlatesttags(repo, ctx, cache):
118 '''return date, distance and name for the latest tag of rev'''
118 '''return date, distance and name for the latest tag of rev'''
119
119
120 if 'latesttags' not in cache:
120 if 'latesttags' not in cache:
121 # Cache mapping from rev to a tuple with tag date, tag
121 # Cache mapping from rev to a tuple with tag date, tag
122 # distance and tag name
122 # distance and tag name
123 cache['latesttags'] = {-1: (0, 0, 'null')}
123 cache['latesttags'] = {-1: (0, 0, 'null')}
124 latesttags = cache['latesttags']
124 latesttags = cache['latesttags']
125
125
126 rev = ctx.rev()
126 rev = ctx.rev()
127 todo = [rev]
127 todo = [rev]
128 while todo:
128 while todo:
129 rev = todo.pop()
129 rev = todo.pop()
130 if rev in latesttags:
130 if rev in latesttags:
131 continue
131 continue
132 ctx = repo[rev]
132 ctx = repo[rev]
133 tags = [t for t in ctx.tags()
133 tags = [t for t in ctx.tags()
134 if (repo.tagtype(t) and repo.tagtype(t) != 'local')]
134 if (repo.tagtype(t) and repo.tagtype(t) != 'local')]
135 if tags:
135 if tags:
136 latesttags[rev] = ctx.date()[0], 0, ':'.join(sorted(tags))
136 latesttags[rev] = ctx.date()[0], 0, ':'.join(sorted(tags))
137 continue
137 continue
138 try:
138 try:
139 # The tuples are laid out so the right one can be found by
139 # The tuples are laid out so the right one can be found by
140 # comparison.
140 # comparison.
141 pdate, pdist, ptag = max(
141 pdate, pdist, ptag = max(
142 latesttags[p.rev()] for p in ctx.parents())
142 latesttags[p.rev()] for p in ctx.parents())
143 except KeyError:
143 except KeyError:
144 # Cache miss - recurse
144 # Cache miss - recurse
145 todo.append(rev)
145 todo.append(rev)
146 todo.extend(p.rev() for p in ctx.parents())
146 todo.extend(p.rev() for p in ctx.parents())
147 continue
147 continue
148 latesttags[rev] = pdate, pdist + 1, ptag
148 latesttags[rev] = pdate, pdist + 1, ptag
149 return latesttags[rev]
149 return latesttags[rev]
150
150
151 def getrenamedfn(repo, endrev=None):
151 def getrenamedfn(repo, endrev=None):
152 rcache = {}
152 rcache = {}
153 if endrev is None:
153 if endrev is None:
154 endrev = len(repo)
154 endrev = len(repo)
155
155
156 def getrenamed(fn, rev):
156 def getrenamed(fn, rev):
157 '''looks up all renames for a file (up to endrev) the first
157 '''looks up all renames for a file (up to endrev) the first
158 time the file is given. It indexes on the changerev and only
158 time the file is given. It indexes on the changerev and only
159 parses the manifest if linkrev != changerev.
159 parses the manifest if linkrev != changerev.
160 Returns rename info for fn at changerev rev.'''
160 Returns rename info for fn at changerev rev.'''
161 if fn not in rcache:
161 if fn not in rcache:
162 rcache[fn] = {}
162 rcache[fn] = {}
163 fl = repo.file(fn)
163 fl = repo.file(fn)
164 for i in fl:
164 for i in fl:
165 lr = fl.linkrev(i)
165 lr = fl.linkrev(i)
166 renamed = fl.renamed(fl.node(i))
166 renamed = fl.renamed(fl.node(i))
167 rcache[fn][lr] = renamed
167 rcache[fn][lr] = renamed
168 if lr >= endrev:
168 if lr >= endrev:
169 break
169 break
170 if rev in rcache[fn]:
170 if rev in rcache[fn]:
171 return rcache[fn][rev]
171 return rcache[fn][rev]
172
172
173 # If linkrev != rev (i.e. rev not found in rcache) fallback to
173 # If linkrev != rev (i.e. rev not found in rcache) fallback to
174 # filectx logic.
174 # filectx logic.
175 try:
175 try:
176 return repo[rev][fn].renamed()
176 return repo[rev][fn].renamed()
177 except error.LookupError:
177 except error.LookupError:
178 return None
178 return None
179
179
180 return getrenamed
180 return getrenamed
181
181
182
182
183 def showauthor(repo, ctx, templ, **args):
183 def showauthor(repo, ctx, templ, **args):
184 """:author: String. The unmodified author of the changeset."""
184 """:author: String. The unmodified author of the changeset."""
185 return ctx.user()
185 return ctx.user()
186
186
187 def showbisect(repo, ctx, templ, **args):
187 def showbisect(repo, ctx, templ, **args):
188 """:bisect: String. The changeset bisection status."""
188 """:bisect: String. The changeset bisection status."""
189 return hbisect.label(repo, ctx.node())
189 return hbisect.label(repo, ctx.node())
190
190
191 def showbranch(**args):
191 def showbranch(**args):
192 """:branch: String. The name of the branch on which the changeset was
192 """:branch: String. The name of the branch on which the changeset was
193 committed.
193 committed.
194 """
194 """
195 return args['ctx'].branch()
195 return args['ctx'].branch()
196
196
197 def showbranches(**args):
197 def showbranches(**args):
198 """:branches: List of strings. The name of the branch on which the
198 """:branches: List of strings. The name of the branch on which the
199 changeset was committed. Will be empty if the branch name was
199 changeset was committed. Will be empty if the branch name was
200 default.
200 default.
201 """
201 """
202 branch = args['ctx'].branch()
202 branch = args['ctx'].branch()
203 if branch != 'default':
203 if branch != 'default':
204 return showlist('branch', [branch], plural='branches', **args)
204 return showlist('branch', [branch], plural='branches', **args)
205 return showlist('branch', [], plural='branches', **args)
205 return showlist('branch', [], plural='branches', **args)
206
206
207 def showbookmarks(**args):
207 def showbookmarks(**args):
208 """:bookmarks: List of strings. Any bookmarks associated with the
208 """:bookmarks: List of strings. Any bookmarks associated with the
209 changeset. Also sets 'active', the name of the active bookmark.
209 changeset. Also sets 'active', the name of the active bookmark.
210 """
210 """
211 repo = args['ctx']._repo
211 repo = args['ctx']._repo
212 bookmarks = args['ctx'].bookmarks()
212 bookmarks = args['ctx'].bookmarks()
213 active = repo._activebookmark
213 active = repo._activebookmark
214 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active}
214 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active}
215 f = _showlist('bookmark', bookmarks, **args)
215 f = _showlist('bookmark', bookmarks, **args)
216 return _hybrid(f, bookmarks, makemap, lambda x: x['bookmark'])
216 return _hybrid(f, bookmarks, makemap, lambda x: x['bookmark'])
217
217
218 def showchildren(**args):
218 def showchildren(**args):
219 """:children: List of strings. The children of the changeset."""
219 """:children: List of strings. The children of the changeset."""
220 ctx = args['ctx']
220 ctx = args['ctx']
221 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
221 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
222 return showlist('children', childrevs, element='child', **args)
222 return showlist('children', childrevs, element='child', **args)
223
223
224 # Deprecated, but kept alive for help generation a purpose.
224 # Deprecated, but kept alive for help generation a purpose.
225 def showcurrentbookmark(**args):
225 def showcurrentbookmark(**args):
226 """:currentbookmark: String. The active bookmark, if it is
226 """:currentbookmark: String. The active bookmark, if it is
227 associated with the changeset (DEPRECATED)"""
227 associated with the changeset (DEPRECATED)"""
228 return showactivebookmark(**args)
228 return showactivebookmark(**args)
229
229
230 def showactivebookmark(**args):
230 def showactivebookmark(**args):
231 """:activetbookmark: String. The active bookmark, if it is
231 """:activebookmark: String. The active bookmark, if it is
232 associated with the changeset"""
232 associated with the changeset"""
233 active = args['repo']._activebookmark
233 active = args['repo']._activebookmark
234 if active and active in args['ctx'].bookmarks():
234 if active and active in args['ctx'].bookmarks():
235 return active
235 return active
236 return ''
236 return ''
237
237
238 def showdate(repo, ctx, templ, **args):
238 def showdate(repo, ctx, templ, **args):
239 """:date: Date information. The date when the changeset was committed."""
239 """:date: Date information. The date when the changeset was committed."""
240 return ctx.date()
240 return ctx.date()
241
241
242 def showdescription(repo, ctx, templ, **args):
242 def showdescription(repo, ctx, templ, **args):
243 """:desc: String. The text of the changeset description."""
243 """:desc: String. The text of the changeset description."""
244 return ctx.description().strip()
244 return ctx.description().strip()
245
245
246 def showdiffstat(repo, ctx, templ, **args):
246 def showdiffstat(repo, ctx, templ, **args):
247 """:diffstat: String. Statistics of changes with the following format:
247 """:diffstat: String. Statistics of changes with the following format:
248 "modified files: +added/-removed lines"
248 "modified files: +added/-removed lines"
249 """
249 """
250 stats = patch.diffstatdata(util.iterlines(ctx.diff()))
250 stats = patch.diffstatdata(util.iterlines(ctx.diff()))
251 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
251 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
252 return '%s: +%s/-%s' % (len(stats), adds, removes)
252 return '%s: +%s/-%s' % (len(stats), adds, removes)
253
253
254 def showextras(**args):
254 def showextras(**args):
255 """:extras: List of dicts with key, value entries of the 'extras'
255 """:extras: List of dicts with key, value entries of the 'extras'
256 field of this changeset."""
256 field of this changeset."""
257 extras = args['ctx'].extra()
257 extras = args['ctx'].extra()
258 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
258 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
259 makemap = lambda k: {'key': k, 'value': extras[k]}
259 makemap = lambda k: {'key': k, 'value': extras[k]}
260 c = [makemap(k) for k in extras]
260 c = [makemap(k) for k in extras]
261 f = _showlist('extra', c, plural='extras', **args)
261 f = _showlist('extra', c, plural='extras', **args)
262 return _hybrid(f, extras, makemap,
262 return _hybrid(f, extras, makemap,
263 lambda x: '%s=%s' % (x['key'], x['value']))
263 lambda x: '%s=%s' % (x['key'], x['value']))
264
264
265 def showfileadds(**args):
265 def showfileadds(**args):
266 """:file_adds: List of strings. Files added by this changeset."""
266 """:file_adds: List of strings. Files added by this changeset."""
267 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
267 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
268 return showlist('file_add', getfiles(repo, ctx, revcache)[1],
268 return showlist('file_add', getfiles(repo, ctx, revcache)[1],
269 element='file', **args)
269 element='file', **args)
270
270
271 def showfilecopies(**args):
271 def showfilecopies(**args):
272 """:file_copies: List of strings. Files copied in this changeset with
272 """:file_copies: List of strings. Files copied in this changeset with
273 their sources.
273 their sources.
274 """
274 """
275 cache, ctx = args['cache'], args['ctx']
275 cache, ctx = args['cache'], args['ctx']
276 copies = args['revcache'].get('copies')
276 copies = args['revcache'].get('copies')
277 if copies is None:
277 if copies is None:
278 if 'getrenamed' not in cache:
278 if 'getrenamed' not in cache:
279 cache['getrenamed'] = getrenamedfn(args['repo'])
279 cache['getrenamed'] = getrenamedfn(args['repo'])
280 copies = []
280 copies = []
281 getrenamed = cache['getrenamed']
281 getrenamed = cache['getrenamed']
282 for fn in ctx.files():
282 for fn in ctx.files():
283 rename = getrenamed(fn, ctx.rev())
283 rename = getrenamed(fn, ctx.rev())
284 if rename:
284 if rename:
285 copies.append((fn, rename[0]))
285 copies.append((fn, rename[0]))
286
286
287 copies = util.sortdict(copies)
287 copies = util.sortdict(copies)
288 makemap = lambda k: {'name': k, 'source': copies[k]}
288 makemap = lambda k: {'name': k, 'source': copies[k]}
289 c = [makemap(k) for k in copies]
289 c = [makemap(k) for k in copies]
290 f = _showlist('file_copy', c, plural='file_copies', **args)
290 f = _showlist('file_copy', c, plural='file_copies', **args)
291 return _hybrid(f, copies, makemap,
291 return _hybrid(f, copies, makemap,
292 lambda x: '%s (%s)' % (x['name'], x['source']))
292 lambda x: '%s (%s)' % (x['name'], x['source']))
293
293
294 # showfilecopiesswitch() displays file copies only if copy records are
294 # showfilecopiesswitch() displays file copies only if copy records are
295 # provided before calling the templater, usually with a --copies
295 # provided before calling the templater, usually with a --copies
296 # command line switch.
296 # command line switch.
297 def showfilecopiesswitch(**args):
297 def showfilecopiesswitch(**args):
298 """:file_copies_switch: List of strings. Like "file_copies" but displayed
298 """:file_copies_switch: List of strings. Like "file_copies" but displayed
299 only if the --copied switch is set.
299 only if the --copied switch is set.
300 """
300 """
301 copies = args['revcache'].get('copies') or []
301 copies = args['revcache'].get('copies') or []
302 copies = util.sortdict(copies)
302 copies = util.sortdict(copies)
303 makemap = lambda k: {'name': k, 'source': copies[k]}
303 makemap = lambda k: {'name': k, 'source': copies[k]}
304 c = [makemap(k) for k in copies]
304 c = [makemap(k) for k in copies]
305 f = _showlist('file_copy', c, plural='file_copies', **args)
305 f = _showlist('file_copy', c, plural='file_copies', **args)
306 return _hybrid(f, copies, makemap,
306 return _hybrid(f, copies, makemap,
307 lambda x: '%s (%s)' % (x['name'], x['source']))
307 lambda x: '%s (%s)' % (x['name'], x['source']))
308
308
309 def showfiledels(**args):
309 def showfiledels(**args):
310 """:file_dels: List of strings. Files removed by this changeset."""
310 """:file_dels: List of strings. Files removed by this changeset."""
311 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
311 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
312 return showlist('file_del', getfiles(repo, ctx, revcache)[2],
312 return showlist('file_del', getfiles(repo, ctx, revcache)[2],
313 element='file', **args)
313 element='file', **args)
314
314
315 def showfilemods(**args):
315 def showfilemods(**args):
316 """:file_mods: List of strings. Files modified by this changeset."""
316 """:file_mods: List of strings. Files modified by this changeset."""
317 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
317 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
318 return showlist('file_mod', getfiles(repo, ctx, revcache)[0],
318 return showlist('file_mod', getfiles(repo, ctx, revcache)[0],
319 element='file', **args)
319 element='file', **args)
320
320
321 def showfiles(**args):
321 def showfiles(**args):
322 """:files: List of strings. All files modified, added, or removed by this
322 """:files: List of strings. All files modified, added, or removed by this
323 changeset.
323 changeset.
324 """
324 """
325 return showlist('file', args['ctx'].files(), **args)
325 return showlist('file', args['ctx'].files(), **args)
326
326
327 def showlatesttag(repo, ctx, templ, cache, **args):
327 def showlatesttag(repo, ctx, templ, cache, **args):
328 """:latesttag: String. Most recent global tag in the ancestors of this
328 """:latesttag: String. Most recent global tag in the ancestors of this
329 changeset.
329 changeset.
330 """
330 """
331 return getlatesttags(repo, ctx, cache)[2]
331 return getlatesttags(repo, ctx, cache)[2]
332
332
333 def showlatesttagdistance(repo, ctx, templ, cache, **args):
333 def showlatesttagdistance(repo, ctx, templ, cache, **args):
334 """:latesttagdistance: Integer. Longest path to the latest tag."""
334 """:latesttagdistance: Integer. Longest path to the latest tag."""
335 return getlatesttags(repo, ctx, cache)[1]
335 return getlatesttags(repo, ctx, cache)[1]
336
336
337 def showmanifest(**args):
337 def showmanifest(**args):
338 repo, ctx, templ = args['repo'], args['ctx'], args['templ']
338 repo, ctx, templ = args['repo'], args['ctx'], args['templ']
339 mnode = ctx.manifestnode()
339 mnode = ctx.manifestnode()
340 args = args.copy()
340 args = args.copy()
341 args.update({'rev': repo.manifest.rev(mnode), 'node': hex(mnode)})
341 args.update({'rev': repo.manifest.rev(mnode), 'node': hex(mnode)})
342 return templ('manifest', **args)
342 return templ('manifest', **args)
343
343
344 def shownode(repo, ctx, templ, **args):
344 def shownode(repo, ctx, templ, **args):
345 """:node: String. The changeset identification hash, as a 40 hexadecimal
345 """:node: String. The changeset identification hash, as a 40 hexadecimal
346 digit string.
346 digit string.
347 """
347 """
348 return ctx.hex()
348 return ctx.hex()
349
349
350 def showp1rev(repo, ctx, templ, **args):
350 def showp1rev(repo, ctx, templ, **args):
351 """:p1rev: Integer. The repository-local revision number of the changeset's
351 """:p1rev: Integer. The repository-local revision number of the changeset's
352 first parent, or -1 if the changeset has no parents."""
352 first parent, or -1 if the changeset has no parents."""
353 return ctx.p1().rev()
353 return ctx.p1().rev()
354
354
355 def showp2rev(repo, ctx, templ, **args):
355 def showp2rev(repo, ctx, templ, **args):
356 """:p2rev: Integer. The repository-local revision number of the changeset's
356 """:p2rev: Integer. The repository-local revision number of the changeset's
357 second parent, or -1 if the changeset has no second parent."""
357 second parent, or -1 if the changeset has no second parent."""
358 return ctx.p2().rev()
358 return ctx.p2().rev()
359
359
360 def showp1node(repo, ctx, templ, **args):
360 def showp1node(repo, ctx, templ, **args):
361 """:p1node: String. The identification hash of the changeset's first parent,
361 """:p1node: String. The identification hash of the changeset's first parent,
362 as a 40 digit hexadecimal string. If the changeset has no parents, all
362 as a 40 digit hexadecimal string. If the changeset has no parents, all
363 digits are 0."""
363 digits are 0."""
364 return ctx.p1().hex()
364 return ctx.p1().hex()
365
365
366 def showp2node(repo, ctx, templ, **args):
366 def showp2node(repo, ctx, templ, **args):
367 """:p2node: String. The identification hash of the changeset's second
367 """:p2node: String. The identification hash of the changeset's second
368 parent, as a 40 digit hexadecimal string. If the changeset has no second
368 parent, as a 40 digit hexadecimal string. If the changeset has no second
369 parent, all digits are 0."""
369 parent, all digits are 0."""
370 return ctx.p2().hex()
370 return ctx.p2().hex()
371
371
372 def showphase(repo, ctx, templ, **args):
372 def showphase(repo, ctx, templ, **args):
373 """:phase: String. The changeset phase name."""
373 """:phase: String. The changeset phase name."""
374 return ctx.phasestr()
374 return ctx.phasestr()
375
375
376 def showphaseidx(repo, ctx, templ, **args):
376 def showphaseidx(repo, ctx, templ, **args):
377 """:phaseidx: Integer. The changeset phase index."""
377 """:phaseidx: Integer. The changeset phase index."""
378 return ctx.phase()
378 return ctx.phase()
379
379
380 def showrev(repo, ctx, templ, **args):
380 def showrev(repo, ctx, templ, **args):
381 """:rev: Integer. The repository-local changeset revision number."""
381 """:rev: Integer. The repository-local changeset revision number."""
382 return ctx.rev()
382 return ctx.rev()
383
383
384 def showsubrepos(**args):
384 def showsubrepos(**args):
385 """:subrepos: List of strings. Updated subrepositories in the changeset."""
385 """:subrepos: List of strings. Updated subrepositories in the changeset."""
386 ctx = args['ctx']
386 ctx = args['ctx']
387 substate = ctx.substate
387 substate = ctx.substate
388 if not substate:
388 if not substate:
389 return showlist('subrepo', [], **args)
389 return showlist('subrepo', [], **args)
390 psubstate = ctx.parents()[0].substate or {}
390 psubstate = ctx.parents()[0].substate or {}
391 subrepos = []
391 subrepos = []
392 for sub in substate:
392 for sub in substate:
393 if sub not in psubstate or substate[sub] != psubstate[sub]:
393 if sub not in psubstate or substate[sub] != psubstate[sub]:
394 subrepos.append(sub) # modified or newly added in ctx
394 subrepos.append(sub) # modified or newly added in ctx
395 for sub in psubstate:
395 for sub in psubstate:
396 if sub not in substate:
396 if sub not in substate:
397 subrepos.append(sub) # removed in ctx
397 subrepos.append(sub) # removed in ctx
398 return showlist('subrepo', sorted(subrepos), **args)
398 return showlist('subrepo', sorted(subrepos), **args)
399
399
400 def shownames(namespace, **args):
400 def shownames(namespace, **args):
401 """helper method to generate a template keyword for a namespace"""
401 """helper method to generate a template keyword for a namespace"""
402 ctx = args['ctx']
402 ctx = args['ctx']
403 repo = ctx.repo()
403 repo = ctx.repo()
404 ns = repo.names[namespace]
404 ns = repo.names[namespace]
405 names = ns.names(repo, ctx.node())
405 names = ns.names(repo, ctx.node())
406 return showlist(ns.templatename, names, plural=namespace, **args)
406 return showlist(ns.templatename, names, plural=namespace, **args)
407
407
408 # don't remove "showtags" definition, even though namespaces will put
408 # don't remove "showtags" definition, even though namespaces will put
409 # a helper function for "tags" keyword into "keywords" map automatically,
409 # a helper function for "tags" keyword into "keywords" map automatically,
410 # because online help text is built without namespaces initialization
410 # because online help text is built without namespaces initialization
411 def showtags(**args):
411 def showtags(**args):
412 """:tags: List of strings. Any tags associated with the changeset."""
412 """:tags: List of strings. Any tags associated with the changeset."""
413 return shownames('tags', **args)
413 return shownames('tags', **args)
414
414
415 # keywords are callables like:
415 # keywords are callables like:
416 # fn(repo, ctx, templ, cache, revcache, **args)
416 # fn(repo, ctx, templ, cache, revcache, **args)
417 # with:
417 # with:
418 # repo - current repository instance
418 # repo - current repository instance
419 # ctx - the changectx being displayed
419 # ctx - the changectx being displayed
420 # templ - the templater instance
420 # templ - the templater instance
421 # cache - a cache dictionary for the whole templater run
421 # cache - a cache dictionary for the whole templater run
422 # revcache - a cache dictionary for the current revision
422 # revcache - a cache dictionary for the current revision
423 keywords = {
423 keywords = {
424 'activebookmark': showactivebookmark,
424 'activebookmark': showactivebookmark,
425 'author': showauthor,
425 'author': showauthor,
426 'bisect': showbisect,
426 'bisect': showbisect,
427 'branch': showbranch,
427 'branch': showbranch,
428 'branches': showbranches,
428 'branches': showbranches,
429 'bookmarks': showbookmarks,
429 'bookmarks': showbookmarks,
430 'children': showchildren,
430 'children': showchildren,
431 # currentbookmark is deprecated
431 # currentbookmark is deprecated
432 'currentbookmark': showcurrentbookmark,
432 'currentbookmark': showcurrentbookmark,
433 'date': showdate,
433 'date': showdate,
434 'desc': showdescription,
434 'desc': showdescription,
435 'diffstat': showdiffstat,
435 'diffstat': showdiffstat,
436 'extras': showextras,
436 'extras': showextras,
437 'file_adds': showfileadds,
437 'file_adds': showfileadds,
438 'file_copies': showfilecopies,
438 'file_copies': showfilecopies,
439 'file_copies_switch': showfilecopiesswitch,
439 'file_copies_switch': showfilecopiesswitch,
440 'file_dels': showfiledels,
440 'file_dels': showfiledels,
441 'file_mods': showfilemods,
441 'file_mods': showfilemods,
442 'files': showfiles,
442 'files': showfiles,
443 'latesttag': showlatesttag,
443 'latesttag': showlatesttag,
444 'latesttagdistance': showlatesttagdistance,
444 'latesttagdistance': showlatesttagdistance,
445 'manifest': showmanifest,
445 'manifest': showmanifest,
446 'node': shownode,
446 'node': shownode,
447 'p1rev': showp1rev,
447 'p1rev': showp1rev,
448 'p1node': showp1node,
448 'p1node': showp1node,
449 'p2rev': showp2rev,
449 'p2rev': showp2rev,
450 'p2node': showp2node,
450 'p2node': showp2node,
451 'phase': showphase,
451 'phase': showphase,
452 'phaseidx': showphaseidx,
452 'phaseidx': showphaseidx,
453 'rev': showrev,
453 'rev': showrev,
454 'subrepos': showsubrepos,
454 'subrepos': showsubrepos,
455 'tags': showtags,
455 'tags': showtags,
456 }
456 }
457
457
458 def _showparents(**args):
458 def _showparents(**args):
459 """:parents: List of strings. The parents of the changeset in "rev:node"
459 """:parents: List of strings. The parents of the changeset in "rev:node"
460 format. If the changeset has only one "natural" parent (the predecessor
460 format. If the changeset has only one "natural" parent (the predecessor
461 revision) nothing is shown."""
461 revision) nothing is shown."""
462 pass
462 pass
463
463
464 dockeywords = {
464 dockeywords = {
465 'parents': _showparents,
465 'parents': _showparents,
466 }
466 }
467 dockeywords.update(keywords)
467 dockeywords.update(keywords)
468 del dockeywords['branches']
468 del dockeywords['branches']
469
469
470 # tell hggettext to extract docstrings from these functions:
470 # tell hggettext to extract docstrings from these functions:
471 i18nfunctions = dockeywords.values()
471 i18nfunctions = dockeywords.values()
General Comments 0
You need to be logged in to leave comments. Login now