##// END OF EJS Templates
help: populate template functions via docstrings...
Gregory Szorc -
r24587:76c0b4cf default
parent child Browse files
Show More
@@ -1,513 +1,515
1 1 # help.py - help data for mercurial
2 2 #
3 3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from i18n import gettext, _
9 9 import itertools, os, textwrap
10 10 import error
11 11 import extensions, revset, fileset, templatekw, templatefilters, filemerge
12 import templater
12 13 import encoding, util, minirst
13 14 import cmdutil
14 15 import hgweb.webcommands as webcommands
15 16
16 17 def listexts(header, exts, indent=1, showdeprecated=False):
17 18 '''return a text listing of the given extensions'''
18 19 rst = []
19 20 if exts:
20 21 rst.append('\n%s\n\n' % header)
21 22 for name, desc in sorted(exts.iteritems()):
22 23 if '(DEPRECATED)' in desc and not showdeprecated:
23 24 continue
24 25 rst.append('%s:%s: %s\n' % (' ' * indent, name, desc))
25 26 return rst
26 27
27 28 def extshelp():
28 29 rst = loaddoc('extensions')().splitlines(True)
29 30 rst.extend(listexts(
30 31 _('enabled extensions:'), extensions.enabled(), showdeprecated=True))
31 32 rst.extend(listexts(_('disabled extensions:'), extensions.disabled()))
32 33 doc = ''.join(rst)
33 34 return doc
34 35
35 36 def optrst(header, options, verbose):
36 37 data = []
37 38 multioccur = False
38 39 for option in options:
39 40 if len(option) == 5:
40 41 shortopt, longopt, default, desc, optlabel = option
41 42 else:
42 43 shortopt, longopt, default, desc = option
43 44 optlabel = _("VALUE") # default label
44 45
45 46 if not verbose and ("DEPRECATED" in desc or _("DEPRECATED") in desc):
46 47 continue
47 48
48 49 so = ''
49 50 if shortopt:
50 51 so = '-' + shortopt
51 52 lo = '--' + longopt
52 53 if default:
53 54 desc += _(" (default: %s)") % default
54 55
55 56 if isinstance(default, list):
56 57 lo += " %s [+]" % optlabel
57 58 multioccur = True
58 59 elif (default is not None) and not isinstance(default, bool):
59 60 lo += " %s" % optlabel
60 61
61 62 data.append((so, lo, desc))
62 63
63 64 if multioccur:
64 65 header += (_(" ([+] can be repeated)"))
65 66
66 67 rst = ['\n%s:\n\n' % header]
67 68 rst.extend(minirst.maketable(data, 1))
68 69
69 70 return ''.join(rst)
70 71
71 72 def indicateomitted(rst, omitted, notomitted=None):
72 73 rst.append('\n\n.. container:: omitted\n\n %s\n\n' % omitted)
73 74 if notomitted:
74 75 rst.append('\n\n.. container:: notomitted\n\n %s\n\n' % notomitted)
75 76
76 77 def topicmatch(kw):
77 78 """Return help topics matching kw.
78 79
79 80 Returns {'section': [(name, summary), ...], ...} where section is
80 81 one of topics, commands, extensions, or extensioncommands.
81 82 """
82 83 kw = encoding.lower(kw)
83 84 def lowercontains(container):
84 85 return kw in encoding.lower(container) # translated in helptable
85 86 results = {'topics': [],
86 87 'commands': [],
87 88 'extensions': [],
88 89 'extensioncommands': [],
89 90 }
90 91 for names, header, doc in helptable:
91 92 # Old extensions may use a str as doc.
92 93 if (sum(map(lowercontains, names))
93 94 or lowercontains(header)
94 95 or (callable(doc) and lowercontains(doc()))):
95 96 results['topics'].append((names[0], header))
96 97 import commands # avoid cycle
97 98 for cmd, entry in commands.table.iteritems():
98 99 if len(entry) == 3:
99 100 summary = entry[2]
100 101 else:
101 102 summary = ''
102 103 # translate docs *before* searching there
103 104 docs = _(getattr(entry[0], '__doc__', None)) or ''
104 105 if kw in cmd or lowercontains(summary) or lowercontains(docs):
105 106 doclines = docs.splitlines()
106 107 if doclines:
107 108 summary = doclines[0]
108 109 cmdname = cmd.split('|')[0].lstrip('^')
109 110 results['commands'].append((cmdname, summary))
110 111 for name, docs in itertools.chain(
111 112 extensions.enabled(False).iteritems(),
112 113 extensions.disabled().iteritems()):
113 114 # extensions.load ignores the UI argument
114 115 mod = extensions.load(None, name, '')
115 116 name = name.split('.')[-1]
116 117 if lowercontains(name) or lowercontains(docs):
117 118 # extension docs are already translated
118 119 results['extensions'].append((name, docs.splitlines()[0]))
119 120 for cmd, entry in getattr(mod, 'cmdtable', {}).iteritems():
120 121 if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
121 122 cmdname = cmd.split('|')[0].lstrip('^')
122 123 if entry[0].__doc__:
123 124 cmddoc = gettext(entry[0].__doc__).splitlines()[0]
124 125 else:
125 126 cmddoc = _('(no help text available)')
126 127 results['extensioncommands'].append((cmdname, cmddoc))
127 128 return results
128 129
129 130 def loaddoc(topic):
130 131 """Return a delayed loader for help/topic.txt."""
131 132
132 133 def loader():
133 134 docdir = os.path.join(util.datapath, 'help')
134 135 path = os.path.join(docdir, topic + ".txt")
135 136 doc = gettext(util.readfile(path))
136 137 for rewriter in helphooks.get(topic, []):
137 138 doc = rewriter(topic, doc)
138 139 return doc
139 140
140 141 return loader
141 142
142 143 helptable = sorted([
143 144 (["config", "hgrc"], _("Configuration Files"), loaddoc('config')),
144 145 (["dates"], _("Date Formats"), loaddoc('dates')),
145 146 (["patterns"], _("File Name Patterns"), loaddoc('patterns')),
146 147 (['environment', 'env'], _('Environment Variables'),
147 148 loaddoc('environment')),
148 149 (['revisions', 'revs'], _('Specifying Single Revisions'),
149 150 loaddoc('revisions')),
150 151 (['multirevs', 'mrevs'], _('Specifying Multiple Revisions'),
151 152 loaddoc('multirevs')),
152 153 (['revsets', 'revset'], _("Specifying Revision Sets"), loaddoc('revsets')),
153 154 (['filesets', 'fileset'], _("Specifying File Sets"), loaddoc('filesets')),
154 155 (['diffs'], _('Diff Formats'), loaddoc('diffs')),
155 156 (['merge-tools', 'mergetools'], _('Merge Tools'), loaddoc('merge-tools')),
156 157 (['templating', 'templates', 'template', 'style'], _('Template Usage'),
157 158 loaddoc('templates')),
158 159 (['urls'], _('URL Paths'), loaddoc('urls')),
159 160 (["extensions"], _("Using Additional Features"), extshelp),
160 161 (["subrepos", "subrepo"], _("Subrepositories"), loaddoc('subrepos')),
161 162 (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb')),
162 163 (["glossary"], _("Glossary"), loaddoc('glossary')),
163 164 (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),
164 165 loaddoc('hgignore')),
165 166 (["phases"], _("Working with Phases"), loaddoc('phases')),
166 167 ])
167 168
168 169 # Map topics to lists of callable taking the current topic help and
169 170 # returning the updated version
170 171 helphooks = {}
171 172
172 173 def addtopichook(topic, rewriter):
173 174 helphooks.setdefault(topic, []).append(rewriter)
174 175
175 176 def makeitemsdoc(topic, doc, marker, items, dedent=False):
176 177 """Extract docstring from the items key to function mapping, build a
177 178 .single documentation block and use it to overwrite the marker in doc
178 179 """
179 180 entries = []
180 181 for name in sorted(items):
181 182 text = (items[name].__doc__ or '').rstrip()
182 183 if not text:
183 184 continue
184 185 text = gettext(text)
185 186 if dedent:
186 187 text = textwrap.dedent(text)
187 188 lines = text.splitlines()
188 189 doclines = [(lines[0])]
189 190 for l in lines[1:]:
190 191 # Stop once we find some Python doctest
191 192 if l.strip().startswith('>>>'):
192 193 break
193 194 if dedent:
194 195 doclines.append(l.rstrip())
195 196 else:
196 197 doclines.append(' ' + l.strip())
197 198 entries.append('\n'.join(doclines))
198 199 entries = '\n\n'.join(entries)
199 200 return doc.replace(marker, entries)
200 201
201 202 def addtopicsymbols(topic, marker, symbols, dedent=False):
202 203 def add(topic, doc):
203 204 return makeitemsdoc(topic, doc, marker, symbols, dedent=dedent)
204 205 addtopichook(topic, add)
205 206
206 207 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols)
207 208 addtopicsymbols('merge-tools', '.. internaltoolsmarker',
208 209 filemerge.internalsdoc)
209 210 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols)
210 211 addtopicsymbols('templates', '.. keywordsmarker', templatekw.dockeywords)
211 212 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters)
213 addtopicsymbols('templates', '.. functionsmarker', templater.funcs)
212 214 addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands,
213 215 dedent=True)
214 216
215 217 def help_(ui, name, unknowncmd=False, full=True, **opts):
216 218 '''
217 219 Generate the help for 'name' as unformatted restructured text. If
218 220 'name' is None, describe the commands available.
219 221 '''
220 222
221 223 import commands # avoid cycle
222 224
223 225 def helpcmd(name):
224 226 try:
225 227 aliases, entry = cmdutil.findcmd(name, commands.table,
226 228 strict=unknowncmd)
227 229 except error.AmbiguousCommand, inst:
228 230 # py3k fix: except vars can't be used outside the scope of the
229 231 # except block, nor can be used inside a lambda. python issue4617
230 232 prefix = inst.args[0]
231 233 select = lambda c: c.lstrip('^').startswith(prefix)
232 234 rst = helplist(select)
233 235 return rst
234 236
235 237 rst = []
236 238
237 239 # check if it's an invalid alias and display its error if it is
238 240 if getattr(entry[0], 'badalias', None):
239 241 rst.append(entry[0].badalias + '\n')
240 242 if entry[0].unknowncmd:
241 243 try:
242 244 rst.extend(helpextcmd(entry[0].cmdname))
243 245 except error.UnknownCommand:
244 246 pass
245 247 return rst
246 248
247 249 # synopsis
248 250 if len(entry) > 2:
249 251 if entry[2].startswith('hg'):
250 252 rst.append("%s\n" % entry[2])
251 253 else:
252 254 rst.append('hg %s %s\n' % (aliases[0], entry[2]))
253 255 else:
254 256 rst.append('hg %s\n' % aliases[0])
255 257 # aliases
256 258 if full and not ui.quiet and len(aliases) > 1:
257 259 rst.append(_("\naliases: %s\n") % ', '.join(aliases[1:]))
258 260 rst.append('\n')
259 261
260 262 # description
261 263 doc = gettext(entry[0].__doc__)
262 264 if not doc:
263 265 doc = _("(no help text available)")
264 266 if util.safehasattr(entry[0], 'definition'): # aliased command
265 267 if entry[0].definition.startswith('!'): # shell alias
266 268 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
267 269 else:
268 270 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
269 271 doc = doc.splitlines(True)
270 272 if ui.quiet or not full:
271 273 rst.append(doc[0])
272 274 else:
273 275 rst.extend(doc)
274 276 rst.append('\n')
275 277
276 278 # check if this command shadows a non-trivial (multi-line)
277 279 # extension help text
278 280 try:
279 281 mod = extensions.find(name)
280 282 doc = gettext(mod.__doc__) or ''
281 283 if '\n' in doc.strip():
282 284 msg = _('(use "hg help -e %s" to show help for '
283 285 'the %s extension)') % (name, name)
284 286 rst.append('\n%s\n' % msg)
285 287 except KeyError:
286 288 pass
287 289
288 290 # options
289 291 if not ui.quiet and entry[1]:
290 292 rst.append(optrst(_("options"), entry[1], ui.verbose))
291 293
292 294 if ui.verbose:
293 295 rst.append(optrst(_("global options"),
294 296 commands.globalopts, ui.verbose))
295 297
296 298 if not ui.verbose:
297 299 if not full:
298 300 rst.append(_('\n(use "hg %s -h" to show more help)\n')
299 301 % name)
300 302 elif not ui.quiet:
301 303 rst.append(_('\n(some details hidden, use --verbose '
302 304 'to show complete help)'))
303 305
304 306 return rst
305 307
306 308
307 309 def helplist(select=None):
308 310 # list of commands
309 311 if name == "shortlist":
310 312 header = _('basic commands:\n\n')
311 313 elif name == "debug":
312 314 header = _('debug commands (internal and unsupported):\n\n')
313 315 else:
314 316 header = _('list of commands:\n\n')
315 317
316 318 h = {}
317 319 cmds = {}
318 320 for c, e in commands.table.iteritems():
319 321 f = c.split("|", 1)[0]
320 322 if select and not select(f):
321 323 continue
322 324 if (not select and name != 'shortlist' and
323 325 e[0].__module__ != commands.__name__):
324 326 continue
325 327 if name == "shortlist" and not f.startswith("^"):
326 328 continue
327 329 f = f.lstrip("^")
328 330 if not ui.debugflag and f.startswith("debug") and name != "debug":
329 331 continue
330 332 doc = e[0].__doc__
331 333 if doc and 'DEPRECATED' in doc and not ui.verbose:
332 334 continue
333 335 doc = gettext(doc)
334 336 if not doc:
335 337 doc = _("(no help text available)")
336 338 h[f] = doc.splitlines()[0].rstrip()
337 339 cmds[f] = c.lstrip("^")
338 340
339 341 rst = []
340 342 if not h:
341 343 if not ui.quiet:
342 344 rst.append(_('no commands defined\n'))
343 345 return rst
344 346
345 347 if not ui.quiet:
346 348 rst.append(header)
347 349 fns = sorted(h)
348 350 for f in fns:
349 351 if ui.verbose:
350 352 commacmds = cmds[f].replace("|",", ")
351 353 rst.append(" :%s: %s\n" % (commacmds, h[f]))
352 354 else:
353 355 rst.append(' :%s: %s\n' % (f, h[f]))
354 356
355 357 if not name:
356 358 exts = listexts(_('enabled extensions:'), extensions.enabled())
357 359 if exts:
358 360 rst.append('\n')
359 361 rst.extend(exts)
360 362
361 363 rst.append(_("\nadditional help topics:\n\n"))
362 364 topics = []
363 365 for names, header, doc in helptable:
364 366 topics.append((names[0], header))
365 367 for t, desc in topics:
366 368 rst.append(" :%s: %s\n" % (t, desc))
367 369
368 370 if ui.quiet:
369 371 pass
370 372 elif ui.verbose:
371 373 rst.append('\n%s\n' % optrst(_("global options"),
372 374 commands.globalopts, ui.verbose))
373 375 if name == 'shortlist':
374 376 rst.append(_('\n(use "hg help" for the full list '
375 377 'of commands)\n'))
376 378 else:
377 379 if name == 'shortlist':
378 380 rst.append(_('\n(use "hg help" for the full list of commands '
379 381 'or "hg -v" for details)\n'))
380 382 elif name and not full:
381 383 rst.append(_('\n(use "hg help %s" to show the full help '
382 384 'text)\n') % name)
383 385 elif name and cmds and name in cmds.keys():
384 386 rst.append(_('\n(use "hg help -v -e %s" to show built-in '
385 387 'aliases and global options)\n') % name)
386 388 else:
387 389 rst.append(_('\n(use "hg help -v%s" to show built-in aliases '
388 390 'and global options)\n')
389 391 % (name and " " + name or ""))
390 392 return rst
391 393
392 394 def helptopic(name):
393 395 for names, header, doc in helptable:
394 396 if name in names:
395 397 break
396 398 else:
397 399 raise error.UnknownCommand(name)
398 400
399 401 rst = [minirst.section(header)]
400 402
401 403 # description
402 404 if not doc:
403 405 rst.append(" %s\n" % _("(no help text available)"))
404 406 if callable(doc):
405 407 rst += [" %s\n" % l for l in doc().splitlines()]
406 408
407 409 if not ui.verbose:
408 410 omitted = _('(some details hidden, use --verbose'
409 411 ' to show complete help)')
410 412 indicateomitted(rst, omitted)
411 413
412 414 try:
413 415 cmdutil.findcmd(name, commands.table)
414 416 rst.append(_('\nuse "hg help -c %s" to see help for '
415 417 'the %s command\n') % (name, name))
416 418 except error.UnknownCommand:
417 419 pass
418 420 return rst
419 421
420 422 def helpext(name):
421 423 try:
422 424 mod = extensions.find(name)
423 425 doc = gettext(mod.__doc__) or _('no help text available')
424 426 except KeyError:
425 427 mod = None
426 428 doc = extensions.disabledext(name)
427 429 if not doc:
428 430 raise error.UnknownCommand(name)
429 431
430 432 if '\n' not in doc:
431 433 head, tail = doc, ""
432 434 else:
433 435 head, tail = doc.split('\n', 1)
434 436 rst = [_('%s extension - %s\n\n') % (name.split('.')[-1], head)]
435 437 if tail:
436 438 rst.extend(tail.splitlines(True))
437 439 rst.append('\n')
438 440
439 441 if not ui.verbose:
440 442 omitted = _('(some details hidden, use --verbose'
441 443 ' to show complete help)')
442 444 indicateomitted(rst, omitted)
443 445
444 446 if mod:
445 447 try:
446 448 ct = mod.cmdtable
447 449 except AttributeError:
448 450 ct = {}
449 451 modcmds = set([c.split('|', 1)[0] for c in ct])
450 452 rst.extend(helplist(modcmds.__contains__))
451 453 else:
452 454 rst.append(_('(use "hg help extensions" for information on enabling'
453 455 ' extensions)\n'))
454 456 return rst
455 457
456 458 def helpextcmd(name):
457 459 cmd, ext, mod = extensions.disabledcmd(ui, name,
458 460 ui.configbool('ui', 'strict'))
459 461 doc = gettext(mod.__doc__).splitlines()[0]
460 462
461 463 rst = listexts(_("'%s' is provided by the following "
462 464 "extension:") % cmd, {ext: doc}, indent=4)
463 465 rst.append('\n')
464 466 rst.append(_('(use "hg help extensions" for information on enabling '
465 467 'extensions)\n'))
466 468 return rst
467 469
468 470
469 471 rst = []
470 472 kw = opts.get('keyword')
471 473 if kw:
472 474 matches = topicmatch(kw)
473 475 for t, title in (('topics', _('Topics')),
474 476 ('commands', _('Commands')),
475 477 ('extensions', _('Extensions')),
476 478 ('extensioncommands', _('Extension Commands'))):
477 479 if matches[t]:
478 480 rst.append('%s:\n\n' % title)
479 481 rst.extend(minirst.maketable(sorted(matches[t]), 1))
480 482 rst.append('\n')
481 483 if not rst:
482 484 msg = _('no matches')
483 485 hint = _('try "hg help" for a list of topics')
484 486 raise util.Abort(msg, hint=hint)
485 487 elif name and name != 'shortlist':
486 488 if unknowncmd:
487 489 queries = (helpextcmd,)
488 490 elif opts.get('extension'):
489 491 queries = (helpext,)
490 492 elif opts.get('command'):
491 493 queries = (helpcmd,)
492 494 else:
493 495 queries = (helptopic, helpcmd, helpext, helpextcmd)
494 496 for f in queries:
495 497 try:
496 498 rst = f(name)
497 499 break
498 500 except error.UnknownCommand:
499 501 pass
500 502 else:
501 503 if unknowncmd:
502 504 raise error.UnknownCommand(name)
503 505 else:
504 506 msg = _('no such help topic: %s') % name
505 507 hint = _('try "hg help --keyword %s"') % name
506 508 raise util.Abort(msg, hint=hint)
507 509 else:
508 510 # program name
509 511 if not ui.quiet:
510 512 rst = [_("Mercurial Distributed SCM\n"), '\n']
511 513 rst.extend(helplist())
512 514
513 515 return ''.join(rst)
@@ -1,139 +1,107
1 1 Mercurial allows you to customize output of commands through
2 2 templates. You can either pass in a template or select an existing
3 3 template-style from the command line, via the --template option.
4 4
5 5 You can customize output for any "log-like" command: log,
6 6 outgoing, incoming, tip, parents, and heads.
7 7
8 8 Some built-in styles are packaged with Mercurial. These can be listed
9 9 with :hg:`log --template list`. Example usage::
10 10
11 11 $ hg log -r1.0::1.1 --template changelog
12 12
13 13 A template is a piece of text, with markup to invoke variable
14 14 expansion::
15 15
16 16 $ hg log -r1 --template "{node}\n"
17 17 b56ce7b07c52de7d5fd79fb89701ea538af65746
18 18
19 19 Strings in curly braces are called keywords. The availability of
20 20 keywords depends on the exact context of the templater. These
21 21 keywords are usually available for templating a log-like command:
22 22
23 23 .. keywordsmarker
24 24
25 25 The "date" keyword does not produce human-readable output. If you
26 26 want to use a date in your output, you can use a filter to process
27 27 it. Filters are functions which return a string based on the input
28 28 variable. Be sure to use the stringify filter first when you're
29 29 applying a string-input filter to a list-like input variable.
30 30 You can also use a chain of filters to get the desired output::
31 31
32 32 $ hg tip --template "{date|isodate}\n"
33 33 2008-08-21 18:22 +0000
34 34
35 35 List of filters:
36 36
37 37 .. filtersmarker
38 38
39 39 Note that a filter is nothing more than a function call, i.e.
40 40 ``expr|filter`` is equivalent to ``filter(expr)``.
41 41
42 42 In addition to filters, there are some basic built-in functions:
43 43
44 - date(date[, fmt])
45
46 - diff([includepattern [, excludepattern]])
47
48 - fill(text[, width])
49
50 - get(dict, key)
51
52 - if(expr, then[, else])
53
54 - ifcontains(expr, expr, then[, else])
55
56 - ifeq(expr, expr, then[, else])
57
58 - join(list, sep)
59
60 - label(label, expr)
61
62 - pad(text, width[, fillchar, right])
63
64 - revset(query[, formatargs])
65
66 - rstdoc(text, style)
67
68 - shortest(node)
69
70 - startswith(string, text)
71
72 - strip(text[, chars])
73
74 - sub(pat, repl, expr)
75
76 - word(number, text[, separator])
44 .. functionsmarker
77 45
78 46 Also, for any expression that returns a list, there is a list operator:
79 47
80 48 - expr % "{template}"
81 49
82 50 Some sample command line templates:
83 51
84 52 - Format lists, e.g. files::
85 53
86 54 $ hg log -r 0 --template "files:\n{files % ' {file}\n'}"
87 55
88 56 - Join the list of files with a ", "::
89 57
90 58 $ hg log -r 0 --template "files: {join(files, ', ')}\n"
91 59
92 60 - Modify each line of a commit description::
93 61
94 62 $ hg log --template "{splitlines(desc) % '**** {line}\n'}"
95 63
96 64 - Format date::
97 65
98 66 $ hg log -r 0 --template "{date(date, '%Y')}\n"
99 67
100 68 - Output the description set to a fill-width of 30::
101 69
102 70 $ hg log -r 0 --template "{fill(desc, '30')}"
103 71
104 72 - Use a conditional to test for the default branch::
105 73
106 74 $ hg log -r 0 --template "{ifeq(branch, 'default', 'on the main branch',
107 75 'on branch {branch}')}\n"
108 76
109 77 - Append a newline if not empty::
110 78
111 79 $ hg tip --template "{if(author, '{author}\n')}"
112 80
113 81 - Label the output for use with the color extension::
114 82
115 83 $ hg log -r 0 --template "{label('changeset.{phase}', node|short)}\n"
116 84
117 85 - Invert the firstline filter, i.e. everything but the first line::
118 86
119 87 $ hg log -r 0 --template "{sub(r'^.*\n?\n?', '', desc)}\n"
120 88
121 89 - Display the contents of the 'extra' field, one per line::
122 90
123 91 $ hg log -r 0 --template "{join(extras, '\n')}\n"
124 92
125 93 - Mark the current bookmark with '*'::
126 94
127 95 $ hg log --template "{bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}\n"
128 96
129 97 - Mark the working copy parent with '@'::
130 98
131 99 $ hg log --template "{ifcontains(rev, revset('.'), '@')}\n"
132 100
133 101 - Show only commit descriptions that start with "template"::
134 102
135 103 $ hg log --template "{startswith(\"template\", firstline(desc))}\n"
136 104
137 105 - Print the first word of each line of a commit message::
138 106
139 107 $ hg log --template "{word(\"0\", desc)}\n"
General Comments 0
You need to be logged in to leave comments. Login now