##// END OF EJS Templates
template: provide a termwidth keyword (issue5395)...
Simon Farnsworth -
r30088:d1f5f158 default
parent child Browse files
Show More
@@ -1,593 +1,598 b''
1 1 # templatekw.py - common changeset template keywords
2 2 #
3 3 # Copyright 2005-2009 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 __future__ import absolute_import
9 9
10 10 from .node import hex, nullid
11 11 from . import (
12 12 encoding,
13 13 error,
14 14 hbisect,
15 15 patch,
16 16 registrar,
17 17 scmutil,
18 18 util,
19 19 )
20 20
21 21 # This helper class allows us to handle both:
22 22 # "{files}" (legacy command-line-specific list hack) and
23 23 # "{files % '{file}\n'}" (hgweb-style with inlining and function support)
24 24 # and to access raw values:
25 25 # "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
26 26 # "{get(extras, key)}"
27 27
28 28 class _hybrid(object):
29 29 def __init__(self, gen, values, makemap, joinfmt):
30 30 self.gen = gen
31 31 self.values = values
32 32 self._makemap = makemap
33 33 self.joinfmt = joinfmt
34 34 def __iter__(self):
35 35 return self.gen
36 36 def itermaps(self):
37 37 makemap = self._makemap
38 38 for x in self.values:
39 39 yield makemap(x)
40 40 def __contains__(self, x):
41 41 return x in self.values
42 42 def __len__(self):
43 43 return len(self.values)
44 44 def __getattr__(self, name):
45 45 if name != 'get':
46 46 raise AttributeError(name)
47 47 return getattr(self.values, name)
48 48
49 49 def showlist(name, values, plural=None, element=None, separator=' ', **args):
50 50 if not element:
51 51 element = name
52 52 f = _showlist(name, values, plural, separator, **args)
53 53 return _hybrid(f, values, lambda x: {element: x}, lambda d: d[element])
54 54
55 55 def _showlist(name, values, plural=None, separator=' ', **args):
56 56 '''expand set of values.
57 57 name is name of key in template map.
58 58 values is list of strings or dicts.
59 59 plural is plural of name, if not simply name + 's'.
60 60 separator is used to join values as a string
61 61
62 62 expansion works like this, given name 'foo'.
63 63
64 64 if values is empty, expand 'no_foos'.
65 65
66 66 if 'foo' not in template map, return values as a string,
67 67 joined by 'separator'.
68 68
69 69 expand 'start_foos'.
70 70
71 71 for each value, expand 'foo'. if 'last_foo' in template
72 72 map, expand it instead of 'foo' for last key.
73 73
74 74 expand 'end_foos'.
75 75 '''
76 76 templ = args['templ']
77 77 if plural:
78 78 names = plural
79 79 else: names = name + 's'
80 80 if not values:
81 81 noname = 'no_' + names
82 82 if noname in templ:
83 83 yield templ(noname, **args)
84 84 return
85 85 if name not in templ:
86 86 if isinstance(values[0], str):
87 87 yield separator.join(values)
88 88 else:
89 89 for v in values:
90 90 yield dict(v, **args)
91 91 return
92 92 startname = 'start_' + names
93 93 if startname in templ:
94 94 yield templ(startname, **args)
95 95 vargs = args.copy()
96 96 def one(v, tag=name):
97 97 try:
98 98 vargs.update(v)
99 99 except (AttributeError, ValueError):
100 100 try:
101 101 for a, b in v:
102 102 vargs[a] = b
103 103 except ValueError:
104 104 vargs[name] = v
105 105 return templ(tag, **vargs)
106 106 lastname = 'last_' + name
107 107 if lastname in templ:
108 108 last = values.pop()
109 109 else:
110 110 last = None
111 111 for v in values:
112 112 yield one(v)
113 113 if last is not None:
114 114 yield one(last, tag=lastname)
115 115 endname = 'end_' + names
116 116 if endname in templ:
117 117 yield templ(endname, **args)
118 118
119 119 def _formatrevnode(ctx):
120 120 """Format changeset as '{rev}:{node|formatnode}', which is the default
121 121 template provided by cmdutil.changeset_templater"""
122 122 repo = ctx.repo()
123 123 if repo.ui.debugflag:
124 124 hexnode = ctx.hex()
125 125 else:
126 126 hexnode = ctx.hex()[:12]
127 127 return '%d:%s' % (scmutil.intrev(ctx.rev()), hexnode)
128 128
129 129 def getfiles(repo, ctx, revcache):
130 130 if 'files' not in revcache:
131 131 revcache['files'] = repo.status(ctx.p1(), ctx)[:3]
132 132 return revcache['files']
133 133
134 134 def getlatesttags(repo, ctx, cache, pattern=None):
135 135 '''return date, distance and name for the latest tag of rev'''
136 136
137 137 cachename = 'latesttags'
138 138 if pattern is not None:
139 139 cachename += '-' + pattern
140 140 match = util.stringmatcher(pattern)[2]
141 141 else:
142 142 match = util.always
143 143
144 144 if cachename not in cache:
145 145 # Cache mapping from rev to a tuple with tag date, tag
146 146 # distance and tag name
147 147 cache[cachename] = {-1: (0, 0, ['null'])}
148 148 latesttags = cache[cachename]
149 149
150 150 rev = ctx.rev()
151 151 todo = [rev]
152 152 while todo:
153 153 rev = todo.pop()
154 154 if rev in latesttags:
155 155 continue
156 156 ctx = repo[rev]
157 157 tags = [t for t in ctx.tags()
158 158 if (repo.tagtype(t) and repo.tagtype(t) != 'local'
159 159 and match(t))]
160 160 if tags:
161 161 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
162 162 continue
163 163 try:
164 164 # The tuples are laid out so the right one can be found by
165 165 # comparison.
166 166 pdate, pdist, ptag = max(
167 167 latesttags[p.rev()] for p in ctx.parents())
168 168 except KeyError:
169 169 # Cache miss - recurse
170 170 todo.append(rev)
171 171 todo.extend(p.rev() for p in ctx.parents())
172 172 continue
173 173 latesttags[rev] = pdate, pdist + 1, ptag
174 174 return latesttags[rev]
175 175
176 176 def getrenamedfn(repo, endrev=None):
177 177 rcache = {}
178 178 if endrev is None:
179 179 endrev = len(repo)
180 180
181 181 def getrenamed(fn, rev):
182 182 '''looks up all renames for a file (up to endrev) the first
183 183 time the file is given. It indexes on the changerev and only
184 184 parses the manifest if linkrev != changerev.
185 185 Returns rename info for fn at changerev rev.'''
186 186 if fn not in rcache:
187 187 rcache[fn] = {}
188 188 fl = repo.file(fn)
189 189 for i in fl:
190 190 lr = fl.linkrev(i)
191 191 renamed = fl.renamed(fl.node(i))
192 192 rcache[fn][lr] = renamed
193 193 if lr >= endrev:
194 194 break
195 195 if rev in rcache[fn]:
196 196 return rcache[fn][rev]
197 197
198 198 # If linkrev != rev (i.e. rev not found in rcache) fallback to
199 199 # filectx logic.
200 200 try:
201 201 return repo[rev][fn].renamed()
202 202 except error.LookupError:
203 203 return None
204 204
205 205 return getrenamed
206 206
207 207 # keywords are callables like:
208 208 # fn(repo, ctx, templ, cache, revcache, **args)
209 209 # with:
210 210 # repo - current repository instance
211 211 # ctx - the changectx being displayed
212 212 # templ - the templater instance
213 213 # cache - a cache dictionary for the whole templater run
214 214 # revcache - a cache dictionary for the current revision
215 215 keywords = {}
216 216
217 217 templatekeyword = registrar.templatekeyword(keywords)
218 218
219 219 @templatekeyword('author')
220 220 def showauthor(repo, ctx, templ, **args):
221 221 """String. The unmodified author of the changeset."""
222 222 return ctx.user()
223 223
224 224 @templatekeyword('bisect')
225 225 def showbisect(repo, ctx, templ, **args):
226 226 """String. The changeset bisection status."""
227 227 return hbisect.label(repo, ctx.node())
228 228
229 229 @templatekeyword('branch')
230 230 def showbranch(**args):
231 231 """String. The name of the branch on which the changeset was
232 232 committed.
233 233 """
234 234 return args['ctx'].branch()
235 235
236 236 @templatekeyword('branches')
237 237 def showbranches(**args):
238 238 """List of strings. The name of the branch on which the
239 239 changeset was committed. Will be empty if the branch name was
240 240 default. (DEPRECATED)
241 241 """
242 242 branch = args['ctx'].branch()
243 243 if branch != 'default':
244 244 return showlist('branch', [branch], plural='branches', **args)
245 245 return showlist('branch', [], plural='branches', **args)
246 246
247 247 @templatekeyword('bookmarks')
248 248 def showbookmarks(**args):
249 249 """List of strings. Any bookmarks associated with the
250 250 changeset. Also sets 'active', the name of the active bookmark.
251 251 """
252 252 repo = args['ctx']._repo
253 253 bookmarks = args['ctx'].bookmarks()
254 254 active = repo._activebookmark
255 255 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active}
256 256 f = _showlist('bookmark', bookmarks, **args)
257 257 return _hybrid(f, bookmarks, makemap, lambda x: x['bookmark'])
258 258
259 259 @templatekeyword('children')
260 260 def showchildren(**args):
261 261 """List of strings. The children of the changeset."""
262 262 ctx = args['ctx']
263 263 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
264 264 return showlist('children', childrevs, element='child', **args)
265 265
266 266 # Deprecated, but kept alive for help generation a purpose.
267 267 @templatekeyword('currentbookmark')
268 268 def showcurrentbookmark(**args):
269 269 """String. The active bookmark, if it is
270 270 associated with the changeset (DEPRECATED)"""
271 271 return showactivebookmark(**args)
272 272
273 273 @templatekeyword('activebookmark')
274 274 def showactivebookmark(**args):
275 275 """String. The active bookmark, if it is
276 276 associated with the changeset"""
277 277 active = args['repo']._activebookmark
278 278 if active and active in args['ctx'].bookmarks():
279 279 return active
280 280 return ''
281 281
282 282 @templatekeyword('date')
283 283 def showdate(repo, ctx, templ, **args):
284 284 """Date information. The date when the changeset was committed."""
285 285 return ctx.date()
286 286
287 287 @templatekeyword('desc')
288 288 def showdescription(repo, ctx, templ, **args):
289 289 """String. The text of the changeset description."""
290 290 s = ctx.description()
291 291 if isinstance(s, encoding.localstr):
292 292 # try hard to preserve utf-8 bytes
293 293 return encoding.tolocal(encoding.fromlocal(s).strip())
294 294 else:
295 295 return s.strip()
296 296
297 297 @templatekeyword('diffstat')
298 298 def showdiffstat(repo, ctx, templ, **args):
299 299 """String. Statistics of changes with the following format:
300 300 "modified files: +added/-removed lines"
301 301 """
302 302 stats = patch.diffstatdata(util.iterlines(ctx.diff()))
303 303 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
304 304 return '%s: +%s/-%s' % (len(stats), adds, removes)
305 305
306 306 @templatekeyword('extras')
307 307 def showextras(**args):
308 308 """List of dicts with key, value entries of the 'extras'
309 309 field of this changeset."""
310 310 extras = args['ctx'].extra()
311 311 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
312 312 makemap = lambda k: {'key': k, 'value': extras[k]}
313 313 c = [makemap(k) for k in extras]
314 314 f = _showlist('extra', c, plural='extras', **args)
315 315 return _hybrid(f, extras, makemap,
316 316 lambda x: '%s=%s' % (x['key'], x['value']))
317 317
318 318 @templatekeyword('file_adds')
319 319 def showfileadds(**args):
320 320 """List of strings. Files added by this changeset."""
321 321 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
322 322 return showlist('file_add', getfiles(repo, ctx, revcache)[1],
323 323 element='file', **args)
324 324
325 325 @templatekeyword('file_copies')
326 326 def showfilecopies(**args):
327 327 """List of strings. Files copied in this changeset with
328 328 their sources.
329 329 """
330 330 cache, ctx = args['cache'], args['ctx']
331 331 copies = args['revcache'].get('copies')
332 332 if copies is None:
333 333 if 'getrenamed' not in cache:
334 334 cache['getrenamed'] = getrenamedfn(args['repo'])
335 335 copies = []
336 336 getrenamed = cache['getrenamed']
337 337 for fn in ctx.files():
338 338 rename = getrenamed(fn, ctx.rev())
339 339 if rename:
340 340 copies.append((fn, rename[0]))
341 341
342 342 copies = util.sortdict(copies)
343 343 makemap = lambda k: {'name': k, 'source': copies[k]}
344 344 c = [makemap(k) for k in copies]
345 345 f = _showlist('file_copy', c, plural='file_copies', **args)
346 346 return _hybrid(f, copies, makemap,
347 347 lambda x: '%s (%s)' % (x['name'], x['source']))
348 348
349 349 # showfilecopiesswitch() displays file copies only if copy records are
350 350 # provided before calling the templater, usually with a --copies
351 351 # command line switch.
352 352 @templatekeyword('file_copies_switch')
353 353 def showfilecopiesswitch(**args):
354 354 """List of strings. Like "file_copies" but displayed
355 355 only if the --copied switch is set.
356 356 """
357 357 copies = args['revcache'].get('copies') or []
358 358 copies = util.sortdict(copies)
359 359 makemap = lambda k: {'name': k, 'source': copies[k]}
360 360 c = [makemap(k) for k in copies]
361 361 f = _showlist('file_copy', c, plural='file_copies', **args)
362 362 return _hybrid(f, copies, makemap,
363 363 lambda x: '%s (%s)' % (x['name'], x['source']))
364 364
365 365 @templatekeyword('file_dels')
366 366 def showfiledels(**args):
367 367 """List of strings. Files removed by this changeset."""
368 368 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
369 369 return showlist('file_del', getfiles(repo, ctx, revcache)[2],
370 370 element='file', **args)
371 371
372 372 @templatekeyword('file_mods')
373 373 def showfilemods(**args):
374 374 """List of strings. Files modified by this changeset."""
375 375 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
376 376 return showlist('file_mod', getfiles(repo, ctx, revcache)[0],
377 377 element='file', **args)
378 378
379 379 @templatekeyword('files')
380 380 def showfiles(**args):
381 381 """List of strings. All files modified, added, or removed by this
382 382 changeset.
383 383 """
384 384 return showlist('file', args['ctx'].files(), **args)
385 385
386 386 @templatekeyword('graphnode')
387 387 def showgraphnode(repo, ctx, **args):
388 388 """String. The character representing the changeset node in
389 389 an ASCII revision graph"""
390 390 wpnodes = repo.dirstate.parents()
391 391 if wpnodes[1] == nullid:
392 392 wpnodes = wpnodes[:1]
393 393 if ctx.node() in wpnodes:
394 394 return '@'
395 395 elif ctx.obsolete():
396 396 return 'x'
397 397 elif ctx.closesbranch():
398 398 return '_'
399 399 else:
400 400 return 'o'
401 401
402 402 @templatekeyword('latesttag')
403 403 def showlatesttag(**args):
404 404 """List of strings. The global tags on the most recent globally
405 405 tagged ancestor of this changeset.
406 406 """
407 407 return showlatesttags(None, **args)
408 408
409 409 def showlatesttags(pattern, **args):
410 410 """helper method for the latesttag keyword and function"""
411 411 repo, ctx = args['repo'], args['ctx']
412 412 cache = args['cache']
413 413 latesttags = getlatesttags(repo, ctx, cache, pattern)
414 414
415 415 # latesttag[0] is an implementation detail for sorting csets on different
416 416 # branches in a stable manner- it is the date the tagged cset was created,
417 417 # not the date the tag was created. Therefore it isn't made visible here.
418 418 makemap = lambda v: {
419 419 'changes': _showchangessincetag,
420 420 'distance': latesttags[1],
421 421 'latesttag': v, # BC with {latesttag % '{latesttag}'}
422 422 'tag': v
423 423 }
424 424
425 425 tags = latesttags[2]
426 426 f = _showlist('latesttag', tags, separator=':', **args)
427 427 return _hybrid(f, tags, makemap, lambda x: x['latesttag'])
428 428
429 429 @templatekeyword('latesttagdistance')
430 430 def showlatesttagdistance(repo, ctx, templ, cache, **args):
431 431 """Integer. Longest path to the latest tag."""
432 432 return getlatesttags(repo, ctx, cache)[1]
433 433
434 434 @templatekeyword('changessincelatesttag')
435 435 def showchangessincelatesttag(repo, ctx, templ, cache, **args):
436 436 """Integer. All ancestors not in the latest tag."""
437 437 latesttag = getlatesttags(repo, ctx, cache)[2][0]
438 438
439 439 return _showchangessincetag(repo, ctx, tag=latesttag, **args)
440 440
441 441 def _showchangessincetag(repo, ctx, **args):
442 442 offset = 0
443 443 revs = [ctx.rev()]
444 444 tag = args['tag']
445 445
446 446 # The only() revset doesn't currently support wdir()
447 447 if ctx.rev() is None:
448 448 offset = 1
449 449 revs = [p.rev() for p in ctx.parents()]
450 450
451 451 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset
452 452
453 453 @templatekeyword('manifest')
454 454 def showmanifest(**args):
455 455 repo, ctx, templ = args['repo'], args['ctx'], args['templ']
456 456 mnode = ctx.manifestnode()
457 457 if mnode is None:
458 458 # just avoid crash, we might want to use the 'ff...' hash in future
459 459 return
460 460 args = args.copy()
461 461 args.update({'rev': repo.manifest.rev(mnode), 'node': hex(mnode)})
462 462 return templ('manifest', **args)
463 463
464 464 def shownames(namespace, **args):
465 465 """helper method to generate a template keyword for a namespace"""
466 466 ctx = args['ctx']
467 467 repo = ctx.repo()
468 468 ns = repo.names[namespace]
469 469 names = ns.names(repo, ctx.node())
470 470 return showlist(ns.templatename, names, plural=namespace, **args)
471 471
472 472 @templatekeyword('namespaces')
473 473 def shownamespaces(**args):
474 474 """Dict of lists. Names attached to this changeset per
475 475 namespace."""
476 476 ctx = args['ctx']
477 477 repo = ctx.repo()
478 478 namespaces = util.sortdict((k, showlist('name', ns.names(repo, ctx.node()),
479 479 **args))
480 480 for k, ns in repo.names.iteritems())
481 481 f = _showlist('namespace', list(namespaces), **args)
482 482 return _hybrid(f, namespaces,
483 483 lambda k: {'namespace': k, 'names': namespaces[k]},
484 484 lambda x: x['namespace'])
485 485
486 486 @templatekeyword('node')
487 487 def shownode(repo, ctx, templ, **args):
488 488 """String. The changeset identification hash, as a 40 hexadecimal
489 489 digit string.
490 490 """
491 491 return ctx.hex()
492 492
493 493 @templatekeyword('p1rev')
494 494 def showp1rev(repo, ctx, templ, **args):
495 495 """Integer. The repository-local revision number of the changeset's
496 496 first parent, or -1 if the changeset has no parents."""
497 497 return ctx.p1().rev()
498 498
499 499 @templatekeyword('p2rev')
500 500 def showp2rev(repo, ctx, templ, **args):
501 501 """Integer. The repository-local revision number of the changeset's
502 502 second parent, or -1 if the changeset has no second parent."""
503 503 return ctx.p2().rev()
504 504
505 505 @templatekeyword('p1node')
506 506 def showp1node(repo, ctx, templ, **args):
507 507 """String. The identification hash of the changeset's first parent,
508 508 as a 40 digit hexadecimal string. If the changeset has no parents, all
509 509 digits are 0."""
510 510 return ctx.p1().hex()
511 511
512 512 @templatekeyword('p2node')
513 513 def showp2node(repo, ctx, templ, **args):
514 514 """String. The identification hash of the changeset's second
515 515 parent, as a 40 digit hexadecimal string. If the changeset has no second
516 516 parent, all digits are 0."""
517 517 return ctx.p2().hex()
518 518
519 519 @templatekeyword('parents')
520 520 def showparents(**args):
521 521 """List of strings. The parents of the changeset in "rev:node"
522 522 format. If the changeset has only one "natural" parent (the predecessor
523 523 revision) nothing is shown."""
524 524 repo = args['repo']
525 525 ctx = args['ctx']
526 526 pctxs = scmutil.meaningfulparents(repo, ctx)
527 527 prevs = [str(p.rev()) for p in pctxs] # ifcontains() needs a list of str
528 528 parents = [[('rev', p.rev()),
529 529 ('node', p.hex()),
530 530 ('phase', p.phasestr())]
531 531 for p in pctxs]
532 532 f = _showlist('parent', parents, **args)
533 533 return _hybrid(f, prevs, lambda x: {'ctx': repo[int(x)], 'revcache': {}},
534 534 lambda d: _formatrevnode(d['ctx']))
535 535
536 536 @templatekeyword('phase')
537 537 def showphase(repo, ctx, templ, **args):
538 538 """String. The changeset phase name."""
539 539 return ctx.phasestr()
540 540
541 541 @templatekeyword('phaseidx')
542 542 def showphaseidx(repo, ctx, templ, **args):
543 543 """Integer. The changeset phase index."""
544 544 return ctx.phase()
545 545
546 546 @templatekeyword('rev')
547 547 def showrev(repo, ctx, templ, **args):
548 548 """Integer. The repository-local changeset revision number."""
549 549 return scmutil.intrev(ctx.rev())
550 550
551 551 def showrevslist(name, revs, **args):
552 552 """helper to generate a list of revisions in which a mapped template will
553 553 be evaluated"""
554 554 repo = args['ctx'].repo()
555 555 revs = [str(r) for r in revs] # ifcontains() needs a list of str
556 556 f = _showlist(name, revs, **args)
557 557 return _hybrid(f, revs,
558 558 lambda x: {name: x, 'ctx': repo[int(x)], 'revcache': {}},
559 559 lambda d: d[name])
560 560
561 561 @templatekeyword('subrepos')
562 562 def showsubrepos(**args):
563 563 """List of strings. Updated subrepositories in the changeset."""
564 564 ctx = args['ctx']
565 565 substate = ctx.substate
566 566 if not substate:
567 567 return showlist('subrepo', [], **args)
568 568 psubstate = ctx.parents()[0].substate or {}
569 569 subrepos = []
570 570 for sub in substate:
571 571 if sub not in psubstate or substate[sub] != psubstate[sub]:
572 572 subrepos.append(sub) # modified or newly added in ctx
573 573 for sub in psubstate:
574 574 if sub not in substate:
575 575 subrepos.append(sub) # removed in ctx
576 576 return showlist('subrepo', sorted(subrepos), **args)
577 577
578 578 # don't remove "showtags" definition, even though namespaces will put
579 579 # a helper function for "tags" keyword into "keywords" map automatically,
580 580 # because online help text is built without namespaces initialization
581 581 @templatekeyword('tags')
582 582 def showtags(**args):
583 583 """List of strings. Any tags associated with the changeset."""
584 584 return shownames('tags', **args)
585 585
586 586 def loadkeyword(ui, extname, registrarobj):
587 587 """Load template keyword from specified registrarobj
588 588 """
589 589 for name, func in registrarobj._table.iteritems():
590 590 keywords[name] = func
591 591
592 @templatekeyword('termwidth')
593 def termwidth(repo, ctx, templ, **args):
594 """Integer. The width of the current terminal."""
595 return repo.ui.termwidth()
596
592 597 # tell hggettext to extract docstrings from these functions:
593 598 i18nfunctions = keywords.values()
@@ -1,3946 +1,3951 b''
1 1 $ hg init a
2 2 $ cd a
3 3 $ echo a > a
4 4 $ hg add a
5 5 $ echo line 1 > b
6 6 $ echo line 2 >> b
7 7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
8 8
9 9 $ hg add b
10 10 $ echo other 1 > c
11 11 $ echo other 2 >> c
12 12 $ echo >> c
13 13 $ echo other 3 >> c
14 14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
15 15
16 16 $ hg add c
17 17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
18 18 $ echo c >> c
19 19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
20 20
21 21 $ echo foo > .hg/branch
22 22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
23 23
24 24 $ hg co -q 3
25 25 $ echo other 4 >> d
26 26 $ hg add d
27 27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
28 28
29 29 $ hg merge -q foo
30 30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
31 31
32 32 Second branch starting at nullrev:
33 33
34 34 $ hg update null
35 35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
36 36 $ echo second > second
37 37 $ hg add second
38 38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
39 39 created new head
40 40
41 41 $ echo third > third
42 42 $ hg add third
43 43 $ hg mv second fourth
44 44 $ hg commit -m third -d "2020-01-01 10:01"
45 45
46 46 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
47 47 fourth (second)
48 48 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
49 49 second -> fourth
50 50 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
51 51 8 t
52 52 7 f
53 53
54 54 Working-directory revision has special identifiers, though they are still
55 55 experimental:
56 56
57 57 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
58 58 2147483647:ffffffffffffffffffffffffffffffffffffffff
59 59
60 60 Some keywords are invalid for working-directory revision, but they should
61 61 never cause crash:
62 62
63 63 $ hg log -r 'wdir()' -T '{manifest}\n'
64 64
65 65
66 66 Quoting for ui.logtemplate
67 67
68 68 $ hg tip --config "ui.logtemplate={rev}\n"
69 69 8
70 70 $ hg tip --config "ui.logtemplate='{rev}\n'"
71 71 8
72 72 $ hg tip --config 'ui.logtemplate="{rev}\n"'
73 73 8
74 74 $ hg tip --config 'ui.logtemplate=n{rev}\n'
75 75 n8
76 76
77 77 Make sure user/global hgrc does not affect tests
78 78
79 79 $ echo '[ui]' > .hg/hgrc
80 80 $ echo 'logtemplate =' >> .hg/hgrc
81 81 $ echo 'style =' >> .hg/hgrc
82 82
83 83 Add some simple styles to settings
84 84
85 85 $ echo '[templates]' >> .hg/hgrc
86 86 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
87 87 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
88 88
89 89 $ hg log -l1 -Tsimple
90 90 8
91 91 $ hg log -l1 -Tsimple2
92 92 8
93 93
94 94 Test templates and style maps in files:
95 95
96 96 $ echo "{rev}" > tmpl
97 97 $ hg log -l1 -T./tmpl
98 98 8
99 99 $ hg log -l1 -Tblah/blah
100 100 blah/blah (no-eol)
101 101
102 102 $ printf 'changeset = "{rev}\\n"\n' > map-simple
103 103 $ hg log -l1 -T./map-simple
104 104 8
105 105
106 106 Test template map inheritance
107 107
108 108 $ echo "__base__ = map-cmdline.default" > map-simple
109 109 $ printf 'cset = "changeset: ***{rev}***\\n"\n' >> map-simple
110 110 $ hg log -l1 -T./map-simple
111 111 changeset: ***8***
112 112 tag: tip
113 113 user: test
114 114 date: Wed Jan 01 10:01:00 2020 +0000
115 115 summary: third
116 116
117 117
118 118 Template should precede style option
119 119
120 120 $ hg log -l1 --style default -T '{rev}\n'
121 121 8
122 122
123 123 Add a commit with empty description, to ensure that the templates
124 124 below will omit the description line.
125 125
126 126 $ echo c >> c
127 127 $ hg add c
128 128 $ hg commit -qm ' '
129 129
130 130 Default style is like normal output. Phases style should be the same
131 131 as default style, except for extra phase lines.
132 132
133 133 $ hg log > log.out
134 134 $ hg log --style default > style.out
135 135 $ cmp log.out style.out || diff -u log.out style.out
136 136 $ hg log -T phases > phases.out
137 137 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
138 138 +phase: draft
139 139 +phase: draft
140 140 +phase: draft
141 141 +phase: draft
142 142 +phase: draft
143 143 +phase: draft
144 144 +phase: draft
145 145 +phase: draft
146 146 +phase: draft
147 147 +phase: draft
148 148
149 149 $ hg log -v > log.out
150 150 $ hg log -v --style default > style.out
151 151 $ cmp log.out style.out || diff -u log.out style.out
152 152 $ hg log -v -T phases > phases.out
153 153 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
154 154 +phase: draft
155 155 +phase: draft
156 156 +phase: draft
157 157 +phase: draft
158 158 +phase: draft
159 159 +phase: draft
160 160 +phase: draft
161 161 +phase: draft
162 162 +phase: draft
163 163 +phase: draft
164 164
165 165 $ hg log -q > log.out
166 166 $ hg log -q --style default > style.out
167 167 $ cmp log.out style.out || diff -u log.out style.out
168 168 $ hg log -q -T phases > phases.out
169 169 $ cmp log.out phases.out || diff -u log.out phases.out
170 170
171 171 $ hg log --debug > log.out
172 172 $ hg log --debug --style default > style.out
173 173 $ cmp log.out style.out || diff -u log.out style.out
174 174 $ hg log --debug -T phases > phases.out
175 175 $ cmp log.out phases.out || diff -u log.out phases.out
176 176
177 177 Default style of working-directory revision should also be the same (but
178 178 date may change while running tests):
179 179
180 180 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
181 181 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
182 182 $ cmp log.out style.out || diff -u log.out style.out
183 183
184 184 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
185 185 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
186 186 $ cmp log.out style.out || diff -u log.out style.out
187 187
188 188 $ hg log -r 'wdir()' -q > log.out
189 189 $ hg log -r 'wdir()' -q --style default > style.out
190 190 $ cmp log.out style.out || diff -u log.out style.out
191 191
192 192 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
193 193 $ hg log -r 'wdir()' --debug --style default \
194 194 > | sed 's|^date:.*|date:|' > style.out
195 195 $ cmp log.out style.out || diff -u log.out style.out
196 196
197 197 Default style should also preserve color information (issue2866):
198 198
199 199 $ cp $HGRCPATH $HGRCPATH-bak
200 200 $ cat <<EOF >> $HGRCPATH
201 201 > [extensions]
202 202 > color=
203 203 > EOF
204 204
205 205 $ hg --color=debug log > log.out
206 206 $ hg --color=debug log --style default > style.out
207 207 $ cmp log.out style.out || diff -u log.out style.out
208 208 $ hg --color=debug log -T phases > phases.out
209 209 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
210 210 +[log.phase|phase: draft]
211 211 +[log.phase|phase: draft]
212 212 +[log.phase|phase: draft]
213 213 +[log.phase|phase: draft]
214 214 +[log.phase|phase: draft]
215 215 +[log.phase|phase: draft]
216 216 +[log.phase|phase: draft]
217 217 +[log.phase|phase: draft]
218 218 +[log.phase|phase: draft]
219 219 +[log.phase|phase: draft]
220 220
221 221 $ hg --color=debug -v log > log.out
222 222 $ hg --color=debug -v log --style default > style.out
223 223 $ cmp log.out style.out || diff -u log.out style.out
224 224 $ hg --color=debug -v log -T phases > phases.out
225 225 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
226 226 +[log.phase|phase: draft]
227 227 +[log.phase|phase: draft]
228 228 +[log.phase|phase: draft]
229 229 +[log.phase|phase: draft]
230 230 +[log.phase|phase: draft]
231 231 +[log.phase|phase: draft]
232 232 +[log.phase|phase: draft]
233 233 +[log.phase|phase: draft]
234 234 +[log.phase|phase: draft]
235 235 +[log.phase|phase: draft]
236 236
237 237 $ hg --color=debug -q log > log.out
238 238 $ hg --color=debug -q log --style default > style.out
239 239 $ cmp log.out style.out || diff -u log.out style.out
240 240 $ hg --color=debug -q log -T phases > phases.out
241 241 $ cmp log.out phases.out || diff -u log.out phases.out
242 242
243 243 $ hg --color=debug --debug log > log.out
244 244 $ hg --color=debug --debug log --style default > style.out
245 245 $ cmp log.out style.out || diff -u log.out style.out
246 246 $ hg --color=debug --debug log -T phases > phases.out
247 247 $ cmp log.out phases.out || diff -u log.out phases.out
248 248
249 249 $ mv $HGRCPATH-bak $HGRCPATH
250 250
251 251 Remove commit with empty commit message, so as to not pollute further
252 252 tests.
253 253
254 254 $ hg --config extensions.strip= strip -q .
255 255
256 256 Revision with no copies (used to print a traceback):
257 257
258 258 $ hg tip -v --template '\n'
259 259
260 260
261 261 Compact style works:
262 262
263 263 $ hg log -Tcompact
264 264 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
265 265 third
266 266
267 267 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
268 268 second
269 269
270 270 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
271 271 merge
272 272
273 273 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
274 274 new head
275 275
276 276 4 bbe44766e73d 1970-01-17 04:53 +0000 person
277 277 new branch
278 278
279 279 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
280 280 no user, no domain
281 281
282 282 2 97054abb4ab8 1970-01-14 21:20 +0000 other
283 283 no person
284 284
285 285 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
286 286 other 1
287 287
288 288 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
289 289 line 1
290 290
291 291
292 292 $ hg log -v --style compact
293 293 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
294 294 third
295 295
296 296 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
297 297 second
298 298
299 299 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
300 300 merge
301 301
302 302 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
303 303 new head
304 304
305 305 4 bbe44766e73d 1970-01-17 04:53 +0000 person
306 306 new branch
307 307
308 308 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
309 309 no user, no domain
310 310
311 311 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
312 312 no person
313 313
314 314 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
315 315 other 1
316 316 other 2
317 317
318 318 other 3
319 319
320 320 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
321 321 line 1
322 322 line 2
323 323
324 324
325 325 $ hg log --debug --style compact
326 326 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
327 327 third
328 328
329 329 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
330 330 second
331 331
332 332 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
333 333 merge
334 334
335 335 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
336 336 new head
337 337
338 338 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
339 339 new branch
340 340
341 341 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
342 342 no user, no domain
343 343
344 344 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
345 345 no person
346 346
347 347 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
348 348 other 1
349 349 other 2
350 350
351 351 other 3
352 352
353 353 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
354 354 line 1
355 355 line 2
356 356
357 357
358 358 Test xml styles:
359 359
360 360 $ hg log --style xml -r 'not all()'
361 361 <?xml version="1.0"?>
362 362 <log>
363 363 </log>
364 364
365 365 $ hg log --style xml
366 366 <?xml version="1.0"?>
367 367 <log>
368 368 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
369 369 <tag>tip</tag>
370 370 <author email="test">test</author>
371 371 <date>2020-01-01T10:01:00+00:00</date>
372 372 <msg xml:space="preserve">third</msg>
373 373 </logentry>
374 374 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
375 375 <parent revision="-1" node="0000000000000000000000000000000000000000" />
376 376 <author email="user@hostname">User Name</author>
377 377 <date>1970-01-12T13:46:40+00:00</date>
378 378 <msg xml:space="preserve">second</msg>
379 379 </logentry>
380 380 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
381 381 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
382 382 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
383 383 <author email="person">person</author>
384 384 <date>1970-01-18T08:40:01+00:00</date>
385 385 <msg xml:space="preserve">merge</msg>
386 386 </logentry>
387 387 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
388 388 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
389 389 <author email="person">person</author>
390 390 <date>1970-01-18T08:40:00+00:00</date>
391 391 <msg xml:space="preserve">new head</msg>
392 392 </logentry>
393 393 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
394 394 <branch>foo</branch>
395 395 <author email="person">person</author>
396 396 <date>1970-01-17T04:53:20+00:00</date>
397 397 <msg xml:space="preserve">new branch</msg>
398 398 </logentry>
399 399 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
400 400 <author email="person">person</author>
401 401 <date>1970-01-16T01:06:40+00:00</date>
402 402 <msg xml:space="preserve">no user, no domain</msg>
403 403 </logentry>
404 404 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
405 405 <author email="other@place">other</author>
406 406 <date>1970-01-14T21:20:00+00:00</date>
407 407 <msg xml:space="preserve">no person</msg>
408 408 </logentry>
409 409 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
410 410 <author email="other@place">A. N. Other</author>
411 411 <date>1970-01-13T17:33:20+00:00</date>
412 412 <msg xml:space="preserve">other 1
413 413 other 2
414 414
415 415 other 3</msg>
416 416 </logentry>
417 417 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
418 418 <author email="user@hostname">User Name</author>
419 419 <date>1970-01-12T13:46:40+00:00</date>
420 420 <msg xml:space="preserve">line 1
421 421 line 2</msg>
422 422 </logentry>
423 423 </log>
424 424
425 425 $ hg log -v --style xml
426 426 <?xml version="1.0"?>
427 427 <log>
428 428 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
429 429 <tag>tip</tag>
430 430 <author email="test">test</author>
431 431 <date>2020-01-01T10:01:00+00:00</date>
432 432 <msg xml:space="preserve">third</msg>
433 433 <paths>
434 434 <path action="A">fourth</path>
435 435 <path action="A">third</path>
436 436 <path action="R">second</path>
437 437 </paths>
438 438 <copies>
439 439 <copy source="second">fourth</copy>
440 440 </copies>
441 441 </logentry>
442 442 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
443 443 <parent revision="-1" node="0000000000000000000000000000000000000000" />
444 444 <author email="user@hostname">User Name</author>
445 445 <date>1970-01-12T13:46:40+00:00</date>
446 446 <msg xml:space="preserve">second</msg>
447 447 <paths>
448 448 <path action="A">second</path>
449 449 </paths>
450 450 </logentry>
451 451 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
452 452 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
453 453 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
454 454 <author email="person">person</author>
455 455 <date>1970-01-18T08:40:01+00:00</date>
456 456 <msg xml:space="preserve">merge</msg>
457 457 <paths>
458 458 </paths>
459 459 </logentry>
460 460 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
461 461 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
462 462 <author email="person">person</author>
463 463 <date>1970-01-18T08:40:00+00:00</date>
464 464 <msg xml:space="preserve">new head</msg>
465 465 <paths>
466 466 <path action="A">d</path>
467 467 </paths>
468 468 </logentry>
469 469 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
470 470 <branch>foo</branch>
471 471 <author email="person">person</author>
472 472 <date>1970-01-17T04:53:20+00:00</date>
473 473 <msg xml:space="preserve">new branch</msg>
474 474 <paths>
475 475 </paths>
476 476 </logentry>
477 477 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
478 478 <author email="person">person</author>
479 479 <date>1970-01-16T01:06:40+00:00</date>
480 480 <msg xml:space="preserve">no user, no domain</msg>
481 481 <paths>
482 482 <path action="M">c</path>
483 483 </paths>
484 484 </logentry>
485 485 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
486 486 <author email="other@place">other</author>
487 487 <date>1970-01-14T21:20:00+00:00</date>
488 488 <msg xml:space="preserve">no person</msg>
489 489 <paths>
490 490 <path action="A">c</path>
491 491 </paths>
492 492 </logentry>
493 493 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
494 494 <author email="other@place">A. N. Other</author>
495 495 <date>1970-01-13T17:33:20+00:00</date>
496 496 <msg xml:space="preserve">other 1
497 497 other 2
498 498
499 499 other 3</msg>
500 500 <paths>
501 501 <path action="A">b</path>
502 502 </paths>
503 503 </logentry>
504 504 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
505 505 <author email="user@hostname">User Name</author>
506 506 <date>1970-01-12T13:46:40+00:00</date>
507 507 <msg xml:space="preserve">line 1
508 508 line 2</msg>
509 509 <paths>
510 510 <path action="A">a</path>
511 511 </paths>
512 512 </logentry>
513 513 </log>
514 514
515 515 $ hg log --debug --style xml
516 516 <?xml version="1.0"?>
517 517 <log>
518 518 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
519 519 <tag>tip</tag>
520 520 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
521 521 <parent revision="-1" node="0000000000000000000000000000000000000000" />
522 522 <author email="test">test</author>
523 523 <date>2020-01-01T10:01:00+00:00</date>
524 524 <msg xml:space="preserve">third</msg>
525 525 <paths>
526 526 <path action="A">fourth</path>
527 527 <path action="A">third</path>
528 528 <path action="R">second</path>
529 529 </paths>
530 530 <copies>
531 531 <copy source="second">fourth</copy>
532 532 </copies>
533 533 <extra key="branch">default</extra>
534 534 </logentry>
535 535 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
536 536 <parent revision="-1" node="0000000000000000000000000000000000000000" />
537 537 <parent revision="-1" node="0000000000000000000000000000000000000000" />
538 538 <author email="user@hostname">User Name</author>
539 539 <date>1970-01-12T13:46:40+00:00</date>
540 540 <msg xml:space="preserve">second</msg>
541 541 <paths>
542 542 <path action="A">second</path>
543 543 </paths>
544 544 <extra key="branch">default</extra>
545 545 </logentry>
546 546 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
547 547 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
548 548 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
549 549 <author email="person">person</author>
550 550 <date>1970-01-18T08:40:01+00:00</date>
551 551 <msg xml:space="preserve">merge</msg>
552 552 <paths>
553 553 </paths>
554 554 <extra key="branch">default</extra>
555 555 </logentry>
556 556 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
557 557 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
558 558 <parent revision="-1" node="0000000000000000000000000000000000000000" />
559 559 <author email="person">person</author>
560 560 <date>1970-01-18T08:40:00+00:00</date>
561 561 <msg xml:space="preserve">new head</msg>
562 562 <paths>
563 563 <path action="A">d</path>
564 564 </paths>
565 565 <extra key="branch">default</extra>
566 566 </logentry>
567 567 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
568 568 <branch>foo</branch>
569 569 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
570 570 <parent revision="-1" node="0000000000000000000000000000000000000000" />
571 571 <author email="person">person</author>
572 572 <date>1970-01-17T04:53:20+00:00</date>
573 573 <msg xml:space="preserve">new branch</msg>
574 574 <paths>
575 575 </paths>
576 576 <extra key="branch">foo</extra>
577 577 </logentry>
578 578 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
579 579 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
580 580 <parent revision="-1" node="0000000000000000000000000000000000000000" />
581 581 <author email="person">person</author>
582 582 <date>1970-01-16T01:06:40+00:00</date>
583 583 <msg xml:space="preserve">no user, no domain</msg>
584 584 <paths>
585 585 <path action="M">c</path>
586 586 </paths>
587 587 <extra key="branch">default</extra>
588 588 </logentry>
589 589 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
590 590 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
591 591 <parent revision="-1" node="0000000000000000000000000000000000000000" />
592 592 <author email="other@place">other</author>
593 593 <date>1970-01-14T21:20:00+00:00</date>
594 594 <msg xml:space="preserve">no person</msg>
595 595 <paths>
596 596 <path action="A">c</path>
597 597 </paths>
598 598 <extra key="branch">default</extra>
599 599 </logentry>
600 600 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
601 601 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
602 602 <parent revision="-1" node="0000000000000000000000000000000000000000" />
603 603 <author email="other@place">A. N. Other</author>
604 604 <date>1970-01-13T17:33:20+00:00</date>
605 605 <msg xml:space="preserve">other 1
606 606 other 2
607 607
608 608 other 3</msg>
609 609 <paths>
610 610 <path action="A">b</path>
611 611 </paths>
612 612 <extra key="branch">default</extra>
613 613 </logentry>
614 614 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
615 615 <parent revision="-1" node="0000000000000000000000000000000000000000" />
616 616 <parent revision="-1" node="0000000000000000000000000000000000000000" />
617 617 <author email="user@hostname">User Name</author>
618 618 <date>1970-01-12T13:46:40+00:00</date>
619 619 <msg xml:space="preserve">line 1
620 620 line 2</msg>
621 621 <paths>
622 622 <path action="A">a</path>
623 623 </paths>
624 624 <extra key="branch">default</extra>
625 625 </logentry>
626 626 </log>
627 627
628 628
629 629 Test JSON style:
630 630
631 631 $ hg log -k nosuch -Tjson
632 632 []
633 633
634 634 $ hg log -qr . -Tjson
635 635 [
636 636 {
637 637 "rev": 8,
638 638 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
639 639 }
640 640 ]
641 641
642 642 $ hg log -vpr . -Tjson --stat
643 643 [
644 644 {
645 645 "rev": 8,
646 646 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
647 647 "branch": "default",
648 648 "phase": "draft",
649 649 "user": "test",
650 650 "date": [1577872860, 0],
651 651 "desc": "third",
652 652 "bookmarks": [],
653 653 "tags": ["tip"],
654 654 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
655 655 "files": ["fourth", "second", "third"],
656 656 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
657 657 "diff": "diff -r 29114dbae42b -r 95c24699272e fourth\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/fourth\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+second\ndiff -r 29114dbae42b -r 95c24699272e second\n--- a/second\tMon Jan 12 13:46:40 1970 +0000\n+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,1 +0,0 @@\n-second\ndiff -r 29114dbae42b -r 95c24699272e third\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/third\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+third\n"
658 658 }
659 659 ]
660 660
661 661 honor --git but not format-breaking diffopts
662 662 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
663 663 [
664 664 {
665 665 "rev": 8,
666 666 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
667 667 "branch": "default",
668 668 "phase": "draft",
669 669 "user": "test",
670 670 "date": [1577872860, 0],
671 671 "desc": "third",
672 672 "bookmarks": [],
673 673 "tags": ["tip"],
674 674 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
675 675 "files": ["fourth", "second", "third"],
676 676 "diff": "diff --git a/second b/fourth\nrename from second\nrename to fourth\ndiff --git a/third b/third\nnew file mode 100644\n--- /dev/null\n+++ b/third\n@@ -0,0 +1,1 @@\n+third\n"
677 677 }
678 678 ]
679 679
680 680 $ hg log -T json
681 681 [
682 682 {
683 683 "rev": 8,
684 684 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
685 685 "branch": "default",
686 686 "phase": "draft",
687 687 "user": "test",
688 688 "date": [1577872860, 0],
689 689 "desc": "third",
690 690 "bookmarks": [],
691 691 "tags": ["tip"],
692 692 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
693 693 },
694 694 {
695 695 "rev": 7,
696 696 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
697 697 "branch": "default",
698 698 "phase": "draft",
699 699 "user": "User Name <user@hostname>",
700 700 "date": [1000000, 0],
701 701 "desc": "second",
702 702 "bookmarks": [],
703 703 "tags": [],
704 704 "parents": ["0000000000000000000000000000000000000000"]
705 705 },
706 706 {
707 707 "rev": 6,
708 708 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
709 709 "branch": "default",
710 710 "phase": "draft",
711 711 "user": "person",
712 712 "date": [1500001, 0],
713 713 "desc": "merge",
714 714 "bookmarks": [],
715 715 "tags": [],
716 716 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
717 717 },
718 718 {
719 719 "rev": 5,
720 720 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
721 721 "branch": "default",
722 722 "phase": "draft",
723 723 "user": "person",
724 724 "date": [1500000, 0],
725 725 "desc": "new head",
726 726 "bookmarks": [],
727 727 "tags": [],
728 728 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
729 729 },
730 730 {
731 731 "rev": 4,
732 732 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
733 733 "branch": "foo",
734 734 "phase": "draft",
735 735 "user": "person",
736 736 "date": [1400000, 0],
737 737 "desc": "new branch",
738 738 "bookmarks": [],
739 739 "tags": [],
740 740 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
741 741 },
742 742 {
743 743 "rev": 3,
744 744 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
745 745 "branch": "default",
746 746 "phase": "draft",
747 747 "user": "person",
748 748 "date": [1300000, 0],
749 749 "desc": "no user, no domain",
750 750 "bookmarks": [],
751 751 "tags": [],
752 752 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
753 753 },
754 754 {
755 755 "rev": 2,
756 756 "node": "97054abb4ab824450e9164180baf491ae0078465",
757 757 "branch": "default",
758 758 "phase": "draft",
759 759 "user": "other@place",
760 760 "date": [1200000, 0],
761 761 "desc": "no person",
762 762 "bookmarks": [],
763 763 "tags": [],
764 764 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
765 765 },
766 766 {
767 767 "rev": 1,
768 768 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
769 769 "branch": "default",
770 770 "phase": "draft",
771 771 "user": "A. N. Other <other@place>",
772 772 "date": [1100000, 0],
773 773 "desc": "other 1\nother 2\n\nother 3",
774 774 "bookmarks": [],
775 775 "tags": [],
776 776 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
777 777 },
778 778 {
779 779 "rev": 0,
780 780 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
781 781 "branch": "default",
782 782 "phase": "draft",
783 783 "user": "User Name <user@hostname>",
784 784 "date": [1000000, 0],
785 785 "desc": "line 1\nline 2",
786 786 "bookmarks": [],
787 787 "tags": [],
788 788 "parents": ["0000000000000000000000000000000000000000"]
789 789 }
790 790 ]
791 791
792 792 $ hg heads -v -Tjson
793 793 [
794 794 {
795 795 "rev": 8,
796 796 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
797 797 "branch": "default",
798 798 "phase": "draft",
799 799 "user": "test",
800 800 "date": [1577872860, 0],
801 801 "desc": "third",
802 802 "bookmarks": [],
803 803 "tags": ["tip"],
804 804 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
805 805 "files": ["fourth", "second", "third"]
806 806 },
807 807 {
808 808 "rev": 6,
809 809 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
810 810 "branch": "default",
811 811 "phase": "draft",
812 812 "user": "person",
813 813 "date": [1500001, 0],
814 814 "desc": "merge",
815 815 "bookmarks": [],
816 816 "tags": [],
817 817 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
818 818 "files": []
819 819 },
820 820 {
821 821 "rev": 4,
822 822 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
823 823 "branch": "foo",
824 824 "phase": "draft",
825 825 "user": "person",
826 826 "date": [1400000, 0],
827 827 "desc": "new branch",
828 828 "bookmarks": [],
829 829 "tags": [],
830 830 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
831 831 "files": []
832 832 }
833 833 ]
834 834
835 835 $ hg log --debug -Tjson
836 836 [
837 837 {
838 838 "rev": 8,
839 839 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
840 840 "branch": "default",
841 841 "phase": "draft",
842 842 "user": "test",
843 843 "date": [1577872860, 0],
844 844 "desc": "third",
845 845 "bookmarks": [],
846 846 "tags": ["tip"],
847 847 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
848 848 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
849 849 "extra": {"branch": "default"},
850 850 "modified": [],
851 851 "added": ["fourth", "third"],
852 852 "removed": ["second"]
853 853 },
854 854 {
855 855 "rev": 7,
856 856 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
857 857 "branch": "default",
858 858 "phase": "draft",
859 859 "user": "User Name <user@hostname>",
860 860 "date": [1000000, 0],
861 861 "desc": "second",
862 862 "bookmarks": [],
863 863 "tags": [],
864 864 "parents": ["0000000000000000000000000000000000000000"],
865 865 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
866 866 "extra": {"branch": "default"},
867 867 "modified": [],
868 868 "added": ["second"],
869 869 "removed": []
870 870 },
871 871 {
872 872 "rev": 6,
873 873 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
874 874 "branch": "default",
875 875 "phase": "draft",
876 876 "user": "person",
877 877 "date": [1500001, 0],
878 878 "desc": "merge",
879 879 "bookmarks": [],
880 880 "tags": [],
881 881 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
882 882 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
883 883 "extra": {"branch": "default"},
884 884 "modified": [],
885 885 "added": [],
886 886 "removed": []
887 887 },
888 888 {
889 889 "rev": 5,
890 890 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
891 891 "branch": "default",
892 892 "phase": "draft",
893 893 "user": "person",
894 894 "date": [1500000, 0],
895 895 "desc": "new head",
896 896 "bookmarks": [],
897 897 "tags": [],
898 898 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
899 899 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
900 900 "extra": {"branch": "default"},
901 901 "modified": [],
902 902 "added": ["d"],
903 903 "removed": []
904 904 },
905 905 {
906 906 "rev": 4,
907 907 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
908 908 "branch": "foo",
909 909 "phase": "draft",
910 910 "user": "person",
911 911 "date": [1400000, 0],
912 912 "desc": "new branch",
913 913 "bookmarks": [],
914 914 "tags": [],
915 915 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
916 916 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
917 917 "extra": {"branch": "foo"},
918 918 "modified": [],
919 919 "added": [],
920 920 "removed": []
921 921 },
922 922 {
923 923 "rev": 3,
924 924 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
925 925 "branch": "default",
926 926 "phase": "draft",
927 927 "user": "person",
928 928 "date": [1300000, 0],
929 929 "desc": "no user, no domain",
930 930 "bookmarks": [],
931 931 "tags": [],
932 932 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
933 933 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
934 934 "extra": {"branch": "default"},
935 935 "modified": ["c"],
936 936 "added": [],
937 937 "removed": []
938 938 },
939 939 {
940 940 "rev": 2,
941 941 "node": "97054abb4ab824450e9164180baf491ae0078465",
942 942 "branch": "default",
943 943 "phase": "draft",
944 944 "user": "other@place",
945 945 "date": [1200000, 0],
946 946 "desc": "no person",
947 947 "bookmarks": [],
948 948 "tags": [],
949 949 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
950 950 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
951 951 "extra": {"branch": "default"},
952 952 "modified": [],
953 953 "added": ["c"],
954 954 "removed": []
955 955 },
956 956 {
957 957 "rev": 1,
958 958 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
959 959 "branch": "default",
960 960 "phase": "draft",
961 961 "user": "A. N. Other <other@place>",
962 962 "date": [1100000, 0],
963 963 "desc": "other 1\nother 2\n\nother 3",
964 964 "bookmarks": [],
965 965 "tags": [],
966 966 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
967 967 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
968 968 "extra": {"branch": "default"},
969 969 "modified": [],
970 970 "added": ["b"],
971 971 "removed": []
972 972 },
973 973 {
974 974 "rev": 0,
975 975 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
976 976 "branch": "default",
977 977 "phase": "draft",
978 978 "user": "User Name <user@hostname>",
979 979 "date": [1000000, 0],
980 980 "desc": "line 1\nline 2",
981 981 "bookmarks": [],
982 982 "tags": [],
983 983 "parents": ["0000000000000000000000000000000000000000"],
984 984 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
985 985 "extra": {"branch": "default"},
986 986 "modified": [],
987 987 "added": ["a"],
988 988 "removed": []
989 989 }
990 990 ]
991 991
992 992 Error if style not readable:
993 993
994 994 #if unix-permissions no-root
995 995 $ touch q
996 996 $ chmod 0 q
997 997 $ hg log --style ./q
998 998 abort: Permission denied: ./q
999 999 [255]
1000 1000 #endif
1001 1001
1002 1002 Error if no style:
1003 1003
1004 1004 $ hg log --style notexist
1005 1005 abort: style 'notexist' not found
1006 1006 (available styles: bisect, changelog, compact, default, phases, status, xml)
1007 1007 [255]
1008 1008
1009 1009 $ hg log -T list
1010 1010 available styles: bisect, changelog, compact, default, phases, status, xml
1011 1011 abort: specify a template
1012 1012 [255]
1013 1013
1014 1014 Error if style missing key:
1015 1015
1016 1016 $ echo 'q = q' > t
1017 1017 $ hg log --style ./t
1018 1018 abort: "changeset" not in template map
1019 1019 [255]
1020 1020
1021 1021 Error if style missing value:
1022 1022
1023 1023 $ echo 'changeset =' > t
1024 1024 $ hg log --style t
1025 1025 hg: parse error at t:1: missing value
1026 1026 [255]
1027 1027
1028 1028 Error if include fails:
1029 1029
1030 1030 $ echo 'changeset = q' >> t
1031 1031 #if unix-permissions no-root
1032 1032 $ hg log --style ./t
1033 1033 abort: template file ./q: Permission denied
1034 1034 [255]
1035 1035 $ rm -f q
1036 1036 #endif
1037 1037
1038 1038 Include works:
1039 1039
1040 1040 $ echo '{rev}' > q
1041 1041 $ hg log --style ./t
1042 1042 8
1043 1043 7
1044 1044 6
1045 1045 5
1046 1046 4
1047 1047 3
1048 1048 2
1049 1049 1
1050 1050 0
1051 1051
1052 1052 Check that recursive reference does not fall into RuntimeError (issue4758):
1053 1053
1054 1054 common mistake:
1055 1055
1056 1056 $ hg log -T '{changeset}\n'
1057 1057 abort: recursive reference 'changeset' in template
1058 1058 [255]
1059 1059
1060 1060 circular reference:
1061 1061
1062 1062 $ cat << EOF > issue4758
1063 1063 > changeset = '{foo}'
1064 1064 > foo = '{changeset}'
1065 1065 > EOF
1066 1066 $ hg log --style ./issue4758
1067 1067 abort: recursive reference 'foo' in template
1068 1068 [255]
1069 1069
1070 1070 buildmap() -> gettemplate(), where no thunk was made:
1071 1071
1072 1072 $ hg log -T '{files % changeset}\n'
1073 1073 abort: recursive reference 'changeset' in template
1074 1074 [255]
1075 1075
1076 1076 not a recursion if a keyword of the same name exists:
1077 1077
1078 1078 $ cat << EOF > issue4758
1079 1079 > changeset = '{tags % rev}'
1080 1080 > rev = '{rev} {tag}\n'
1081 1081 > EOF
1082 1082 $ hg log --style ./issue4758 -r tip
1083 1083 8 tip
1084 1084
1085 1085 Check that {phase} works correctly on parents:
1086 1086
1087 1087 $ cat << EOF > parentphase
1088 1088 > changeset_debug = '{rev} ({phase}):{parents}\n'
1089 1089 > parent = ' {rev} ({phase})'
1090 1090 > EOF
1091 1091 $ hg phase -r 5 --public
1092 1092 $ hg phase -r 7 --secret --force
1093 1093 $ hg log --debug -G --style ./parentphase
1094 1094 @ 8 (secret): 7 (secret) -1 (public)
1095 1095 |
1096 1096 o 7 (secret): -1 (public) -1 (public)
1097 1097
1098 1098 o 6 (draft): 5 (public) 4 (draft)
1099 1099 |\
1100 1100 | o 5 (public): 3 (public) -1 (public)
1101 1101 | |
1102 1102 o | 4 (draft): 3 (public) -1 (public)
1103 1103 |/
1104 1104 o 3 (public): 2 (public) -1 (public)
1105 1105 |
1106 1106 o 2 (public): 1 (public) -1 (public)
1107 1107 |
1108 1108 o 1 (public): 0 (public) -1 (public)
1109 1109 |
1110 1110 o 0 (public): -1 (public) -1 (public)
1111 1111
1112 1112
1113 1113 Missing non-standard names give no error (backward compatibility):
1114 1114
1115 1115 $ echo "changeset = '{c}'" > t
1116 1116 $ hg log --style ./t
1117 1117
1118 1118 Defining non-standard name works:
1119 1119
1120 1120 $ cat <<EOF > t
1121 1121 > changeset = '{c}'
1122 1122 > c = q
1123 1123 > EOF
1124 1124 $ hg log --style ./t
1125 1125 8
1126 1126 7
1127 1127 6
1128 1128 5
1129 1129 4
1130 1130 3
1131 1131 2
1132 1132 1
1133 1133 0
1134 1134
1135 1135 ui.style works:
1136 1136
1137 1137 $ echo '[ui]' > .hg/hgrc
1138 1138 $ echo 'style = t' >> .hg/hgrc
1139 1139 $ hg log
1140 1140 8
1141 1141 7
1142 1142 6
1143 1143 5
1144 1144 4
1145 1145 3
1146 1146 2
1147 1147 1
1148 1148 0
1149 1149
1150 1150
1151 1151 Issue338:
1152 1152
1153 1153 $ hg log --style=changelog > changelog
1154 1154
1155 1155 $ cat changelog
1156 1156 2020-01-01 test <test>
1157 1157
1158 1158 * fourth, second, third:
1159 1159 third
1160 1160 [95c24699272e] [tip]
1161 1161
1162 1162 1970-01-12 User Name <user@hostname>
1163 1163
1164 1164 * second:
1165 1165 second
1166 1166 [29114dbae42b]
1167 1167
1168 1168 1970-01-18 person <person>
1169 1169
1170 1170 * merge
1171 1171 [d41e714fe50d]
1172 1172
1173 1173 * d:
1174 1174 new head
1175 1175 [13207e5a10d9]
1176 1176
1177 1177 1970-01-17 person <person>
1178 1178
1179 1179 * new branch
1180 1180 [bbe44766e73d] <foo>
1181 1181
1182 1182 1970-01-16 person <person>
1183 1183
1184 1184 * c:
1185 1185 no user, no domain
1186 1186 [10e46f2dcbf4]
1187 1187
1188 1188 1970-01-14 other <other@place>
1189 1189
1190 1190 * c:
1191 1191 no person
1192 1192 [97054abb4ab8]
1193 1193
1194 1194 1970-01-13 A. N. Other <other@place>
1195 1195
1196 1196 * b:
1197 1197 other 1 other 2
1198 1198
1199 1199 other 3
1200 1200 [b608e9d1a3f0]
1201 1201
1202 1202 1970-01-12 User Name <user@hostname>
1203 1203
1204 1204 * a:
1205 1205 line 1 line 2
1206 1206 [1e4e1b8f71e0]
1207 1207
1208 1208
1209 1209 Issue2130: xml output for 'hg heads' is malformed
1210 1210
1211 1211 $ hg heads --style changelog
1212 1212 2020-01-01 test <test>
1213 1213
1214 1214 * fourth, second, third:
1215 1215 third
1216 1216 [95c24699272e] [tip]
1217 1217
1218 1218 1970-01-18 person <person>
1219 1219
1220 1220 * merge
1221 1221 [d41e714fe50d]
1222 1222
1223 1223 1970-01-17 person <person>
1224 1224
1225 1225 * new branch
1226 1226 [bbe44766e73d] <foo>
1227 1227
1228 1228
1229 1229 Keys work:
1230 1230
1231 1231 $ for key in author branch branches date desc file_adds file_dels file_mods \
1232 1232 > file_copies file_copies_switch files \
1233 1233 > manifest node parents rev tags diffstat extras \
1234 1234 > p1rev p2rev p1node p2node; do
1235 1235 > for mode in '' --verbose --debug; do
1236 1236 > hg log $mode --template "$key$mode: {$key}\n"
1237 1237 > done
1238 1238 > done
1239 1239 author: test
1240 1240 author: User Name <user@hostname>
1241 1241 author: person
1242 1242 author: person
1243 1243 author: person
1244 1244 author: person
1245 1245 author: other@place
1246 1246 author: A. N. Other <other@place>
1247 1247 author: User Name <user@hostname>
1248 1248 author--verbose: test
1249 1249 author--verbose: User Name <user@hostname>
1250 1250 author--verbose: person
1251 1251 author--verbose: person
1252 1252 author--verbose: person
1253 1253 author--verbose: person
1254 1254 author--verbose: other@place
1255 1255 author--verbose: A. N. Other <other@place>
1256 1256 author--verbose: User Name <user@hostname>
1257 1257 author--debug: test
1258 1258 author--debug: User Name <user@hostname>
1259 1259 author--debug: person
1260 1260 author--debug: person
1261 1261 author--debug: person
1262 1262 author--debug: person
1263 1263 author--debug: other@place
1264 1264 author--debug: A. N. Other <other@place>
1265 1265 author--debug: User Name <user@hostname>
1266 1266 branch: default
1267 1267 branch: default
1268 1268 branch: default
1269 1269 branch: default
1270 1270 branch: foo
1271 1271 branch: default
1272 1272 branch: default
1273 1273 branch: default
1274 1274 branch: default
1275 1275 branch--verbose: default
1276 1276 branch--verbose: default
1277 1277 branch--verbose: default
1278 1278 branch--verbose: default
1279 1279 branch--verbose: foo
1280 1280 branch--verbose: default
1281 1281 branch--verbose: default
1282 1282 branch--verbose: default
1283 1283 branch--verbose: default
1284 1284 branch--debug: default
1285 1285 branch--debug: default
1286 1286 branch--debug: default
1287 1287 branch--debug: default
1288 1288 branch--debug: foo
1289 1289 branch--debug: default
1290 1290 branch--debug: default
1291 1291 branch--debug: default
1292 1292 branch--debug: default
1293 1293 branches:
1294 1294 branches:
1295 1295 branches:
1296 1296 branches:
1297 1297 branches: foo
1298 1298 branches:
1299 1299 branches:
1300 1300 branches:
1301 1301 branches:
1302 1302 branches--verbose:
1303 1303 branches--verbose:
1304 1304 branches--verbose:
1305 1305 branches--verbose:
1306 1306 branches--verbose: foo
1307 1307 branches--verbose:
1308 1308 branches--verbose:
1309 1309 branches--verbose:
1310 1310 branches--verbose:
1311 1311 branches--debug:
1312 1312 branches--debug:
1313 1313 branches--debug:
1314 1314 branches--debug:
1315 1315 branches--debug: foo
1316 1316 branches--debug:
1317 1317 branches--debug:
1318 1318 branches--debug:
1319 1319 branches--debug:
1320 1320 date: 1577872860.00
1321 1321 date: 1000000.00
1322 1322 date: 1500001.00
1323 1323 date: 1500000.00
1324 1324 date: 1400000.00
1325 1325 date: 1300000.00
1326 1326 date: 1200000.00
1327 1327 date: 1100000.00
1328 1328 date: 1000000.00
1329 1329 date--verbose: 1577872860.00
1330 1330 date--verbose: 1000000.00
1331 1331 date--verbose: 1500001.00
1332 1332 date--verbose: 1500000.00
1333 1333 date--verbose: 1400000.00
1334 1334 date--verbose: 1300000.00
1335 1335 date--verbose: 1200000.00
1336 1336 date--verbose: 1100000.00
1337 1337 date--verbose: 1000000.00
1338 1338 date--debug: 1577872860.00
1339 1339 date--debug: 1000000.00
1340 1340 date--debug: 1500001.00
1341 1341 date--debug: 1500000.00
1342 1342 date--debug: 1400000.00
1343 1343 date--debug: 1300000.00
1344 1344 date--debug: 1200000.00
1345 1345 date--debug: 1100000.00
1346 1346 date--debug: 1000000.00
1347 1347 desc: third
1348 1348 desc: second
1349 1349 desc: merge
1350 1350 desc: new head
1351 1351 desc: new branch
1352 1352 desc: no user, no domain
1353 1353 desc: no person
1354 1354 desc: other 1
1355 1355 other 2
1356 1356
1357 1357 other 3
1358 1358 desc: line 1
1359 1359 line 2
1360 1360 desc--verbose: third
1361 1361 desc--verbose: second
1362 1362 desc--verbose: merge
1363 1363 desc--verbose: new head
1364 1364 desc--verbose: new branch
1365 1365 desc--verbose: no user, no domain
1366 1366 desc--verbose: no person
1367 1367 desc--verbose: other 1
1368 1368 other 2
1369 1369
1370 1370 other 3
1371 1371 desc--verbose: line 1
1372 1372 line 2
1373 1373 desc--debug: third
1374 1374 desc--debug: second
1375 1375 desc--debug: merge
1376 1376 desc--debug: new head
1377 1377 desc--debug: new branch
1378 1378 desc--debug: no user, no domain
1379 1379 desc--debug: no person
1380 1380 desc--debug: other 1
1381 1381 other 2
1382 1382
1383 1383 other 3
1384 1384 desc--debug: line 1
1385 1385 line 2
1386 1386 file_adds: fourth third
1387 1387 file_adds: second
1388 1388 file_adds:
1389 1389 file_adds: d
1390 1390 file_adds:
1391 1391 file_adds:
1392 1392 file_adds: c
1393 1393 file_adds: b
1394 1394 file_adds: a
1395 1395 file_adds--verbose: fourth third
1396 1396 file_adds--verbose: second
1397 1397 file_adds--verbose:
1398 1398 file_adds--verbose: d
1399 1399 file_adds--verbose:
1400 1400 file_adds--verbose:
1401 1401 file_adds--verbose: c
1402 1402 file_adds--verbose: b
1403 1403 file_adds--verbose: a
1404 1404 file_adds--debug: fourth third
1405 1405 file_adds--debug: second
1406 1406 file_adds--debug:
1407 1407 file_adds--debug: d
1408 1408 file_adds--debug:
1409 1409 file_adds--debug:
1410 1410 file_adds--debug: c
1411 1411 file_adds--debug: b
1412 1412 file_adds--debug: a
1413 1413 file_dels: second
1414 1414 file_dels:
1415 1415 file_dels:
1416 1416 file_dels:
1417 1417 file_dels:
1418 1418 file_dels:
1419 1419 file_dels:
1420 1420 file_dels:
1421 1421 file_dels:
1422 1422 file_dels--verbose: second
1423 1423 file_dels--verbose:
1424 1424 file_dels--verbose:
1425 1425 file_dels--verbose:
1426 1426 file_dels--verbose:
1427 1427 file_dels--verbose:
1428 1428 file_dels--verbose:
1429 1429 file_dels--verbose:
1430 1430 file_dels--verbose:
1431 1431 file_dels--debug: second
1432 1432 file_dels--debug:
1433 1433 file_dels--debug:
1434 1434 file_dels--debug:
1435 1435 file_dels--debug:
1436 1436 file_dels--debug:
1437 1437 file_dels--debug:
1438 1438 file_dels--debug:
1439 1439 file_dels--debug:
1440 1440 file_mods:
1441 1441 file_mods:
1442 1442 file_mods:
1443 1443 file_mods:
1444 1444 file_mods:
1445 1445 file_mods: c
1446 1446 file_mods:
1447 1447 file_mods:
1448 1448 file_mods:
1449 1449 file_mods--verbose:
1450 1450 file_mods--verbose:
1451 1451 file_mods--verbose:
1452 1452 file_mods--verbose:
1453 1453 file_mods--verbose:
1454 1454 file_mods--verbose: c
1455 1455 file_mods--verbose:
1456 1456 file_mods--verbose:
1457 1457 file_mods--verbose:
1458 1458 file_mods--debug:
1459 1459 file_mods--debug:
1460 1460 file_mods--debug:
1461 1461 file_mods--debug:
1462 1462 file_mods--debug:
1463 1463 file_mods--debug: c
1464 1464 file_mods--debug:
1465 1465 file_mods--debug:
1466 1466 file_mods--debug:
1467 1467 file_copies: fourth (second)
1468 1468 file_copies:
1469 1469 file_copies:
1470 1470 file_copies:
1471 1471 file_copies:
1472 1472 file_copies:
1473 1473 file_copies:
1474 1474 file_copies:
1475 1475 file_copies:
1476 1476 file_copies--verbose: fourth (second)
1477 1477 file_copies--verbose:
1478 1478 file_copies--verbose:
1479 1479 file_copies--verbose:
1480 1480 file_copies--verbose:
1481 1481 file_copies--verbose:
1482 1482 file_copies--verbose:
1483 1483 file_copies--verbose:
1484 1484 file_copies--verbose:
1485 1485 file_copies--debug: fourth (second)
1486 1486 file_copies--debug:
1487 1487 file_copies--debug:
1488 1488 file_copies--debug:
1489 1489 file_copies--debug:
1490 1490 file_copies--debug:
1491 1491 file_copies--debug:
1492 1492 file_copies--debug:
1493 1493 file_copies--debug:
1494 1494 file_copies_switch:
1495 1495 file_copies_switch:
1496 1496 file_copies_switch:
1497 1497 file_copies_switch:
1498 1498 file_copies_switch:
1499 1499 file_copies_switch:
1500 1500 file_copies_switch:
1501 1501 file_copies_switch:
1502 1502 file_copies_switch:
1503 1503 file_copies_switch--verbose:
1504 1504 file_copies_switch--verbose:
1505 1505 file_copies_switch--verbose:
1506 1506 file_copies_switch--verbose:
1507 1507 file_copies_switch--verbose:
1508 1508 file_copies_switch--verbose:
1509 1509 file_copies_switch--verbose:
1510 1510 file_copies_switch--verbose:
1511 1511 file_copies_switch--verbose:
1512 1512 file_copies_switch--debug:
1513 1513 file_copies_switch--debug:
1514 1514 file_copies_switch--debug:
1515 1515 file_copies_switch--debug:
1516 1516 file_copies_switch--debug:
1517 1517 file_copies_switch--debug:
1518 1518 file_copies_switch--debug:
1519 1519 file_copies_switch--debug:
1520 1520 file_copies_switch--debug:
1521 1521 files: fourth second third
1522 1522 files: second
1523 1523 files:
1524 1524 files: d
1525 1525 files:
1526 1526 files: c
1527 1527 files: c
1528 1528 files: b
1529 1529 files: a
1530 1530 files--verbose: fourth second third
1531 1531 files--verbose: second
1532 1532 files--verbose:
1533 1533 files--verbose: d
1534 1534 files--verbose:
1535 1535 files--verbose: c
1536 1536 files--verbose: c
1537 1537 files--verbose: b
1538 1538 files--verbose: a
1539 1539 files--debug: fourth second third
1540 1540 files--debug: second
1541 1541 files--debug:
1542 1542 files--debug: d
1543 1543 files--debug:
1544 1544 files--debug: c
1545 1545 files--debug: c
1546 1546 files--debug: b
1547 1547 files--debug: a
1548 1548 manifest: 6:94961b75a2da
1549 1549 manifest: 5:f2dbc354b94e
1550 1550 manifest: 4:4dc3def4f9b4
1551 1551 manifest: 4:4dc3def4f9b4
1552 1552 manifest: 3:cb5a1327723b
1553 1553 manifest: 3:cb5a1327723b
1554 1554 manifest: 2:6e0e82995c35
1555 1555 manifest: 1:4e8d705b1e53
1556 1556 manifest: 0:a0c8bcbbb45c
1557 1557 manifest--verbose: 6:94961b75a2da
1558 1558 manifest--verbose: 5:f2dbc354b94e
1559 1559 manifest--verbose: 4:4dc3def4f9b4
1560 1560 manifest--verbose: 4:4dc3def4f9b4
1561 1561 manifest--verbose: 3:cb5a1327723b
1562 1562 manifest--verbose: 3:cb5a1327723b
1563 1563 manifest--verbose: 2:6e0e82995c35
1564 1564 manifest--verbose: 1:4e8d705b1e53
1565 1565 manifest--verbose: 0:a0c8bcbbb45c
1566 1566 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1567 1567 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1568 1568 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1569 1569 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1570 1570 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1571 1571 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1572 1572 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1573 1573 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1574 1574 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1575 1575 node: 95c24699272ef57d062b8bccc32c878bf841784a
1576 1576 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1577 1577 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1578 1578 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1579 1579 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1580 1580 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1581 1581 node: 97054abb4ab824450e9164180baf491ae0078465
1582 1582 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1583 1583 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1584 1584 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1585 1585 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1586 1586 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1587 1587 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1588 1588 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1589 1589 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1590 1590 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1591 1591 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1592 1592 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1593 1593 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1594 1594 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1595 1595 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1596 1596 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1597 1597 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1598 1598 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1599 1599 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1600 1600 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1601 1601 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1602 1602 parents:
1603 1603 parents: -1:000000000000
1604 1604 parents: 5:13207e5a10d9 4:bbe44766e73d
1605 1605 parents: 3:10e46f2dcbf4
1606 1606 parents:
1607 1607 parents:
1608 1608 parents:
1609 1609 parents:
1610 1610 parents:
1611 1611 parents--verbose:
1612 1612 parents--verbose: -1:000000000000
1613 1613 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1614 1614 parents--verbose: 3:10e46f2dcbf4
1615 1615 parents--verbose:
1616 1616 parents--verbose:
1617 1617 parents--verbose:
1618 1618 parents--verbose:
1619 1619 parents--verbose:
1620 1620 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1621 1621 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1622 1622 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1623 1623 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1624 1624 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1625 1625 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1626 1626 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1627 1627 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1628 1628 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1629 1629 rev: 8
1630 1630 rev: 7
1631 1631 rev: 6
1632 1632 rev: 5
1633 1633 rev: 4
1634 1634 rev: 3
1635 1635 rev: 2
1636 1636 rev: 1
1637 1637 rev: 0
1638 1638 rev--verbose: 8
1639 1639 rev--verbose: 7
1640 1640 rev--verbose: 6
1641 1641 rev--verbose: 5
1642 1642 rev--verbose: 4
1643 1643 rev--verbose: 3
1644 1644 rev--verbose: 2
1645 1645 rev--verbose: 1
1646 1646 rev--verbose: 0
1647 1647 rev--debug: 8
1648 1648 rev--debug: 7
1649 1649 rev--debug: 6
1650 1650 rev--debug: 5
1651 1651 rev--debug: 4
1652 1652 rev--debug: 3
1653 1653 rev--debug: 2
1654 1654 rev--debug: 1
1655 1655 rev--debug: 0
1656 1656 tags: tip
1657 1657 tags:
1658 1658 tags:
1659 1659 tags:
1660 1660 tags:
1661 1661 tags:
1662 1662 tags:
1663 1663 tags:
1664 1664 tags:
1665 1665 tags--verbose: tip
1666 1666 tags--verbose:
1667 1667 tags--verbose:
1668 1668 tags--verbose:
1669 1669 tags--verbose:
1670 1670 tags--verbose:
1671 1671 tags--verbose:
1672 1672 tags--verbose:
1673 1673 tags--verbose:
1674 1674 tags--debug: tip
1675 1675 tags--debug:
1676 1676 tags--debug:
1677 1677 tags--debug:
1678 1678 tags--debug:
1679 1679 tags--debug:
1680 1680 tags--debug:
1681 1681 tags--debug:
1682 1682 tags--debug:
1683 1683 diffstat: 3: +2/-1
1684 1684 diffstat: 1: +1/-0
1685 1685 diffstat: 0: +0/-0
1686 1686 diffstat: 1: +1/-0
1687 1687 diffstat: 0: +0/-0
1688 1688 diffstat: 1: +1/-0
1689 1689 diffstat: 1: +4/-0
1690 1690 diffstat: 1: +2/-0
1691 1691 diffstat: 1: +1/-0
1692 1692 diffstat--verbose: 3: +2/-1
1693 1693 diffstat--verbose: 1: +1/-0
1694 1694 diffstat--verbose: 0: +0/-0
1695 1695 diffstat--verbose: 1: +1/-0
1696 1696 diffstat--verbose: 0: +0/-0
1697 1697 diffstat--verbose: 1: +1/-0
1698 1698 diffstat--verbose: 1: +4/-0
1699 1699 diffstat--verbose: 1: +2/-0
1700 1700 diffstat--verbose: 1: +1/-0
1701 1701 diffstat--debug: 3: +2/-1
1702 1702 diffstat--debug: 1: +1/-0
1703 1703 diffstat--debug: 0: +0/-0
1704 1704 diffstat--debug: 1: +1/-0
1705 1705 diffstat--debug: 0: +0/-0
1706 1706 diffstat--debug: 1: +1/-0
1707 1707 diffstat--debug: 1: +4/-0
1708 1708 diffstat--debug: 1: +2/-0
1709 1709 diffstat--debug: 1: +1/-0
1710 1710 extras: branch=default
1711 1711 extras: branch=default
1712 1712 extras: branch=default
1713 1713 extras: branch=default
1714 1714 extras: branch=foo
1715 1715 extras: branch=default
1716 1716 extras: branch=default
1717 1717 extras: branch=default
1718 1718 extras: branch=default
1719 1719 extras--verbose: branch=default
1720 1720 extras--verbose: branch=default
1721 1721 extras--verbose: branch=default
1722 1722 extras--verbose: branch=default
1723 1723 extras--verbose: branch=foo
1724 1724 extras--verbose: branch=default
1725 1725 extras--verbose: branch=default
1726 1726 extras--verbose: branch=default
1727 1727 extras--verbose: branch=default
1728 1728 extras--debug: branch=default
1729 1729 extras--debug: branch=default
1730 1730 extras--debug: branch=default
1731 1731 extras--debug: branch=default
1732 1732 extras--debug: branch=foo
1733 1733 extras--debug: branch=default
1734 1734 extras--debug: branch=default
1735 1735 extras--debug: branch=default
1736 1736 extras--debug: branch=default
1737 1737 p1rev: 7
1738 1738 p1rev: -1
1739 1739 p1rev: 5
1740 1740 p1rev: 3
1741 1741 p1rev: 3
1742 1742 p1rev: 2
1743 1743 p1rev: 1
1744 1744 p1rev: 0
1745 1745 p1rev: -1
1746 1746 p1rev--verbose: 7
1747 1747 p1rev--verbose: -1
1748 1748 p1rev--verbose: 5
1749 1749 p1rev--verbose: 3
1750 1750 p1rev--verbose: 3
1751 1751 p1rev--verbose: 2
1752 1752 p1rev--verbose: 1
1753 1753 p1rev--verbose: 0
1754 1754 p1rev--verbose: -1
1755 1755 p1rev--debug: 7
1756 1756 p1rev--debug: -1
1757 1757 p1rev--debug: 5
1758 1758 p1rev--debug: 3
1759 1759 p1rev--debug: 3
1760 1760 p1rev--debug: 2
1761 1761 p1rev--debug: 1
1762 1762 p1rev--debug: 0
1763 1763 p1rev--debug: -1
1764 1764 p2rev: -1
1765 1765 p2rev: -1
1766 1766 p2rev: 4
1767 1767 p2rev: -1
1768 1768 p2rev: -1
1769 1769 p2rev: -1
1770 1770 p2rev: -1
1771 1771 p2rev: -1
1772 1772 p2rev: -1
1773 1773 p2rev--verbose: -1
1774 1774 p2rev--verbose: -1
1775 1775 p2rev--verbose: 4
1776 1776 p2rev--verbose: -1
1777 1777 p2rev--verbose: -1
1778 1778 p2rev--verbose: -1
1779 1779 p2rev--verbose: -1
1780 1780 p2rev--verbose: -1
1781 1781 p2rev--verbose: -1
1782 1782 p2rev--debug: -1
1783 1783 p2rev--debug: -1
1784 1784 p2rev--debug: 4
1785 1785 p2rev--debug: -1
1786 1786 p2rev--debug: -1
1787 1787 p2rev--debug: -1
1788 1788 p2rev--debug: -1
1789 1789 p2rev--debug: -1
1790 1790 p2rev--debug: -1
1791 1791 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1792 1792 p1node: 0000000000000000000000000000000000000000
1793 1793 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1794 1794 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1795 1795 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1796 1796 p1node: 97054abb4ab824450e9164180baf491ae0078465
1797 1797 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1798 1798 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1799 1799 p1node: 0000000000000000000000000000000000000000
1800 1800 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1801 1801 p1node--verbose: 0000000000000000000000000000000000000000
1802 1802 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1803 1803 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1804 1804 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1805 1805 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1806 1806 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1807 1807 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1808 1808 p1node--verbose: 0000000000000000000000000000000000000000
1809 1809 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1810 1810 p1node--debug: 0000000000000000000000000000000000000000
1811 1811 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1812 1812 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1813 1813 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1814 1814 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1815 1815 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1816 1816 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1817 1817 p1node--debug: 0000000000000000000000000000000000000000
1818 1818 p2node: 0000000000000000000000000000000000000000
1819 1819 p2node: 0000000000000000000000000000000000000000
1820 1820 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1821 1821 p2node: 0000000000000000000000000000000000000000
1822 1822 p2node: 0000000000000000000000000000000000000000
1823 1823 p2node: 0000000000000000000000000000000000000000
1824 1824 p2node: 0000000000000000000000000000000000000000
1825 1825 p2node: 0000000000000000000000000000000000000000
1826 1826 p2node: 0000000000000000000000000000000000000000
1827 1827 p2node--verbose: 0000000000000000000000000000000000000000
1828 1828 p2node--verbose: 0000000000000000000000000000000000000000
1829 1829 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1830 1830 p2node--verbose: 0000000000000000000000000000000000000000
1831 1831 p2node--verbose: 0000000000000000000000000000000000000000
1832 1832 p2node--verbose: 0000000000000000000000000000000000000000
1833 1833 p2node--verbose: 0000000000000000000000000000000000000000
1834 1834 p2node--verbose: 0000000000000000000000000000000000000000
1835 1835 p2node--verbose: 0000000000000000000000000000000000000000
1836 1836 p2node--debug: 0000000000000000000000000000000000000000
1837 1837 p2node--debug: 0000000000000000000000000000000000000000
1838 1838 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1839 1839 p2node--debug: 0000000000000000000000000000000000000000
1840 1840 p2node--debug: 0000000000000000000000000000000000000000
1841 1841 p2node--debug: 0000000000000000000000000000000000000000
1842 1842 p2node--debug: 0000000000000000000000000000000000000000
1843 1843 p2node--debug: 0000000000000000000000000000000000000000
1844 1844 p2node--debug: 0000000000000000000000000000000000000000
1845 1845
1846 1846 Filters work:
1847 1847
1848 1848 $ hg log --template '{author|domain}\n'
1849 1849
1850 1850 hostname
1851 1851
1852 1852
1853 1853
1854 1854
1855 1855 place
1856 1856 place
1857 1857 hostname
1858 1858
1859 1859 $ hg log --template '{author|person}\n'
1860 1860 test
1861 1861 User Name
1862 1862 person
1863 1863 person
1864 1864 person
1865 1865 person
1866 1866 other
1867 1867 A. N. Other
1868 1868 User Name
1869 1869
1870 1870 $ hg log --template '{author|user}\n'
1871 1871 test
1872 1872 user
1873 1873 person
1874 1874 person
1875 1875 person
1876 1876 person
1877 1877 other
1878 1878 other
1879 1879 user
1880 1880
1881 1881 $ hg log --template '{date|date}\n'
1882 1882 Wed Jan 01 10:01:00 2020 +0000
1883 1883 Mon Jan 12 13:46:40 1970 +0000
1884 1884 Sun Jan 18 08:40:01 1970 +0000
1885 1885 Sun Jan 18 08:40:00 1970 +0000
1886 1886 Sat Jan 17 04:53:20 1970 +0000
1887 1887 Fri Jan 16 01:06:40 1970 +0000
1888 1888 Wed Jan 14 21:20:00 1970 +0000
1889 1889 Tue Jan 13 17:33:20 1970 +0000
1890 1890 Mon Jan 12 13:46:40 1970 +0000
1891 1891
1892 1892 $ hg log --template '{date|isodate}\n'
1893 1893 2020-01-01 10:01 +0000
1894 1894 1970-01-12 13:46 +0000
1895 1895 1970-01-18 08:40 +0000
1896 1896 1970-01-18 08:40 +0000
1897 1897 1970-01-17 04:53 +0000
1898 1898 1970-01-16 01:06 +0000
1899 1899 1970-01-14 21:20 +0000
1900 1900 1970-01-13 17:33 +0000
1901 1901 1970-01-12 13:46 +0000
1902 1902
1903 1903 $ hg log --template '{date|isodatesec}\n'
1904 1904 2020-01-01 10:01:00 +0000
1905 1905 1970-01-12 13:46:40 +0000
1906 1906 1970-01-18 08:40:01 +0000
1907 1907 1970-01-18 08:40:00 +0000
1908 1908 1970-01-17 04:53:20 +0000
1909 1909 1970-01-16 01:06:40 +0000
1910 1910 1970-01-14 21:20:00 +0000
1911 1911 1970-01-13 17:33:20 +0000
1912 1912 1970-01-12 13:46:40 +0000
1913 1913
1914 1914 $ hg log --template '{date|rfc822date}\n'
1915 1915 Wed, 01 Jan 2020 10:01:00 +0000
1916 1916 Mon, 12 Jan 1970 13:46:40 +0000
1917 1917 Sun, 18 Jan 1970 08:40:01 +0000
1918 1918 Sun, 18 Jan 1970 08:40:00 +0000
1919 1919 Sat, 17 Jan 1970 04:53:20 +0000
1920 1920 Fri, 16 Jan 1970 01:06:40 +0000
1921 1921 Wed, 14 Jan 1970 21:20:00 +0000
1922 1922 Tue, 13 Jan 1970 17:33:20 +0000
1923 1923 Mon, 12 Jan 1970 13:46:40 +0000
1924 1924
1925 1925 $ hg log --template '{desc|firstline}\n'
1926 1926 third
1927 1927 second
1928 1928 merge
1929 1929 new head
1930 1930 new branch
1931 1931 no user, no domain
1932 1932 no person
1933 1933 other 1
1934 1934 line 1
1935 1935
1936 1936 $ hg log --template '{node|short}\n'
1937 1937 95c24699272e
1938 1938 29114dbae42b
1939 1939 d41e714fe50d
1940 1940 13207e5a10d9
1941 1941 bbe44766e73d
1942 1942 10e46f2dcbf4
1943 1943 97054abb4ab8
1944 1944 b608e9d1a3f0
1945 1945 1e4e1b8f71e0
1946 1946
1947 1947 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1948 1948 <changeset author="test"/>
1949 1949 <changeset author="User Name &lt;user@hostname&gt;"/>
1950 1950 <changeset author="person"/>
1951 1951 <changeset author="person"/>
1952 1952 <changeset author="person"/>
1953 1953 <changeset author="person"/>
1954 1954 <changeset author="other@place"/>
1955 1955 <changeset author="A. N. Other &lt;other@place&gt;"/>
1956 1956 <changeset author="User Name &lt;user@hostname&gt;"/>
1957 1957
1958 1958 $ hg log --template '{rev}: {children}\n'
1959 1959 8:
1960 1960 7: 8:95c24699272e
1961 1961 6:
1962 1962 5: 6:d41e714fe50d
1963 1963 4: 6:d41e714fe50d
1964 1964 3: 4:bbe44766e73d 5:13207e5a10d9
1965 1965 2: 3:10e46f2dcbf4
1966 1966 1: 2:97054abb4ab8
1967 1967 0: 1:b608e9d1a3f0
1968 1968
1969 1969 Formatnode filter works:
1970 1970
1971 1971 $ hg -q log -r 0 --template '{node|formatnode}\n'
1972 1972 1e4e1b8f71e0
1973 1973
1974 1974 $ hg log -r 0 --template '{node|formatnode}\n'
1975 1975 1e4e1b8f71e0
1976 1976
1977 1977 $ hg -v log -r 0 --template '{node|formatnode}\n'
1978 1978 1e4e1b8f71e0
1979 1979
1980 1980 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1981 1981 1e4e1b8f71e05681d422154f5421e385fec3454f
1982 1982
1983 1983 Age filter:
1984 1984
1985 1985 $ hg init unstable-hash
1986 1986 $ cd unstable-hash
1987 1987 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1988 1988
1989 1989 >>> from datetime import datetime, timedelta
1990 1990 >>> fp = open('a', 'w')
1991 1991 >>> n = datetime.now() + timedelta(366 * 7)
1992 1992 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1993 1993 >>> fp.close()
1994 1994 $ hg add a
1995 1995 $ hg commit -m future -d "`cat a`"
1996 1996
1997 1997 $ hg log -l1 --template '{date|age}\n'
1998 1998 7 years from now
1999 1999
2000 2000 $ cd ..
2001 2001 $ rm -rf unstable-hash
2002 2002
2003 2003 Add a dummy commit to make up for the instability of the above:
2004 2004
2005 2005 $ echo a > a
2006 2006 $ hg add a
2007 2007 $ hg ci -m future
2008 2008
2009 2009 Count filter:
2010 2010
2011 2011 $ hg log -l1 --template '{node|count} {node|short|count}\n'
2012 2012 40 12
2013 2013
2014 2014 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
2015 2015 0 1 4
2016 2016
2017 2017 $ hg log -G --template '{rev}: children: {children|count}, \
2018 2018 > tags: {tags|count}, file_adds: {file_adds|count}, \
2019 2019 > ancestors: {revset("ancestors(%s)", rev)|count}'
2020 2020 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
2021 2021 |
2022 2022 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
2023 2023 |
2024 2024 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
2025 2025
2026 2026 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
2027 2027 |\
2028 2028 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
2029 2029 | |
2030 2030 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
2031 2031 |/
2032 2032 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
2033 2033 |
2034 2034 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
2035 2035 |
2036 2036 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
2037 2037 |
2038 2038 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
2039 2039
2040 2040
2041 2041 Upper/lower filters:
2042 2042
2043 2043 $ hg log -r0 --template '{branch|upper}\n'
2044 2044 DEFAULT
2045 2045 $ hg log -r0 --template '{author|lower}\n'
2046 2046 user name <user@hostname>
2047 2047 $ hg log -r0 --template '{date|upper}\n'
2048 2048 abort: template filter 'upper' is not compatible with keyword 'date'
2049 2049 [255]
2050 2050
2051 2051 Add a commit that does all possible modifications at once
2052 2052
2053 2053 $ echo modify >> third
2054 2054 $ touch b
2055 2055 $ hg add b
2056 2056 $ hg mv fourth fifth
2057 2057 $ hg rm a
2058 2058 $ hg ci -m "Modify, add, remove, rename"
2059 2059
2060 2060 Check the status template
2061 2061
2062 2062 $ cat <<EOF >> $HGRCPATH
2063 2063 > [extensions]
2064 2064 > color=
2065 2065 > EOF
2066 2066
2067 2067 $ hg log -T status -r 10
2068 2068 changeset: 10:0f9759ec227a
2069 2069 tag: tip
2070 2070 user: test
2071 2071 date: Thu Jan 01 00:00:00 1970 +0000
2072 2072 summary: Modify, add, remove, rename
2073 2073 files:
2074 2074 M third
2075 2075 A b
2076 2076 A fifth
2077 2077 R a
2078 2078 R fourth
2079 2079
2080 2080 $ hg log -T status -C -r 10
2081 2081 changeset: 10:0f9759ec227a
2082 2082 tag: tip
2083 2083 user: test
2084 2084 date: Thu Jan 01 00:00:00 1970 +0000
2085 2085 summary: Modify, add, remove, rename
2086 2086 files:
2087 2087 M third
2088 2088 A b
2089 2089 A fifth
2090 2090 fourth
2091 2091 R a
2092 2092 R fourth
2093 2093
2094 2094 $ hg log -T status -C -r 10 -v
2095 2095 changeset: 10:0f9759ec227a
2096 2096 tag: tip
2097 2097 user: test
2098 2098 date: Thu Jan 01 00:00:00 1970 +0000
2099 2099 description:
2100 2100 Modify, add, remove, rename
2101 2101
2102 2102 files:
2103 2103 M third
2104 2104 A b
2105 2105 A fifth
2106 2106 fourth
2107 2107 R a
2108 2108 R fourth
2109 2109
2110 2110 $ hg log -T status -C -r 10 --debug
2111 2111 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2112 2112 tag: tip
2113 2113 phase: secret
2114 2114 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2115 2115 parent: -1:0000000000000000000000000000000000000000
2116 2116 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2117 2117 user: test
2118 2118 date: Thu Jan 01 00:00:00 1970 +0000
2119 2119 extra: branch=default
2120 2120 description:
2121 2121 Modify, add, remove, rename
2122 2122
2123 2123 files:
2124 2124 M third
2125 2125 A b
2126 2126 A fifth
2127 2127 fourth
2128 2128 R a
2129 2129 R fourth
2130 2130
2131 2131 $ hg log -T status -C -r 10 --quiet
2132 2132 10:0f9759ec227a
2133 2133 $ hg --color=debug log -T status -r 10
2134 2134 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2135 2135 [log.tag|tag: tip]
2136 2136 [log.user|user: test]
2137 2137 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2138 2138 [log.summary|summary: Modify, add, remove, rename]
2139 2139 [ui.note log.files|files:]
2140 2140 [status.modified|M third]
2141 2141 [status.added|A b]
2142 2142 [status.added|A fifth]
2143 2143 [status.removed|R a]
2144 2144 [status.removed|R fourth]
2145 2145
2146 2146 $ hg --color=debug log -T status -C -r 10
2147 2147 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2148 2148 [log.tag|tag: tip]
2149 2149 [log.user|user: test]
2150 2150 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2151 2151 [log.summary|summary: Modify, add, remove, rename]
2152 2152 [ui.note log.files|files:]
2153 2153 [status.modified|M third]
2154 2154 [status.added|A b]
2155 2155 [status.added|A fifth]
2156 2156 [status.copied| fourth]
2157 2157 [status.removed|R a]
2158 2158 [status.removed|R fourth]
2159 2159
2160 2160 $ hg --color=debug log -T status -C -r 10 -v
2161 2161 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2162 2162 [log.tag|tag: tip]
2163 2163 [log.user|user: test]
2164 2164 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2165 2165 [ui.note log.description|description:]
2166 2166 [ui.note log.description|Modify, add, remove, rename]
2167 2167
2168 2168 [ui.note log.files|files:]
2169 2169 [status.modified|M third]
2170 2170 [status.added|A b]
2171 2171 [status.added|A fifth]
2172 2172 [status.copied| fourth]
2173 2173 [status.removed|R a]
2174 2174 [status.removed|R fourth]
2175 2175
2176 2176 $ hg --color=debug log -T status -C -r 10 --debug
2177 2177 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2178 2178 [log.tag|tag: tip]
2179 2179 [log.phase|phase: secret]
2180 2180 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2181 2181 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2182 2182 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2183 2183 [log.user|user: test]
2184 2184 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2185 2185 [ui.debug log.extra|extra: branch=default]
2186 2186 [ui.note log.description|description:]
2187 2187 [ui.note log.description|Modify, add, remove, rename]
2188 2188
2189 2189 [ui.note log.files|files:]
2190 2190 [status.modified|M third]
2191 2191 [status.added|A b]
2192 2192 [status.added|A fifth]
2193 2193 [status.copied| fourth]
2194 2194 [status.removed|R a]
2195 2195 [status.removed|R fourth]
2196 2196
2197 2197 $ hg --color=debug log -T status -C -r 10 --quiet
2198 2198 [log.node|10:0f9759ec227a]
2199 2199
2200 2200 Check the bisect template
2201 2201
2202 2202 $ hg bisect -g 1
2203 2203 $ hg bisect -b 3 --noupdate
2204 2204 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2205 2205 $ hg log -T bisect -r 0:4
2206 2206 changeset: 0:1e4e1b8f71e0
2207 2207 bisect: good (implicit)
2208 2208 user: User Name <user@hostname>
2209 2209 date: Mon Jan 12 13:46:40 1970 +0000
2210 2210 summary: line 1
2211 2211
2212 2212 changeset: 1:b608e9d1a3f0
2213 2213 bisect: good
2214 2214 user: A. N. Other <other@place>
2215 2215 date: Tue Jan 13 17:33:20 1970 +0000
2216 2216 summary: other 1
2217 2217
2218 2218 changeset: 2:97054abb4ab8
2219 2219 bisect: untested
2220 2220 user: other@place
2221 2221 date: Wed Jan 14 21:20:00 1970 +0000
2222 2222 summary: no person
2223 2223
2224 2224 changeset: 3:10e46f2dcbf4
2225 2225 bisect: bad
2226 2226 user: person
2227 2227 date: Fri Jan 16 01:06:40 1970 +0000
2228 2228 summary: no user, no domain
2229 2229
2230 2230 changeset: 4:bbe44766e73d
2231 2231 bisect: bad (implicit)
2232 2232 branch: foo
2233 2233 user: person
2234 2234 date: Sat Jan 17 04:53:20 1970 +0000
2235 2235 summary: new branch
2236 2236
2237 2237 $ hg log --debug -T bisect -r 0:4
2238 2238 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2239 2239 bisect: good (implicit)
2240 2240 phase: public
2241 2241 parent: -1:0000000000000000000000000000000000000000
2242 2242 parent: -1:0000000000000000000000000000000000000000
2243 2243 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2244 2244 user: User Name <user@hostname>
2245 2245 date: Mon Jan 12 13:46:40 1970 +0000
2246 2246 files+: a
2247 2247 extra: branch=default
2248 2248 description:
2249 2249 line 1
2250 2250 line 2
2251 2251
2252 2252
2253 2253 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2254 2254 bisect: good
2255 2255 phase: public
2256 2256 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2257 2257 parent: -1:0000000000000000000000000000000000000000
2258 2258 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2259 2259 user: A. N. Other <other@place>
2260 2260 date: Tue Jan 13 17:33:20 1970 +0000
2261 2261 files+: b
2262 2262 extra: branch=default
2263 2263 description:
2264 2264 other 1
2265 2265 other 2
2266 2266
2267 2267 other 3
2268 2268
2269 2269
2270 2270 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2271 2271 bisect: untested
2272 2272 phase: public
2273 2273 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2274 2274 parent: -1:0000000000000000000000000000000000000000
2275 2275 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2276 2276 user: other@place
2277 2277 date: Wed Jan 14 21:20:00 1970 +0000
2278 2278 files+: c
2279 2279 extra: branch=default
2280 2280 description:
2281 2281 no person
2282 2282
2283 2283
2284 2284 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2285 2285 bisect: bad
2286 2286 phase: public
2287 2287 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2288 2288 parent: -1:0000000000000000000000000000000000000000
2289 2289 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2290 2290 user: person
2291 2291 date: Fri Jan 16 01:06:40 1970 +0000
2292 2292 files: c
2293 2293 extra: branch=default
2294 2294 description:
2295 2295 no user, no domain
2296 2296
2297 2297
2298 2298 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2299 2299 bisect: bad (implicit)
2300 2300 branch: foo
2301 2301 phase: draft
2302 2302 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2303 2303 parent: -1:0000000000000000000000000000000000000000
2304 2304 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2305 2305 user: person
2306 2306 date: Sat Jan 17 04:53:20 1970 +0000
2307 2307 extra: branch=foo
2308 2308 description:
2309 2309 new branch
2310 2310
2311 2311
2312 2312 $ hg log -v -T bisect -r 0:4
2313 2313 changeset: 0:1e4e1b8f71e0
2314 2314 bisect: good (implicit)
2315 2315 user: User Name <user@hostname>
2316 2316 date: Mon Jan 12 13:46:40 1970 +0000
2317 2317 files: a
2318 2318 description:
2319 2319 line 1
2320 2320 line 2
2321 2321
2322 2322
2323 2323 changeset: 1:b608e9d1a3f0
2324 2324 bisect: good
2325 2325 user: A. N. Other <other@place>
2326 2326 date: Tue Jan 13 17:33:20 1970 +0000
2327 2327 files: b
2328 2328 description:
2329 2329 other 1
2330 2330 other 2
2331 2331
2332 2332 other 3
2333 2333
2334 2334
2335 2335 changeset: 2:97054abb4ab8
2336 2336 bisect: untested
2337 2337 user: other@place
2338 2338 date: Wed Jan 14 21:20:00 1970 +0000
2339 2339 files: c
2340 2340 description:
2341 2341 no person
2342 2342
2343 2343
2344 2344 changeset: 3:10e46f2dcbf4
2345 2345 bisect: bad
2346 2346 user: person
2347 2347 date: Fri Jan 16 01:06:40 1970 +0000
2348 2348 files: c
2349 2349 description:
2350 2350 no user, no domain
2351 2351
2352 2352
2353 2353 changeset: 4:bbe44766e73d
2354 2354 bisect: bad (implicit)
2355 2355 branch: foo
2356 2356 user: person
2357 2357 date: Sat Jan 17 04:53:20 1970 +0000
2358 2358 description:
2359 2359 new branch
2360 2360
2361 2361
2362 2362 $ hg --color=debug log -T bisect -r 0:4
2363 2363 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2364 2364 [log.bisect bisect.good|bisect: good (implicit)]
2365 2365 [log.user|user: User Name <user@hostname>]
2366 2366 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2367 2367 [log.summary|summary: line 1]
2368 2368
2369 2369 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2370 2370 [log.bisect bisect.good|bisect: good]
2371 2371 [log.user|user: A. N. Other <other@place>]
2372 2372 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2373 2373 [log.summary|summary: other 1]
2374 2374
2375 2375 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2376 2376 [log.bisect bisect.untested|bisect: untested]
2377 2377 [log.user|user: other@place]
2378 2378 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2379 2379 [log.summary|summary: no person]
2380 2380
2381 2381 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2382 2382 [log.bisect bisect.bad|bisect: bad]
2383 2383 [log.user|user: person]
2384 2384 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2385 2385 [log.summary|summary: no user, no domain]
2386 2386
2387 2387 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2388 2388 [log.bisect bisect.bad|bisect: bad (implicit)]
2389 2389 [log.branch|branch: foo]
2390 2390 [log.user|user: person]
2391 2391 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2392 2392 [log.summary|summary: new branch]
2393 2393
2394 2394 $ hg --color=debug log --debug -T bisect -r 0:4
2395 2395 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2396 2396 [log.bisect bisect.good|bisect: good (implicit)]
2397 2397 [log.phase|phase: public]
2398 2398 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2399 2399 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2400 2400 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2401 2401 [log.user|user: User Name <user@hostname>]
2402 2402 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2403 2403 [ui.debug log.files|files+: a]
2404 2404 [ui.debug log.extra|extra: branch=default]
2405 2405 [ui.note log.description|description:]
2406 2406 [ui.note log.description|line 1
2407 2407 line 2]
2408 2408
2409 2409
2410 2410 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2411 2411 [log.bisect bisect.good|bisect: good]
2412 2412 [log.phase|phase: public]
2413 2413 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2414 2414 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2415 2415 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2416 2416 [log.user|user: A. N. Other <other@place>]
2417 2417 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2418 2418 [ui.debug log.files|files+: b]
2419 2419 [ui.debug log.extra|extra: branch=default]
2420 2420 [ui.note log.description|description:]
2421 2421 [ui.note log.description|other 1
2422 2422 other 2
2423 2423
2424 2424 other 3]
2425 2425
2426 2426
2427 2427 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2428 2428 [log.bisect bisect.untested|bisect: untested]
2429 2429 [log.phase|phase: public]
2430 2430 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2431 2431 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2432 2432 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2433 2433 [log.user|user: other@place]
2434 2434 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2435 2435 [ui.debug log.files|files+: c]
2436 2436 [ui.debug log.extra|extra: branch=default]
2437 2437 [ui.note log.description|description:]
2438 2438 [ui.note log.description|no person]
2439 2439
2440 2440
2441 2441 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2442 2442 [log.bisect bisect.bad|bisect: bad]
2443 2443 [log.phase|phase: public]
2444 2444 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2445 2445 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2446 2446 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2447 2447 [log.user|user: person]
2448 2448 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2449 2449 [ui.debug log.files|files: c]
2450 2450 [ui.debug log.extra|extra: branch=default]
2451 2451 [ui.note log.description|description:]
2452 2452 [ui.note log.description|no user, no domain]
2453 2453
2454 2454
2455 2455 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2456 2456 [log.bisect bisect.bad|bisect: bad (implicit)]
2457 2457 [log.branch|branch: foo]
2458 2458 [log.phase|phase: draft]
2459 2459 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2460 2460 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2461 2461 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2462 2462 [log.user|user: person]
2463 2463 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2464 2464 [ui.debug log.extra|extra: branch=foo]
2465 2465 [ui.note log.description|description:]
2466 2466 [ui.note log.description|new branch]
2467 2467
2468 2468
2469 2469 $ hg --color=debug log -v -T bisect -r 0:4
2470 2470 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2471 2471 [log.bisect bisect.good|bisect: good (implicit)]
2472 2472 [log.user|user: User Name <user@hostname>]
2473 2473 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2474 2474 [ui.note log.files|files: a]
2475 2475 [ui.note log.description|description:]
2476 2476 [ui.note log.description|line 1
2477 2477 line 2]
2478 2478
2479 2479
2480 2480 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2481 2481 [log.bisect bisect.good|bisect: good]
2482 2482 [log.user|user: A. N. Other <other@place>]
2483 2483 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2484 2484 [ui.note log.files|files: b]
2485 2485 [ui.note log.description|description:]
2486 2486 [ui.note log.description|other 1
2487 2487 other 2
2488 2488
2489 2489 other 3]
2490 2490
2491 2491
2492 2492 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2493 2493 [log.bisect bisect.untested|bisect: untested]
2494 2494 [log.user|user: other@place]
2495 2495 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2496 2496 [ui.note log.files|files: c]
2497 2497 [ui.note log.description|description:]
2498 2498 [ui.note log.description|no person]
2499 2499
2500 2500
2501 2501 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2502 2502 [log.bisect bisect.bad|bisect: bad]
2503 2503 [log.user|user: person]
2504 2504 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2505 2505 [ui.note log.files|files: c]
2506 2506 [ui.note log.description|description:]
2507 2507 [ui.note log.description|no user, no domain]
2508 2508
2509 2509
2510 2510 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2511 2511 [log.bisect bisect.bad|bisect: bad (implicit)]
2512 2512 [log.branch|branch: foo]
2513 2513 [log.user|user: person]
2514 2514 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2515 2515 [ui.note log.description|description:]
2516 2516 [ui.note log.description|new branch]
2517 2517
2518 2518
2519 2519 $ hg bisect --reset
2520 2520
2521 2521 Error on syntax:
2522 2522
2523 2523 $ echo 'x = "f' >> t
2524 2524 $ hg log
2525 2525 hg: parse error at t:3: unmatched quotes
2526 2526 [255]
2527 2527
2528 2528 $ hg log -T '{date'
2529 2529 hg: parse error at 1: unterminated template expansion
2530 2530 [255]
2531 2531
2532 2532 Behind the scenes, this will throw TypeError
2533 2533
2534 2534 $ hg log -l 3 --template '{date|obfuscate}\n'
2535 2535 abort: template filter 'obfuscate' is not compatible with keyword 'date'
2536 2536 [255]
2537 2537
2538 2538 Behind the scenes, this will throw a ValueError
2539 2539
2540 2540 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2541 2541 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2542 2542 [255]
2543 2543
2544 2544 Behind the scenes, this will throw AttributeError
2545 2545
2546 2546 $ hg log -l 3 --template 'line: {date|escape}\n'
2547 2547 abort: template filter 'escape' is not compatible with keyword 'date'
2548 2548 [255]
2549 2549
2550 2550 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2551 2551 hg: parse error: localdate expects a date information
2552 2552 [255]
2553 2553
2554 2554 Behind the scenes, this will throw ValueError
2555 2555
2556 2556 $ hg tip --template '{author|email|date}\n'
2557 2557 hg: parse error: date expects a date information
2558 2558 [255]
2559 2559
2560 2560 Error in nested template:
2561 2561
2562 2562 $ hg log -T '{"date'
2563 2563 hg: parse error at 2: unterminated string
2564 2564 [255]
2565 2565
2566 2566 $ hg log -T '{"foo{date|=}"}'
2567 2567 hg: parse error at 11: syntax error
2568 2568 [255]
2569 2569
2570 2570 Thrown an error if a template function doesn't exist
2571 2571
2572 2572 $ hg tip --template '{foo()}\n'
2573 2573 hg: parse error: unknown function 'foo'
2574 2574 [255]
2575 2575
2576 2576 Pass generator object created by template function to filter
2577 2577
2578 2578 $ hg log -l 1 --template '{if(author, author)|user}\n'
2579 2579 test
2580 2580
2581 2581 Test diff function:
2582 2582
2583 2583 $ hg diff -c 8
2584 2584 diff -r 29114dbae42b -r 95c24699272e fourth
2585 2585 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2586 2586 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2587 2587 @@ -0,0 +1,1 @@
2588 2588 +second
2589 2589 diff -r 29114dbae42b -r 95c24699272e second
2590 2590 --- a/second Mon Jan 12 13:46:40 1970 +0000
2591 2591 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2592 2592 @@ -1,1 +0,0 @@
2593 2593 -second
2594 2594 diff -r 29114dbae42b -r 95c24699272e third
2595 2595 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2596 2596 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2597 2597 @@ -0,0 +1,1 @@
2598 2598 +third
2599 2599
2600 2600 $ hg log -r 8 -T "{diff()}"
2601 2601 diff -r 29114dbae42b -r 95c24699272e fourth
2602 2602 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2603 2603 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2604 2604 @@ -0,0 +1,1 @@
2605 2605 +second
2606 2606 diff -r 29114dbae42b -r 95c24699272e second
2607 2607 --- a/second Mon Jan 12 13:46:40 1970 +0000
2608 2608 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2609 2609 @@ -1,1 +0,0 @@
2610 2610 -second
2611 2611 diff -r 29114dbae42b -r 95c24699272e third
2612 2612 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2613 2613 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2614 2614 @@ -0,0 +1,1 @@
2615 2615 +third
2616 2616
2617 2617 $ hg log -r 8 -T "{diff('glob:f*')}"
2618 2618 diff -r 29114dbae42b -r 95c24699272e fourth
2619 2619 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2620 2620 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2621 2621 @@ -0,0 +1,1 @@
2622 2622 +second
2623 2623
2624 2624 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2625 2625 diff -r 29114dbae42b -r 95c24699272e second
2626 2626 --- a/second Mon Jan 12 13:46:40 1970 +0000
2627 2627 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2628 2628 @@ -1,1 +0,0 @@
2629 2629 -second
2630 2630 diff -r 29114dbae42b -r 95c24699272e third
2631 2631 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2632 2632 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2633 2633 @@ -0,0 +1,1 @@
2634 2634 +third
2635 2635
2636 2636 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2637 2637 diff -r 29114dbae42b -r 95c24699272e fourth
2638 2638 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2639 2639 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2640 2640 @@ -0,0 +1,1 @@
2641 2641 +second
2642 2642
2643 2643 $ cd ..
2644 2644
2645 2645
2646 2646 latesttag:
2647 2647
2648 2648 $ hg init latesttag
2649 2649 $ cd latesttag
2650 2650
2651 2651 $ echo a > file
2652 2652 $ hg ci -Am a -d '0 0'
2653 2653 adding file
2654 2654
2655 2655 $ echo b >> file
2656 2656 $ hg ci -m b -d '1 0'
2657 2657
2658 2658 $ echo c >> head1
2659 2659 $ hg ci -Am h1c -d '2 0'
2660 2660 adding head1
2661 2661
2662 2662 $ hg update -q 1
2663 2663 $ echo d >> head2
2664 2664 $ hg ci -Am h2d -d '3 0'
2665 2665 adding head2
2666 2666 created new head
2667 2667
2668 2668 $ echo e >> head2
2669 2669 $ hg ci -m h2e -d '4 0'
2670 2670
2671 2671 $ hg merge -q
2672 2672 $ hg ci -m merge -d '5 -3600'
2673 2673
2674 2674 No tag set:
2675 2675
2676 2676 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2677 2677 5: null+5
2678 2678 4: null+4
2679 2679 3: null+3
2680 2680 2: null+3
2681 2681 1: null+2
2682 2682 0: null+1
2683 2683
2684 2684 One common tag: longest path wins:
2685 2685
2686 2686 $ hg tag -r 1 -m t1 -d '6 0' t1
2687 2687 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2688 2688 6: t1+4
2689 2689 5: t1+3
2690 2690 4: t1+2
2691 2691 3: t1+1
2692 2692 2: t1+1
2693 2693 1: t1+0
2694 2694 0: null+1
2695 2695
2696 2696 One ancestor tag: more recent wins:
2697 2697
2698 2698 $ hg tag -r 2 -m t2 -d '7 0' t2
2699 2699 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2700 2700 7: t2+3
2701 2701 6: t2+2
2702 2702 5: t2+1
2703 2703 4: t1+2
2704 2704 3: t1+1
2705 2705 2: t2+0
2706 2706 1: t1+0
2707 2707 0: null+1
2708 2708
2709 2709 Two branch tags: more recent wins:
2710 2710
2711 2711 $ hg tag -r 3 -m t3 -d '8 0' t3
2712 2712 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2713 2713 8: t3+5
2714 2714 7: t3+4
2715 2715 6: t3+3
2716 2716 5: t3+2
2717 2717 4: t3+1
2718 2718 3: t3+0
2719 2719 2: t2+0
2720 2720 1: t1+0
2721 2721 0: null+1
2722 2722
2723 2723 Merged tag overrides:
2724 2724
2725 2725 $ hg tag -r 5 -m t5 -d '9 0' t5
2726 2726 $ hg tag -r 3 -m at3 -d '10 0' at3
2727 2727 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2728 2728 10: t5+5
2729 2729 9: t5+4
2730 2730 8: t5+3
2731 2731 7: t5+2
2732 2732 6: t5+1
2733 2733 5: t5+0
2734 2734 4: at3:t3+1
2735 2735 3: at3:t3+0
2736 2736 2: t2+0
2737 2737 1: t1+0
2738 2738 0: null+1
2739 2739
2740 2740 $ hg log --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
2741 2741 10: t5+5,5
2742 2742 9: t5+4,4
2743 2743 8: t5+3,3
2744 2744 7: t5+2,2
2745 2745 6: t5+1,1
2746 2746 5: t5+0,0
2747 2747 4: at3+1,1 t3+1,1
2748 2748 3: at3+0,0 t3+0,0
2749 2749 2: t2+0,0
2750 2750 1: t1+0,0
2751 2751 0: null+1,1
2752 2752
2753 2753 $ hg log --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
2754 2754 10: t3, C: 8, D: 7
2755 2755 9: t3, C: 7, D: 6
2756 2756 8: t3, C: 6, D: 5
2757 2757 7: t3, C: 5, D: 4
2758 2758 6: t3, C: 4, D: 3
2759 2759 5: t3, C: 3, D: 2
2760 2760 4: t3, C: 1, D: 1
2761 2761 3: t3, C: 0, D: 0
2762 2762 2: t1, C: 1, D: 1
2763 2763 1: t1, C: 0, D: 0
2764 2764 0: null, C: 1, D: 1
2765 2765
2766 2766 $ cd ..
2767 2767
2768 2768
2769 2769 Style path expansion: issue1948 - ui.style option doesn't work on OSX
2770 2770 if it is a relative path
2771 2771
2772 2772 $ mkdir -p home/styles
2773 2773
2774 2774 $ cat > home/styles/teststyle <<EOF
2775 2775 > changeset = 'test {rev}:{node|short}\n'
2776 2776 > EOF
2777 2777
2778 2778 $ HOME=`pwd`/home; export HOME
2779 2779
2780 2780 $ cat > latesttag/.hg/hgrc <<EOF
2781 2781 > [ui]
2782 2782 > style = ~/styles/teststyle
2783 2783 > EOF
2784 2784
2785 2785 $ hg -R latesttag tip
2786 2786 test 10:9b4a630e5f5f
2787 2787
2788 2788 Test recursive showlist template (issue1989):
2789 2789
2790 2790 $ cat > style1989 <<EOF
2791 2791 > changeset = '{file_mods}{manifest}{extras}'
2792 2792 > file_mod = 'M|{author|person}\n'
2793 2793 > manifest = '{rev},{author}\n'
2794 2794 > extra = '{key}: {author}\n'
2795 2795 > EOF
2796 2796
2797 2797 $ hg -R latesttag log -r tip --style=style1989
2798 2798 M|test
2799 2799 10,test
2800 2800 branch: test
2801 2801
2802 2802 Test new-style inline templating:
2803 2803
2804 2804 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
2805 2805 modified files: .hgtags
2806 2806
2807 2807
2808 2808 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
2809 2809 hg: parse error: keyword 'rev' is not iterable
2810 2810 [255]
2811 2811 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
2812 2812 hg: parse error: None is not iterable
2813 2813 [255]
2814 2814
2815 2815 Test the sub function of templating for expansion:
2816 2816
2817 2817 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
2818 2818 xx
2819 2819
2820 2820 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
2821 2821 hg: parse error: sub got an invalid pattern: [
2822 2822 [255]
2823 2823 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
2824 2824 hg: parse error: sub got an invalid replacement: \1
2825 2825 [255]
2826 2826
2827 2827 Test the strip function with chars specified:
2828 2828
2829 2829 $ hg log -R latesttag --template '{desc}\n'
2830 2830 at3
2831 2831 t5
2832 2832 t3
2833 2833 t2
2834 2834 t1
2835 2835 merge
2836 2836 h2e
2837 2837 h2d
2838 2838 h1c
2839 2839 b
2840 2840 a
2841 2841
2842 2842 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2843 2843 at3
2844 2844 5
2845 2845 3
2846 2846 2
2847 2847 1
2848 2848 merg
2849 2849 h2
2850 2850 h2d
2851 2851 h1c
2852 2852 b
2853 2853 a
2854 2854
2855 2855 Test date format:
2856 2856
2857 2857 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2858 2858 date: 70 01 01 10 +0000
2859 2859 date: 70 01 01 09 +0000
2860 2860 date: 70 01 01 08 +0000
2861 2861 date: 70 01 01 07 +0000
2862 2862 date: 70 01 01 06 +0000
2863 2863 date: 70 01 01 05 +0100
2864 2864 date: 70 01 01 04 +0000
2865 2865 date: 70 01 01 03 +0000
2866 2866 date: 70 01 01 02 +0000
2867 2867 date: 70 01 01 01 +0000
2868 2868 date: 70 01 01 00 +0000
2869 2869
2870 2870 Test invalid date:
2871 2871
2872 2872 $ hg log -R latesttag -T '{date(rev)}\n'
2873 2873 hg: parse error: date expects a date information
2874 2874 [255]
2875 2875
2876 2876 Test integer literal:
2877 2877
2878 2878 $ hg debugtemplate -v '{(0)}\n'
2879 2879 (template
2880 2880 (group
2881 2881 ('integer', '0'))
2882 2882 ('string', '\n'))
2883 2883 0
2884 2884 $ hg debugtemplate -v '{(123)}\n'
2885 2885 (template
2886 2886 (group
2887 2887 ('integer', '123'))
2888 2888 ('string', '\n'))
2889 2889 123
2890 2890 $ hg debugtemplate -v '{(-4)}\n'
2891 2891 (template
2892 2892 (group
2893 2893 ('integer', '-4'))
2894 2894 ('string', '\n'))
2895 2895 -4
2896 2896 $ hg debugtemplate '{(-)}\n'
2897 2897 hg: parse error at 2: integer literal without digits
2898 2898 [255]
2899 2899 $ hg debugtemplate '{(-a)}\n'
2900 2900 hg: parse error at 2: integer literal without digits
2901 2901 [255]
2902 2902
2903 2903 top-level integer literal is interpreted as symbol (i.e. variable name):
2904 2904
2905 2905 $ hg debugtemplate -D 1=one -v '{1}\n'
2906 2906 (template
2907 2907 ('integer', '1')
2908 2908 ('string', '\n'))
2909 2909 one
2910 2910 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
2911 2911 (template
2912 2912 (func
2913 2913 ('symbol', 'if')
2914 2914 (list
2915 2915 ('string', 't')
2916 2916 (template
2917 2917 ('integer', '1'))))
2918 2918 ('string', '\n'))
2919 2919 one
2920 2920 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
2921 2921 (template
2922 2922 (|
2923 2923 ('integer', '1')
2924 2924 ('symbol', 'stringify'))
2925 2925 ('string', '\n'))
2926 2926 one
2927 2927
2928 2928 unless explicit symbol is expected:
2929 2929
2930 2930 $ hg log -Ra -r0 -T '{desc|1}\n'
2931 2931 hg: parse error: expected a symbol, got 'integer'
2932 2932 [255]
2933 2933 $ hg log -Ra -r0 -T '{1()}\n'
2934 2934 hg: parse error: expected a symbol, got 'integer'
2935 2935 [255]
2936 2936
2937 2937 Test string literal:
2938 2938
2939 2939 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
2940 2940 (template
2941 2941 ('string', 'string with no template fragment')
2942 2942 ('string', '\n'))
2943 2943 string with no template fragment
2944 2944 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
2945 2945 (template
2946 2946 (template
2947 2947 ('string', 'template: ')
2948 2948 ('symbol', 'rev'))
2949 2949 ('string', '\n'))
2950 2950 template: 0
2951 2951 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
2952 2952 (template
2953 2953 ('string', 'rawstring: {rev}')
2954 2954 ('string', '\n'))
2955 2955 rawstring: {rev}
2956 2956 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
2957 2957 (template
2958 2958 (%
2959 2959 ('symbol', 'files')
2960 2960 ('string', 'rawstring: {file}'))
2961 2961 ('string', '\n'))
2962 2962 rawstring: {file}
2963 2963
2964 2964 Test string escaping:
2965 2965
2966 2966 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2967 2967 >
2968 2968 <>\n<[>
2969 2969 <>\n<]>
2970 2970 <>\n<
2971 2971
2972 2972 $ hg log -R latesttag -r 0 \
2973 2973 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2974 2974 >
2975 2975 <>\n<[>
2976 2976 <>\n<]>
2977 2977 <>\n<
2978 2978
2979 2979 $ hg log -R latesttag -r 0 -T esc \
2980 2980 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2981 2981 >
2982 2982 <>\n<[>
2983 2983 <>\n<]>
2984 2984 <>\n<
2985 2985
2986 2986 $ cat <<'EOF' > esctmpl
2987 2987 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2988 2988 > EOF
2989 2989 $ hg log -R latesttag -r 0 --style ./esctmpl
2990 2990 >
2991 2991 <>\n<[>
2992 2992 <>\n<]>
2993 2993 <>\n<
2994 2994
2995 2995 Test string escaping of quotes:
2996 2996
2997 2997 $ hg log -Ra -r0 -T '{"\""}\n'
2998 2998 "
2999 2999 $ hg log -Ra -r0 -T '{"\\\""}\n'
3000 3000 \"
3001 3001 $ hg log -Ra -r0 -T '{r"\""}\n'
3002 3002 \"
3003 3003 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3004 3004 \\\"
3005 3005
3006 3006
3007 3007 $ hg log -Ra -r0 -T '{"\""}\n'
3008 3008 "
3009 3009 $ hg log -Ra -r0 -T '{"\\\""}\n'
3010 3010 \"
3011 3011 $ hg log -Ra -r0 -T '{r"\""}\n'
3012 3012 \"
3013 3013 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3014 3014 \\\"
3015 3015
3016 3016 Test exception in quoted template. single backslash before quotation mark is
3017 3017 stripped before parsing:
3018 3018
3019 3019 $ cat <<'EOF' > escquotetmpl
3020 3020 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
3021 3021 > EOF
3022 3022 $ cd latesttag
3023 3023 $ hg log -r 2 --style ../escquotetmpl
3024 3024 " \" \" \\" head1
3025 3025
3026 3026 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
3027 3027 valid
3028 3028 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
3029 3029 valid
3030 3030
3031 3031 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
3032 3032 _evalifliteral() templates (issue4733):
3033 3033
3034 3034 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
3035 3035 "2
3036 3036 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
3037 3037 "2
3038 3038 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
3039 3039 "2
3040 3040
3041 3041 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
3042 3042 \"
3043 3043 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
3044 3044 \"
3045 3045 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3046 3046 \"
3047 3047
3048 3048 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
3049 3049 \\\"
3050 3050 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
3051 3051 \\\"
3052 3052 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3053 3053 \\\"
3054 3054
3055 3055 escaped single quotes and errors:
3056 3056
3057 3057 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
3058 3058 foo
3059 3059 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
3060 3060 foo
3061 3061 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3062 3062 hg: parse error at 21: unterminated string
3063 3063 [255]
3064 3064 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3065 3065 hg: parse error: trailing \ in string
3066 3066 [255]
3067 3067 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3068 3068 hg: parse error: trailing \ in string
3069 3069 [255]
3070 3070
3071 3071 $ cd ..
3072 3072
3073 3073 Test leading backslashes:
3074 3074
3075 3075 $ cd latesttag
3076 3076 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3077 3077 {rev} {file}
3078 3078 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3079 3079 \2 \head1
3080 3080 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3081 3081 \{rev} \{file}
3082 3082 $ cd ..
3083 3083
3084 3084 Test leading backslashes in "if" expression (issue4714):
3085 3085
3086 3086 $ cd latesttag
3087 3087 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3088 3088 {rev} \{rev}
3089 3089 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3090 3090 \2 \\{rev}
3091 3091 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3092 3092 \{rev} \\\{rev}
3093 3093 $ cd ..
3094 3094
3095 3095 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3096 3096
3097 3097 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3098 3098 \x6e
3099 3099 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3100 3100 \x5c\x786e
3101 3101 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3102 3102 \x6e
3103 3103 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3104 3104 \x5c\x786e
3105 3105
3106 3106 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3107 3107 \x6e
3108 3108 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3109 3109 \x5c\x786e
3110 3110 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3111 3111 \x6e
3112 3112 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3113 3113 \x5c\x786e
3114 3114
3115 3115 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3116 3116 fourth
3117 3117 second
3118 3118 third
3119 3119 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3120 3120 fourth\nsecond\nthird
3121 3121
3122 3122 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3123 3123 <p>
3124 3124 1st
3125 3125 </p>
3126 3126 <p>
3127 3127 2nd
3128 3128 </p>
3129 3129 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3130 3130 <p>
3131 3131 1st\n\n2nd
3132 3132 </p>
3133 3133 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3134 3134 1st
3135 3135
3136 3136 2nd
3137 3137
3138 3138 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3139 3139 o perso
3140 3140 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3141 3141 no person
3142 3142 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3143 3143 o perso
3144 3144 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3145 3145 no perso
3146 3146
3147 3147 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3148 3148 -o perso-
3149 3149 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3150 3150 no person
3151 3151 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3152 3152 \x2do perso\x2d
3153 3153 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3154 3154 -o perso-
3155 3155 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3156 3156 \x2do perso\x6e
3157 3157
3158 3158 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3159 3159 fourth
3160 3160 second
3161 3161 third
3162 3162
3163 3163 Test string escaping in nested expression:
3164 3164
3165 3165 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3166 3166 fourth\x6esecond\x6ethird
3167 3167 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3168 3168 fourth\x6esecond\x6ethird
3169 3169
3170 3170 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3171 3171 fourth\x6esecond\x6ethird
3172 3172 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3173 3173 fourth\x5c\x786esecond\x5c\x786ethird
3174 3174
3175 3175 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3176 3176 3:\x6eo user, \x6eo domai\x6e
3177 3177 4:\x5c\x786eew bra\x5c\x786ech
3178 3178
3179 3179 Test quotes in nested expression are evaluated just like a $(command)
3180 3180 substitution in POSIX shells:
3181 3181
3182 3182 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3183 3183 8:95c24699272e
3184 3184 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3185 3185 {8} "95c24699272e"
3186 3186
3187 3187 Test recursive evaluation:
3188 3188
3189 3189 $ hg init r
3190 3190 $ cd r
3191 3191 $ echo a > a
3192 3192 $ hg ci -Am '{rev}'
3193 3193 adding a
3194 3194 $ hg log -r 0 --template '{if(rev, desc)}\n'
3195 3195 {rev}
3196 3196 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3197 3197 test 0
3198 3198
3199 3199 $ hg branch -q 'text.{rev}'
3200 3200 $ echo aa >> aa
3201 3201 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3202 3202
3203 3203 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3204 3204 {node|short}desc to
3205 3205 text.{rev}be wrapped
3206 3206 text.{rev}desc to be
3207 3207 text.{rev}wrapped (no-eol)
3208 3208 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3209 3209 bcc7ff960b8e:desc to
3210 3210 text.1:be wrapped
3211 3211 text.1:desc to be
3212 3212 text.1:wrapped (no-eol)
3213 3213 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3214 3214 hg: parse error: fill expects an integer width
3215 3215 [255]
3216 3216
3217 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
3218 bcc7ff960b8e:desc to be
3219 termwidth.1:wrapped desc
3220 termwidth.1:to be wrapped (no-eol)
3221
3217 3222 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3218 3223 {node|short} (no-eol)
3219 3224 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3220 3225 bcc-ff---b-e (no-eol)
3221 3226
3222 3227 $ cat >> .hg/hgrc <<EOF
3223 3228 > [extensions]
3224 3229 > color=
3225 3230 > [color]
3226 3231 > mode=ansi
3227 3232 > text.{rev} = red
3228 3233 > text.1 = green
3229 3234 > EOF
3230 3235 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3231 3236 \x1b[0;31mtext\x1b[0m (esc)
3232 3237 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3233 3238 \x1b[0;32mtext\x1b[0m (esc)
3234 3239
3235 3240 color effect can be specified without quoting:
3236 3241
3237 3242 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
3238 3243 \x1b[0;31mtext\x1b[0m (esc)
3239 3244
3240 3245 label should be no-op if color is disabled:
3241 3246
3242 3247 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
3243 3248 text
3244 3249 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
3245 3250 text
3246 3251
3247 3252 Test branches inside if statement:
3248 3253
3249 3254 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3250 3255 no
3251 3256
3252 3257 Test get function:
3253 3258
3254 3259 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3255 3260 default
3256 3261 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3257 3262 default
3258 3263 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3259 3264 hg: parse error: get() expects a dict as first argument
3260 3265 [255]
3261 3266
3262 3267 Test localdate(date, tz) function:
3263 3268
3264 3269 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3265 3270 1970-01-01 09:00 +0900
3266 3271 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3267 3272 1970-01-01 00:00 +0000
3268 3273 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "blahUTC")|isodate}\n'
3269 3274 hg: parse error: localdate expects a timezone
3270 3275 [255]
3271 3276 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3272 3277 1970-01-01 02:00 +0200
3273 3278 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3274 3279 1970-01-01 00:00 +0000
3275 3280 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3276 3281 1970-01-01 00:00 +0000
3277 3282 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3278 3283 hg: parse error: localdate expects a timezone
3279 3284 [255]
3280 3285 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3281 3286 hg: parse error: localdate expects a timezone
3282 3287 [255]
3283 3288
3284 3289 Test shortest(node) function:
3285 3290
3286 3291 $ echo b > b
3287 3292 $ hg ci -qAm b
3288 3293 $ hg log --template '{shortest(node)}\n'
3289 3294 e777
3290 3295 bcc7
3291 3296 f776
3292 3297 $ hg log --template '{shortest(node, 10)}\n'
3293 3298 e777603221
3294 3299 bcc7ff960b
3295 3300 f7769ec2ab
3296 3301 $ hg log --template '{node|shortest}\n' -l1
3297 3302 e777
3298 3303
3299 3304 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
3300 3305 f7769ec2ab
3301 3306 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
3302 3307 hg: parse error: shortest() expects an integer minlength
3303 3308 [255]
3304 3309
3305 3310 Test pad function
3306 3311
3307 3312 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3308 3313 2 test
3309 3314 1 {node|short}
3310 3315 0 test
3311 3316
3312 3317 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3313 3318 2 test
3314 3319 1 {node|short}
3315 3320 0 test
3316 3321
3317 3322 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3318 3323 2------------------- test
3319 3324 1------------------- {node|short}
3320 3325 0------------------- test
3321 3326
3322 3327 Test template string in pad function
3323 3328
3324 3329 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3325 3330 {0} test
3326 3331
3327 3332 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3328 3333 \{rev} test
3329 3334
3330 3335 Test width argument passed to pad function
3331 3336
3332 3337 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
3333 3338 0 test
3334 3339 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
3335 3340 hg: parse error: pad() expects an integer width
3336 3341 [255]
3337 3342
3338 3343 Test boolean argument passed to pad function
3339 3344
3340 3345 no crash
3341 3346
3342 3347 $ hg log -r 0 -T '{pad(rev, 10, "-", "f{"oo"}")}\n'
3343 3348 ---------0
3344 3349
3345 3350 string/literal
3346 3351
3347 3352 $ hg log -r 0 -T '{pad(rev, 10, "-", "false")}\n'
3348 3353 ---------0
3349 3354 $ hg log -r 0 -T '{pad(rev, 10, "-", false)}\n'
3350 3355 0---------
3351 3356 $ hg log -r 0 -T '{pad(rev, 10, "-", "")}\n'
3352 3357 0---------
3353 3358
3354 3359 unknown keyword is evaluated to ''
3355 3360
3356 3361 $ hg log -r 0 -T '{pad(rev, 10, "-", unknownkeyword)}\n'
3357 3362 0---------
3358 3363
3359 3364 Test separate function
3360 3365
3361 3366 $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
3362 3367 a-b-c
3363 3368 $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
3364 3369 0:f7769ec2ab97 test default
3365 3370 $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
3366 3371 a \x1b[0;31mb\x1b[0m c d (esc)
3367 3372
3368 3373 Test boolean expression/literal passed to if function
3369 3374
3370 3375 $ hg log -r 0 -T '{if(rev, "rev 0 is True")}\n'
3371 3376 rev 0 is True
3372 3377 $ hg log -r 0 -T '{if(0, "literal 0 is True as well")}\n'
3373 3378 literal 0 is True as well
3374 3379 $ hg log -r 0 -T '{if("", "", "empty string is False")}\n'
3375 3380 empty string is False
3376 3381 $ hg log -r 0 -T '{if(revset(r"0 - 0"), "", "empty list is False")}\n'
3377 3382 empty list is False
3378 3383 $ hg log -r 0 -T '{if(true, "true is True")}\n'
3379 3384 true is True
3380 3385 $ hg log -r 0 -T '{if(false, "", "false is False")}\n'
3381 3386 false is False
3382 3387 $ hg log -r 0 -T '{if("false", "non-empty string is True")}\n'
3383 3388 non-empty string is True
3384 3389
3385 3390 Test ifcontains function
3386 3391
3387 3392 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
3388 3393 2 is in the string
3389 3394 1 is not
3390 3395 0 is in the string
3391 3396
3392 3397 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
3393 3398 2 is in the string
3394 3399 1 is not
3395 3400 0 is in the string
3396 3401
3397 3402 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
3398 3403 2 did not add a
3399 3404 1 did not add a
3400 3405 0 added a
3401 3406
3402 3407 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
3403 3408 2 is parent of 1
3404 3409 1
3405 3410 0
3406 3411
3407 3412 Test revset function
3408 3413
3409 3414 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
3410 3415 2 current rev
3411 3416 1 not current rev
3412 3417 0 not current rev
3413 3418
3414 3419 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
3415 3420 2 match rev
3416 3421 1 match rev
3417 3422 0 not match rev
3418 3423
3419 3424 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
3420 3425 2 Parents: 1
3421 3426 1 Parents: 0
3422 3427 0 Parents:
3423 3428
3424 3429 $ cat >> .hg/hgrc <<EOF
3425 3430 > [revsetalias]
3426 3431 > myparents(\$1) = parents(\$1)
3427 3432 > EOF
3428 3433 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
3429 3434 2 Parents: 1
3430 3435 1 Parents: 0
3431 3436 0 Parents:
3432 3437
3433 3438 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
3434 3439 Rev: 2
3435 3440 Ancestor: 0
3436 3441 Ancestor: 1
3437 3442 Ancestor: 2
3438 3443
3439 3444 Rev: 1
3440 3445 Ancestor: 0
3441 3446 Ancestor: 1
3442 3447
3443 3448 Rev: 0
3444 3449 Ancestor: 0
3445 3450
3446 3451 $ hg log --template '{revset("TIP"|lower)}\n' -l1
3447 3452 2
3448 3453
3449 3454 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
3450 3455 2
3451 3456
3452 3457 a list template is evaluated for each item of revset/parents
3453 3458
3454 3459 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
3455 3460 2 p: 1:bcc7ff960b8e
3456 3461 1 p: 0:f7769ec2ab97
3457 3462 0 p:
3458 3463
3459 3464 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
3460 3465 2 p: 1:bcc7ff960b8e -1:000000000000
3461 3466 1 p: 0:f7769ec2ab97 -1:000000000000
3462 3467 0 p: -1:000000000000 -1:000000000000
3463 3468
3464 3469 therefore, 'revcache' should be recreated for each rev
3465 3470
3466 3471 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
3467 3472 2 aa b
3468 3473 p
3469 3474 1
3470 3475 p a
3471 3476 0 a
3472 3477 p
3473 3478
3474 3479 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
3475 3480 2 aa b
3476 3481 p
3477 3482 1
3478 3483 p a
3479 3484 0 a
3480 3485 p
3481 3486
3482 3487 a revset item must be evaluated as an integer revision, not an offset from tip
3483 3488
3484 3489 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
3485 3490 -1:000000000000
3486 3491 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
3487 3492 -1:000000000000
3488 3493
3489 3494 join() should pick '{rev}' from revset items:
3490 3495
3491 3496 $ hg log -R ../a -T '{join(revset("parents(%d)", rev), ", ")}\n' -r6
3492 3497 4, 5
3493 3498
3494 3499 on the other hand, parents are formatted as '{rev}:{node|formatnode}' by
3495 3500 default. join() should agree with the default formatting:
3496 3501
3497 3502 $ hg log -R ../a -T '{join(parents, ", ")}\n' -r6
3498 3503 5:13207e5a10d9, 4:bbe44766e73d
3499 3504
3500 3505 $ hg log -R ../a -T '{join(parents, ",\n")}\n' -r6 --debug
3501 3506 5:13207e5a10d9fd28ec424934298e176197f2c67f,
3502 3507 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
3503 3508
3504 3509 Test files function
3505 3510
3506 3511 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
3507 3512 2
3508 3513 a
3509 3514 aa
3510 3515 b
3511 3516 1
3512 3517 a
3513 3518 0
3514 3519 a
3515 3520
3516 3521 $ hg log -T "{rev}\n{join(files('aa'), '\n')}\n"
3517 3522 2
3518 3523 aa
3519 3524 1
3520 3525
3521 3526 0
3522 3527
3523 3528
3524 3529 Test relpath function
3525 3530
3526 3531 $ hg log -r0 -T '{files % "{file|relpath}\n"}'
3527 3532 a
3528 3533 $ cd ..
3529 3534 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
3530 3535 r/a (glob)
3531 3536 $ cd r
3532 3537
3533 3538 Test active bookmark templating
3534 3539
3535 3540 $ hg book foo
3536 3541 $ hg book bar
3537 3542 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
3538 3543 2 bar* foo
3539 3544 1
3540 3545 0
3541 3546 $ hg log --template "{rev} {activebookmark}\n"
3542 3547 2 bar
3543 3548 1
3544 3549 0
3545 3550 $ hg bookmarks --inactive bar
3546 3551 $ hg log --template "{rev} {activebookmark}\n"
3547 3552 2
3548 3553 1
3549 3554 0
3550 3555 $ hg book -r1 baz
3551 3556 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
3552 3557 2 bar foo
3553 3558 1 baz
3554 3559 0
3555 3560 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
3556 3561 2 t
3557 3562 1 f
3558 3563 0 f
3559 3564
3560 3565 Test namespaces dict
3561 3566
3562 3567 $ hg log -T '{rev}{namespaces % " {namespace}={join(names, ",")}"}\n'
3563 3568 2 bookmarks=bar,foo tags=tip branches=text.{rev}
3564 3569 1 bookmarks=baz tags= branches=text.{rev}
3565 3570 0 bookmarks= tags= branches=default
3566 3571 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
3567 3572 bookmarks: bar foo
3568 3573 tags: tip
3569 3574 branches: text.{rev}
3570 3575 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
3571 3576 bookmarks:
3572 3577 bar
3573 3578 foo
3574 3579 tags:
3575 3580 tip
3576 3581 branches:
3577 3582 text.{rev}
3578 3583 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
3579 3584 bar
3580 3585 foo
3581 3586
3582 3587 Test stringify on sub expressions
3583 3588
3584 3589 $ cd ..
3585 3590 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
3586 3591 fourth, second, third
3587 3592 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
3588 3593 abc
3589 3594
3590 3595 Test splitlines
3591 3596
3592 3597 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
3593 3598 @ foo Modify, add, remove, rename
3594 3599 |
3595 3600 o foo future
3596 3601 |
3597 3602 o foo third
3598 3603 |
3599 3604 o foo second
3600 3605
3601 3606 o foo merge
3602 3607 |\
3603 3608 | o foo new head
3604 3609 | |
3605 3610 o | foo new branch
3606 3611 |/
3607 3612 o foo no user, no domain
3608 3613 |
3609 3614 o foo no person
3610 3615 |
3611 3616 o foo other 1
3612 3617 | foo other 2
3613 3618 | foo
3614 3619 | foo other 3
3615 3620 o foo line 1
3616 3621 foo line 2
3617 3622
3618 3623 Test startswith
3619 3624 $ hg log -Gv -R a --template "{startswith(desc)}"
3620 3625 hg: parse error: startswith expects two arguments
3621 3626 [255]
3622 3627
3623 3628 $ hg log -Gv -R a --template "{startswith('line', desc)}"
3624 3629 @
3625 3630 |
3626 3631 o
3627 3632 |
3628 3633 o
3629 3634 |
3630 3635 o
3631 3636
3632 3637 o
3633 3638 |\
3634 3639 | o
3635 3640 | |
3636 3641 o |
3637 3642 |/
3638 3643 o
3639 3644 |
3640 3645 o
3641 3646 |
3642 3647 o
3643 3648 |
3644 3649 o line 1
3645 3650 line 2
3646 3651
3647 3652 Test bad template with better error message
3648 3653
3649 3654 $ hg log -Gv -R a --template '{desc|user()}'
3650 3655 hg: parse error: expected a symbol, got 'func'
3651 3656 [255]
3652 3657
3653 3658 Test word function (including index out of bounds graceful failure)
3654 3659
3655 3660 $ hg log -Gv -R a --template "{word('1', desc)}"
3656 3661 @ add,
3657 3662 |
3658 3663 o
3659 3664 |
3660 3665 o
3661 3666 |
3662 3667 o
3663 3668
3664 3669 o
3665 3670 |\
3666 3671 | o head
3667 3672 | |
3668 3673 o | branch
3669 3674 |/
3670 3675 o user,
3671 3676 |
3672 3677 o person
3673 3678 |
3674 3679 o 1
3675 3680 |
3676 3681 o 1
3677 3682
3678 3683
3679 3684 Test word third parameter used as splitter
3680 3685
3681 3686 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
3682 3687 @ M
3683 3688 |
3684 3689 o future
3685 3690 |
3686 3691 o third
3687 3692 |
3688 3693 o sec
3689 3694
3690 3695 o merge
3691 3696 |\
3692 3697 | o new head
3693 3698 | |
3694 3699 o | new branch
3695 3700 |/
3696 3701 o n
3697 3702 |
3698 3703 o n
3699 3704 |
3700 3705 o
3701 3706 |
3702 3707 o line 1
3703 3708 line 2
3704 3709
3705 3710 Test word error messages for not enough and too many arguments
3706 3711
3707 3712 $ hg log -Gv -R a --template "{word('0')}"
3708 3713 hg: parse error: word expects two or three arguments, got 1
3709 3714 [255]
3710 3715
3711 3716 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
3712 3717 hg: parse error: word expects two or three arguments, got 7
3713 3718 [255]
3714 3719
3715 3720 Test word for integer literal
3716 3721
3717 3722 $ hg log -R a --template "{word(2, desc)}\n" -r0
3718 3723 line
3719 3724
3720 3725 Test word for invalid numbers
3721 3726
3722 3727 $ hg log -Gv -R a --template "{word('a', desc)}"
3723 3728 hg: parse error: word expects an integer index
3724 3729 [255]
3725 3730
3726 3731 Test word for out of range
3727 3732
3728 3733 $ hg log -R a --template "{word(10000, desc)}"
3729 3734 $ hg log -R a --template "{word(-10000, desc)}"
3730 3735
3731 3736 Test indent and not adding to empty lines
3732 3737
3733 3738 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
3734 3739 -----
3735 3740 > line 1
3736 3741 >> line 2
3737 3742 -----
3738 3743 > other 1
3739 3744 >> other 2
3740 3745
3741 3746 >> other 3
3742 3747
3743 3748 Test with non-strings like dates
3744 3749
3745 3750 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3746 3751 1200000.00
3747 3752 1300000.00
3748 3753
3749 3754 Test broken string escapes:
3750 3755
3751 3756 $ hg log -T "bogus\\" -R a
3752 3757 hg: parse error: trailing \ in string
3753 3758 [255]
3754 3759 $ hg log -T "\\xy" -R a
3755 3760 hg: parse error: invalid \x escape
3756 3761 [255]
3757 3762
3758 3763 json filter should escape HTML tags so that the output can be embedded in hgweb:
3759 3764
3760 3765 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
3761 3766 "\u003cfoo@example.org\u003e"
3762 3767
3763 3768 Templater supports aliases of symbol and func() styles:
3764 3769
3765 3770 $ hg clone -q a aliases
3766 3771 $ cd aliases
3767 3772 $ cat <<EOF >> .hg/hgrc
3768 3773 > [templatealias]
3769 3774 > r = rev
3770 3775 > rn = "{r}:{node|short}"
3771 3776 > status(c, files) = files % "{c} {file}\n"
3772 3777 > utcdate(d) = localdate(d, "UTC")
3773 3778 > EOF
3774 3779
3775 3780 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
3776 3781 (template
3777 3782 ('symbol', 'rn')
3778 3783 ('string', ' ')
3779 3784 (|
3780 3785 (func
3781 3786 ('symbol', 'utcdate')
3782 3787 ('symbol', 'date'))
3783 3788 ('symbol', 'isodate'))
3784 3789 ('string', '\n'))
3785 3790 * expanded:
3786 3791 (template
3787 3792 (template
3788 3793 ('symbol', 'rev')
3789 3794 ('string', ':')
3790 3795 (|
3791 3796 ('symbol', 'node')
3792 3797 ('symbol', 'short')))
3793 3798 ('string', ' ')
3794 3799 (|
3795 3800 (func
3796 3801 ('symbol', 'localdate')
3797 3802 (list
3798 3803 ('symbol', 'date')
3799 3804 ('string', 'UTC')))
3800 3805 ('symbol', 'isodate'))
3801 3806 ('string', '\n'))
3802 3807 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3803 3808
3804 3809 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
3805 3810 (template
3806 3811 (func
3807 3812 ('symbol', 'status')
3808 3813 (list
3809 3814 ('string', 'A')
3810 3815 ('symbol', 'file_adds'))))
3811 3816 * expanded:
3812 3817 (template
3813 3818 (%
3814 3819 ('symbol', 'file_adds')
3815 3820 (template
3816 3821 ('string', 'A')
3817 3822 ('string', ' ')
3818 3823 ('symbol', 'file')
3819 3824 ('string', '\n'))))
3820 3825 A a
3821 3826
3822 3827 A unary function alias can be called as a filter:
3823 3828
3824 3829 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
3825 3830 (template
3826 3831 (|
3827 3832 (|
3828 3833 ('symbol', 'date')
3829 3834 ('symbol', 'utcdate'))
3830 3835 ('symbol', 'isodate'))
3831 3836 ('string', '\n'))
3832 3837 * expanded:
3833 3838 (template
3834 3839 (|
3835 3840 (func
3836 3841 ('symbol', 'localdate')
3837 3842 (list
3838 3843 ('symbol', 'date')
3839 3844 ('string', 'UTC')))
3840 3845 ('symbol', 'isodate'))
3841 3846 ('string', '\n'))
3842 3847 1970-01-12 13:46 +0000
3843 3848
3844 3849 Aliases should be applied only to command arguments and templates in hgrc.
3845 3850 Otherwise, our stock styles and web templates could be corrupted:
3846 3851
3847 3852 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
3848 3853 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3849 3854
3850 3855 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
3851 3856 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3852 3857
3853 3858 $ cat <<EOF > tmpl
3854 3859 > changeset = 'nothing expanded:{rn}\n'
3855 3860 > EOF
3856 3861 $ hg log -r0 --style ./tmpl
3857 3862 nothing expanded:
3858 3863
3859 3864 Aliases in formatter:
3860 3865
3861 3866 $ hg branches -T '{pad(branch, 7)} {rn}\n'
3862 3867 default 6:d41e714fe50d
3863 3868 foo 4:bbe44766e73d
3864 3869
3865 3870 Aliases should honor HGPLAIN:
3866 3871
3867 3872 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
3868 3873 nothing expanded:
3869 3874 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
3870 3875 0:1e4e1b8f71e0
3871 3876
3872 3877 Unparsable alias:
3873 3878
3874 3879 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
3875 3880 (template
3876 3881 ('symbol', 'bad'))
3877 3882 abort: bad definition of template alias "bad": at 2: not a prefix: end
3878 3883 [255]
3879 3884 $ hg log --config templatealias.bad='x(' -T '{bad}'
3880 3885 abort: bad definition of template alias "bad": at 2: not a prefix: end
3881 3886 [255]
3882 3887
3883 3888 $ cd ..
3884 3889
3885 3890 Set up repository for non-ascii encoding tests:
3886 3891
3887 3892 $ hg init nonascii
3888 3893 $ cd nonascii
3889 3894 $ python <<EOF
3890 3895 > open('latin1', 'w').write('\xe9')
3891 3896 > open('utf-8', 'w').write('\xc3\xa9')
3892 3897 > EOF
3893 3898 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
3894 3899 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
3895 3900
3896 3901 json filter should try round-trip conversion to utf-8:
3897 3902
3898 3903 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
3899 3904 "\u00e9"
3900 3905 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
3901 3906 "non-ascii branch: \u00e9"
3902 3907
3903 3908 json filter takes input as utf-8b:
3904 3909
3905 3910 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
3906 3911 "\u00e9"
3907 3912 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
3908 3913 "\udce9"
3909 3914
3910 3915 utf8 filter:
3911 3916
3912 3917 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
3913 3918 round-trip: c3a9
3914 3919 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
3915 3920 decoded: c3a9
3916 3921 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
3917 3922 abort: decoding near * (glob)
3918 3923 [255]
3919 3924 $ hg log -T "invalid type: {rev|utf8}\n" -r0
3920 3925 abort: template filter 'utf8' is not compatible with keyword 'rev'
3921 3926 [255]
3922 3927
3923 3928 $ cd ..
3924 3929
3925 3930 Test that template function in extension is registered as expected
3926 3931
3927 3932 $ cd a
3928 3933
3929 3934 $ cat <<EOF > $TESTTMP/customfunc.py
3930 3935 > from mercurial import registrar
3931 3936 >
3932 3937 > templatefunc = registrar.templatefunc()
3933 3938 >
3934 3939 > @templatefunc('custom()')
3935 3940 > def custom(context, mapping, args):
3936 3941 > return 'custom'
3937 3942 > EOF
3938 3943 $ cat <<EOF > .hg/hgrc
3939 3944 > [extensions]
3940 3945 > customfunc = $TESTTMP/customfunc.py
3941 3946 > EOF
3942 3947
3943 3948 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
3944 3949 custom
3945 3950
3946 3951 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now