##// END OF EJS Templates
templatekw: populate all keywords depending on predecessor in map operation...
Yuya Nishihara -
r32910:498e9dcc default
parent child Browse files
Show More
@@ -1,687 +1,688 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 .i18n import _
11 11 from .node import (
12 12 hex,
13 13 nullid,
14 14 short,
15 15 )
16 16
17 17 from . import (
18 18 encoding,
19 19 error,
20 20 hbisect,
21 21 obsutil,
22 22 patch,
23 23 registrar,
24 24 scmutil,
25 25 util,
26 26 )
27 27
28 28 class _hybrid(object):
29 29 """Wrapper for list or dict to support legacy template
30 30
31 31 This class allows us to handle both:
32 32 - "{files}" (legacy command-line-specific list hack) and
33 33 - "{files % '{file}\n'}" (hgweb-style with inlining and function support)
34 34 and to access raw values:
35 35 - "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
36 36 - "{get(extras, key)}"
37 37 - "{files|json}"
38 38 """
39 39
40 40 def __init__(self, gen, values, makemap, joinfmt):
41 41 if gen is not None:
42 42 self.gen = gen
43 43 self._values = values
44 44 self._makemap = makemap
45 45 self.joinfmt = joinfmt
46 46 @util.propertycache
47 47 def gen(self):
48 48 return self._defaultgen()
49 49 def _defaultgen(self):
50 50 """Generator to stringify this as {join(self, ' ')}"""
51 51 for i, d in enumerate(self.itermaps()):
52 52 if i > 0:
53 53 yield ' '
54 54 yield self.joinfmt(d)
55 55 def itermaps(self):
56 56 makemap = self._makemap
57 57 for x in self._values:
58 58 yield makemap(x)
59 59 def __contains__(self, x):
60 60 return x in self._values
61 61 def __len__(self):
62 62 return len(self._values)
63 63 def __iter__(self):
64 64 return iter(self._values)
65 65 def __getattr__(self, name):
66 66 if name not in ('get', 'items', 'iteritems', 'iterkeys', 'itervalues',
67 67 'keys', 'values'):
68 68 raise AttributeError(name)
69 69 return getattr(self._values, name)
70 70
71 71 def hybriddict(data, key='key', value='value', fmt='%s=%s', gen=None):
72 72 """Wrap data to support both dict-like and string-like operations"""
73 73 return _hybrid(gen, data, lambda k: {key: k, value: data[k]},
74 74 lambda d: fmt % (d[key], d[value]))
75 75
76 76 def hybridlist(data, name, fmt='%s', gen=None):
77 77 """Wrap data to support both list-like and string-like operations"""
78 78 return _hybrid(gen, data, lambda x: {name: x}, lambda d: fmt % d[name])
79 79
80 80 def unwraphybrid(thing):
81 81 """Return an object which can be stringified possibly by using a legacy
82 82 template"""
83 83 if not util.safehasattr(thing, 'gen'):
84 84 return thing
85 85 return thing.gen
86 86
87 87 def showdict(name, data, mapping, plural=None, key='key', value='value',
88 88 fmt='%s=%s', separator=' '):
89 89 c = [{key: k, value: v} for k, v in data.iteritems()]
90 90 f = _showlist(name, c, mapping, plural, separator)
91 91 return hybriddict(data, key=key, value=value, fmt=fmt, gen=f)
92 92
93 93 def showlist(name, values, mapping, plural=None, element=None, separator=' '):
94 94 if not element:
95 95 element = name
96 96 f = _showlist(name, values, mapping, plural, separator)
97 97 return hybridlist(values, name=element, gen=f)
98 98
99 99 def _showlist(name, values, mapping, plural=None, separator=' '):
100 100 '''expand set of values.
101 101 name is name of key in template map.
102 102 values is list of strings or dicts.
103 103 plural is plural of name, if not simply name + 's'.
104 104 separator is used to join values as a string
105 105
106 106 expansion works like this, given name 'foo'.
107 107
108 108 if values is empty, expand 'no_foos'.
109 109
110 110 if 'foo' not in template map, return values as a string,
111 111 joined by 'separator'.
112 112
113 113 expand 'start_foos'.
114 114
115 115 for each value, expand 'foo'. if 'last_foo' in template
116 116 map, expand it instead of 'foo' for last key.
117 117
118 118 expand 'end_foos'.
119 119 '''
120 120 templ = mapping['templ']
121 121 if not plural:
122 122 plural = name + 's'
123 123 if not values:
124 124 noname = 'no_' + plural
125 125 if noname in templ:
126 126 yield templ(noname, **mapping)
127 127 return
128 128 if name not in templ:
129 129 if isinstance(values[0], str):
130 130 yield separator.join(values)
131 131 else:
132 132 for v in values:
133 133 yield dict(v, **mapping)
134 134 return
135 135 startname = 'start_' + plural
136 136 if startname in templ:
137 137 yield templ(startname, **mapping)
138 138 vmapping = mapping.copy()
139 139 def one(v, tag=name):
140 140 try:
141 141 vmapping.update(v)
142 142 except (AttributeError, ValueError):
143 143 try:
144 144 for a, b in v:
145 145 vmapping[a] = b
146 146 except ValueError:
147 147 vmapping[name] = v
148 148 return templ(tag, **vmapping)
149 149 lastname = 'last_' + name
150 150 if lastname in templ:
151 151 last = values.pop()
152 152 else:
153 153 last = None
154 154 for v in values:
155 155 yield one(v)
156 156 if last is not None:
157 157 yield one(last, tag=lastname)
158 158 endname = 'end_' + plural
159 159 if endname in templ:
160 160 yield templ(endname, **mapping)
161 161
162 162 def _formatrevnode(ctx):
163 163 """Format changeset as '{rev}:{node|formatnode}', which is the default
164 164 template provided by cmdutil.changeset_templater"""
165 165 repo = ctx.repo()
166 166 if repo.ui.debugflag:
167 167 hexfunc = hex
168 168 else:
169 169 hexfunc = short
170 170 return '%d:%s' % (scmutil.intrev(ctx), hexfunc(scmutil.binnode(ctx)))
171 171
172 172 def getfiles(repo, ctx, revcache):
173 173 if 'files' not in revcache:
174 174 revcache['files'] = repo.status(ctx.p1(), ctx)[:3]
175 175 return revcache['files']
176 176
177 177 def getlatesttags(repo, ctx, cache, pattern=None):
178 178 '''return date, distance and name for the latest tag of rev'''
179 179
180 180 cachename = 'latesttags'
181 181 if pattern is not None:
182 182 cachename += '-' + pattern
183 183 match = util.stringmatcher(pattern)[2]
184 184 else:
185 185 match = util.always
186 186
187 187 if cachename not in cache:
188 188 # Cache mapping from rev to a tuple with tag date, tag
189 189 # distance and tag name
190 190 cache[cachename] = {-1: (0, 0, ['null'])}
191 191 latesttags = cache[cachename]
192 192
193 193 rev = ctx.rev()
194 194 todo = [rev]
195 195 while todo:
196 196 rev = todo.pop()
197 197 if rev in latesttags:
198 198 continue
199 199 ctx = repo[rev]
200 200 tags = [t for t in ctx.tags()
201 201 if (repo.tagtype(t) and repo.tagtype(t) != 'local'
202 202 and match(t))]
203 203 if tags:
204 204 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
205 205 continue
206 206 try:
207 207 # The tuples are laid out so the right one can be found by
208 208 # comparison.
209 209 pdate, pdist, ptag = max(
210 210 latesttags[p.rev()] for p in ctx.parents())
211 211 except KeyError:
212 212 # Cache miss - recurse
213 213 todo.append(rev)
214 214 todo.extend(p.rev() for p in ctx.parents())
215 215 continue
216 216 latesttags[rev] = pdate, pdist + 1, ptag
217 217 return latesttags[rev]
218 218
219 219 def getrenamedfn(repo, endrev=None):
220 220 rcache = {}
221 221 if endrev is None:
222 222 endrev = len(repo)
223 223
224 224 def getrenamed(fn, rev):
225 225 '''looks up all renames for a file (up to endrev) the first
226 226 time the file is given. It indexes on the changerev and only
227 227 parses the manifest if linkrev != changerev.
228 228 Returns rename info for fn at changerev rev.'''
229 229 if fn not in rcache:
230 230 rcache[fn] = {}
231 231 fl = repo.file(fn)
232 232 for i in fl:
233 233 lr = fl.linkrev(i)
234 234 renamed = fl.renamed(fl.node(i))
235 235 rcache[fn][lr] = renamed
236 236 if lr >= endrev:
237 237 break
238 238 if rev in rcache[fn]:
239 239 return rcache[fn][rev]
240 240
241 241 # If linkrev != rev (i.e. rev not found in rcache) fallback to
242 242 # filectx logic.
243 243 try:
244 244 return repo[rev][fn].renamed()
245 245 except error.LookupError:
246 246 return None
247 247
248 248 return getrenamed
249 249
250 250 # default templates internally used for rendering of lists
251 251 defaulttempl = {
252 252 'parent': '{rev}:{node|formatnode} ',
253 253 'manifest': '{rev}:{node|formatnode}',
254 254 'file_copy': '{name} ({source})',
255 255 'envvar': '{key}={value}',
256 256 'extra': '{key}={value|stringescape}'
257 257 }
258 258 # filecopy is preserved for compatibility reasons
259 259 defaulttempl['filecopy'] = defaulttempl['file_copy']
260 260
261 261 # keywords are callables like:
262 262 # fn(repo, ctx, templ, cache, revcache, **args)
263 263 # with:
264 264 # repo - current repository instance
265 265 # ctx - the changectx being displayed
266 266 # templ - the templater instance
267 267 # cache - a cache dictionary for the whole templater run
268 268 # revcache - a cache dictionary for the current revision
269 269 keywords = {}
270 270
271 271 templatekeyword = registrar.templatekeyword(keywords)
272 272
273 273 @templatekeyword('author')
274 274 def showauthor(repo, ctx, templ, **args):
275 275 """String. The unmodified author of the changeset."""
276 276 return ctx.user()
277 277
278 278 @templatekeyword('bisect')
279 279 def showbisect(repo, ctx, templ, **args):
280 280 """String. The changeset bisection status."""
281 281 return hbisect.label(repo, ctx.node())
282 282
283 283 @templatekeyword('branch')
284 284 def showbranch(**args):
285 285 """String. The name of the branch on which the changeset was
286 286 committed.
287 287 """
288 288 return args['ctx'].branch()
289 289
290 290 @templatekeyword('branches')
291 291 def showbranches(**args):
292 292 """List of strings. The name of the branch on which the
293 293 changeset was committed. Will be empty if the branch name was
294 294 default. (DEPRECATED)
295 295 """
296 296 branch = args['ctx'].branch()
297 297 if branch != 'default':
298 298 return showlist('branch', [branch], args, plural='branches')
299 299 return showlist('branch', [], args, plural='branches')
300 300
301 301 @templatekeyword('bookmarks')
302 302 def showbookmarks(**args):
303 303 """List of strings. Any bookmarks associated with the
304 304 changeset. Also sets 'active', the name of the active bookmark.
305 305 """
306 306 repo = args['ctx']._repo
307 307 bookmarks = args['ctx'].bookmarks()
308 308 active = repo._activebookmark
309 309 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active}
310 310 f = _showlist('bookmark', bookmarks, args)
311 311 return _hybrid(f, bookmarks, makemap, lambda x: x['bookmark'])
312 312
313 313 @templatekeyword('children')
314 314 def showchildren(**args):
315 315 """List of strings. The children of the changeset."""
316 316 ctx = args['ctx']
317 317 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
318 318 return showlist('children', childrevs, args, element='child')
319 319
320 320 # Deprecated, but kept alive for help generation a purpose.
321 321 @templatekeyword('currentbookmark')
322 322 def showcurrentbookmark(**args):
323 323 """String. The active bookmark, if it is
324 324 associated with the changeset (DEPRECATED)"""
325 325 return showactivebookmark(**args)
326 326
327 327 @templatekeyword('activebookmark')
328 328 def showactivebookmark(**args):
329 329 """String. The active bookmark, if it is
330 330 associated with the changeset"""
331 331 active = args['repo']._activebookmark
332 332 if active and active in args['ctx'].bookmarks():
333 333 return active
334 334 return ''
335 335
336 336 @templatekeyword('date')
337 337 def showdate(repo, ctx, templ, **args):
338 338 """Date information. The date when the changeset was committed."""
339 339 return ctx.date()
340 340
341 341 @templatekeyword('desc')
342 342 def showdescription(repo, ctx, templ, **args):
343 343 """String. The text of the changeset description."""
344 344 s = ctx.description()
345 345 if isinstance(s, encoding.localstr):
346 346 # try hard to preserve utf-8 bytes
347 347 return encoding.tolocal(encoding.fromlocal(s).strip())
348 348 else:
349 349 return s.strip()
350 350
351 351 @templatekeyword('diffstat')
352 352 def showdiffstat(repo, ctx, templ, **args):
353 353 """String. Statistics of changes with the following format:
354 354 "modified files: +added/-removed lines"
355 355 """
356 356 stats = patch.diffstatdata(util.iterlines(ctx.diff(noprefix=False)))
357 357 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
358 358 return '%s: +%s/-%s' % (len(stats), adds, removes)
359 359
360 360 @templatekeyword('envvars')
361 361 def showenvvars(repo, **args):
362 362 """A dictionary of environment variables. (EXPERIMENTAL)"""
363 363 env = repo.ui.exportableenviron()
364 364 env = util.sortdict((k, env[k]) for k in sorted(env))
365 365 return showdict('envvar', env, args, plural='envvars')
366 366
367 367 @templatekeyword('extras')
368 368 def showextras(**args):
369 369 """List of dicts with key, value entries of the 'extras'
370 370 field of this changeset."""
371 371 extras = args['ctx'].extra()
372 372 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
373 373 makemap = lambda k: {'key': k, 'value': extras[k]}
374 374 c = [makemap(k) for k in extras]
375 375 f = _showlist('extra', c, args, plural='extras')
376 376 return _hybrid(f, extras, makemap,
377 377 lambda x: '%s=%s' % (x['key'], util.escapestr(x['value'])))
378 378
379 379 @templatekeyword('file_adds')
380 380 def showfileadds(**args):
381 381 """List of strings. Files added by this changeset."""
382 382 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
383 383 return showlist('file_add', getfiles(repo, ctx, revcache)[1], args,
384 384 element='file')
385 385
386 386 @templatekeyword('file_copies')
387 387 def showfilecopies(**args):
388 388 """List of strings. Files copied in this changeset with
389 389 their sources.
390 390 """
391 391 cache, ctx = args['cache'], args['ctx']
392 392 copies = args['revcache'].get('copies')
393 393 if copies is None:
394 394 if 'getrenamed' not in cache:
395 395 cache['getrenamed'] = getrenamedfn(args['repo'])
396 396 copies = []
397 397 getrenamed = cache['getrenamed']
398 398 for fn in ctx.files():
399 399 rename = getrenamed(fn, ctx.rev())
400 400 if rename:
401 401 copies.append((fn, rename[0]))
402 402
403 403 copies = util.sortdict(copies)
404 404 return showdict('file_copy', copies, args, plural='file_copies',
405 405 key='name', value='source', fmt='%s (%s)')
406 406
407 407 # showfilecopiesswitch() displays file copies only if copy records are
408 408 # provided before calling the templater, usually with a --copies
409 409 # command line switch.
410 410 @templatekeyword('file_copies_switch')
411 411 def showfilecopiesswitch(**args):
412 412 """List of strings. Like "file_copies" but displayed
413 413 only if the --copied switch is set.
414 414 """
415 415 copies = args['revcache'].get('copies') or []
416 416 copies = util.sortdict(copies)
417 417 return showdict('file_copy', copies, args, plural='file_copies',
418 418 key='name', value='source', fmt='%s (%s)')
419 419
420 420 @templatekeyword('file_dels')
421 421 def showfiledels(**args):
422 422 """List of strings. Files removed by this changeset."""
423 423 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
424 424 return showlist('file_del', getfiles(repo, ctx, revcache)[2], args,
425 425 element='file')
426 426
427 427 @templatekeyword('file_mods')
428 428 def showfilemods(**args):
429 429 """List of strings. Files modified by this changeset."""
430 430 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
431 431 return showlist('file_mod', getfiles(repo, ctx, revcache)[0], args,
432 432 element='file')
433 433
434 434 @templatekeyword('files')
435 435 def showfiles(**args):
436 436 """List of strings. All files modified, added, or removed by this
437 437 changeset.
438 438 """
439 439 return showlist('file', args['ctx'].files(), args)
440 440
441 441 @templatekeyword('graphnode')
442 442 def showgraphnode(repo, ctx, **args):
443 443 """String. The character representing the changeset node in
444 444 an ASCII revision graph"""
445 445 wpnodes = repo.dirstate.parents()
446 446 if wpnodes[1] == nullid:
447 447 wpnodes = wpnodes[:1]
448 448 if ctx.node() in wpnodes:
449 449 return '@'
450 450 elif ctx.obsolete():
451 451 return 'x'
452 452 elif ctx.closesbranch():
453 453 return '_'
454 454 else:
455 455 return 'o'
456 456
457 457 @templatekeyword('index')
458 458 def showindex(**args):
459 459 """Integer. The current iteration of the loop. (0 indexed)"""
460 460 # just hosts documentation; should be overridden by template mapping
461 461 raise error.Abort(_("can't use index in this context"))
462 462
463 463 @templatekeyword('latesttag')
464 464 def showlatesttag(**args):
465 465 """List of strings. The global tags on the most recent globally
466 466 tagged ancestor of this changeset. If no such tags exist, the list
467 467 consists of the single string "null".
468 468 """
469 469 return showlatesttags(None, **args)
470 470
471 471 def showlatesttags(pattern, **args):
472 472 """helper method for the latesttag keyword and function"""
473 473 repo, ctx = args['repo'], args['ctx']
474 474 cache = args['cache']
475 475 latesttags = getlatesttags(repo, ctx, cache, pattern)
476 476
477 477 # latesttag[0] is an implementation detail for sorting csets on different
478 478 # branches in a stable manner- it is the date the tagged cset was created,
479 479 # not the date the tag was created. Therefore it isn't made visible here.
480 480 makemap = lambda v: {
481 481 'changes': _showchangessincetag,
482 482 'distance': latesttags[1],
483 483 'latesttag': v, # BC with {latesttag % '{latesttag}'}
484 484 'tag': v
485 485 }
486 486
487 487 tags = latesttags[2]
488 488 f = _showlist('latesttag', tags, args, separator=':')
489 489 return _hybrid(f, tags, makemap, lambda x: x['latesttag'])
490 490
491 491 @templatekeyword('latesttagdistance')
492 492 def showlatesttagdistance(repo, ctx, templ, cache, **args):
493 493 """Integer. Longest path to the latest tag."""
494 494 return getlatesttags(repo, ctx, cache)[1]
495 495
496 496 @templatekeyword('changessincelatesttag')
497 497 def showchangessincelatesttag(repo, ctx, templ, cache, **args):
498 498 """Integer. All ancestors not in the latest tag."""
499 499 latesttag = getlatesttags(repo, ctx, cache)[2][0]
500 500
501 501 return _showchangessincetag(repo, ctx, tag=latesttag, **args)
502 502
503 503 def _showchangessincetag(repo, ctx, **args):
504 504 offset = 0
505 505 revs = [ctx.rev()]
506 506 tag = args['tag']
507 507
508 508 # The only() revset doesn't currently support wdir()
509 509 if ctx.rev() is None:
510 510 offset = 1
511 511 revs = [p.rev() for p in ctx.parents()]
512 512
513 513 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset
514 514
515 515 @templatekeyword('manifest')
516 516 def showmanifest(**args):
517 517 repo, ctx, templ = args['repo'], args['ctx'], args['templ']
518 518 mnode = ctx.manifestnode()
519 519 if mnode is None:
520 520 # just avoid crash, we might want to use the 'ff...' hash in future
521 521 return
522 522 args = args.copy()
523 523 args.update({'rev': repo.manifestlog._revlog.rev(mnode),
524 524 'node': hex(mnode)})
525 525 return templ('manifest', **args)
526 526
527 527 def shownames(namespace, **args):
528 528 """helper method to generate a template keyword for a namespace"""
529 529 ctx = args['ctx']
530 530 repo = ctx.repo()
531 531 ns = repo.names[namespace]
532 532 names = ns.names(repo, ctx.node())
533 533 return showlist(ns.templatename, names, args, plural=namespace)
534 534
535 535 @templatekeyword('namespaces')
536 536 def shownamespaces(**args):
537 537 """Dict of lists. Names attached to this changeset per
538 538 namespace."""
539 539 ctx = args['ctx']
540 540 repo = ctx.repo()
541 541 namespaces = util.sortdict((k, showlist('name', ns.names(repo, ctx.node()),
542 542 args))
543 543 for k, ns in repo.names.iteritems())
544 544 f = _showlist('namespace', list(namespaces), args)
545 545 return _hybrid(f, namespaces,
546 546 lambda k: {'namespace': k, 'names': namespaces[k]},
547 547 lambda x: x['namespace'])
548 548
549 549 @templatekeyword('node')
550 550 def shownode(repo, ctx, templ, **args):
551 551 """String. The changeset identification hash, as a 40 hexadecimal
552 552 digit string.
553 553 """
554 554 return ctx.hex()
555 555
556 556 @templatekeyword('obsolete')
557 557 def showobsolete(repo, ctx, templ, **args):
558 558 """String. Whether the changeset is obsolete.
559 559 """
560 560 if ctx.obsolete():
561 561 return 'obsolete'
562 562 return ''
563 563
564 564 @templatekeyword("predecessors")
565 565 def showpredecessors(repo, ctx, **args):
566 566 """Returns the list if the closest visible successors
567 567 """
568 568 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
569 569 predecessors = map(hex, predecessors)
570 570
571 return _hybrid(None, predecessors, lambda x: {'node': x},
572 lambda d: d['node'][:12])
571 return _hybrid(None, predecessors,
572 lambda x: {'ctx': repo[x], 'revcache': {}},
573 lambda d: short(scmutil.binnode(d['ctx'])))
573 574
574 575 @templatekeyword('p1rev')
575 576 def showp1rev(repo, ctx, templ, **args):
576 577 """Integer. The repository-local revision number of the changeset's
577 578 first parent, or -1 if the changeset has no parents."""
578 579 return ctx.p1().rev()
579 580
580 581 @templatekeyword('p2rev')
581 582 def showp2rev(repo, ctx, templ, **args):
582 583 """Integer. The repository-local revision number of the changeset's
583 584 second parent, or -1 if the changeset has no second parent."""
584 585 return ctx.p2().rev()
585 586
586 587 @templatekeyword('p1node')
587 588 def showp1node(repo, ctx, templ, **args):
588 589 """String. The identification hash of the changeset's first parent,
589 590 as a 40 digit hexadecimal string. If the changeset has no parents, all
590 591 digits are 0."""
591 592 return ctx.p1().hex()
592 593
593 594 @templatekeyword('p2node')
594 595 def showp2node(repo, ctx, templ, **args):
595 596 """String. The identification hash of the changeset's second
596 597 parent, as a 40 digit hexadecimal string. If the changeset has no second
597 598 parent, all digits are 0."""
598 599 return ctx.p2().hex()
599 600
600 601 @templatekeyword('parents')
601 602 def showparents(**args):
602 603 """List of strings. The parents of the changeset in "rev:node"
603 604 format. If the changeset has only one "natural" parent (the predecessor
604 605 revision) nothing is shown."""
605 606 repo = args['repo']
606 607 ctx = args['ctx']
607 608 pctxs = scmutil.meaningfulparents(repo, ctx)
608 609 prevs = [str(p.rev()) for p in pctxs] # ifcontains() needs a list of str
609 610 parents = [[('rev', p.rev()),
610 611 ('node', p.hex()),
611 612 ('phase', p.phasestr())]
612 613 for p in pctxs]
613 614 f = _showlist('parent', parents, args)
614 615 return _hybrid(f, prevs, lambda x: {'ctx': repo[int(x)], 'revcache': {}},
615 616 lambda d: _formatrevnode(d['ctx']))
616 617
617 618 @templatekeyword('phase')
618 619 def showphase(repo, ctx, templ, **args):
619 620 """String. The changeset phase name."""
620 621 return ctx.phasestr()
621 622
622 623 @templatekeyword('phaseidx')
623 624 def showphaseidx(repo, ctx, templ, **args):
624 625 """Integer. The changeset phase index."""
625 626 return ctx.phase()
626 627
627 628 @templatekeyword('rev')
628 629 def showrev(repo, ctx, templ, **args):
629 630 """Integer. The repository-local changeset revision number."""
630 631 return scmutil.intrev(ctx)
631 632
632 633 def showrevslist(name, revs, **args):
633 634 """helper to generate a list of revisions in which a mapped template will
634 635 be evaluated"""
635 636 repo = args['ctx'].repo()
636 637 revs = [str(r) for r in revs] # ifcontains() needs a list of str
637 638 f = _showlist(name, revs, args)
638 639 return _hybrid(f, revs,
639 640 lambda x: {name: x, 'ctx': repo[int(x)], 'revcache': {}},
640 641 lambda d: d[name])
641 642
642 643 @templatekeyword('subrepos')
643 644 def showsubrepos(**args):
644 645 """List of strings. Updated subrepositories in the changeset."""
645 646 ctx = args['ctx']
646 647 substate = ctx.substate
647 648 if not substate:
648 649 return showlist('subrepo', [], args)
649 650 psubstate = ctx.parents()[0].substate or {}
650 651 subrepos = []
651 652 for sub in substate:
652 653 if sub not in psubstate or substate[sub] != psubstate[sub]:
653 654 subrepos.append(sub) # modified or newly added in ctx
654 655 for sub in psubstate:
655 656 if sub not in substate:
656 657 subrepos.append(sub) # removed in ctx
657 658 return showlist('subrepo', sorted(subrepos), args)
658 659
659 660 # don't remove "showtags" definition, even though namespaces will put
660 661 # a helper function for "tags" keyword into "keywords" map automatically,
661 662 # because online help text is built without namespaces initialization
662 663 @templatekeyword('tags')
663 664 def showtags(**args):
664 665 """List of strings. Any tags associated with the changeset."""
665 666 return shownames('tags', **args)
666 667
667 668 def loadkeyword(ui, extname, registrarobj):
668 669 """Load template keyword from specified registrarobj
669 670 """
670 671 for name, func in registrarobj._table.iteritems():
671 672 keywords[name] = func
672 673
673 674 @templatekeyword('termwidth')
674 675 def termwidth(repo, ctx, templ, **args):
675 676 """Integer. The width of the current terminal."""
676 677 return repo.ui.termwidth()
677 678
678 679 @templatekeyword('troubles')
679 680 def showtroubles(**args):
680 681 """List of strings. Evolution troubles affecting the changeset.
681 682
682 683 (EXPERIMENTAL)
683 684 """
684 685 return showlist('trouble', args['ctx'].troubles(), args)
685 686
686 687 # tell hggettext to extract docstrings from these functions:
687 688 i18nfunctions = keywords.values()
@@ -1,888 +1,888 b''
1 1 This test file test the various templates related to obsmarkers.
2 2
3 3 Global setup
4 4 ============
5 5
6 6 $ . $TESTDIR/testlib/obsmarker-common.sh
7 7 $ cat >> $HGRCPATH <<EOF
8 8 > [ui]
9 9 > interactive = true
10 10 > [phases]
11 11 > publish=False
12 12 > [experimental]
13 13 > evolution=all
14 14 > [alias]
15 15 > tlog = log -G -T '{node|short}\
16 16 > {if(predecessors, "\n Predecessors: {predecessors}")}\
17 17 > {if(predecessors, "\n semi-colon: {join(predecessors, "; ")}")}\
18 18 > {if(predecessors, "\n json: {predecessors|json}")}\
19 > {if(predecessors, "\n map: {join(predecessors % "{node}", " ")}")}\n'
19 > {if(predecessors, "\n map: {join(predecessors % "{rev}:{node}", " ")}")}\n'
20 20 > EOF
21 21
22 22 Test templates on amended commit
23 23 ================================
24 24
25 25 Test setup
26 26 ----------
27 27
28 28 $ hg init $TESTTMP/templates-local-amend
29 29 $ cd $TESTTMP/templates-local-amend
30 30 $ mkcommit ROOT
31 31 $ mkcommit A0
32 32 $ echo 42 >> A0
33 33 $ hg commit --amend -m "A1"
34 34 $ hg commit --amend -m "A2"
35 35
36 36 $ hg log --hidden -G
37 37 @ changeset: 4:d004c8f274b9
38 38 | tag: tip
39 39 | parent: 0:ea207398892e
40 40 | user: test
41 41 | date: Thu Jan 01 00:00:00 1970 +0000
42 42 | summary: A2
43 43 |
44 44 | x changeset: 3:a468dc9b3633
45 45 |/ parent: 0:ea207398892e
46 46 | user: test
47 47 | date: Thu Jan 01 00:00:00 1970 +0000
48 48 | summary: A1
49 49 |
50 50 | x changeset: 2:f137d23bb3e1
51 51 | | user: test
52 52 | | date: Thu Jan 01 00:00:00 1970 +0000
53 53 | | summary: temporary amend commit for 471f378eab4c
54 54 | |
55 55 | x changeset: 1:471f378eab4c
56 56 |/ user: test
57 57 | date: Thu Jan 01 00:00:00 1970 +0000
58 58 | summary: A0
59 59 |
60 60 o changeset: 0:ea207398892e
61 61 user: test
62 62 date: Thu Jan 01 00:00:00 1970 +0000
63 63 summary: ROOT
64 64
65 65 Check templates
66 66 ---------------
67 67 $ hg up 'desc(A0)' --hidden
68 68 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
69 69
70 70 Predecessors template should show current revision as it is the working copy
71 71 $ hg tlog
72 72 o d004c8f274b9
73 73 | Predecessors: 471f378eab4c
74 74 | semi-colon: 471f378eab4c
75 75 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
76 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
76 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
77 77 | @ 471f378eab4c
78 78 |/
79 79 o ea207398892e
80 80
81 81 $ hg up 'desc(A1)' --hidden
82 82 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
83 83
84 84 Predecessors template should show current revision as it is the working copy
85 85 $ hg tlog
86 86 o d004c8f274b9
87 87 | Predecessors: a468dc9b3633
88 88 | semi-colon: a468dc9b3633
89 89 | json: ["a468dc9b36338b14fdb7825f55ce3df4e71517ad"]
90 | map: a468dc9b36338b14fdb7825f55ce3df4e71517ad
90 | map: 3:a468dc9b36338b14fdb7825f55ce3df4e71517ad
91 91 | @ a468dc9b3633
92 92 |/
93 93 o ea207398892e
94 94
95 95 Predecessors template should show all the predecessors as we force their display
96 96 with --hidden
97 97 $ hg tlog --hidden
98 98 o d004c8f274b9
99 99 | Predecessors: a468dc9b3633
100 100 | semi-colon: a468dc9b3633
101 101 | json: ["a468dc9b36338b14fdb7825f55ce3df4e71517ad"]
102 | map: a468dc9b36338b14fdb7825f55ce3df4e71517ad
102 | map: 3:a468dc9b36338b14fdb7825f55ce3df4e71517ad
103 103 | @ a468dc9b3633
104 104 |/ Predecessors: 471f378eab4c
105 105 | semi-colon: 471f378eab4c
106 106 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
107 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
107 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
108 108 | x f137d23bb3e1
109 109 | |
110 110 | x 471f378eab4c
111 111 |/
112 112 o ea207398892e
113 113
114 114
115 115 Predecessors template shouldn't show anything as all obsolete commit are not
116 116 visible.
117 117 $ hg up 'desc(A2)'
118 118 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
119 119 $ hg tlog
120 120 @ d004c8f274b9
121 121 |
122 122 o ea207398892e
123 123
124 124 $ hg tlog --hidden
125 125 @ d004c8f274b9
126 126 | Predecessors: a468dc9b3633
127 127 | semi-colon: a468dc9b3633
128 128 | json: ["a468dc9b36338b14fdb7825f55ce3df4e71517ad"]
129 | map: a468dc9b36338b14fdb7825f55ce3df4e71517ad
129 | map: 3:a468dc9b36338b14fdb7825f55ce3df4e71517ad
130 130 | x a468dc9b3633
131 131 |/ Predecessors: 471f378eab4c
132 132 | semi-colon: 471f378eab4c
133 133 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
134 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
134 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
135 135 | x f137d23bb3e1
136 136 | |
137 137 | x 471f378eab4c
138 138 |/
139 139 o ea207398892e
140 140
141 141
142 142 Test templates with splitted commit
143 143 ===================================
144 144
145 145 $ hg init $TESTTMP/templates-local-split
146 146 $ cd $TESTTMP/templates-local-split
147 147 $ mkcommit ROOT
148 148 $ echo 42 >> a
149 149 $ echo 43 >> b
150 150 $ hg commit -A -m "A0"
151 151 adding a
152 152 adding b
153 153 $ hg log --hidden -G
154 154 @ changeset: 1:471597cad322
155 155 | tag: tip
156 156 | user: test
157 157 | date: Thu Jan 01 00:00:00 1970 +0000
158 158 | summary: A0
159 159 |
160 160 o changeset: 0:ea207398892e
161 161 user: test
162 162 date: Thu Jan 01 00:00:00 1970 +0000
163 163 summary: ROOT
164 164
165 165 # Simulate split
166 166 $ hg up -r "desc(ROOT)"
167 167 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
168 168 $ echo 42 >> a
169 169 $ hg commit -A -m "A0"
170 170 adding a
171 171 created new head
172 172 $ echo 43 >> b
173 173 $ hg commit -A -m "A0"
174 174 adding b
175 175 $ hg debugobsolete `getid "1"` `getid "2"` `getid "3"`
176 176
177 177 $ hg log --hidden -G
178 178 @ changeset: 3:f257fde29c7a
179 179 | tag: tip
180 180 | user: test
181 181 | date: Thu Jan 01 00:00:00 1970 +0000
182 182 | summary: A0
183 183 |
184 184 o changeset: 2:337fec4d2edc
185 185 | parent: 0:ea207398892e
186 186 | user: test
187 187 | date: Thu Jan 01 00:00:00 1970 +0000
188 188 | summary: A0
189 189 |
190 190 | x changeset: 1:471597cad322
191 191 |/ user: test
192 192 | date: Thu Jan 01 00:00:00 1970 +0000
193 193 | summary: A0
194 194 |
195 195 o changeset: 0:ea207398892e
196 196 user: test
197 197 date: Thu Jan 01 00:00:00 1970 +0000
198 198 summary: ROOT
199 199
200 200 Check templates
201 201 ---------------
202 202
203 203 $ hg up 'obsolete()' --hidden
204 204 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
205 205
206 206 Predecessors template should show current revision as it is the working copy
207 207 $ hg tlog
208 208 o f257fde29c7a
209 209 | Predecessors: 471597cad322
210 210 | semi-colon: 471597cad322
211 211 | json: ["471597cad322d1f659bb169751be9133dad92ef3"]
212 | map: 471597cad322d1f659bb169751be9133dad92ef3
212 | map: 1:471597cad322d1f659bb169751be9133dad92ef3
213 213 o 337fec4d2edc
214 214 | Predecessors: 471597cad322
215 215 | semi-colon: 471597cad322
216 216 | json: ["471597cad322d1f659bb169751be9133dad92ef3"]
217 | map: 471597cad322d1f659bb169751be9133dad92ef3
217 | map: 1:471597cad322d1f659bb169751be9133dad92ef3
218 218 | @ 471597cad322
219 219 |/
220 220 o ea207398892e
221 221
222 222 $ hg up f257fde29c7a
223 223 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 224
225 225 Predecessors template should not show a predecessor as it's not displayed in
226 226 the log
227 227 $ hg tlog
228 228 @ f257fde29c7a
229 229 |
230 230 o 337fec4d2edc
231 231 |
232 232 o ea207398892e
233 233
234 234 Predecessors template should show both predecessors as we force their display
235 235 with --hidden
236 236 $ hg tlog --hidden
237 237 @ f257fde29c7a
238 238 | Predecessors: 471597cad322
239 239 | semi-colon: 471597cad322
240 240 | json: ["471597cad322d1f659bb169751be9133dad92ef3"]
241 | map: 471597cad322d1f659bb169751be9133dad92ef3
241 | map: 1:471597cad322d1f659bb169751be9133dad92ef3
242 242 o 337fec4d2edc
243 243 | Predecessors: 471597cad322
244 244 | semi-colon: 471597cad322
245 245 | json: ["471597cad322d1f659bb169751be9133dad92ef3"]
246 | map: 471597cad322d1f659bb169751be9133dad92ef3
246 | map: 1:471597cad322d1f659bb169751be9133dad92ef3
247 247 | x 471597cad322
248 248 |/
249 249 o ea207398892e
250 250
251 251 Test templates with folded commit
252 252 =================================
253 253
254 254 Test setup
255 255 ----------
256 256
257 257 $ hg init $TESTTMP/templates-local-fold
258 258 $ cd $TESTTMP/templates-local-fold
259 259 $ mkcommit ROOT
260 260 $ mkcommit A0
261 261 $ mkcommit B0
262 262 $ hg log --hidden -G
263 263 @ changeset: 2:0dec01379d3b
264 264 | tag: tip
265 265 | user: test
266 266 | date: Thu Jan 01 00:00:00 1970 +0000
267 267 | summary: B0
268 268 |
269 269 o changeset: 1:471f378eab4c
270 270 | user: test
271 271 | date: Thu Jan 01 00:00:00 1970 +0000
272 272 | summary: A0
273 273 |
274 274 o changeset: 0:ea207398892e
275 275 user: test
276 276 date: Thu Jan 01 00:00:00 1970 +0000
277 277 summary: ROOT
278 278
279 279 Simulate a fold
280 280 $ hg up -r "desc(ROOT)"
281 281 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
282 282 $ echo "A0" > A0
283 283 $ echo "B0" > B0
284 284 $ hg commit -A -m "C0"
285 285 adding A0
286 286 adding B0
287 287 created new head
288 288 $ hg debugobsolete `getid "desc(A0)"` `getid "desc(C0)"`
289 289 $ hg debugobsolete `getid "desc(B0)"` `getid "desc(C0)"`
290 290
291 291 $ hg log --hidden -G
292 292 @ changeset: 3:eb5a0daa2192
293 293 | tag: tip
294 294 | parent: 0:ea207398892e
295 295 | user: test
296 296 | date: Thu Jan 01 00:00:00 1970 +0000
297 297 | summary: C0
298 298 |
299 299 | x changeset: 2:0dec01379d3b
300 300 | | user: test
301 301 | | date: Thu Jan 01 00:00:00 1970 +0000
302 302 | | summary: B0
303 303 | |
304 304 | x changeset: 1:471f378eab4c
305 305 |/ user: test
306 306 | date: Thu Jan 01 00:00:00 1970 +0000
307 307 | summary: A0
308 308 |
309 309 o changeset: 0:ea207398892e
310 310 user: test
311 311 date: Thu Jan 01 00:00:00 1970 +0000
312 312 summary: ROOT
313 313
314 314 Check templates
315 315 ---------------
316 316
317 317 $ hg up 'desc(A0)' --hidden
318 318 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
319 319
320 320 Predecessors template should show current revision as it is the working copy
321 321 $ hg tlog
322 322 o eb5a0daa2192
323 323 | Predecessors: 471f378eab4c
324 324 | semi-colon: 471f378eab4c
325 325 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
326 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
326 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
327 327 | @ 471f378eab4c
328 328 |/
329 329 o ea207398892e
330 330
331 331 $ hg up 'desc(B0)' --hidden
332 332 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
333 333
334 334 Predecessors template should show both predecessors as they should be both
335 335 displayed
336 336 $ hg tlog
337 337 o eb5a0daa2192
338 338 | Predecessors: 0dec01379d3b 471f378eab4c
339 339 | semi-colon: 0dec01379d3b; 471f378eab4c
340 340 | json: ["0dec01379d3be6318c470ead31b1fe7ae7cb53d5", "471f378eab4c5e25f6c77f785b27c936efb22874"]
341 | map: 0dec01379d3be6318c470ead31b1fe7ae7cb53d5 471f378eab4c5e25f6c77f785b27c936efb22874
341 | map: 2:0dec01379d3be6318c470ead31b1fe7ae7cb53d5 1:471f378eab4c5e25f6c77f785b27c936efb22874
342 342 | @ 0dec01379d3b
343 343 | |
344 344 | x 471f378eab4c
345 345 |/
346 346 o ea207398892e
347 347
348 348 $ hg up 'desc(C0)'
349 349 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
350 350
351 351 Predecessors template should not show predecessors as they are not displayed in
352 352 the log
353 353 $ hg tlog
354 354 @ eb5a0daa2192
355 355 |
356 356 o ea207398892e
357 357
358 358 Predecessors template should show both predecessors as we force their display
359 359 with --hidden
360 360 $ hg tlog --hidden
361 361 @ eb5a0daa2192
362 362 | Predecessors: 0dec01379d3b 471f378eab4c
363 363 | semi-colon: 0dec01379d3b; 471f378eab4c
364 364 | json: ["0dec01379d3be6318c470ead31b1fe7ae7cb53d5", "471f378eab4c5e25f6c77f785b27c936efb22874"]
365 | map: 0dec01379d3be6318c470ead31b1fe7ae7cb53d5 471f378eab4c5e25f6c77f785b27c936efb22874
365 | map: 2:0dec01379d3be6318c470ead31b1fe7ae7cb53d5 1:471f378eab4c5e25f6c77f785b27c936efb22874
366 366 | x 0dec01379d3b
367 367 | |
368 368 | x 471f378eab4c
369 369 |/
370 370 o ea207398892e
371 371
372 372
373 373 Test templates with divergence
374 374 ==============================
375 375
376 376 Test setup
377 377 ----------
378 378
379 379 $ hg init $TESTTMP/templates-local-divergence
380 380 $ cd $TESTTMP/templates-local-divergence
381 381 $ mkcommit ROOT
382 382 $ mkcommit A0
383 383 $ hg commit --amend -m "A1"
384 384 $ hg log --hidden -G
385 385 @ changeset: 2:fdf9bde5129a
386 386 | tag: tip
387 387 | parent: 0:ea207398892e
388 388 | user: test
389 389 | date: Thu Jan 01 00:00:00 1970 +0000
390 390 | summary: A1
391 391 |
392 392 | x changeset: 1:471f378eab4c
393 393 |/ user: test
394 394 | date: Thu Jan 01 00:00:00 1970 +0000
395 395 | summary: A0
396 396 |
397 397 o changeset: 0:ea207398892e
398 398 user: test
399 399 date: Thu Jan 01 00:00:00 1970 +0000
400 400 summary: ROOT
401 401
402 402 $ hg update --hidden 'desc(A0)'
403 403 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
404 404 $ hg commit --amend -m "A2"
405 405 $ hg log --hidden -G
406 406 @ changeset: 3:65b757b745b9
407 407 | tag: tip
408 408 | parent: 0:ea207398892e
409 409 | user: test
410 410 | date: Thu Jan 01 00:00:00 1970 +0000
411 411 | trouble: divergent
412 412 | summary: A2
413 413 |
414 414 | o changeset: 2:fdf9bde5129a
415 415 |/ parent: 0:ea207398892e
416 416 | user: test
417 417 | date: Thu Jan 01 00:00:00 1970 +0000
418 418 | trouble: divergent
419 419 | summary: A1
420 420 |
421 421 | x changeset: 1:471f378eab4c
422 422 |/ user: test
423 423 | date: Thu Jan 01 00:00:00 1970 +0000
424 424 | summary: A0
425 425 |
426 426 o changeset: 0:ea207398892e
427 427 user: test
428 428 date: Thu Jan 01 00:00:00 1970 +0000
429 429 summary: ROOT
430 430
431 431 $ hg commit --amend -m 'A3'
432 432 $ hg log --hidden -G
433 433 @ changeset: 4:019fadeab383
434 434 | tag: tip
435 435 | parent: 0:ea207398892e
436 436 | user: test
437 437 | date: Thu Jan 01 00:00:00 1970 +0000
438 438 | trouble: divergent
439 439 | summary: A3
440 440 |
441 441 | x changeset: 3:65b757b745b9
442 442 |/ parent: 0:ea207398892e
443 443 | user: test
444 444 | date: Thu Jan 01 00:00:00 1970 +0000
445 445 | summary: A2
446 446 |
447 447 | o changeset: 2:fdf9bde5129a
448 448 |/ parent: 0:ea207398892e
449 449 | user: test
450 450 | date: Thu Jan 01 00:00:00 1970 +0000
451 451 | trouble: divergent
452 452 | summary: A1
453 453 |
454 454 | x changeset: 1:471f378eab4c
455 455 |/ user: test
456 456 | date: Thu Jan 01 00:00:00 1970 +0000
457 457 | summary: A0
458 458 |
459 459 o changeset: 0:ea207398892e
460 460 user: test
461 461 date: Thu Jan 01 00:00:00 1970 +0000
462 462 summary: ROOT
463 463
464 464
465 465 Check templates
466 466 ---------------
467 467
468 468 $ hg up 'desc(A0)' --hidden
469 469 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
470 470
471 471 Predecessors template should show current revision as it is the working copy
472 472 $ hg tlog
473 473 o 019fadeab383
474 474 | Predecessors: 471f378eab4c
475 475 | semi-colon: 471f378eab4c
476 476 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
477 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
477 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
478 478 | o fdf9bde5129a
479 479 |/ Predecessors: 471f378eab4c
480 480 | semi-colon: 471f378eab4c
481 481 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
482 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
482 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
483 483 | @ 471f378eab4c
484 484 |/
485 485 o ea207398892e
486 486
487 487 $ hg up 'desc(A1)'
488 488 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
489 489
490 490 Predecessors template should not show predecessors as they are not displayed in
491 491 the log
492 492 $ hg tlog
493 493 o 019fadeab383
494 494 |
495 495 | @ fdf9bde5129a
496 496 |/
497 497 o ea207398892e
498 498
499 499 Predecessors template should the predecessors as we force their display with
500 500 --hidden
501 501 $ hg tlog --hidden
502 502 o 019fadeab383
503 503 | Predecessors: 65b757b745b9
504 504 | semi-colon: 65b757b745b9
505 505 | json: ["65b757b745b935093c87a2bccd877521cccffcbd"]
506 | map: 65b757b745b935093c87a2bccd877521cccffcbd
506 | map: 3:65b757b745b935093c87a2bccd877521cccffcbd
507 507 | x 65b757b745b9
508 508 |/ Predecessors: 471f378eab4c
509 509 | semi-colon: 471f378eab4c
510 510 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
511 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
511 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
512 512 | @ fdf9bde5129a
513 513 |/ Predecessors: 471f378eab4c
514 514 | semi-colon: 471f378eab4c
515 515 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
516 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
516 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
517 517 | x 471f378eab4c
518 518 |/
519 519 o ea207398892e
520 520
521 521
522 522 Test templates with amended + folded commit
523 523 ===========================================
524 524
525 525 Test setup
526 526 ----------
527 527
528 528 $ hg init $TESTTMP/templates-local-amend-fold
529 529 $ cd $TESTTMP/templates-local-amend-fold
530 530 $ mkcommit ROOT
531 531 $ mkcommit A0
532 532 $ mkcommit B0
533 533 $ hg commit --amend -m "B1"
534 534 $ hg log --hidden -G
535 535 @ changeset: 3:b7ea6d14e664
536 536 | tag: tip
537 537 | parent: 1:471f378eab4c
538 538 | user: test
539 539 | date: Thu Jan 01 00:00:00 1970 +0000
540 540 | summary: B1
541 541 |
542 542 | x changeset: 2:0dec01379d3b
543 543 |/ user: test
544 544 | date: Thu Jan 01 00:00:00 1970 +0000
545 545 | summary: B0
546 546 |
547 547 o changeset: 1:471f378eab4c
548 548 | user: test
549 549 | date: Thu Jan 01 00:00:00 1970 +0000
550 550 | summary: A0
551 551 |
552 552 o changeset: 0:ea207398892e
553 553 user: test
554 554 date: Thu Jan 01 00:00:00 1970 +0000
555 555 summary: ROOT
556 556
557 557 # Simulate a fold
558 558 $ hg up -r "desc(ROOT)"
559 559 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
560 560 $ echo "A0" > A0
561 561 $ echo "B0" > B0
562 562 $ hg commit -A -m "C0"
563 563 adding A0
564 564 adding B0
565 565 created new head
566 566 $ hg debugobsolete `getid "desc(A0)"` `getid "desc(C0)"`
567 567 $ hg debugobsolete `getid "desc(B1)"` `getid "desc(C0)"`
568 568
569 569 $ hg log --hidden -G
570 570 @ changeset: 4:eb5a0daa2192
571 571 | tag: tip
572 572 | parent: 0:ea207398892e
573 573 | user: test
574 574 | date: Thu Jan 01 00:00:00 1970 +0000
575 575 | summary: C0
576 576 |
577 577 | x changeset: 3:b7ea6d14e664
578 578 | | parent: 1:471f378eab4c
579 579 | | user: test
580 580 | | date: Thu Jan 01 00:00:00 1970 +0000
581 581 | | summary: B1
582 582 | |
583 583 | | x changeset: 2:0dec01379d3b
584 584 | |/ user: test
585 585 | | date: Thu Jan 01 00:00:00 1970 +0000
586 586 | | summary: B0
587 587 | |
588 588 | x changeset: 1:471f378eab4c
589 589 |/ user: test
590 590 | date: Thu Jan 01 00:00:00 1970 +0000
591 591 | summary: A0
592 592 |
593 593 o changeset: 0:ea207398892e
594 594 user: test
595 595 date: Thu Jan 01 00:00:00 1970 +0000
596 596 summary: ROOT
597 597
598 598 Check templates
599 599 ---------------
600 600
601 601 $ hg up 'desc(A0)' --hidden
602 602 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
603 603
604 604 Predecessors template should show current revision as it is the working copy
605 605 $ hg tlog
606 606 o eb5a0daa2192
607 607 | Predecessors: 471f378eab4c
608 608 | semi-colon: 471f378eab4c
609 609 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
610 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
610 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
611 611 | @ 471f378eab4c
612 612 |/
613 613 o ea207398892e
614 614
615 615 $ hg up 'desc(B0)' --hidden
616 616 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
617 617
618 618 Predecessors template should both predecessors as they are visible
619 619 $ hg tlog
620 620 o eb5a0daa2192
621 621 | Predecessors: 0dec01379d3b 471f378eab4c
622 622 | semi-colon: 0dec01379d3b; 471f378eab4c
623 623 | json: ["0dec01379d3be6318c470ead31b1fe7ae7cb53d5", "471f378eab4c5e25f6c77f785b27c936efb22874"]
624 | map: 0dec01379d3be6318c470ead31b1fe7ae7cb53d5 471f378eab4c5e25f6c77f785b27c936efb22874
624 | map: 2:0dec01379d3be6318c470ead31b1fe7ae7cb53d5 1:471f378eab4c5e25f6c77f785b27c936efb22874
625 625 | @ 0dec01379d3b
626 626 | |
627 627 | x 471f378eab4c
628 628 |/
629 629 o ea207398892e
630 630
631 631 $ hg up 'desc(B1)' --hidden
632 632 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
633 633
634 634 Predecessors template should both predecessors as they are visible
635 635 $ hg tlog
636 636 o eb5a0daa2192
637 637 | Predecessors: 471f378eab4c b7ea6d14e664
638 638 | semi-colon: 471f378eab4c; b7ea6d14e664
639 639 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874", "b7ea6d14e664bdc8922221f7992631b50da3fb07"]
640 | map: 471f378eab4c5e25f6c77f785b27c936efb22874 b7ea6d14e664bdc8922221f7992631b50da3fb07
640 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874 3:b7ea6d14e664bdc8922221f7992631b50da3fb07
641 641 | @ b7ea6d14e664
642 642 | |
643 643 | x 471f378eab4c
644 644 |/
645 645 o ea207398892e
646 646
647 647 $ hg up 'desc(C0)'
648 648 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
649 649
650 650 Predecessors template should show no predecessors as they are both non visible
651 651 $ hg tlog
652 652 @ eb5a0daa2192
653 653 |
654 654 o ea207398892e
655 655
656 656 Predecessors template should show all predecessors as we force their display
657 657 with --hidden
658 658 $ hg tlog --hidden
659 659 @ eb5a0daa2192
660 660 | Predecessors: 471f378eab4c b7ea6d14e664
661 661 | semi-colon: 471f378eab4c; b7ea6d14e664
662 662 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874", "b7ea6d14e664bdc8922221f7992631b50da3fb07"]
663 | map: 471f378eab4c5e25f6c77f785b27c936efb22874 b7ea6d14e664bdc8922221f7992631b50da3fb07
663 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874 3:b7ea6d14e664bdc8922221f7992631b50da3fb07
664 664 | x b7ea6d14e664
665 665 | | Predecessors: 0dec01379d3b
666 666 | | semi-colon: 0dec01379d3b
667 667 | | json: ["0dec01379d3be6318c470ead31b1fe7ae7cb53d5"]
668 | | map: 0dec01379d3be6318c470ead31b1fe7ae7cb53d5
668 | | map: 2:0dec01379d3be6318c470ead31b1fe7ae7cb53d5
669 669 | | x 0dec01379d3b
670 670 | |/
671 671 | x 471f378eab4c
672 672 |/
673 673 o ea207398892e
674 674
675 675
676 676 Test template with pushed and pulled obs markers
677 677 ================================================
678 678
679 679 Test setup
680 680 ----------
681 681
682 682 $ hg init $TESTTMP/templates-local-remote-markers-1
683 683 $ cd $TESTTMP/templates-local-remote-markers-1
684 684 $ mkcommit ROOT
685 685 $ mkcommit A0
686 686 $ hg clone $TESTTMP/templates-local-remote-markers-1 $TESTTMP/templates-local-remote-markers-2
687 687 updating to branch default
688 688 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
689 689 $ cd $TESTTMP/templates-local-remote-markers-2
690 690 $ hg log --hidden -G
691 691 @ changeset: 1:471f378eab4c
692 692 | tag: tip
693 693 | user: test
694 694 | date: Thu Jan 01 00:00:00 1970 +0000
695 695 | summary: A0
696 696 |
697 697 o changeset: 0:ea207398892e
698 698 user: test
699 699 date: Thu Jan 01 00:00:00 1970 +0000
700 700 summary: ROOT
701 701
702 702 $ cd $TESTTMP/templates-local-remote-markers-1
703 703 $ hg commit --amend -m "A1"
704 704 $ hg commit --amend -m "A2"
705 705 $ hg log --hidden -G
706 706 @ changeset: 3:7a230b46bf61
707 707 | tag: tip
708 708 | parent: 0:ea207398892e
709 709 | user: test
710 710 | date: Thu Jan 01 00:00:00 1970 +0000
711 711 | summary: A2
712 712 |
713 713 | x changeset: 2:fdf9bde5129a
714 714 |/ parent: 0:ea207398892e
715 715 | user: test
716 716 | date: Thu Jan 01 00:00:00 1970 +0000
717 717 | summary: A1
718 718 |
719 719 | x changeset: 1:471f378eab4c
720 720 |/ user: test
721 721 | date: Thu Jan 01 00:00:00 1970 +0000
722 722 | summary: A0
723 723 |
724 724 o changeset: 0:ea207398892e
725 725 user: test
726 726 date: Thu Jan 01 00:00:00 1970 +0000
727 727 summary: ROOT
728 728
729 729 $ cd $TESTTMP/templates-local-remote-markers-2
730 730 $ hg pull
731 731 pulling from $TESTTMP/templates-local-remote-markers-1 (glob)
732 732 searching for changes
733 733 adding changesets
734 734 adding manifests
735 735 adding file changes
736 736 added 1 changesets with 0 changes to 1 files (+1 heads)
737 737 2 new obsolescence markers
738 738 (run 'hg heads' to see heads, 'hg merge' to merge)
739 739 $ hg log --hidden -G
740 740 o changeset: 2:7a230b46bf61
741 741 | tag: tip
742 742 | parent: 0:ea207398892e
743 743 | user: test
744 744 | date: Thu Jan 01 00:00:00 1970 +0000
745 745 | summary: A2
746 746 |
747 747 | @ changeset: 1:471f378eab4c
748 748 |/ user: test
749 749 | date: Thu Jan 01 00:00:00 1970 +0000
750 750 | summary: A0
751 751 |
752 752 o changeset: 0:ea207398892e
753 753 user: test
754 754 date: Thu Jan 01 00:00:00 1970 +0000
755 755 summary: ROOT
756 756
757 757
758 758 $ hg debugobsolete
759 759 471f378eab4c5e25f6c77f785b27c936efb22874 fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
760 760 fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e 7a230b46bf61e50b30308c6cfd7bd1269ef54702 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
761 761
762 762 Check templates
763 763 ---------------
764 764
765 765 Predecessors template should show current revision as it is the working copy
766 766 $ hg tlog
767 767 o 7a230b46bf61
768 768 | Predecessors: 471f378eab4c
769 769 | semi-colon: 471f378eab4c
770 770 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
771 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
771 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
772 772 | @ 471f378eab4c
773 773 |/
774 774 o ea207398892e
775 775
776 776 $ hg up 'desc(A2)'
777 777 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
778 778
779 779 Predecessors template should show no predecessors as they are non visible
780 780 $ hg tlog
781 781 @ 7a230b46bf61
782 782 |
783 783 o ea207398892e
784 784
785 785 Predecessors template should show all predecessors as we force their display
786 786 with --hidden
787 787 $ hg tlog --hidden
788 788 @ 7a230b46bf61
789 789 | Predecessors: 471f378eab4c
790 790 | semi-colon: 471f378eab4c
791 791 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
792 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
792 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
793 793 | x 471f378eab4c
794 794 |/
795 795 o ea207398892e
796 796
797 797
798 798 Test template with obsmarkers cycle
799 799 ===================================
800 800
801 801 Test setup
802 802 ----------
803 803
804 804 $ hg init $TESTTMP/templates-local-cycle
805 805 $ cd $TESTTMP/templates-local-cycle
806 806 $ mkcommit ROOT
807 807 $ mkcommit A0
808 808 $ mkcommit B0
809 809 $ hg up -r 0
810 810 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
811 811 $ mkcommit C0
812 812 created new head
813 813
814 814 Create the cycle
815 815
816 816 $ hg debugobsolete `getid "desc(A0)"` `getid "desc(B0)"`
817 817 $ hg debugobsolete `getid "desc(B0)"` `getid "desc(C0)"`
818 818 $ hg debugobsolete `getid "desc(B0)"` `getid "desc(A0)"`
819 819
820 820 Check templates
821 821 ---------------
822 822
823 823 $ hg tlog
824 824 @ f897c6137566
825 825 |
826 826 o ea207398892e
827 827
828 828
829 829 $ hg up -r "desc(B0)" --hidden
830 830 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
831 831 $ hg tlog
832 832 o f897c6137566
833 833 | Predecessors: 0dec01379d3b
834 834 | semi-colon: 0dec01379d3b
835 835 | json: ["0dec01379d3be6318c470ead31b1fe7ae7cb53d5"]
836 | map: 0dec01379d3be6318c470ead31b1fe7ae7cb53d5
836 | map: 2:0dec01379d3be6318c470ead31b1fe7ae7cb53d5
837 837 | @ 0dec01379d3b
838 838 | | Predecessors: 471f378eab4c
839 839 | | semi-colon: 471f378eab4c
840 840 | | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
841 | | map: 471f378eab4c5e25f6c77f785b27c936efb22874
841 | | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
842 842 | x 471f378eab4c
843 843 |/ Predecessors: 0dec01379d3b
844 844 | semi-colon: 0dec01379d3b
845 845 | json: ["0dec01379d3be6318c470ead31b1fe7ae7cb53d5"]
846 | map: 0dec01379d3be6318c470ead31b1fe7ae7cb53d5
846 | map: 2:0dec01379d3be6318c470ead31b1fe7ae7cb53d5
847 847 o ea207398892e
848 848
849 849
850 850 $ hg up -r "desc(A0)" --hidden
851 851 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
852 852 $ hg tlog
853 853 o f897c6137566
854 854 | Predecessors: 471f378eab4c
855 855 | semi-colon: 471f378eab4c
856 856 | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
857 | map: 471f378eab4c5e25f6c77f785b27c936efb22874
857 | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
858 858 | @ 471f378eab4c
859 859 |/
860 860 o ea207398892e
861 861
862 862
863 863 $ hg up -r "desc(ROOT)" --hidden
864 864 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
865 865 $ hg tlog
866 866 o f897c6137566
867 867 |
868 868 @ ea207398892e
869 869
870 870
871 871 $ hg tlog --hidden
872 872 o f897c6137566
873 873 | Predecessors: 0dec01379d3b
874 874 | semi-colon: 0dec01379d3b
875 875 | json: ["0dec01379d3be6318c470ead31b1fe7ae7cb53d5"]
876 | map: 0dec01379d3be6318c470ead31b1fe7ae7cb53d5
876 | map: 2:0dec01379d3be6318c470ead31b1fe7ae7cb53d5
877 877 | x 0dec01379d3b
878 878 | | Predecessors: 471f378eab4c
879 879 | | semi-colon: 471f378eab4c
880 880 | | json: ["471f378eab4c5e25f6c77f785b27c936efb22874"]
881 | | map: 471f378eab4c5e25f6c77f785b27c936efb22874
881 | | map: 1:471f378eab4c5e25f6c77f785b27c936efb22874
882 882 | x 471f378eab4c
883 883 |/ Predecessors: 0dec01379d3b
884 884 | semi-colon: 0dec01379d3b
885 885 | json: ["0dec01379d3be6318c470ead31b1fe7ae7cb53d5"]
886 | map: 0dec01379d3be6318c470ead31b1fe7ae7cb53d5
886 | map: 2:0dec01379d3be6318c470ead31b1fe7ae7cb53d5
887 887 @ ea207398892e
888 888
General Comments 0
You need to be logged in to leave comments. Login now