##// END OF EJS Templates
tests: extract test-template-keywords.t from test-command-template.t
Yuya Nishihara -
r38455:da4508cd default
parent child Browse files
Show More
@@ -1,526 +1,527
1 1 test-abort-checkin.t
2 2 test-add.t
3 3 test-addremove-similar.t
4 4 test-addremove.t
5 5 test-amend-subrepo.t
6 6 test-amend.t
7 7 test-ancestor.py
8 8 test-annotate.py
9 9 test-annotate.t
10 10 test-archive-symlinks.t
11 11 test-atomictempfile.py
12 12 test-audit-path.t
13 13 test-audit-subrepo.t
14 14 test-automv.t
15 15 test-backout.t
16 16 test-backwards-remove.t
17 17 test-basic.t
18 18 test-bheads.t
19 19 test-bisect.t
20 20 test-bisect2.t
21 21 test-bisect3.t
22 22 test-blackbox.t
23 23 test-bookmarks-current.t
24 24 test-bookmarks-merge.t
25 25 test-bookmarks-rebase.t
26 26 test-bookmarks-strip.t
27 27 test-bookmarks.t
28 28 test-branch-change.t
29 29 test-branch-option.t
30 30 test-branch-tag-confict.t
31 31 test-branches.t
32 32 test-bundle-phases.t
33 33 test-bundle-type.t
34 34 test-bundle-vs-outgoing.t
35 35 test-bundle2-multiple-changegroups.t
36 36 test-cappedreader.py
37 37 test-casecollision.t
38 38 test-cat.t
39 39 test-cbor.py
40 40 test-censor.t
41 41 test-changelog-exec.t
42 42 test-check-commit.t
43 43 test-check-execute.t
44 44 test-check-interfaces.py
45 45 test-check-module-imports.t
46 46 test-check-pyflakes.t
47 47 test-check-pylint.t
48 48 test-check-shbang.t
49 49 test-children.t
50 50 test-clone-cgi.t
51 51 test-clone-pull-corruption.t
52 52 test-clone-r.t
53 53 test-clone-update-order.t
54 54 test-command-template.t
55 55 test-commit-amend.t
56 56 test-commit-interactive.t
57 57 test-commit-multiple.t
58 58 test-commit-unresolved.t
59 59 test-commit.t
60 60 test-committer.t
61 61 test-completion.t
62 62 test-config-env.py
63 63 test-config.t
64 64 test-conflict.t
65 65 test-confused-revert.t
66 66 test-context.py
67 67 test-contrib-check-code.t
68 68 test-contrib-check-commit.t
69 69 test-convert-authormap.t
70 70 test-convert-clonebranches.t
71 71 test-convert-cvs-branch.t
72 72 test-convert-cvs-detectmerge.t
73 73 test-convert-cvs-synthetic.t
74 74 test-convert-cvs.t
75 75 test-convert-cvsnt-mergepoints.t
76 76 test-convert-datesort.t
77 77 test-convert-filemap.t
78 78 test-convert-hg-sink.t
79 79 test-convert-hg-source.t
80 80 test-convert-hg-startrev.t
81 81 test-convert-splicemap.t
82 82 test-convert-tagsbranch-topology.t
83 83 test-copy-move-merge.t
84 84 test-copy.t
85 85 test-copytrace-heuristics.t
86 86 test-debugbuilddag.t
87 87 test-debugbundle.t
88 88 test-debugextensions.t
89 89 test-debugindexdot.t
90 90 test-debugrename.t
91 91 test-default-push.t
92 92 test-diff-binary-file.t
93 93 test-diff-change.t
94 94 test-diff-copy-depth.t
95 95 test-diff-hashes.t
96 96 test-diff-ignore-whitespace.t
97 97 test-diff-indent-heuristic.t
98 98 test-diff-issue2761.t
99 99 test-diff-newlines.t
100 100 test-diff-reverse.t
101 101 test-diff-subdir.t
102 102 test-diff-unified.t
103 103 test-diff-upgrade.t
104 104 test-diffdir.t
105 105 test-diffstat.t
106 106 test-directaccess.t
107 107 test-dirstate-backup.t
108 108 test-dirstate-nonnormalset.t
109 109 test-dirstate.t
110 110 test-dispatch.py
111 111 test-doctest.py
112 112 test-double-merge.t
113 113 test-drawdag.t
114 114 test-duplicateoptions.py
115 115 test-editor-filename.t
116 116 test-empty-dir.t
117 117 test-empty-file.t
118 118 test-empty-group.t
119 119 test-empty.t
120 120 test-encode.t
121 121 test-encoding-func.py
122 122 test-encoding.t
123 123 test-eol-add.t
124 124 test-eol-clone.t
125 125 test-eol-hook.t
126 126 test-eol-patch.t
127 127 test-eol-tag.t
128 128 test-eol-update.t
129 129 test-eol.t
130 130 test-eolfilename.t
131 131 test-excessive-merge.t
132 132 test-exchange-obsmarkers-case-A1.t
133 133 test-exchange-obsmarkers-case-A2.t
134 134 test-exchange-obsmarkers-case-A3.t
135 135 test-exchange-obsmarkers-case-A4.t
136 136 test-exchange-obsmarkers-case-A5.t
137 137 test-exchange-obsmarkers-case-A6.t
138 138 test-exchange-obsmarkers-case-A7.t
139 139 test-exchange-obsmarkers-case-B1.t
140 140 test-exchange-obsmarkers-case-B2.t
141 141 test-exchange-obsmarkers-case-B3.t
142 142 test-exchange-obsmarkers-case-B4.t
143 143 test-exchange-obsmarkers-case-B5.t
144 144 test-exchange-obsmarkers-case-B6.t
145 145 test-exchange-obsmarkers-case-B7.t
146 146 test-exchange-obsmarkers-case-C1.t
147 147 test-exchange-obsmarkers-case-C2.t
148 148 test-exchange-obsmarkers-case-C3.t
149 149 test-exchange-obsmarkers-case-C4.t
150 150 test-exchange-obsmarkers-case-D1.t
151 151 test-exchange-obsmarkers-case-D2.t
152 152 test-exchange-obsmarkers-case-D3.t
153 153 test-exchange-obsmarkers-case-D4.t
154 154 test-execute-bit.t
155 155 test-export.t
156 156 test-extdata.t
157 157 test-extdiff.t
158 158 test-extensions-afterloaded.t
159 159 test-extensions-wrapfunction.py
160 160 test-extra-filelog-entry.t
161 161 test-fetch.t
162 162 test-filebranch.t
163 163 test-filecache.py
164 164 test-filelog.py
165 165 test-fileset-generated.t
166 166 test-fileset.t
167 167 test-fix-topology.t
168 168 test-flags.t
169 169 test-generaldelta.t
170 170 test-getbundle.t
171 171 test-git-export.t
172 172 test-glog-topological.t
173 173 test-gpg.t
174 174 test-graft.t
175 175 test-hg-parseurl.py
176 176 test-hghave.t
177 177 test-hgignore.t
178 178 test-hgk.t
179 179 test-hgrc.t
180 180 test-hgweb-bundle.t
181 181 test-hgweb-descend-empties.t
182 182 test-hgweb-empty.t
183 183 test-hgweb-removed.t
184 184 test-hgwebdir-paths.py
185 185 test-hgwebdirsym.t
186 186 test-histedit-arguments.t
187 187 test-histedit-base.t
188 188 test-histedit-bookmark-motion.t
189 189 test-histedit-commute.t
190 190 test-histedit-drop.t
191 191 test-histedit-edit.t
192 192 test-histedit-fold-non-commute.t
193 193 test-histedit-fold.t
194 194 test-histedit-no-change.t
195 195 test-histedit-non-commute-abort.t
196 196 test-histedit-non-commute.t
197 197 test-histedit-obsolete.t
198 198 test-histedit-outgoing.t
199 199 test-histedit-templates.t
200 200 test-http-branchmap.t
201 201 test-http-bundle1.t
202 202 test-http-clone-r.t
203 203 test-http.t
204 204 test-hybridencode.py
205 205 test-identify.t
206 206 test-impexp-branch.t
207 207 test-import-bypass.t
208 208 test-import-eol.t
209 209 test-import-merge.t
210 210 test-import-unknown.t
211 211 test-import.t
212 212 test-imports-checker.t
213 213 test-incoming-outgoing.t
214 214 test-inherit-mode.t
215 215 test-init.t
216 216 test-issue1089.t
217 217 test-issue1102.t
218 218 test-issue1175.t
219 219 test-issue1306.t
220 220 test-issue1438.t
221 221 test-issue1502.t
222 222 test-issue1802.t
223 223 test-issue1877.t
224 224 test-issue1993.t
225 225 test-issue2137.t
226 226 test-issue3084.t
227 227 test-issue4074.t
228 228 test-issue522.t
229 229 test-issue586.t
230 230 test-issue612.t
231 231 test-issue619.t
232 232 test-issue660.t
233 233 test-issue672.t
234 234 test-issue842.t
235 235 test-journal-exists.t
236 236 test-journal-share.t
237 237 test-journal.t
238 238 test-known.t
239 239 test-largefiles-cache.t
240 240 test-largefiles-misc.t
241 241 test-largefiles-small-disk.t
242 242 test-largefiles-update.t
243 243 test-largefiles.t
244 244 test-lfs-largefiles.t
245 245 test-lfs-pointer.py
246 246 test-linerange.py
247 247 test-locate.t
248 248 test-lock-badness.t
249 249 test-log-linerange.t
250 250 test-log.t
251 251 test-logexchange.t
252 252 test-lrucachedict.py
253 253 test-mactext.t
254 254 test-mailmap.t
255 255 test-manifest-merging.t
256 256 test-manifest.py
257 257 test-manifest.t
258 258 test-match.py
259 259 test-mdiff.py
260 260 test-merge-changedelete.t
261 261 test-merge-closedheads.t
262 262 test-merge-commit.t
263 263 test-merge-criss-cross.t
264 264 test-merge-default.t
265 265 test-merge-force.t
266 266 test-merge-halt.t
267 267 test-merge-internal-tools-pattern.t
268 268 test-merge-local.t
269 269 test-merge-remove.t
270 270 test-merge-revert.t
271 271 test-merge-revert2.t
272 272 test-merge-subrepos.t
273 273 test-merge-symlinks.t
274 274 test-merge-tools.t
275 275 test-merge-types.t
276 276 test-merge1.t
277 277 test-merge10.t
278 278 test-merge2.t
279 279 test-merge4.t
280 280 test-merge5.t
281 281 test-merge6.t
282 282 test-merge7.t
283 283 test-merge8.t
284 284 test-merge9.t
285 285 test-minifileset.py
286 286 test-minirst.py
287 287 test-mq-git.t
288 288 test-mq-header-date.t
289 289 test-mq-header-from.t
290 290 test-mq-merge.t
291 291 test-mq-pull-from-bundle.t
292 292 test-mq-qclone-http.t
293 293 test-mq-qdelete.t
294 294 test-mq-qdiff.t
295 295 test-mq-qfold.t
296 296 test-mq-qgoto.t
297 297 test-mq-qimport-fail-cleanup.t
298 298 test-mq-qnew.t
299 299 test-mq-qpush-exact.t
300 300 test-mq-qqueue.t
301 301 test-mq-qrefresh-interactive.t
302 302 test-mq-qrefresh-replace-log-message.t
303 303 test-mq-qrefresh.t
304 304 test-mq-qrename.t
305 305 test-mq-qsave.t
306 306 test-mq-safety.t
307 307 test-mq-subrepo.t
308 308 test-mq-symlinks.t
309 309 test-mv-cp-st-diff.t
310 310 test-narrow-archive.t
311 311 test-narrow-clone-no-ellipsis.t
312 312 test-narrow-clone-non-narrow-server.t
313 313 test-narrow-clone-nonlinear.t
314 314 test-narrow-clone.t
315 315 test-narrow-commit.t
316 316 test-narrow-copies.t
317 317 test-narrow-debugcommands.t
318 318 test-narrow-debugrebuilddirstate.t
319 319 test-narrow-exchange-merges.t
320 320 test-narrow-exchange.t
321 321 test-narrow-expanddirstate.t
322 322 test-narrow-merge.t
323 323 test-narrow-patch.t
324 324 test-narrow-patterns.t
325 325 test-narrow-pull.t
326 326 test-narrow-rebase.t
327 327 test-narrow-shallow-merges.t
328 328 test-narrow-shallow.t
329 329 test-narrow-strip.t
330 330 test-narrow-update.t
331 331 test-narrow-widen.t
332 332 test-narrow.t
333 333 test-nested-repo.t
334 334 test-newbranch.t
335 335 test-obshistory.t
336 336 test-obsmarker-template.t
337 337 test-obsmarkers-effectflag.t
338 338 test-obsolete-bundle-strip.t
339 339 test-obsolete-changeset-exchange.t
340 340 test-obsolete-checkheads.t
341 341 test-obsolete-distributed.t
342 342 test-obsolete-tag-cache.t
343 343 test-pager.t
344 344 test-parents.t
345 345 test-parseindex2.py
346 346 test-patch-offset.t
347 347 test-patch.t
348 348 test-pathconflicts-merge.t
349 349 test-pathconflicts-update.t
350 350 test-pathencode.py
351 351 test-pending.t
352 352 test-permissions.t
353 353 test-phases.t
354 354 test-pull-branch.t
355 355 test-pull-http.t
356 356 test-pull-permission.t
357 357 test-pull-pull-corruption.t
358 358 test-pull-r.t
359 359 test-pull-update.t
360 360 test-pull.t
361 361 test-purge.t
362 362 test-push-checkheads-partial-C1.t
363 363 test-push-checkheads-partial-C2.t
364 364 test-push-checkheads-partial-C3.t
365 365 test-push-checkheads-partial-C4.t
366 366 test-push-checkheads-pruned-B1.t
367 367 test-push-checkheads-pruned-B2.t
368 368 test-push-checkheads-pruned-B3.t
369 369 test-push-checkheads-pruned-B4.t
370 370 test-push-checkheads-pruned-B5.t
371 371 test-push-checkheads-pruned-B6.t
372 372 test-push-checkheads-pruned-B7.t
373 373 test-push-checkheads-pruned-B8.t
374 374 test-push-checkheads-superceed-A1.t
375 375 test-push-checkheads-superceed-A2.t
376 376 test-push-checkheads-superceed-A3.t
377 377 test-push-checkheads-superceed-A4.t
378 378 test-push-checkheads-superceed-A5.t
379 379 test-push-checkheads-superceed-A6.t
380 380 test-push-checkheads-superceed-A7.t
381 381 test-push-checkheads-superceed-A8.t
382 382 test-push-checkheads-unpushed-D1.t
383 383 test-push-checkheads-unpushed-D2.t
384 384 test-push-checkheads-unpushed-D3.t
385 385 test-push-checkheads-unpushed-D4.t
386 386 test-push-checkheads-unpushed-D5.t
387 387 test-push-checkheads-unpushed-D6.t
388 388 test-push-checkheads-unpushed-D7.t
389 389 test-push-http.t
390 390 test-push-warn.t
391 391 test-push.t
392 392 test-pushvars.t
393 393 test-qrecord.t
394 394 test-rebase-abort.t
395 395 test-rebase-base-flag.t
396 396 test-rebase-bookmarks.t
397 397 test-rebase-brute-force.t
398 398 test-rebase-cache.t
399 399 test-rebase-check-restore.t
400 400 test-rebase-collapse.t
401 401 test-rebase-conflicts.t
402 402 test-rebase-dest.t
403 403 test-rebase-detach.t
404 404 test-rebase-emptycommit.t
405 405 test-rebase-inmemory.t
406 406 test-rebase-interruptions.t
407 407 test-rebase-issue-noparam-single-rev.t
408 408 test-rebase-legacy.t
409 409 test-rebase-mq-skip.t
410 410 test-rebase-mq.t
411 411 test-rebase-named-branches.t
412 412 test-rebase-newancestor.t
413 413 test-rebase-obsolete.t
414 414 test-rebase-parameters.t
415 415 test-rebase-partial.t
416 416 test-rebase-pull.t
417 417 test-rebase-rename.t
418 418 test-rebase-scenario-global.t
419 419 test-rebase-templates.t
420 420 test-rebase-transaction.t
421 421 test-rebuildstate.t
422 422 test-record.t
423 423 test-relink.t
424 424 test-remove.t
425 425 test-rename-after-merge.t
426 426 test-rename-dir-merge.t
427 427 test-rename-merge1.t
428 428 test-rename.t
429 429 test-repair-strip.t
430 430 test-repo-compengines.t
431 431 test-resolve.t
432 432 test-revert-flags.t
433 433 test-revert-interactive.t
434 434 test-revert-unknown.t
435 435 test-revlog-ancestry.py
436 436 test-revlog-group-emptyiter.t
437 437 test-revlog-mmapindex.t
438 438 test-revlog-packentry.t
439 439 test-revlog-raw.py
440 440 test-revlog-v2.t
441 441 test-revset-dirstate-parents.t
442 442 test-revset-legacy-lookup.t
443 443 test-revset-outgoing.t
444 444 test-rollback.t
445 445 test-run-tests.py
446 446 test-run-tests.t
447 447 test-schemes.t
448 448 test-serve.t
449 449 test-setdiscovery.t
450 450 test-share.t
451 451 test-shelve.t
452 452 test-show-stack.t
453 453 test-show-work.t
454 454 test-show.t
455 455 test-simple-update.t
456 456 test-simplekeyvaluefile.py
457 457 test-simplemerge.py
458 458 test-single-head.t
459 459 test-sparse-clear.t
460 460 test-sparse-clone.t
461 461 test-sparse-import.t
462 462 test-sparse-merges.t
463 463 test-sparse-profiles.t
464 464 test-sparse-requirement.t
465 465 test-sparse-verbose-json.t
466 466 test-sparse.t
467 467 test-split.t
468 468 test-ssh-bundle1.t
469 469 test-ssh-clone-r.t
470 470 test-ssh-proto-unbundle.t
471 471 test-ssh-proto.t
472 472 test-ssh.t
473 473 test-sshserver.py
474 474 test-stack.t
475 475 test-status-inprocess.py
476 476 test-status-rev.t
477 477 test-status-terse.t
478 478 test-strict.t
479 479 test-strip-cross.t
480 480 test-strip.t
481 481 test-subrepo-deep-nested-change.t
482 482 test-subrepo-missing.t
483 483 test-subrepo-paths.t
484 484 test-subrepo-recursion.t
485 485 test-subrepo-relative-path.t
486 486 test-subrepo.t
487 487 test-symlink-os-yes-fs-no.py
488 488 test-symlink-placeholder.t
489 489 test-symlinks.t
490 490 test-tag.t
491 491 test-tags.t
492 492 test-template-functions.t
493 test-template-keywords.t
493 494 test-template-map.t
494 495 test-transplant.t
495 496 test-treemanifest.t
496 497 test-ui-color.py
497 498 test-ui-config.py
498 499 test-ui-verbosity.py
499 500 test-unamend.t
500 501 test-unbundlehash.t
501 502 test-uncommit.t
502 503 test-unified-test.t
503 504 test-unionrepo.t
504 505 test-unrelated-pull.t
505 506 test-up-local-change.t
506 507 test-update-branches.t
507 508 test-update-dest.t
508 509 test-update-issue1456.t
509 510 test-update-names.t
510 511 test-update-reverse.t
511 512 test-upgrade-repo.t
512 513 test-url-download.t
513 514 test-url-rev.t
514 515 test-url.py
515 516 test-username-newline.t
516 517 test-verify.t
517 518 test-walk.t
518 519 test-walkrepo.py
519 520 test-websub.t
520 521 test-win32text.t
521 522 test-wireproto-clientreactor.py
522 523 test-wireproto-framing.py
523 524 test-wireproto-serverreactor.py
524 525 test-wireproto.py
525 526 test-wsgirequest.py
526 527 test-xdg.t
This diff has been collapsed as it changes many lines, (1079 lines changed) Show them Hide them
@@ -1,2160 +1,1085
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 Test arithmetic operators have the right precedence:
33 33
34 34 $ hg log -l 1 -T '{date(date, "%Y") + 5 * 10} {date(date, "%Y") - 2 * 3}\n'
35 35 2020 1964
36 36 $ hg log -l 1 -T '{date(date, "%Y") * 5 + 10} {date(date, "%Y") * 3 - 2}\n'
37 37 9860 5908
38 38
39 39 Test division:
40 40
41 41 $ hg debugtemplate -r0 -v '{5 / 2} {mod(5, 2)}\n'
42 42 (template
43 43 (/
44 44 (integer '5')
45 45 (integer '2'))
46 46 (string ' ')
47 47 (func
48 48 (symbol 'mod')
49 49 (list
50 50 (integer '5')
51 51 (integer '2')))
52 52 (string '\n'))
53 53 * keywords:
54 54 * functions: mod
55 55 2 1
56 56 $ hg debugtemplate -r0 -v '{5 / -2} {mod(5, -2)}\n'
57 57 (template
58 58 (/
59 59 (integer '5')
60 60 (negate
61 61 (integer '2')))
62 62 (string ' ')
63 63 (func
64 64 (symbol 'mod')
65 65 (list
66 66 (integer '5')
67 67 (negate
68 68 (integer '2'))))
69 69 (string '\n'))
70 70 * keywords:
71 71 * functions: mod
72 72 -3 -1
73 73 $ hg debugtemplate -r0 -v '{-5 / 2} {mod(-5, 2)}\n'
74 74 (template
75 75 (/
76 76 (negate
77 77 (integer '5'))
78 78 (integer '2'))
79 79 (string ' ')
80 80 (func
81 81 (symbol 'mod')
82 82 (list
83 83 (negate
84 84 (integer '5'))
85 85 (integer '2')))
86 86 (string '\n'))
87 87 * keywords:
88 88 * functions: mod
89 89 -3 1
90 90 $ hg debugtemplate -r0 -v '{-5 / -2} {mod(-5, -2)}\n'
91 91 (template
92 92 (/
93 93 (negate
94 94 (integer '5'))
95 95 (negate
96 96 (integer '2')))
97 97 (string ' ')
98 98 (func
99 99 (symbol 'mod')
100 100 (list
101 101 (negate
102 102 (integer '5'))
103 103 (negate
104 104 (integer '2'))))
105 105 (string '\n'))
106 106 * keywords:
107 107 * functions: mod
108 108 2 -1
109 109
110 110 Filters bind closer than arithmetic:
111 111
112 112 $ hg debugtemplate -r0 -v '{revset(".")|count - 1}\n'
113 113 (template
114 114 (-
115 115 (|
116 116 (func
117 117 (symbol 'revset')
118 118 (string '.'))
119 119 (symbol 'count'))
120 120 (integer '1'))
121 121 (string '\n'))
122 122 * keywords:
123 123 * functions: count, revset
124 124 0
125 125
126 126 But negate binds closer still:
127 127
128 128 $ hg debugtemplate -r0 -v '{1-3|stringify}\n'
129 129 (template
130 130 (-
131 131 (integer '1')
132 132 (|
133 133 (integer '3')
134 134 (symbol 'stringify')))
135 135 (string '\n'))
136 136 * keywords:
137 137 * functions: stringify
138 138 hg: parse error: arithmetic only defined on integers
139 139 [255]
140 140 $ hg debugtemplate -r0 -v '{-3|stringify}\n'
141 141 (template
142 142 (|
143 143 (negate
144 144 (integer '3'))
145 145 (symbol 'stringify'))
146 146 (string '\n'))
147 147 * keywords:
148 148 * functions: stringify
149 149 -3
150 150
151 151 Filters bind as close as map operator:
152 152
153 153 $ hg debugtemplate -r0 -v '{desc|splitlines % "{line}\n"}'
154 154 (template
155 155 (%
156 156 (|
157 157 (symbol 'desc')
158 158 (symbol 'splitlines'))
159 159 (template
160 160 (symbol 'line')
161 161 (string '\n'))))
162 162 * keywords: desc, line
163 163 * functions: splitlines
164 164 line 1
165 165 line 2
166 166
167 167 Keyword arguments:
168 168
169 169 $ hg debugtemplate -r0 -v '{foo=bar|baz}'
170 170 (template
171 171 (keyvalue
172 172 (symbol 'foo')
173 173 (|
174 174 (symbol 'bar')
175 175 (symbol 'baz'))))
176 176 * keywords: bar, foo
177 177 * functions: baz
178 178 hg: parse error: can't use a key-value pair in this context
179 179 [255]
180 180
181 181 $ hg debugtemplate '{pad("foo", width=10, left=true)}\n'
182 182 foo
183 183
184 184 Call function which takes named arguments by filter syntax:
185 185
186 186 $ hg debugtemplate '{" "|separate}'
187 187 $ hg debugtemplate '{("not", "an", "argument", "list")|separate}'
188 188 hg: parse error: unknown method 'list'
189 189 [255]
190 190
191 191 Second branch starting at nullrev:
192 192
193 193 $ hg update null
194 194 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
195 195 $ echo second > second
196 196 $ hg add second
197 197 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
198 198 created new head
199 199
200 200 $ echo third > third
201 201 $ hg add third
202 202 $ hg mv second fourth
203 203 $ hg commit -m third -d "2020-01-01 10:01"
204 204
205 205 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
206 206 fourth (second)
207 207 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
208 208 second -> fourth
209 209 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
210 210 8 t
211 211 7 f
212 212
213 Working-directory revision has special identifiers, though they are still
214 experimental:
215
216 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
217 2147483647:ffffffffffffffffffffffffffffffffffffffff
218
219 Some keywords are invalid for working-directory revision, but they should
220 never cause crash:
221
222 $ hg log -r 'wdir()' -T '{manifest}\n'
223
224
225 213 Internal resources shouldn't be exposed (issue5699):
226 214
227 215 $ hg log -r. -T '{cache}{ctx}{repo}{revcache}{templ}{ui}'
228 216
229 217 Never crash on internal resource not available:
230 218
231 219 $ hg --cwd .. debugtemplate '{"c0bebeef"|shortest}\n'
232 220 abort: template resource not available: repo
233 221 [255]
234 222
235 223 $ hg config -T '{author}'
236 224
237 225 Quoting for ui.logtemplate
238 226
239 227 $ hg tip --config "ui.logtemplate={rev}\n"
240 228 8
241 229 $ hg tip --config "ui.logtemplate='{rev}\n'"
242 230 8
243 231 $ hg tip --config 'ui.logtemplate="{rev}\n"'
244 232 8
245 233 $ hg tip --config 'ui.logtemplate=n{rev}\n'
246 234 n8
247 235
248 236 Check that recursive reference does not fall into RuntimeError (issue4758):
249 237
250 238 common mistake:
251 239
252 240 $ cat << EOF > issue4758
253 241 > changeset = '{changeset}\n'
254 242 > EOF
255 243 $ hg log --style ./issue4758
256 244 abort: recursive reference 'changeset' in template
257 245 [255]
258 246
259 247 circular reference:
260 248
261 249 $ cat << EOF > issue4758
262 250 > changeset = '{foo}'
263 251 > foo = '{changeset}'
264 252 > EOF
265 253 $ hg log --style ./issue4758
266 254 abort: recursive reference 'foo' in template
267 255 [255]
268 256
269 257 buildmap() -> gettemplate(), where no thunk was made:
270 258
271 259 $ cat << EOF > issue4758
272 260 > changeset = '{files % changeset}\n'
273 261 > EOF
274 262 $ hg log --style ./issue4758
275 263 abort: recursive reference 'changeset' in template
276 264 [255]
277 265
278 266 not a recursion if a keyword of the same name exists:
279 267
280 268 $ cat << EOF > issue4758
281 269 > changeset = '{tags % rev}'
282 270 > rev = '{rev} {tag}\n'
283 271 > EOF
284 272 $ hg log --style ./issue4758 -r tip
285 273 8 tip
286 274
287 Check that {phase} works correctly on parents:
275 Set up phase:
288 276
289 $ cat << EOF > parentphase
290 > changeset_debug = '{rev} ({phase}):{parents}\n'
291 > parent = ' {rev} ({phase})'
292 > EOF
293 277 $ hg phase -r 5 --public
294 278 $ hg phase -r 7 --secret --force
295 $ hg log --debug -G --style ./parentphase
296 @ 8 (secret): 7 (secret) -1 (public)
297 |
298 o 7 (secret): -1 (public) -1 (public)
299
300 o 6 (draft): 5 (public) 4 (draft)
301 |\
302 | o 5 (public): 3 (public) -1 (public)
303 | |
304 o | 4 (draft): 3 (public) -1 (public)
305 |/
306 o 3 (public): 2 (public) -1 (public)
307 |
308 o 2 (public): 1 (public) -1 (public)
309 |
310 o 1 (public): 0 (public) -1 (public)
311 |
312 o 0 (public): -1 (public) -1 (public)
313
314
315 Keys work:
316
317 $ for key in author branch branches date desc file_adds file_dels file_mods \
318 > file_copies file_copies_switch files \
319 > manifest node parents rev tags diffstat extras \
320 > p1rev p2rev p1node p2node; do
321 > for mode in '' --verbose --debug; do
322 > hg log $mode --template "$key$mode: {$key}\n"
323 > done
324 > done
325 author: test
326 author: User Name <user@hostname>
327 author: person
328 author: person
329 author: person
330 author: person
331 author: other@place
332 author: A. N. Other <other@place>
333 author: User Name <user@hostname>
334 author--verbose: test
335 author--verbose: User Name <user@hostname>
336 author--verbose: person
337 author--verbose: person
338 author--verbose: person
339 author--verbose: person
340 author--verbose: other@place
341 author--verbose: A. N. Other <other@place>
342 author--verbose: User Name <user@hostname>
343 author--debug: test
344 author--debug: User Name <user@hostname>
345 author--debug: person
346 author--debug: person
347 author--debug: person
348 author--debug: person
349 author--debug: other@place
350 author--debug: A. N. Other <other@place>
351 author--debug: User Name <user@hostname>
352 branch: default
353 branch: default
354 branch: default
355 branch: default
356 branch: foo
357 branch: default
358 branch: default
359 branch: default
360 branch: default
361 branch--verbose: default
362 branch--verbose: default
363 branch--verbose: default
364 branch--verbose: default
365 branch--verbose: foo
366 branch--verbose: default
367 branch--verbose: default
368 branch--verbose: default
369 branch--verbose: default
370 branch--debug: default
371 branch--debug: default
372 branch--debug: default
373 branch--debug: default
374 branch--debug: foo
375 branch--debug: default
376 branch--debug: default
377 branch--debug: default
378 branch--debug: default
379 branches:
380 branches:
381 branches:
382 branches:
383 branches: foo
384 branches:
385 branches:
386 branches:
387 branches:
388 branches--verbose:
389 branches--verbose:
390 branches--verbose:
391 branches--verbose:
392 branches--verbose: foo
393 branches--verbose:
394 branches--verbose:
395 branches--verbose:
396 branches--verbose:
397 branches--debug:
398 branches--debug:
399 branches--debug:
400 branches--debug:
401 branches--debug: foo
402 branches--debug:
403 branches--debug:
404 branches--debug:
405 branches--debug:
406 date: 1577872860.00
407 date: 1000000.00
408 date: 1500001.00
409 date: 1500000.00
410 date: 1400000.00
411 date: 1300000.00
412 date: 1200000.00
413 date: 1100000.00
414 date: 1000000.00
415 date--verbose: 1577872860.00
416 date--verbose: 1000000.00
417 date--verbose: 1500001.00
418 date--verbose: 1500000.00
419 date--verbose: 1400000.00
420 date--verbose: 1300000.00
421 date--verbose: 1200000.00
422 date--verbose: 1100000.00
423 date--verbose: 1000000.00
424 date--debug: 1577872860.00
425 date--debug: 1000000.00
426 date--debug: 1500001.00
427 date--debug: 1500000.00
428 date--debug: 1400000.00
429 date--debug: 1300000.00
430 date--debug: 1200000.00
431 date--debug: 1100000.00
432 date--debug: 1000000.00
433 desc: third
434 desc: second
435 desc: merge
436 desc: new head
437 desc: new branch
438 desc: no user, no domain
439 desc: no person
440 desc: other 1
441 other 2
442
443 other 3
444 desc: line 1
445 line 2
446 desc--verbose: third
447 desc--verbose: second
448 desc--verbose: merge
449 desc--verbose: new head
450 desc--verbose: new branch
451 desc--verbose: no user, no domain
452 desc--verbose: no person
453 desc--verbose: other 1
454 other 2
455
456 other 3
457 desc--verbose: line 1
458 line 2
459 desc--debug: third
460 desc--debug: second
461 desc--debug: merge
462 desc--debug: new head
463 desc--debug: new branch
464 desc--debug: no user, no domain
465 desc--debug: no person
466 desc--debug: other 1
467 other 2
468
469 other 3
470 desc--debug: line 1
471 line 2
472 file_adds: fourth third
473 file_adds: second
474 file_adds:
475 file_adds: d
476 file_adds:
477 file_adds:
478 file_adds: c
479 file_adds: b
480 file_adds: a
481 file_adds--verbose: fourth third
482 file_adds--verbose: second
483 file_adds--verbose:
484 file_adds--verbose: d
485 file_adds--verbose:
486 file_adds--verbose:
487 file_adds--verbose: c
488 file_adds--verbose: b
489 file_adds--verbose: a
490 file_adds--debug: fourth third
491 file_adds--debug: second
492 file_adds--debug:
493 file_adds--debug: d
494 file_adds--debug:
495 file_adds--debug:
496 file_adds--debug: c
497 file_adds--debug: b
498 file_adds--debug: a
499 file_dels: second
500 file_dels:
501 file_dels:
502 file_dels:
503 file_dels:
504 file_dels:
505 file_dels:
506 file_dels:
507 file_dels:
508 file_dels--verbose: second
509 file_dels--verbose:
510 file_dels--verbose:
511 file_dels--verbose:
512 file_dels--verbose:
513 file_dels--verbose:
514 file_dels--verbose:
515 file_dels--verbose:
516 file_dels--verbose:
517 file_dels--debug: second
518 file_dels--debug:
519 file_dels--debug:
520 file_dels--debug:
521 file_dels--debug:
522 file_dels--debug:
523 file_dels--debug:
524 file_dels--debug:
525 file_dels--debug:
526 file_mods:
527 file_mods:
528 file_mods:
529 file_mods:
530 file_mods:
531 file_mods: c
532 file_mods:
533 file_mods:
534 file_mods:
535 file_mods--verbose:
536 file_mods--verbose:
537 file_mods--verbose:
538 file_mods--verbose:
539 file_mods--verbose:
540 file_mods--verbose: c
541 file_mods--verbose:
542 file_mods--verbose:
543 file_mods--verbose:
544 file_mods--debug:
545 file_mods--debug:
546 file_mods--debug:
547 file_mods--debug:
548 file_mods--debug:
549 file_mods--debug: c
550 file_mods--debug:
551 file_mods--debug:
552 file_mods--debug:
553 file_copies: fourth (second)
554 file_copies:
555 file_copies:
556 file_copies:
557 file_copies:
558 file_copies:
559 file_copies:
560 file_copies:
561 file_copies:
562 file_copies--verbose: fourth (second)
563 file_copies--verbose:
564 file_copies--verbose:
565 file_copies--verbose:
566 file_copies--verbose:
567 file_copies--verbose:
568 file_copies--verbose:
569 file_copies--verbose:
570 file_copies--verbose:
571 file_copies--debug: fourth (second)
572 file_copies--debug:
573 file_copies--debug:
574 file_copies--debug:
575 file_copies--debug:
576 file_copies--debug:
577 file_copies--debug:
578 file_copies--debug:
579 file_copies--debug:
580 file_copies_switch:
581 file_copies_switch:
582 file_copies_switch:
583 file_copies_switch:
584 file_copies_switch:
585 file_copies_switch:
586 file_copies_switch:
587 file_copies_switch:
588 file_copies_switch:
589 file_copies_switch--verbose:
590 file_copies_switch--verbose:
591 file_copies_switch--verbose:
592 file_copies_switch--verbose:
593 file_copies_switch--verbose:
594 file_copies_switch--verbose:
595 file_copies_switch--verbose:
596 file_copies_switch--verbose:
597 file_copies_switch--verbose:
598 file_copies_switch--debug:
599 file_copies_switch--debug:
600 file_copies_switch--debug:
601 file_copies_switch--debug:
602 file_copies_switch--debug:
603 file_copies_switch--debug:
604 file_copies_switch--debug:
605 file_copies_switch--debug:
606 file_copies_switch--debug:
607 files: fourth second third
608 files: second
609 files:
610 files: d
611 files:
612 files: c
613 files: c
614 files: b
615 files: a
616 files--verbose: fourth second third
617 files--verbose: second
618 files--verbose:
619 files--verbose: d
620 files--verbose:
621 files--verbose: c
622 files--verbose: c
623 files--verbose: b
624 files--verbose: a
625 files--debug: fourth second third
626 files--debug: second
627 files--debug:
628 files--debug: d
629 files--debug:
630 files--debug: c
631 files--debug: c
632 files--debug: b
633 files--debug: a
634 manifest: 6:94961b75a2da
635 manifest: 5:f2dbc354b94e
636 manifest: 4:4dc3def4f9b4
637 manifest: 4:4dc3def4f9b4
638 manifest: 3:cb5a1327723b
639 manifest: 3:cb5a1327723b
640 manifest: 2:6e0e82995c35
641 manifest: 1:4e8d705b1e53
642 manifest: 0:a0c8bcbbb45c
643 manifest--verbose: 6:94961b75a2da
644 manifest--verbose: 5:f2dbc354b94e
645 manifest--verbose: 4:4dc3def4f9b4
646 manifest--verbose: 4:4dc3def4f9b4
647 manifest--verbose: 3:cb5a1327723b
648 manifest--verbose: 3:cb5a1327723b
649 manifest--verbose: 2:6e0e82995c35
650 manifest--verbose: 1:4e8d705b1e53
651 manifest--verbose: 0:a0c8bcbbb45c
652 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
653 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
654 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
655 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
656 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
657 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
658 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
659 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
660 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
661 node: 95c24699272ef57d062b8bccc32c878bf841784a
662 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
663 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
664 node: 13207e5a10d9fd28ec424934298e176197f2c67f
665 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
666 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
667 node: 97054abb4ab824450e9164180baf491ae0078465
668 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
669 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
670 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
671 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
672 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
673 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
674 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
675 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
676 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
677 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
678 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
679 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
680 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
681 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
682 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
683 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
684 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
685 node--debug: 97054abb4ab824450e9164180baf491ae0078465
686 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
687 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
688 parents:
689 parents: -1:000000000000
690 parents: 5:13207e5a10d9 4:bbe44766e73d
691 parents: 3:10e46f2dcbf4
692 parents:
693 parents:
694 parents:
695 parents:
696 parents:
697 parents--verbose:
698 parents--verbose: -1:000000000000
699 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
700 parents--verbose: 3:10e46f2dcbf4
701 parents--verbose:
702 parents--verbose:
703 parents--verbose:
704 parents--verbose:
705 parents--verbose:
706 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
707 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
708 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
709 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
710 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
711 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
712 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
713 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
714 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
715 rev: 8
716 rev: 7
717 rev: 6
718 rev: 5
719 rev: 4
720 rev: 3
721 rev: 2
722 rev: 1
723 rev: 0
724 rev--verbose: 8
725 rev--verbose: 7
726 rev--verbose: 6
727 rev--verbose: 5
728 rev--verbose: 4
729 rev--verbose: 3
730 rev--verbose: 2
731 rev--verbose: 1
732 rev--verbose: 0
733 rev--debug: 8
734 rev--debug: 7
735 rev--debug: 6
736 rev--debug: 5
737 rev--debug: 4
738 rev--debug: 3
739 rev--debug: 2
740 rev--debug: 1
741 rev--debug: 0
742 tags: tip
743 tags:
744 tags:
745 tags:
746 tags:
747 tags:
748 tags:
749 tags:
750 tags:
751 tags--verbose: tip
752 tags--verbose:
753 tags--verbose:
754 tags--verbose:
755 tags--verbose:
756 tags--verbose:
757 tags--verbose:
758 tags--verbose:
759 tags--verbose:
760 tags--debug: tip
761 tags--debug:
762 tags--debug:
763 tags--debug:
764 tags--debug:
765 tags--debug:
766 tags--debug:
767 tags--debug:
768 tags--debug:
769 diffstat: 3: +2/-1
770 diffstat: 1: +1/-0
771 diffstat: 0: +0/-0
772 diffstat: 1: +1/-0
773 diffstat: 0: +0/-0
774 diffstat: 1: +1/-0
775 diffstat: 1: +4/-0
776 diffstat: 1: +2/-0
777 diffstat: 1: +1/-0
778 diffstat--verbose: 3: +2/-1
779 diffstat--verbose: 1: +1/-0
780 diffstat--verbose: 0: +0/-0
781 diffstat--verbose: 1: +1/-0
782 diffstat--verbose: 0: +0/-0
783 diffstat--verbose: 1: +1/-0
784 diffstat--verbose: 1: +4/-0
785 diffstat--verbose: 1: +2/-0
786 diffstat--verbose: 1: +1/-0
787 diffstat--debug: 3: +2/-1
788 diffstat--debug: 1: +1/-0
789 diffstat--debug: 0: +0/-0
790 diffstat--debug: 1: +1/-0
791 diffstat--debug: 0: +0/-0
792 diffstat--debug: 1: +1/-0
793 diffstat--debug: 1: +4/-0
794 diffstat--debug: 1: +2/-0
795 diffstat--debug: 1: +1/-0
796 extras: branch=default
797 extras: branch=default
798 extras: branch=default
799 extras: branch=default
800 extras: branch=foo
801 extras: branch=default
802 extras: branch=default
803 extras: branch=default
804 extras: branch=default
805 extras--verbose: branch=default
806 extras--verbose: branch=default
807 extras--verbose: branch=default
808 extras--verbose: branch=default
809 extras--verbose: branch=foo
810 extras--verbose: branch=default
811 extras--verbose: branch=default
812 extras--verbose: branch=default
813 extras--verbose: branch=default
814 extras--debug: branch=default
815 extras--debug: branch=default
816 extras--debug: branch=default
817 extras--debug: branch=default
818 extras--debug: branch=foo
819 extras--debug: branch=default
820 extras--debug: branch=default
821 extras--debug: branch=default
822 extras--debug: branch=default
823 p1rev: 7
824 p1rev: -1
825 p1rev: 5
826 p1rev: 3
827 p1rev: 3
828 p1rev: 2
829 p1rev: 1
830 p1rev: 0
831 p1rev: -1
832 p1rev--verbose: 7
833 p1rev--verbose: -1
834 p1rev--verbose: 5
835 p1rev--verbose: 3
836 p1rev--verbose: 3
837 p1rev--verbose: 2
838 p1rev--verbose: 1
839 p1rev--verbose: 0
840 p1rev--verbose: -1
841 p1rev--debug: 7
842 p1rev--debug: -1
843 p1rev--debug: 5
844 p1rev--debug: 3
845 p1rev--debug: 3
846 p1rev--debug: 2
847 p1rev--debug: 1
848 p1rev--debug: 0
849 p1rev--debug: -1
850 p2rev: -1
851 p2rev: -1
852 p2rev: 4
853 p2rev: -1
854 p2rev: -1
855 p2rev: -1
856 p2rev: -1
857 p2rev: -1
858 p2rev: -1
859 p2rev--verbose: -1
860 p2rev--verbose: -1
861 p2rev--verbose: 4
862 p2rev--verbose: -1
863 p2rev--verbose: -1
864 p2rev--verbose: -1
865 p2rev--verbose: -1
866 p2rev--verbose: -1
867 p2rev--verbose: -1
868 p2rev--debug: -1
869 p2rev--debug: -1
870 p2rev--debug: 4
871 p2rev--debug: -1
872 p2rev--debug: -1
873 p2rev--debug: -1
874 p2rev--debug: -1
875 p2rev--debug: -1
876 p2rev--debug: -1
877 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
878 p1node: 0000000000000000000000000000000000000000
879 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
880 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
881 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
882 p1node: 97054abb4ab824450e9164180baf491ae0078465
883 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
884 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
885 p1node: 0000000000000000000000000000000000000000
886 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
887 p1node--verbose: 0000000000000000000000000000000000000000
888 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
889 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
890 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
891 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
892 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
893 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
894 p1node--verbose: 0000000000000000000000000000000000000000
895 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
896 p1node--debug: 0000000000000000000000000000000000000000
897 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
898 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
899 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
900 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
901 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
902 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
903 p1node--debug: 0000000000000000000000000000000000000000
904 p2node: 0000000000000000000000000000000000000000
905 p2node: 0000000000000000000000000000000000000000
906 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
907 p2node: 0000000000000000000000000000000000000000
908 p2node: 0000000000000000000000000000000000000000
909 p2node: 0000000000000000000000000000000000000000
910 p2node: 0000000000000000000000000000000000000000
911 p2node: 0000000000000000000000000000000000000000
912 p2node: 0000000000000000000000000000000000000000
913 p2node--verbose: 0000000000000000000000000000000000000000
914 p2node--verbose: 0000000000000000000000000000000000000000
915 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
916 p2node--verbose: 0000000000000000000000000000000000000000
917 p2node--verbose: 0000000000000000000000000000000000000000
918 p2node--verbose: 0000000000000000000000000000000000000000
919 p2node--verbose: 0000000000000000000000000000000000000000
920 p2node--verbose: 0000000000000000000000000000000000000000
921 p2node--verbose: 0000000000000000000000000000000000000000
922 p2node--debug: 0000000000000000000000000000000000000000
923 p2node--debug: 0000000000000000000000000000000000000000
924 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
925 p2node--debug: 0000000000000000000000000000000000000000
926 p2node--debug: 0000000000000000000000000000000000000000
927 p2node--debug: 0000000000000000000000000000000000000000
928 p2node--debug: 0000000000000000000000000000000000000000
929 p2node--debug: 0000000000000000000000000000000000000000
930 p2node--debug: 0000000000000000000000000000000000000000
931 279
932 280 Add a dummy commit to make up for the instability of the above:
933 281
934 282 $ echo a > a
935 283 $ hg add a
936 284 $ hg ci -m future
937 285
938 286 Add a commit that does all possible modifications at once
939 287
940 288 $ echo modify >> third
941 289 $ touch b
942 290 $ hg add b
943 291 $ hg mv fourth fifth
944 292 $ hg rm a
945 293 $ hg ci -m "Modify, add, remove, rename"
946 294
947 295 Error on syntax:
948 296
949 297 $ cat <<EOF > t
950 298 > changeset = '{c}'
951 299 > c = q
952 300 > x = "f
953 301 > EOF
954 302 $ echo '[ui]' > .hg/hgrc
955 303 $ echo 'style = t' >> .hg/hgrc
956 304 $ hg log
957 305 hg: parse error at t:3: unmatched quotes
958 306 [255]
959 307
960 308 $ hg log -T '{date'
961 309 hg: parse error at 1: unterminated template expansion
962 310 ({date
963 311 ^ here)
964 312 [255]
965 313 $ hg log -T '{date(}'
966 314 hg: parse error at 6: not a prefix: end
967 315 ({date(}
968 316 ^ here)
969 317 [255]
970 318 $ hg log -T '{date)}'
971 319 hg: parse error at 5: invalid token
972 320 ({date)}
973 321 ^ here)
974 322 [255]
975 323 $ hg log -T '{date date}'
976 324 hg: parse error at 6: invalid token
977 325 ({date date}
978 326 ^ here)
979 327 [255]
980 328
981 329 $ hg log -T '{}'
982 330 hg: parse error at 1: not a prefix: end
983 331 ({}
984 332 ^ here)
985 333 [255]
986 334 $ hg debugtemplate -v '{()}'
987 335 (template
988 336 (group
989 337 None))
990 338 * keywords:
991 339 * functions:
992 340 hg: parse error: missing argument
993 341 [255]
994 342
995 343 Behind the scenes, this would throw TypeError without intype=bytes
996 344
997 345 $ hg log -l 3 --template '{date|obfuscate}\n'
998 346 &#48;&#46;&#48;&#48;
999 347 &#48;&#46;&#48;&#48;
1000 348 &#49;&#53;&#55;&#55;&#56;&#55;&#50;&#56;&#54;&#48;&#46;&#48;&#48;
1001 349
1002 350 Behind the scenes, this will throw a ValueError
1003 351
1004 352 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1005 353 hg: parse error: invalid date: 'Modify, add, remove, rename'
1006 354 (template filter 'shortdate' is not compatible with keyword 'desc')
1007 355 [255]
1008 356
1009 357 Behind the scenes, this would throw AttributeError without intype=bytes
1010 358
1011 359 $ hg log -l 3 --template 'line: {date|escape}\n'
1012 360 line: 0.00
1013 361 line: 0.00
1014 362 line: 1577872860.00
1015 363
1016 364 $ hg log -l 3 --template 'line: {extras|localdate}\n'
1017 365 hg: parse error: localdate expects a date information
1018 366 [255]
1019 367
1020 368 Behind the scenes, this will throw ValueError
1021 369
1022 370 $ hg tip --template '{author|email|date}\n'
1023 371 hg: parse error: date expects a date information
1024 372 [255]
1025 373
1026 374 $ hg tip -T '{author|email|shortdate}\n'
1027 375 hg: parse error: invalid date: 'test'
1028 376 (template filter 'shortdate' is not compatible with keyword 'author')
1029 377 [255]
1030 378
1031 379 $ hg tip -T '{get(extras, "branch")|shortdate}\n'
1032 380 hg: parse error: invalid date: 'default'
1033 381 (incompatible use of template filter 'shortdate')
1034 382 [255]
1035 383
1036 384 Error in nested template:
1037 385
1038 386 $ hg log -T '{"date'
1039 387 hg: parse error at 2: unterminated string
1040 388 ({"date
1041 389 ^ here)
1042 390 [255]
1043 391
1044 392 $ hg log -T '{"foo{date|?}"}'
1045 393 hg: parse error at 11: syntax error
1046 394 ({"foo{date|?}"}
1047 395 ^ here)
1048 396 [255]
1049 397
1050 398 Thrown an error if a template function doesn't exist
1051 399
1052 400 $ hg tip --template '{foo()}\n'
1053 401 hg: parse error: unknown function 'foo'
1054 402 [255]
1055 403
1056 Test index keyword:
1057
1058 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
1059 10 0:a 1:b 2:fifth 3:fourth 4:third
1060 11 0:a
1061
1062 $ hg branches -T '{index} {branch}\n'
1063 0 default
1064 1 foo
1065
1066 ui verbosity:
1067
1068 $ hg log -l1 -T '{verbosity}\n'
1069
1070 $ hg log -l1 -T '{verbosity}\n' --debug
1071 debug
1072 $ hg log -l1 -T '{verbosity}\n' --quiet
1073 quiet
1074 $ hg log -l1 -T '{verbosity}\n' --verbose
1075 verbose
1076
1077 404 $ cd ..
1078 405
1079
1080 latesttag:
406 Set up latesttag repository:
1081 407
1082 408 $ hg init latesttag
1083 409 $ cd latesttag
1084 410
1085 411 $ echo a > file
1086 412 $ hg ci -Am a -d '0 0'
1087 413 adding file
1088 414
1089 415 $ echo b >> file
1090 416 $ hg ci -m b -d '1 0'
1091 417
1092 418 $ echo c >> head1
1093 419 $ hg ci -Am h1c -d '2 0'
1094 420 adding head1
1095 421
1096 422 $ hg update -q 1
1097 423 $ echo d >> head2
1098 424 $ hg ci -Am h2d -d '3 0'
1099 425 adding head2
1100 426 created new head
1101 427
1102 428 $ echo e >> head2
1103 429 $ hg ci -m h2e -d '4 0'
1104 430
1105 431 $ hg merge -q
1106 432 $ hg ci -m merge -d '5 -3600'
1107 433
1108 No tag set:
1109
1110 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1111 @ 5: null+5
1112 |\
1113 | o 4: null+4
1114 | |
1115 | o 3: null+3
1116 | |
1117 o | 2: null+3
1118 |/
1119 o 1: null+2
1120 |
1121 o 0: null+1
1122
1123
1124 One common tag: longest path wins for {latesttagdistance}:
1125
1126 434 $ hg tag -r 1 -m t1 -d '6 0' t1
1127 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1128 @ 6: t1+4
1129 |
1130 o 5: t1+3
1131 |\
1132 | o 4: t1+2
1133 | |
1134 | o 3: t1+1
1135 | |
1136 o | 2: t1+1
1137 |/
1138 o 1: t1+0
1139 |
1140 o 0: null+1
1141
1142
1143 One ancestor tag: closest wins:
1144
1145 435 $ hg tag -r 2 -m t2 -d '7 0' t2
1146 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1147 @ 7: t2+3
1148 |
1149 o 6: t2+2
1150 |
1151 o 5: t2+1
1152 |\
1153 | o 4: t1+2
1154 | |
1155 | o 3: t1+1
1156 | |
1157 o | 2: t2+0
1158 |/
1159 o 1: t1+0
1160 |
1161 o 0: null+1
1162
1163
1164 Two branch tags: more recent wins if same number of changes:
1165
1166 436 $ hg tag -r 3 -m t3 -d '8 0' t3
1167 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1168 @ 8: t3+5
1169 |
1170 o 7: t3+4
1171 |
1172 o 6: t3+3
1173 |
1174 o 5: t3+2
1175 |\
1176 | o 4: t3+1
1177 | |
1178 | o 3: t3+0
1179 | |
1180 o | 2: t2+0
1181 |/
1182 o 1: t1+0
1183 |
1184 o 0: null+1
1185
1186
1187 Two branch tags: fewest changes wins:
1188
1189 437 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
1190 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1191 @ 9: t4+5,6
1192 |
1193 o 8: t4+4,5
1194 |
1195 o 7: t4+3,4
1196 |
1197 o 6: t4+2,3
1198 |
1199 o 5: t4+1,2
1200 |\
1201 | o 4: t4+0,0
1202 | |
1203 | o 3: t3+0,0
1204 | |
1205 o | 2: t2+0,0
1206 |/
1207 o 1: t1+0,0
1208 |
1209 o 0: null+1,1
1210
1211
1212 Merged tag overrides:
1213
1214 438 $ hg tag -r 5 -m t5 -d '9 0' t5
1215 439 $ hg tag -r 3 -m at3 -d '10 0' at3
1216 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1217 @ 11: t5+6
1218 |
1219 o 10: t5+5
1220 |
1221 o 9: t5+4
1222 |
1223 o 8: t5+3
1224 |
1225 o 7: t5+2
1226 |
1227 o 6: t5+1
1228 |
1229 o 5: t5+0
1230 |\
1231 | o 4: t4+0
1232 | |
1233 | o 3: at3:t3+0
1234 | |
1235 o | 2: t2+0
1236 |/
1237 o 1: t1+0
1238 |
1239 o 0: null+1
1240
1241
1242 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1243 @ 11: t5+6,6
1244 |
1245 o 10: t5+5,5
1246 |
1247 o 9: t5+4,4
1248 |
1249 o 8: t5+3,3
1250 |
1251 o 7: t5+2,2
1252 |
1253 o 6: t5+1,1
1254 |
1255 o 5: t5+0,0
1256 |\
1257 | o 4: t4+0,0
1258 | |
1259 | o 3: at3+0,0 t3+0,0
1260 | |
1261 o | 2: t2+0,0
1262 |/
1263 o 1: t1+0,0
1264 |
1265 o 0: null+1,1
1266
1267 440
1268 441 $ cd ..
1269 442
1270 443 Test new-style inline templating:
1271 444
1272 445 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1273 446 modified files: .hgtags
1274 447
1275 448
1276 449 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
1277 450 hg: parse error: 11 is not iterable of mappings
1278 451 (keyword 'rev' does not support map operation)
1279 452 [255]
1280 453 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
1281 454 hg: parse error: None is not iterable of mappings
1282 455 [255]
1283 456 $ hg log -R latesttag -r tip -T '{extras % "{key}\n" % "{key}\n"}'
1284 457 hg: parse error: list of strings is not mappable
1285 458 [255]
1286 459
1287 460 Test new-style inline templating of non-list/dict type:
1288 461
1289 462 $ hg log -R latesttag -r tip -T '{manifest}\n'
1290 463 11:2bc6e9006ce2
1291 464 $ hg log -R latesttag -r tip -T 'string length: {manifest|count}\n'
1292 465 string length: 15
1293 466 $ hg log -R latesttag -r tip -T '{manifest % "{rev}:{node}"}\n'
1294 467 11:2bc6e9006ce29882383a22d39fd1f4e66dd3e2fc
1295 468
1296 469 $ hg log -R latesttag -r tip -T '{get(extras, "branch") % "{key}: {value}\n"}'
1297 470 branch: default
1298 471 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "{key}\n"}'
1299 472 hg: parse error: None is not iterable of mappings
1300 473 [255]
1301 474 $ hg log -R latesttag -r tip -T '{min(extras) % "{key}: {value}\n"}'
1302 475 branch: default
1303 476 $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}'
1304 477 0:ce3cec86e6c2
1305 478 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
1306 479 9:fbc7cd862e9c
1307 480
1308 481 Test dot operator precedence:
1309 482
1310 483 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
1311 484 (template
1312 485 (|
1313 486 (.
1314 487 (symbol 'manifest')
1315 488 (symbol 'node'))
1316 489 (symbol 'short'))
1317 490 (string '\n'))
1318 491 * keywords: manifest, node, rev
1319 492 * functions: formatnode, short
1320 493 89f4071fec70
1321 494
1322 495 (the following examples are invalid, but seem natural in parsing POV)
1323 496
1324 497 $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null
1325 498 (template
1326 499 (|
1327 500 (symbol 'foo')
1328 501 (.
1329 502 (symbol 'bar')
1330 503 (symbol 'baz')))
1331 504 (string '\n'))
1332 505 [255]
1333 506 $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null
1334 507 (template
1335 508 (.
1336 509 (symbol 'foo')
1337 510 (func
1338 511 (symbol 'bar')
1339 512 None))
1340 513 (string '\n'))
1341 514 * keywords: foo
1342 515 * functions: bar
1343 516 [255]
1344 517
1345 518 Test evaluation of dot operator:
1346 519
1347 520 $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n'
1348 521 ce3cec86e6c26bd9bdfc590a6b92abc9680f1796
1349 522 $ hg log -R latesttag -r0 -T '{extras.branch}\n'
1350 523 default
1351 524 $ hg log -R latesttag -r0 -T '{date.unixtime} {localdate(date, "+0200").tzoffset}\n'
1352 525 0 -7200
1353 526
1354 527 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
1355 528 hg: parse error: 'test' is not a dictionary
1356 529 (keyword 'author' does not support member operation)
1357 530 [255]
1358 531 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
1359 532 hg: parse error: 'a' is not a dictionary
1360 533 [255]
1361 534
1362 535 Test integer literal:
1363 536
1364 537 $ hg debugtemplate -v '{(0)}\n'
1365 538 (template
1366 539 (group
1367 540 (integer '0'))
1368 541 (string '\n'))
1369 542 * keywords:
1370 543 * functions:
1371 544 0
1372 545 $ hg debugtemplate -v '{(123)}\n'
1373 546 (template
1374 547 (group
1375 548 (integer '123'))
1376 549 (string '\n'))
1377 550 * keywords:
1378 551 * functions:
1379 552 123
1380 553 $ hg debugtemplate -v '{(-4)}\n'
1381 554 (template
1382 555 (group
1383 556 (negate
1384 557 (integer '4')))
1385 558 (string '\n'))
1386 559 * keywords:
1387 560 * functions:
1388 561 -4
1389 562 $ hg debugtemplate '{(-)}\n'
1390 563 hg: parse error at 3: not a prefix: )
1391 564 ({(-)}\n
1392 565 ^ here)
1393 566 [255]
1394 567 $ hg debugtemplate '{(-a)}\n'
1395 568 hg: parse error: negation needs an integer argument
1396 569 [255]
1397 570
1398 571 top-level integer literal is interpreted as symbol (i.e. variable name):
1399 572
1400 573 $ hg debugtemplate -D 1=one -v '{1}\n'
1401 574 (template
1402 575 (integer '1')
1403 576 (string '\n'))
1404 577 * keywords:
1405 578 * functions:
1406 579 one
1407 580 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
1408 581 (template
1409 582 (func
1410 583 (symbol 'if')
1411 584 (list
1412 585 (string 't')
1413 586 (template
1414 587 (integer '1'))))
1415 588 (string '\n'))
1416 589 * keywords:
1417 590 * functions: if
1418 591 one
1419 592 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
1420 593 (template
1421 594 (|
1422 595 (integer '1')
1423 596 (symbol 'stringify'))
1424 597 (string '\n'))
1425 598 * keywords:
1426 599 * functions: stringify
1427 600 one
1428 601
1429 602 unless explicit symbol is expected:
1430 603
1431 604 $ hg log -Ra -r0 -T '{desc|1}\n'
1432 605 hg: parse error: expected a symbol, got 'integer'
1433 606 [255]
1434 607 $ hg log -Ra -r0 -T '{1()}\n'
1435 608 hg: parse error: expected a symbol, got 'integer'
1436 609 [255]
1437 610
1438 611 Test string literal:
1439 612
1440 613 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
1441 614 (template
1442 615 (string 'string with no template fragment')
1443 616 (string '\n'))
1444 617 * keywords:
1445 618 * functions:
1446 619 string with no template fragment
1447 620 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
1448 621 (template
1449 622 (template
1450 623 (string 'template: ')
1451 624 (symbol 'rev'))
1452 625 (string '\n'))
1453 626 * keywords: rev
1454 627 * functions:
1455 628 template: 0
1456 629 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
1457 630 (template
1458 631 (string 'rawstring: {rev}')
1459 632 (string '\n'))
1460 633 * keywords:
1461 634 * functions:
1462 635 rawstring: {rev}
1463 636 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
1464 637 (template
1465 638 (%
1466 639 (symbol 'files')
1467 640 (string 'rawstring: {file}'))
1468 641 (string '\n'))
1469 642 * keywords: files
1470 643 * functions:
1471 644 rawstring: {file}
1472 645
1473 646 Test string escaping:
1474 647
1475 648 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1476 649 >
1477 650 <>\n<[>
1478 651 <>\n<]>
1479 652 <>\n<
1480 653
1481 654 $ hg log -R latesttag -r 0 \
1482 655 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1483 656 >
1484 657 <>\n<[>
1485 658 <>\n<]>
1486 659 <>\n<
1487 660
1488 661 $ hg log -R latesttag -r 0 -T esc \
1489 662 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1490 663 >
1491 664 <>\n<[>
1492 665 <>\n<]>
1493 666 <>\n<
1494 667
1495 668 $ cat <<'EOF' > esctmpl
1496 669 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1497 670 > EOF
1498 671 $ hg log -R latesttag -r 0 --style ./esctmpl
1499 672 >
1500 673 <>\n<[>
1501 674 <>\n<]>
1502 675 <>\n<
1503 676
1504 677 Test string escaping of quotes:
1505 678
1506 679 $ hg log -Ra -r0 -T '{"\""}\n'
1507 680 "
1508 681 $ hg log -Ra -r0 -T '{"\\\""}\n'
1509 682 \"
1510 683 $ hg log -Ra -r0 -T '{r"\""}\n'
1511 684 \"
1512 685 $ hg log -Ra -r0 -T '{r"\\\""}\n'
1513 686 \\\"
1514 687
1515 688
1516 689 $ hg log -Ra -r0 -T '{"\""}\n'
1517 690 "
1518 691 $ hg log -Ra -r0 -T '{"\\\""}\n'
1519 692 \"
1520 693 $ hg log -Ra -r0 -T '{r"\""}\n'
1521 694 \"
1522 695 $ hg log -Ra -r0 -T '{r"\\\""}\n'
1523 696 \\\"
1524 697
1525 698 Test exception in quoted template. single backslash before quotation mark is
1526 699 stripped before parsing:
1527 700
1528 701 $ cat <<'EOF' > escquotetmpl
1529 702 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
1530 703 > EOF
1531 704 $ cd latesttag
1532 705 $ hg log -r 2 --style ../escquotetmpl
1533 706 " \" \" \\" head1
1534 707
1535 708 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
1536 709 valid
1537 710 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
1538 711 valid
1539 712
1540 713 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
1541 714 _evalifliteral() templates (issue4733):
1542 715
1543 716 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
1544 717 "2
1545 718 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
1546 719 "2
1547 720 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
1548 721 "2
1549 722
1550 723 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
1551 724 \"
1552 725 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
1553 726 \"
1554 727 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
1555 728 \"
1556 729
1557 730 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
1558 731 \\\"
1559 732 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
1560 733 \\\"
1561 734 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
1562 735 \\\"
1563 736
1564 737 escaped single quotes and errors:
1565 738
1566 739 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
1567 740 foo
1568 741 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
1569 742 foo
1570 743 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
1571 744 hg: parse error at 21: unterminated string
1572 745 ({if(rev, "{if(rev, \")}")}\n
1573 746 ^ here)
1574 747 [255]
1575 748 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
1576 749 hg: parse error: trailing \ in string
1577 750 [255]
1578 751 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
1579 752 hg: parse error: trailing \ in string
1580 753 [255]
1581 754
1582 755 $ cd ..
1583 756
1584 757 Test leading backslashes:
1585 758
1586 759 $ cd latesttag
1587 760 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
1588 761 {rev} {file}
1589 762 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
1590 763 \2 \head1
1591 764 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
1592 765 \{rev} \{file}
1593 766 $ cd ..
1594 767
1595 768 Test leading backslashes in "if" expression (issue4714):
1596 769
1597 770 $ cd latesttag
1598 771 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
1599 772 {rev} \{rev}
1600 773 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
1601 774 \2 \\{rev}
1602 775 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
1603 776 \{rev} \\\{rev}
1604 777 $ cd ..
1605 778
1606 779 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
1607 780
1608 781 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
1609 782 \x6e
1610 783 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
1611 784 \x5c\x786e
1612 785 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
1613 786 \x6e
1614 787 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
1615 788 \x5c\x786e
1616 789
1617 790 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
1618 791 \x6e
1619 792 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
1620 793 \x5c\x786e
1621 794 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
1622 795 \x6e
1623 796 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
1624 797 \x5c\x786e
1625 798
1626 799 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
1627 800 fourth
1628 801 second
1629 802 third
1630 803 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
1631 804 fourth\nsecond\nthird
1632 805
1633 806 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
1634 807 <p>
1635 808 1st
1636 809 </p>
1637 810 <p>
1638 811 2nd
1639 812 </p>
1640 813 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
1641 814 <p>
1642 815 1st\n\n2nd
1643 816 </p>
1644 817 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
1645 818 1st
1646 819
1647 820 2nd
1648 821
1649 822 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
1650 823 o perso
1651 824 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
1652 825 no person
1653 826 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
1654 827 o perso
1655 828 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
1656 829 no perso
1657 830
1658 831 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
1659 832 -o perso-
1660 833 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
1661 834 no person
1662 835 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
1663 836 \x2do perso\x2d
1664 837 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
1665 838 -o perso-
1666 839 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
1667 840 \x2do perso\x6e
1668 841
1669 842 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
1670 843 fourth
1671 844 second
1672 845 third
1673 846
1674 847 Test string escaping in nested expression:
1675 848
1676 849 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
1677 850 fourth\x6esecond\x6ethird
1678 851 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
1679 852 fourth\x6esecond\x6ethird
1680 853
1681 854 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
1682 855 fourth\x6esecond\x6ethird
1683 856 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
1684 857 fourth\x5c\x786esecond\x5c\x786ethird
1685 858
1686 859 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
1687 860 3:\x6eo user, \x6eo domai\x6e
1688 861 4:\x5c\x786eew bra\x5c\x786ech
1689 862
1690 863 Test quotes in nested expression are evaluated just like a $(command)
1691 864 substitution in POSIX shells:
1692 865
1693 866 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
1694 867 8:95c24699272e
1695 868 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
1696 869 {8} "95c24699272e"
1697 870
1698 871 Test recursive evaluation:
1699 872
1700 873 $ hg init r
1701 874 $ cd r
1702 875 $ echo a > a
1703 876 $ hg ci -Am '{rev}'
1704 877 adding a
1705 878 $ hg log -r 0 --template '{if(rev, desc)}\n'
1706 879 {rev}
1707 880 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
1708 881 test 0
1709 882
1710 883 $ hg branch -q 'text.{rev}'
1711 884 $ echo aa >> aa
1712 885 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
1713 886
1714 887 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
1715 888 {node|short}desc to
1716 889 text.{rev}be wrapped
1717 890 text.{rev}desc to be
1718 891 text.{rev}wrapped (no-eol)
1719 892 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
1720 893 bcc7ff960b8e:desc to
1721 894 text.1:be wrapped
1722 895 text.1:desc to be
1723 896 text.1:wrapped (no-eol)
1724 897 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
1725 898 hg: parse error: fill expects an integer width
1726 899 [255]
1727 900
1728 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
1729 bcc7ff960b8e:desc to be
1730 termwidth.1:wrapped desc
1731 termwidth.1:to be wrapped (no-eol)
1732
1733 901 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
1734 902 {node|short} (no-eol)
1735 903 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
1736 904 bcc-ff---b-e (no-eol)
1737 905
1738 906 $ cat >> .hg/hgrc <<EOF
1739 907 > [extensions]
1740 908 > color=
1741 909 > [color]
1742 910 > mode=ansi
1743 911 > text.{rev} = red
1744 912 > text.1 = green
1745 913 > EOF
1746 914 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
1747 915 \x1b[0;31mtext\x1b[0m (esc)
1748 916 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
1749 917 \x1b[0;32mtext\x1b[0m (esc)
1750 918
1751 Just one more commit:
1752
1753 $ echo b > b
1754 $ hg ci -qAm b
1755
1756 Test 'originalnode'
1757
1758 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
1759 000000000000 bcc7ff960b8e
1760 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
1761 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
1762
1763 Test active bookmark templating
1764
1765 $ hg book foo
1766 $ hg book bar
1767 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
1768 2 bar* foo
1769 1
1770 0
1771 $ hg log --template "{rev} {activebookmark}\n"
1772 2 bar
1773 1
1774 0
1775 $ hg bookmarks --inactive bar
1776 $ hg log --template "{rev} {activebookmark}\n"
1777 2
1778 1
1779 0
1780 $ hg book -r1 baz
1781 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
1782 2 bar foo
1783 1 baz
1784 0
1785 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
1786 2 t
1787 1 f
1788 0 f
1789
1790 Test namespaces dict
1791
1792 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
1793 2
1794 bookmarks color=bookmark builtin=True
1795 bar,foo
1796 tags color=tag builtin=True
1797 tip
1798 branches color=branch builtin=True
1799 text.{rev}
1800 revnames color=revname builtin=False
1801 r2
1802
1803 1
1804 bookmarks color=bookmark builtin=True
1805 baz
1806 tags color=tag builtin=True
1807
1808 branches color=branch builtin=True
1809 text.{rev}
1810 revnames color=revname builtin=False
1811 r1
1812
1813 0
1814 bookmarks color=bookmark builtin=True
1815
1816 tags color=tag builtin=True
1817
1818 branches color=branch builtin=True
1819 default
1820 revnames color=revname builtin=False
1821 r0
1822
1823 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
1824 bookmarks: bar foo
1825 tags: tip
1826 branches: text.{rev}
1827 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
1828 bookmarks:
1829 bar
1830 foo
1831 tags:
1832 tip
1833 branches:
1834 text.{rev}
1835 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
1836 bar
1837 foo
1838 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
1839 bar
1840 foo
1841
1842 919 $ cd ..
1843 920
1844 921 Test bad template with better error message
1845 922
1846 923 $ hg log -Gv -R a --template '{desc|user()}'
1847 924 hg: parse error: expected a symbol, got 'func'
1848 925 [255]
1849 926
1850 927 Test broken string escapes:
1851 928
1852 929 $ hg log -T "bogus\\" -R a
1853 930 hg: parse error: trailing \ in string
1854 931 [255]
1855 932 $ hg log -T "\\xy" -R a
1856 933 hg: parse error: invalid \x escape* (glob)
1857 934 [255]
1858 935
1859 936 Templater supports aliases of symbol and func() styles:
1860 937
1861 938 $ hg clone -q a aliases
1862 939 $ cd aliases
1863 940 $ cat <<EOF >> .hg/hgrc
1864 941 > [templatealias]
1865 942 > r = rev
1866 943 > rn = "{r}:{node|short}"
1867 944 > status(c, files) = files % "{c} {file}\n"
1868 945 > utcdate(d) = localdate(d, "UTC")
1869 946 > EOF
1870 947
1871 948 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
1872 949 (template
1873 950 (symbol 'rn')
1874 951 (string ' ')
1875 952 (|
1876 953 (func
1877 954 (symbol 'utcdate')
1878 955 (symbol 'date'))
1879 956 (symbol 'isodate'))
1880 957 (string '\n'))
1881 958 * expanded:
1882 959 (template
1883 960 (template
1884 961 (symbol 'rev')
1885 962 (string ':')
1886 963 (|
1887 964 (symbol 'node')
1888 965 (symbol 'short')))
1889 966 (string ' ')
1890 967 (|
1891 968 (func
1892 969 (symbol 'localdate')
1893 970 (list
1894 971 (symbol 'date')
1895 972 (string 'UTC')))
1896 973 (symbol 'isodate'))
1897 974 (string '\n'))
1898 975 * keywords: date, node, rev
1899 976 * functions: isodate, localdate, short
1900 977 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
1901 978
1902 979 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
1903 980 (template
1904 981 (func
1905 982 (symbol 'status')
1906 983 (list
1907 984 (string 'A')
1908 985 (symbol 'file_adds'))))
1909 986 * expanded:
1910 987 (template
1911 988 (%
1912 989 (symbol 'file_adds')
1913 990 (template
1914 991 (string 'A')
1915 992 (string ' ')
1916 993 (symbol 'file')
1917 994 (string '\n'))))
1918 995 * keywords: file, file_adds
1919 996 * functions:
1920 997 A a
1921 998
1922 999 A unary function alias can be called as a filter:
1923 1000
1924 1001 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
1925 1002 (template
1926 1003 (|
1927 1004 (|
1928 1005 (symbol 'date')
1929 1006 (symbol 'utcdate'))
1930 1007 (symbol 'isodate'))
1931 1008 (string '\n'))
1932 1009 * expanded:
1933 1010 (template
1934 1011 (|
1935 1012 (func
1936 1013 (symbol 'localdate')
1937 1014 (list
1938 1015 (symbol 'date')
1939 1016 (string 'UTC')))
1940 1017 (symbol 'isodate'))
1941 1018 (string '\n'))
1942 1019 * keywords: date
1943 1020 * functions: isodate, localdate
1944 1021 1970-01-12 13:46 +0000
1945 1022
1946 1023 Aliases should be applied only to command arguments and templates in hgrc.
1947 1024 Otherwise, our stock styles and web templates could be corrupted:
1948 1025
1949 1026 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
1950 1027 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
1951 1028
1952 1029 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
1953 1030 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
1954 1031
1955 1032 $ cat <<EOF > tmpl
1956 1033 > changeset = 'nothing expanded:{rn}\n'
1957 1034 > EOF
1958 1035 $ hg log -r0 --style ./tmpl
1959 1036 nothing expanded:
1960 1037
1961 1038 Aliases in formatter:
1962 1039
1963 1040 $ hg branches -T '{pad(branch, 7)} {rn}\n'
1964 1041 default 6:d41e714fe50d
1965 1042 foo 4:bbe44766e73d
1966 1043
1967 1044 Aliases should honor HGPLAIN:
1968 1045
1969 1046 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
1970 1047 nothing expanded:
1971 1048 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
1972 1049 0:1e4e1b8f71e0
1973 1050
1974 1051 Unparsable alias:
1975 1052
1976 1053 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
1977 1054 (template
1978 1055 (symbol 'bad'))
1979 1056 abort: bad definition of template alias "bad": at 2: not a prefix: end
1980 1057 [255]
1981 1058 $ hg log --config templatealias.bad='x(' -T '{bad}'
1982 1059 abort: bad definition of template alias "bad": at 2: not a prefix: end
1983 1060 [255]
1984 1061
1985 1062 $ cd ..
1986 1063
1987 1064 Test that template function in extension is registered as expected
1988 1065
1989 1066 $ cd a
1990 1067
1991 1068 $ cat <<EOF > $TESTTMP/customfunc.py
1992 1069 > from mercurial import registrar
1993 1070 >
1994 1071 > templatefunc = registrar.templatefunc()
1995 1072 >
1996 1073 > @templatefunc(b'custom()')
1997 1074 > def custom(context, mapping, args):
1998 1075 > return b'custom'
1999 1076 > EOF
2000 1077 $ cat <<EOF > .hg/hgrc
2001 1078 > [extensions]
2002 1079 > customfunc = $TESTTMP/customfunc.py
2003 1080 > EOF
2004 1081
2005 1082 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
2006 1083 custom
2007 1084
2008 1085 $ cd ..
2009
2010 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
2011 printed graphwidths 3, 5, 7, etc. should all line up in their respective
2012 columns. We don't care about other aspects of the graph rendering here.
2013
2014 $ hg init graphwidth
2015 $ cd graphwidth
2016
2017 $ wrappabletext="a a a a a a a a a a a a"
2018
2019 $ printf "first\n" > file
2020 $ hg add file
2021 $ hg commit -m "$wrappabletext"
2022
2023 $ printf "first\nsecond\n" > file
2024 $ hg commit -m "$wrappabletext"
2025
2026 $ hg checkout 0
2027 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2028 $ printf "third\nfirst\n" > file
2029 $ hg commit -m "$wrappabletext"
2030 created new head
2031
2032 $ hg merge
2033 merging file
2034 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
2035 (branch merge, don't forget to commit)
2036
2037 $ hg log --graph -T "{graphwidth}"
2038 @ 3
2039 |
2040 | @ 5
2041 |/
2042 o 3
2043
2044 $ hg commit -m "$wrappabletext"
2045
2046 $ hg log --graph -T "{graphwidth}"
2047 @ 5
2048 |\
2049 | o 5
2050 | |
2051 o | 5
2052 |/
2053 o 3
2054
2055
2056 $ hg checkout 0
2057 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2058 $ printf "third\nfirst\nsecond\n" > file
2059 $ hg commit -m "$wrappabletext"
2060 created new head
2061
2062 $ hg log --graph -T "{graphwidth}"
2063 @ 3
2064 |
2065 | o 7
2066 | |\
2067 +---o 7
2068 | |
2069 | o 5
2070 |/
2071 o 3
2072
2073
2074 $ hg log --graph -T "{graphwidth}" -r 3
2075 o 5
2076 |\
2077 ~ ~
2078
2079 $ hg log --graph -T "{graphwidth}" -r 1
2080 o 3
2081 |
2082 ~
2083
2084 $ hg merge
2085 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2086 (branch merge, don't forget to commit)
2087 $ hg commit -m "$wrappabletext"
2088
2089 $ printf "seventh\n" >> file
2090 $ hg commit -m "$wrappabletext"
2091
2092 $ hg log --graph -T "{graphwidth}"
2093 @ 3
2094 |
2095 o 5
2096 |\
2097 | o 5
2098 | |
2099 o | 7
2100 |\ \
2101 | o | 7
2102 | |/
2103 o / 5
2104 |/
2105 o 3
2106
2107
2108 The point of graphwidth is to allow wrapping that accounts for the space taken
2109 by the graph.
2110
2111 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
2112 @ a a a a
2113 | a a a a
2114 | a a a a
2115 o a a a
2116 |\ a a a
2117 | | a a a
2118 | | a a a
2119 | o a a a
2120 | | a a a
2121 | | a a a
2122 | | a a a
2123 o | a a
2124 |\ \ a a
2125 | | | a a
2126 | | | a a
2127 | | | a a
2128 | | | a a
2129 | o | a a
2130 | |/ a a
2131 | | a a
2132 | | a a
2133 | | a a
2134 | | a a
2135 o | a a a
2136 |/ a a a
2137 | a a a
2138 | a a a
2139 o a a a a
2140 a a a a
2141 a a a a
2142
2143 Something tricky happens when there are elided nodes; the next drawn row of
2144 edges can be more than one column wider, but the graph width only increases by
2145 one column. The remaining columns are added in between the nodes.
2146
2147 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
2148 o 5
2149 |\
2150 | \
2151 | :\
2152 o : : 7
2153 :/ /
2154 : o 5
2155 :/
2156 o 3
2157
2158
2159 $ cd ..
2160
This diff has been collapsed as it changes many lines, (975 lines changed) Show them Hide them
@@ -1,2160 +1,1195
1 Test template keywords
2 ======================
3
1 4 $ hg init a
2 5 $ cd a
3 6 $ echo a > a
4 7 $ hg add a
5 8 $ echo line 1 > b
6 9 $ echo line 2 >> b
7 10 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
8 11
9 12 $ hg add b
10 13 $ echo other 1 > c
11 14 $ echo other 2 >> c
12 15 $ echo >> c
13 16 $ echo other 3 >> c
14 17 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
15 18
16 19 $ hg add c
17 20 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
18 21 $ echo c >> c
19 22 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
20 23
21 24 $ echo foo > .hg/branch
22 25 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
23 26
24 27 $ hg co -q 3
25 28 $ echo other 4 >> d
26 29 $ hg add d
27 30 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
28 31
29 32 $ hg merge -q foo
30 33 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
31 34
32 Test arithmetic operators have the right precedence:
33
34 $ hg log -l 1 -T '{date(date, "%Y") + 5 * 10} {date(date, "%Y") - 2 * 3}\n'
35 2020 1964
36 $ hg log -l 1 -T '{date(date, "%Y") * 5 + 10} {date(date, "%Y") * 3 - 2}\n'
37 9860 5908
38
39 Test division:
40
41 $ hg debugtemplate -r0 -v '{5 / 2} {mod(5, 2)}\n'
42 (template
43 (/
44 (integer '5')
45 (integer '2'))
46 (string ' ')
47 (func
48 (symbol 'mod')
49 (list
50 (integer '5')
51 (integer '2')))
52 (string '\n'))
53 * keywords:
54 * functions: mod
55 2 1
56 $ hg debugtemplate -r0 -v '{5 / -2} {mod(5, -2)}\n'
57 (template
58 (/
59 (integer '5')
60 (negate
61 (integer '2')))
62 (string ' ')
63 (func
64 (symbol 'mod')
65 (list
66 (integer '5')
67 (negate
68 (integer '2'))))
69 (string '\n'))
70 * keywords:
71 * functions: mod
72 -3 -1
73 $ hg debugtemplate -r0 -v '{-5 / 2} {mod(-5, 2)}\n'
74 (template
75 (/
76 (negate
77 (integer '5'))
78 (integer '2'))
79 (string ' ')
80 (func
81 (symbol 'mod')
82 (list
83 (negate
84 (integer '5'))
85 (integer '2')))
86 (string '\n'))
87 * keywords:
88 * functions: mod
89 -3 1
90 $ hg debugtemplate -r0 -v '{-5 / -2} {mod(-5, -2)}\n'
91 (template
92 (/
93 (negate
94 (integer '5'))
95 (negate
96 (integer '2')))
97 (string ' ')
98 (func
99 (symbol 'mod')
100 (list
101 (negate
102 (integer '5'))
103 (negate
104 (integer '2'))))
105 (string '\n'))
106 * keywords:
107 * functions: mod
108 2 -1
109
110 Filters bind closer than arithmetic:
111
112 $ hg debugtemplate -r0 -v '{revset(".")|count - 1}\n'
113 (template
114 (-
115 (|
116 (func
117 (symbol 'revset')
118 (string '.'))
119 (symbol 'count'))
120 (integer '1'))
121 (string '\n'))
122 * keywords:
123 * functions: count, revset
124 0
125
126 But negate binds closer still:
127
128 $ hg debugtemplate -r0 -v '{1-3|stringify}\n'
129 (template
130 (-
131 (integer '1')
132 (|
133 (integer '3')
134 (symbol 'stringify')))
135 (string '\n'))
136 * keywords:
137 * functions: stringify
138 hg: parse error: arithmetic only defined on integers
139 [255]
140 $ hg debugtemplate -r0 -v '{-3|stringify}\n'
141 (template
142 (|
143 (negate
144 (integer '3'))
145 (symbol 'stringify'))
146 (string '\n'))
147 * keywords:
148 * functions: stringify
149 -3
150
151 Filters bind as close as map operator:
152
153 $ hg debugtemplate -r0 -v '{desc|splitlines % "{line}\n"}'
154 (template
155 (%
156 (|
157 (symbol 'desc')
158 (symbol 'splitlines'))
159 (template
160 (symbol 'line')
161 (string '\n'))))
162 * keywords: desc, line
163 * functions: splitlines
164 line 1
165 line 2
166
167 Keyword arguments:
168
169 $ hg debugtemplate -r0 -v '{foo=bar|baz}'
170 (template
171 (keyvalue
172 (symbol 'foo')
173 (|
174 (symbol 'bar')
175 (symbol 'baz'))))
176 * keywords: bar, foo
177 * functions: baz
178 hg: parse error: can't use a key-value pair in this context
179 [255]
180
181 $ hg debugtemplate '{pad("foo", width=10, left=true)}\n'
182 foo
183
184 Call function which takes named arguments by filter syntax:
185
186 $ hg debugtemplate '{" "|separate}'
187 $ hg debugtemplate '{("not", "an", "argument", "list")|separate}'
188 hg: parse error: unknown method 'list'
189 [255]
190
191 35 Second branch starting at nullrev:
192 36
193 37 $ hg update null
194 38 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
195 39 $ echo second > second
196 40 $ hg add second
197 41 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
198 42 created new head
199 43
200 44 $ echo third > third
201 45 $ hg add third
202 46 $ hg mv second fourth
203 47 $ hg commit -m third -d "2020-01-01 10:01"
204 48
205 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
206 fourth (second)
207 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
208 second -> fourth
209 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
210 8 t
211 7 f
212
213 49 Working-directory revision has special identifiers, though they are still
214 50 experimental:
215 51
216 52 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
217 53 2147483647:ffffffffffffffffffffffffffffffffffffffff
218 54
219 55 Some keywords are invalid for working-directory revision, but they should
220 56 never cause crash:
221 57
222 58 $ hg log -r 'wdir()' -T '{manifest}\n'
223 59
224 60
225 Internal resources shouldn't be exposed (issue5699):
226
227 $ hg log -r. -T '{cache}{ctx}{repo}{revcache}{templ}{ui}'
228
229 Never crash on internal resource not available:
230
231 $ hg --cwd .. debugtemplate '{"c0bebeef"|shortest}\n'
232 abort: template resource not available: repo
233 [255]
234
235 $ hg config -T '{author}'
236
237 Quoting for ui.logtemplate
238
239 $ hg tip --config "ui.logtemplate={rev}\n"
240 8
241 $ hg tip --config "ui.logtemplate='{rev}\n'"
242 8
243 $ hg tip --config 'ui.logtemplate="{rev}\n"'
244 8
245 $ hg tip --config 'ui.logtemplate=n{rev}\n'
246 n8
247
248 Check that recursive reference does not fall into RuntimeError (issue4758):
249
250 common mistake:
251
252 $ cat << EOF > issue4758
253 > changeset = '{changeset}\n'
254 > EOF
255 $ hg log --style ./issue4758
256 abort: recursive reference 'changeset' in template
257 [255]
258
259 circular reference:
260
261 $ cat << EOF > issue4758
262 > changeset = '{foo}'
263 > foo = '{changeset}'
264 > EOF
265 $ hg log --style ./issue4758
266 abort: recursive reference 'foo' in template
267 [255]
268
269 buildmap() -> gettemplate(), where no thunk was made:
270
271 $ cat << EOF > issue4758
272 > changeset = '{files % changeset}\n'
273 > EOF
274 $ hg log --style ./issue4758
275 abort: recursive reference 'changeset' in template
276 [255]
277
278 not a recursion if a keyword of the same name exists:
279
280 $ cat << EOF > issue4758
281 > changeset = '{tags % rev}'
282 > rev = '{rev} {tag}\n'
283 > EOF
284 $ hg log --style ./issue4758 -r tip
285 8 tip
286
287 61 Check that {phase} works correctly on parents:
288 62
289 63 $ cat << EOF > parentphase
290 64 > changeset_debug = '{rev} ({phase}):{parents}\n'
291 65 > parent = ' {rev} ({phase})'
292 66 > EOF
293 67 $ hg phase -r 5 --public
294 68 $ hg phase -r 7 --secret --force
295 69 $ hg log --debug -G --style ./parentphase
296 70 @ 8 (secret): 7 (secret) -1 (public)
297 71 |
298 72 o 7 (secret): -1 (public) -1 (public)
299 73
300 74 o 6 (draft): 5 (public) 4 (draft)
301 75 |\
302 76 | o 5 (public): 3 (public) -1 (public)
303 77 | |
304 78 o | 4 (draft): 3 (public) -1 (public)
305 79 |/
306 80 o 3 (public): 2 (public) -1 (public)
307 81 |
308 82 o 2 (public): 1 (public) -1 (public)
309 83 |
310 84 o 1 (public): 0 (public) -1 (public)
311 85 |
312 86 o 0 (public): -1 (public) -1 (public)
313 87
314 88
315 89 Keys work:
316 90
317 91 $ for key in author branch branches date desc file_adds file_dels file_mods \
318 92 > file_copies file_copies_switch files \
319 93 > manifest node parents rev tags diffstat extras \
320 94 > p1rev p2rev p1node p2node; do
321 95 > for mode in '' --verbose --debug; do
322 96 > hg log $mode --template "$key$mode: {$key}\n"
323 97 > done
324 98 > done
325 99 author: test
326 100 author: User Name <user@hostname>
327 101 author: person
328 102 author: person
329 103 author: person
330 104 author: person
331 105 author: other@place
332 106 author: A. N. Other <other@place>
333 107 author: User Name <user@hostname>
334 108 author--verbose: test
335 109 author--verbose: User Name <user@hostname>
336 110 author--verbose: person
337 111 author--verbose: person
338 112 author--verbose: person
339 113 author--verbose: person
340 114 author--verbose: other@place
341 115 author--verbose: A. N. Other <other@place>
342 116 author--verbose: User Name <user@hostname>
343 117 author--debug: test
344 118 author--debug: User Name <user@hostname>
345 119 author--debug: person
346 120 author--debug: person
347 121 author--debug: person
348 122 author--debug: person
349 123 author--debug: other@place
350 124 author--debug: A. N. Other <other@place>
351 125 author--debug: User Name <user@hostname>
352 126 branch: default
353 127 branch: default
354 128 branch: default
355 129 branch: default
356 130 branch: foo
357 131 branch: default
358 132 branch: default
359 133 branch: default
360 134 branch: default
361 135 branch--verbose: default
362 136 branch--verbose: default
363 137 branch--verbose: default
364 138 branch--verbose: default
365 139 branch--verbose: foo
366 140 branch--verbose: default
367 141 branch--verbose: default
368 142 branch--verbose: default
369 143 branch--verbose: default
370 144 branch--debug: default
371 145 branch--debug: default
372 146 branch--debug: default
373 147 branch--debug: default
374 148 branch--debug: foo
375 149 branch--debug: default
376 150 branch--debug: default
377 151 branch--debug: default
378 152 branch--debug: default
379 153 branches:
380 154 branches:
381 155 branches:
382 156 branches:
383 157 branches: foo
384 158 branches:
385 159 branches:
386 160 branches:
387 161 branches:
388 162 branches--verbose:
389 163 branches--verbose:
390 164 branches--verbose:
391 165 branches--verbose:
392 166 branches--verbose: foo
393 167 branches--verbose:
394 168 branches--verbose:
395 169 branches--verbose:
396 170 branches--verbose:
397 171 branches--debug:
398 172 branches--debug:
399 173 branches--debug:
400 174 branches--debug:
401 175 branches--debug: foo
402 176 branches--debug:
403 177 branches--debug:
404 178 branches--debug:
405 179 branches--debug:
406 180 date: 1577872860.00
407 181 date: 1000000.00
408 182 date: 1500001.00
409 183 date: 1500000.00
410 184 date: 1400000.00
411 185 date: 1300000.00
412 186 date: 1200000.00
413 187 date: 1100000.00
414 188 date: 1000000.00
415 189 date--verbose: 1577872860.00
416 190 date--verbose: 1000000.00
417 191 date--verbose: 1500001.00
418 192 date--verbose: 1500000.00
419 193 date--verbose: 1400000.00
420 194 date--verbose: 1300000.00
421 195 date--verbose: 1200000.00
422 196 date--verbose: 1100000.00
423 197 date--verbose: 1000000.00
424 198 date--debug: 1577872860.00
425 199 date--debug: 1000000.00
426 200 date--debug: 1500001.00
427 201 date--debug: 1500000.00
428 202 date--debug: 1400000.00
429 203 date--debug: 1300000.00
430 204 date--debug: 1200000.00
431 205 date--debug: 1100000.00
432 206 date--debug: 1000000.00
433 207 desc: third
434 208 desc: second
435 209 desc: merge
436 210 desc: new head
437 211 desc: new branch
438 212 desc: no user, no domain
439 213 desc: no person
440 214 desc: other 1
441 215 other 2
442 216
443 217 other 3
444 218 desc: line 1
445 219 line 2
446 220 desc--verbose: third
447 221 desc--verbose: second
448 222 desc--verbose: merge
449 223 desc--verbose: new head
450 224 desc--verbose: new branch
451 225 desc--verbose: no user, no domain
452 226 desc--verbose: no person
453 227 desc--verbose: other 1
454 228 other 2
455 229
456 230 other 3
457 231 desc--verbose: line 1
458 232 line 2
459 233 desc--debug: third
460 234 desc--debug: second
461 235 desc--debug: merge
462 236 desc--debug: new head
463 237 desc--debug: new branch
464 238 desc--debug: no user, no domain
465 239 desc--debug: no person
466 240 desc--debug: other 1
467 241 other 2
468 242
469 243 other 3
470 244 desc--debug: line 1
471 245 line 2
472 246 file_adds: fourth third
473 247 file_adds: second
474 248 file_adds:
475 249 file_adds: d
476 250 file_adds:
477 251 file_adds:
478 252 file_adds: c
479 253 file_adds: b
480 254 file_adds: a
481 255 file_adds--verbose: fourth third
482 256 file_adds--verbose: second
483 257 file_adds--verbose:
484 258 file_adds--verbose: d
485 259 file_adds--verbose:
486 260 file_adds--verbose:
487 261 file_adds--verbose: c
488 262 file_adds--verbose: b
489 263 file_adds--verbose: a
490 264 file_adds--debug: fourth third
491 265 file_adds--debug: second
492 266 file_adds--debug:
493 267 file_adds--debug: d
494 268 file_adds--debug:
495 269 file_adds--debug:
496 270 file_adds--debug: c
497 271 file_adds--debug: b
498 272 file_adds--debug: a
499 273 file_dels: second
500 274 file_dels:
501 275 file_dels:
502 276 file_dels:
503 277 file_dels:
504 278 file_dels:
505 279 file_dels:
506 280 file_dels:
507 281 file_dels:
508 282 file_dels--verbose: second
509 283 file_dels--verbose:
510 284 file_dels--verbose:
511 285 file_dels--verbose:
512 286 file_dels--verbose:
513 287 file_dels--verbose:
514 288 file_dels--verbose:
515 289 file_dels--verbose:
516 290 file_dels--verbose:
517 291 file_dels--debug: second
518 292 file_dels--debug:
519 293 file_dels--debug:
520 294 file_dels--debug:
521 295 file_dels--debug:
522 296 file_dels--debug:
523 297 file_dels--debug:
524 298 file_dels--debug:
525 299 file_dels--debug:
526 300 file_mods:
527 301 file_mods:
528 302 file_mods:
529 303 file_mods:
530 304 file_mods:
531 305 file_mods: c
532 306 file_mods:
533 307 file_mods:
534 308 file_mods:
535 309 file_mods--verbose:
536 310 file_mods--verbose:
537 311 file_mods--verbose:
538 312 file_mods--verbose:
539 313 file_mods--verbose:
540 314 file_mods--verbose: c
541 315 file_mods--verbose:
542 316 file_mods--verbose:
543 317 file_mods--verbose:
544 318 file_mods--debug:
545 319 file_mods--debug:
546 320 file_mods--debug:
547 321 file_mods--debug:
548 322 file_mods--debug:
549 323 file_mods--debug: c
550 324 file_mods--debug:
551 325 file_mods--debug:
552 326 file_mods--debug:
553 327 file_copies: fourth (second)
554 328 file_copies:
555 329 file_copies:
556 330 file_copies:
557 331 file_copies:
558 332 file_copies:
559 333 file_copies:
560 334 file_copies:
561 335 file_copies:
562 336 file_copies--verbose: fourth (second)
563 337 file_copies--verbose:
564 338 file_copies--verbose:
565 339 file_copies--verbose:
566 340 file_copies--verbose:
567 341 file_copies--verbose:
568 342 file_copies--verbose:
569 343 file_copies--verbose:
570 344 file_copies--verbose:
571 345 file_copies--debug: fourth (second)
572 346 file_copies--debug:
573 347 file_copies--debug:
574 348 file_copies--debug:
575 349 file_copies--debug:
576 350 file_copies--debug:
577 351 file_copies--debug:
578 352 file_copies--debug:
579 353 file_copies--debug:
580 354 file_copies_switch:
581 355 file_copies_switch:
582 356 file_copies_switch:
583 357 file_copies_switch:
584 358 file_copies_switch:
585 359 file_copies_switch:
586 360 file_copies_switch:
587 361 file_copies_switch:
588 362 file_copies_switch:
589 363 file_copies_switch--verbose:
590 364 file_copies_switch--verbose:
591 365 file_copies_switch--verbose:
592 366 file_copies_switch--verbose:
593 367 file_copies_switch--verbose:
594 368 file_copies_switch--verbose:
595 369 file_copies_switch--verbose:
596 370 file_copies_switch--verbose:
597 371 file_copies_switch--verbose:
598 372 file_copies_switch--debug:
599 373 file_copies_switch--debug:
600 374 file_copies_switch--debug:
601 375 file_copies_switch--debug:
602 376 file_copies_switch--debug:
603 377 file_copies_switch--debug:
604 378 file_copies_switch--debug:
605 379 file_copies_switch--debug:
606 380 file_copies_switch--debug:
607 381 files: fourth second third
608 382 files: second
609 383 files:
610 384 files: d
611 385 files:
612 386 files: c
613 387 files: c
614 388 files: b
615 389 files: a
616 390 files--verbose: fourth second third
617 391 files--verbose: second
618 392 files--verbose:
619 393 files--verbose: d
620 394 files--verbose:
621 395 files--verbose: c
622 396 files--verbose: c
623 397 files--verbose: b
624 398 files--verbose: a
625 399 files--debug: fourth second third
626 400 files--debug: second
627 401 files--debug:
628 402 files--debug: d
629 403 files--debug:
630 404 files--debug: c
631 405 files--debug: c
632 406 files--debug: b
633 407 files--debug: a
634 408 manifest: 6:94961b75a2da
635 409 manifest: 5:f2dbc354b94e
636 410 manifest: 4:4dc3def4f9b4
637 411 manifest: 4:4dc3def4f9b4
638 412 manifest: 3:cb5a1327723b
639 413 manifest: 3:cb5a1327723b
640 414 manifest: 2:6e0e82995c35
641 415 manifest: 1:4e8d705b1e53
642 416 manifest: 0:a0c8bcbbb45c
643 417 manifest--verbose: 6:94961b75a2da
644 418 manifest--verbose: 5:f2dbc354b94e
645 419 manifest--verbose: 4:4dc3def4f9b4
646 420 manifest--verbose: 4:4dc3def4f9b4
647 421 manifest--verbose: 3:cb5a1327723b
648 422 manifest--verbose: 3:cb5a1327723b
649 423 manifest--verbose: 2:6e0e82995c35
650 424 manifest--verbose: 1:4e8d705b1e53
651 425 manifest--verbose: 0:a0c8bcbbb45c
652 426 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
653 427 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
654 428 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
655 429 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
656 430 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
657 431 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
658 432 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
659 433 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
660 434 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
661 435 node: 95c24699272ef57d062b8bccc32c878bf841784a
662 436 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
663 437 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
664 438 node: 13207e5a10d9fd28ec424934298e176197f2c67f
665 439 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
666 440 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
667 441 node: 97054abb4ab824450e9164180baf491ae0078465
668 442 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
669 443 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
670 444 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
671 445 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
672 446 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
673 447 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
674 448 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
675 449 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
676 450 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
677 451 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
678 452 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
679 453 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
680 454 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
681 455 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
682 456 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
683 457 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
684 458 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
685 459 node--debug: 97054abb4ab824450e9164180baf491ae0078465
686 460 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
687 461 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
688 462 parents:
689 463 parents: -1:000000000000
690 464 parents: 5:13207e5a10d9 4:bbe44766e73d
691 465 parents: 3:10e46f2dcbf4
692 466 parents:
693 467 parents:
694 468 parents:
695 469 parents:
696 470 parents:
697 471 parents--verbose:
698 472 parents--verbose: -1:000000000000
699 473 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
700 474 parents--verbose: 3:10e46f2dcbf4
701 475 parents--verbose:
702 476 parents--verbose:
703 477 parents--verbose:
704 478 parents--verbose:
705 479 parents--verbose:
706 480 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
707 481 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
708 482 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
709 483 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
710 484 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
711 485 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
712 486 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
713 487 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
714 488 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
715 489 rev: 8
716 490 rev: 7
717 491 rev: 6
718 492 rev: 5
719 493 rev: 4
720 494 rev: 3
721 495 rev: 2
722 496 rev: 1
723 497 rev: 0
724 498 rev--verbose: 8
725 499 rev--verbose: 7
726 500 rev--verbose: 6
727 501 rev--verbose: 5
728 502 rev--verbose: 4
729 503 rev--verbose: 3
730 504 rev--verbose: 2
731 505 rev--verbose: 1
732 506 rev--verbose: 0
733 507 rev--debug: 8
734 508 rev--debug: 7
735 509 rev--debug: 6
736 510 rev--debug: 5
737 511 rev--debug: 4
738 512 rev--debug: 3
739 513 rev--debug: 2
740 514 rev--debug: 1
741 515 rev--debug: 0
742 516 tags: tip
743 517 tags:
744 518 tags:
745 519 tags:
746 520 tags:
747 521 tags:
748 522 tags:
749 523 tags:
750 524 tags:
751 525 tags--verbose: tip
752 526 tags--verbose:
753 527 tags--verbose:
754 528 tags--verbose:
755 529 tags--verbose:
756 530 tags--verbose:
757 531 tags--verbose:
758 532 tags--verbose:
759 533 tags--verbose:
760 534 tags--debug: tip
761 535 tags--debug:
762 536 tags--debug:
763 537 tags--debug:
764 538 tags--debug:
765 539 tags--debug:
766 540 tags--debug:
767 541 tags--debug:
768 542 tags--debug:
769 543 diffstat: 3: +2/-1
770 544 diffstat: 1: +1/-0
771 545 diffstat: 0: +0/-0
772 546 diffstat: 1: +1/-0
773 547 diffstat: 0: +0/-0
774 548 diffstat: 1: +1/-0
775 549 diffstat: 1: +4/-0
776 550 diffstat: 1: +2/-0
777 551 diffstat: 1: +1/-0
778 552 diffstat--verbose: 3: +2/-1
779 553 diffstat--verbose: 1: +1/-0
780 554 diffstat--verbose: 0: +0/-0
781 555 diffstat--verbose: 1: +1/-0
782 556 diffstat--verbose: 0: +0/-0
783 557 diffstat--verbose: 1: +1/-0
784 558 diffstat--verbose: 1: +4/-0
785 559 diffstat--verbose: 1: +2/-0
786 560 diffstat--verbose: 1: +1/-0
787 561 diffstat--debug: 3: +2/-1
788 562 diffstat--debug: 1: +1/-0
789 563 diffstat--debug: 0: +0/-0
790 564 diffstat--debug: 1: +1/-0
791 565 diffstat--debug: 0: +0/-0
792 566 diffstat--debug: 1: +1/-0
793 567 diffstat--debug: 1: +4/-0
794 568 diffstat--debug: 1: +2/-0
795 569 diffstat--debug: 1: +1/-0
796 570 extras: branch=default
797 571 extras: branch=default
798 572 extras: branch=default
799 573 extras: branch=default
800 574 extras: branch=foo
801 575 extras: branch=default
802 576 extras: branch=default
803 577 extras: branch=default
804 578 extras: branch=default
805 579 extras--verbose: branch=default
806 580 extras--verbose: branch=default
807 581 extras--verbose: branch=default
808 582 extras--verbose: branch=default
809 583 extras--verbose: branch=foo
810 584 extras--verbose: branch=default
811 585 extras--verbose: branch=default
812 586 extras--verbose: branch=default
813 587 extras--verbose: branch=default
814 588 extras--debug: branch=default
815 589 extras--debug: branch=default
816 590 extras--debug: branch=default
817 591 extras--debug: branch=default
818 592 extras--debug: branch=foo
819 593 extras--debug: branch=default
820 594 extras--debug: branch=default
821 595 extras--debug: branch=default
822 596 extras--debug: branch=default
823 597 p1rev: 7
824 598 p1rev: -1
825 599 p1rev: 5
826 600 p1rev: 3
827 601 p1rev: 3
828 602 p1rev: 2
829 603 p1rev: 1
830 604 p1rev: 0
831 605 p1rev: -1
832 606 p1rev--verbose: 7
833 607 p1rev--verbose: -1
834 608 p1rev--verbose: 5
835 609 p1rev--verbose: 3
836 610 p1rev--verbose: 3
837 611 p1rev--verbose: 2
838 612 p1rev--verbose: 1
839 613 p1rev--verbose: 0
840 614 p1rev--verbose: -1
841 615 p1rev--debug: 7
842 616 p1rev--debug: -1
843 617 p1rev--debug: 5
844 618 p1rev--debug: 3
845 619 p1rev--debug: 3
846 620 p1rev--debug: 2
847 621 p1rev--debug: 1
848 622 p1rev--debug: 0
849 623 p1rev--debug: -1
850 624 p2rev: -1
851 625 p2rev: -1
852 626 p2rev: 4
853 627 p2rev: -1
854 628 p2rev: -1
855 629 p2rev: -1
856 630 p2rev: -1
857 631 p2rev: -1
858 632 p2rev: -1
859 633 p2rev--verbose: -1
860 634 p2rev--verbose: -1
861 635 p2rev--verbose: 4
862 636 p2rev--verbose: -1
863 637 p2rev--verbose: -1
864 638 p2rev--verbose: -1
865 639 p2rev--verbose: -1
866 640 p2rev--verbose: -1
867 641 p2rev--verbose: -1
868 642 p2rev--debug: -1
869 643 p2rev--debug: -1
870 644 p2rev--debug: 4
871 645 p2rev--debug: -1
872 646 p2rev--debug: -1
873 647 p2rev--debug: -1
874 648 p2rev--debug: -1
875 649 p2rev--debug: -1
876 650 p2rev--debug: -1
877 651 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
878 652 p1node: 0000000000000000000000000000000000000000
879 653 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
880 654 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
881 655 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
882 656 p1node: 97054abb4ab824450e9164180baf491ae0078465
883 657 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
884 658 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
885 659 p1node: 0000000000000000000000000000000000000000
886 660 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
887 661 p1node--verbose: 0000000000000000000000000000000000000000
888 662 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
889 663 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
890 664 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
891 665 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
892 666 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
893 667 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
894 668 p1node--verbose: 0000000000000000000000000000000000000000
895 669 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
896 670 p1node--debug: 0000000000000000000000000000000000000000
897 671 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
898 672 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
899 673 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
900 674 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
901 675 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
902 676 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
903 677 p1node--debug: 0000000000000000000000000000000000000000
904 678 p2node: 0000000000000000000000000000000000000000
905 679 p2node: 0000000000000000000000000000000000000000
906 680 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
907 681 p2node: 0000000000000000000000000000000000000000
908 682 p2node: 0000000000000000000000000000000000000000
909 683 p2node: 0000000000000000000000000000000000000000
910 684 p2node: 0000000000000000000000000000000000000000
911 685 p2node: 0000000000000000000000000000000000000000
912 686 p2node: 0000000000000000000000000000000000000000
913 687 p2node--verbose: 0000000000000000000000000000000000000000
914 688 p2node--verbose: 0000000000000000000000000000000000000000
915 689 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
916 690 p2node--verbose: 0000000000000000000000000000000000000000
917 691 p2node--verbose: 0000000000000000000000000000000000000000
918 692 p2node--verbose: 0000000000000000000000000000000000000000
919 693 p2node--verbose: 0000000000000000000000000000000000000000
920 694 p2node--verbose: 0000000000000000000000000000000000000000
921 695 p2node--verbose: 0000000000000000000000000000000000000000
922 696 p2node--debug: 0000000000000000000000000000000000000000
923 697 p2node--debug: 0000000000000000000000000000000000000000
924 698 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
925 699 p2node--debug: 0000000000000000000000000000000000000000
926 700 p2node--debug: 0000000000000000000000000000000000000000
927 701 p2node--debug: 0000000000000000000000000000000000000000
928 702 p2node--debug: 0000000000000000000000000000000000000000
929 703 p2node--debug: 0000000000000000000000000000000000000000
930 704 p2node--debug: 0000000000000000000000000000000000000000
931 705
932 706 Add a dummy commit to make up for the instability of the above:
933 707
934 708 $ echo a > a
935 709 $ hg add a
936 710 $ hg ci -m future
937 711
938 712 Add a commit that does all possible modifications at once
939 713
940 714 $ echo modify >> third
941 715 $ touch b
942 716 $ hg add b
943 717 $ hg mv fourth fifth
944 718 $ hg rm a
945 719 $ hg ci -m "Modify, add, remove, rename"
946 720
947 Error on syntax:
948
949 $ cat <<EOF > t
950 > changeset = '{c}'
951 > c = q
952 > x = "f
953 > EOF
954 $ echo '[ui]' > .hg/hgrc
955 $ echo 'style = t' >> .hg/hgrc
956 $ hg log
957 hg: parse error at t:3: unmatched quotes
958 [255]
959
960 $ hg log -T '{date'
961 hg: parse error at 1: unterminated template expansion
962 ({date
963 ^ here)
964 [255]
965 $ hg log -T '{date(}'
966 hg: parse error at 6: not a prefix: end
967 ({date(}
968 ^ here)
969 [255]
970 $ hg log -T '{date)}'
971 hg: parse error at 5: invalid token
972 ({date)}
973 ^ here)
974 [255]
975 $ hg log -T '{date date}'
976 hg: parse error at 6: invalid token
977 ({date date}
978 ^ here)
979 [255]
980
981 $ hg log -T '{}'
982 hg: parse error at 1: not a prefix: end
983 ({}
984 ^ here)
985 [255]
986 $ hg debugtemplate -v '{()}'
987 (template
988 (group
989 None))
990 * keywords:
991 * functions:
992 hg: parse error: missing argument
993 [255]
994
995 Behind the scenes, this would throw TypeError without intype=bytes
996
997 $ hg log -l 3 --template '{date|obfuscate}\n'
998 &#48;&#46;&#48;&#48;
999 &#48;&#46;&#48;&#48;
1000 &#49;&#53;&#55;&#55;&#56;&#55;&#50;&#56;&#54;&#48;&#46;&#48;&#48;
1001
1002 Behind the scenes, this will throw a ValueError
1003
1004 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1005 hg: parse error: invalid date: 'Modify, add, remove, rename'
1006 (template filter 'shortdate' is not compatible with keyword 'desc')
1007 [255]
1008
1009 Behind the scenes, this would throw AttributeError without intype=bytes
1010
1011 $ hg log -l 3 --template 'line: {date|escape}\n'
1012 line: 0.00
1013 line: 0.00
1014 line: 1577872860.00
1015
1016 $ hg log -l 3 --template 'line: {extras|localdate}\n'
1017 hg: parse error: localdate expects a date information
1018 [255]
1019
1020 Behind the scenes, this will throw ValueError
1021
1022 $ hg tip --template '{author|email|date}\n'
1023 hg: parse error: date expects a date information
1024 [255]
1025
1026 $ hg tip -T '{author|email|shortdate}\n'
1027 hg: parse error: invalid date: 'test'
1028 (template filter 'shortdate' is not compatible with keyword 'author')
1029 [255]
1030
1031 $ hg tip -T '{get(extras, "branch")|shortdate}\n'
1032 hg: parse error: invalid date: 'default'
1033 (incompatible use of template filter 'shortdate')
1034 [255]
1035
1036 Error in nested template:
1037
1038 $ hg log -T '{"date'
1039 hg: parse error at 2: unterminated string
1040 ({"date
1041 ^ here)
1042 [255]
1043
1044 $ hg log -T '{"foo{date|?}"}'
1045 hg: parse error at 11: syntax error
1046 ({"foo{date|?}"}
1047 ^ here)
1048 [255]
1049
1050 Thrown an error if a template function doesn't exist
1051
1052 $ hg tip --template '{foo()}\n'
1053 hg: parse error: unknown function 'foo'
1054 [255]
1055
1056 721 Test index keyword:
1057 722
1058 723 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
1059 724 10 0:a 1:b 2:fifth 3:fourth 4:third
1060 725 11 0:a
1061 726
1062 727 $ hg branches -T '{index} {branch}\n'
1063 728 0 default
1064 729 1 foo
1065 730
1066 731 ui verbosity:
1067 732
1068 733 $ hg log -l1 -T '{verbosity}\n'
1069 734
1070 735 $ hg log -l1 -T '{verbosity}\n' --debug
1071 736 debug
1072 737 $ hg log -l1 -T '{verbosity}\n' --quiet
1073 738 quiet
1074 739 $ hg log -l1 -T '{verbosity}\n' --verbose
1075 740 verbose
1076 741
1077 742 $ cd ..
1078 743
1079
1080 744 latesttag:
1081 745
1082 746 $ hg init latesttag
1083 747 $ cd latesttag
1084 748
1085 749 $ echo a > file
1086 750 $ hg ci -Am a -d '0 0'
1087 751 adding file
1088 752
1089 753 $ echo b >> file
1090 754 $ hg ci -m b -d '1 0'
1091 755
1092 756 $ echo c >> head1
1093 757 $ hg ci -Am h1c -d '2 0'
1094 758 adding head1
1095 759
1096 760 $ hg update -q 1
1097 761 $ echo d >> head2
1098 762 $ hg ci -Am h2d -d '3 0'
1099 763 adding head2
1100 764 created new head
1101 765
1102 766 $ echo e >> head2
1103 767 $ hg ci -m h2e -d '4 0'
1104 768
1105 769 $ hg merge -q
1106 770 $ hg ci -m merge -d '5 -3600'
1107 771
1108 772 No tag set:
1109 773
1110 774 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1111 775 @ 5: null+5
1112 776 |\
1113 777 | o 4: null+4
1114 778 | |
1115 779 | o 3: null+3
1116 780 | |
1117 781 o | 2: null+3
1118 782 |/
1119 783 o 1: null+2
1120 784 |
1121 785 o 0: null+1
1122 786
1123 787
1124 788 One common tag: longest path wins for {latesttagdistance}:
1125 789
1126 790 $ hg tag -r 1 -m t1 -d '6 0' t1
1127 791 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1128 792 @ 6: t1+4
1129 793 |
1130 794 o 5: t1+3
1131 795 |\
1132 796 | o 4: t1+2
1133 797 | |
1134 798 | o 3: t1+1
1135 799 | |
1136 800 o | 2: t1+1
1137 801 |/
1138 802 o 1: t1+0
1139 803 |
1140 804 o 0: null+1
1141 805
1142 806
1143 807 One ancestor tag: closest wins:
1144 808
1145 809 $ hg tag -r 2 -m t2 -d '7 0' t2
1146 810 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1147 811 @ 7: t2+3
1148 812 |
1149 813 o 6: t2+2
1150 814 |
1151 815 o 5: t2+1
1152 816 |\
1153 817 | o 4: t1+2
1154 818 | |
1155 819 | o 3: t1+1
1156 820 | |
1157 821 o | 2: t2+0
1158 822 |/
1159 823 o 1: t1+0
1160 824 |
1161 825 o 0: null+1
1162 826
1163 827
1164 828 Two branch tags: more recent wins if same number of changes:
1165 829
1166 830 $ hg tag -r 3 -m t3 -d '8 0' t3
1167 831 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1168 832 @ 8: t3+5
1169 833 |
1170 834 o 7: t3+4
1171 835 |
1172 836 o 6: t3+3
1173 837 |
1174 838 o 5: t3+2
1175 839 |\
1176 840 | o 4: t3+1
1177 841 | |
1178 842 | o 3: t3+0
1179 843 | |
1180 844 o | 2: t2+0
1181 845 |/
1182 846 o 1: t1+0
1183 847 |
1184 848 o 0: null+1
1185 849
1186 850
1187 851 Two branch tags: fewest changes wins:
1188 852
1189 853 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
1190 854 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1191 855 @ 9: t4+5,6
1192 856 |
1193 857 o 8: t4+4,5
1194 858 |
1195 859 o 7: t4+3,4
1196 860 |
1197 861 o 6: t4+2,3
1198 862 |
1199 863 o 5: t4+1,2
1200 864 |\
1201 865 | o 4: t4+0,0
1202 866 | |
1203 867 | o 3: t3+0,0
1204 868 | |
1205 869 o | 2: t2+0,0
1206 870 |/
1207 871 o 1: t1+0,0
1208 872 |
1209 873 o 0: null+1,1
1210 874
1211 875
1212 876 Merged tag overrides:
1213 877
1214 878 $ hg tag -r 5 -m t5 -d '9 0' t5
1215 879 $ hg tag -r 3 -m at3 -d '10 0' at3
1216 880 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1217 881 @ 11: t5+6
1218 882 |
1219 883 o 10: t5+5
1220 884 |
1221 885 o 9: t5+4
1222 886 |
1223 887 o 8: t5+3
1224 888 |
1225 889 o 7: t5+2
1226 890 |
1227 891 o 6: t5+1
1228 892 |
1229 893 o 5: t5+0
1230 894 |\
1231 895 | o 4: t4+0
1232 896 | |
1233 897 | o 3: at3:t3+0
1234 898 | |
1235 899 o | 2: t2+0
1236 900 |/
1237 901 o 1: t1+0
1238 902 |
1239 903 o 0: null+1
1240 904
1241 905
1242 906 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1243 907 @ 11: t5+6,6
1244 908 |
1245 909 o 10: t5+5,5
1246 910 |
1247 911 o 9: t5+4,4
1248 912 |
1249 913 o 8: t5+3,3
1250 914 |
1251 915 o 7: t5+2,2
1252 916 |
1253 917 o 6: t5+1,1
1254 918 |
1255 919 o 5: t5+0,0
1256 920 |\
1257 921 | o 4: t4+0,0
1258 922 | |
1259 923 | o 3: at3+0,0 t3+0,0
1260 924 | |
1261 925 o | 2: t2+0,0
1262 926 |/
1263 927 o 1: t1+0,0
1264 928 |
1265 929 o 0: null+1,1
1266 930
1267 931
1268 932 $ cd ..
1269 933
1270 Test new-style inline templating:
1271
1272 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1273 modified files: .hgtags
1274
1275
1276 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
1277 hg: parse error: 11 is not iterable of mappings
1278 (keyword 'rev' does not support map operation)
1279 [255]
1280 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
1281 hg: parse error: None is not iterable of mappings
1282 [255]
1283 $ hg log -R latesttag -r tip -T '{extras % "{key}\n" % "{key}\n"}'
1284 hg: parse error: list of strings is not mappable
1285 [255]
1286
1287 Test new-style inline templating of non-list/dict type:
1288
1289 $ hg log -R latesttag -r tip -T '{manifest}\n'
1290 11:2bc6e9006ce2
1291 $ hg log -R latesttag -r tip -T 'string length: {manifest|count}\n'
1292 string length: 15
1293 $ hg log -R latesttag -r tip -T '{manifest % "{rev}:{node}"}\n'
1294 11:2bc6e9006ce29882383a22d39fd1f4e66dd3e2fc
1295
1296 $ hg log -R latesttag -r tip -T '{get(extras, "branch") % "{key}: {value}\n"}'
1297 branch: default
1298 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "{key}\n"}'
1299 hg: parse error: None is not iterable of mappings
1300 [255]
1301 $ hg log -R latesttag -r tip -T '{min(extras) % "{key}: {value}\n"}'
1302 branch: default
1303 $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}'
1304 0:ce3cec86e6c2
1305 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
1306 9:fbc7cd862e9c
1307
1308 Test dot operator precedence:
1309
1310 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
1311 (template
1312 (|
1313 (.
1314 (symbol 'manifest')
1315 (symbol 'node'))
1316 (symbol 'short'))
1317 (string '\n'))
1318 * keywords: manifest, node, rev
1319 * functions: formatnode, short
1320 89f4071fec70
1321
1322 (the following examples are invalid, but seem natural in parsing POV)
1323
1324 $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null
1325 (template
1326 (|
1327 (symbol 'foo')
1328 (.
1329 (symbol 'bar')
1330 (symbol 'baz')))
1331 (string '\n'))
1332 [255]
1333 $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null
1334 (template
1335 (.
1336 (symbol 'foo')
1337 (func
1338 (symbol 'bar')
1339 None))
1340 (string '\n'))
1341 * keywords: foo
1342 * functions: bar
1343 [255]
1344
1345 Test evaluation of dot operator:
1346
1347 $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n'
1348 ce3cec86e6c26bd9bdfc590a6b92abc9680f1796
1349 $ hg log -R latesttag -r0 -T '{extras.branch}\n'
1350 default
1351 $ hg log -R latesttag -r0 -T '{date.unixtime} {localdate(date, "+0200").tzoffset}\n'
1352 0 -7200
1353
1354 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
1355 hg: parse error: 'test' is not a dictionary
1356 (keyword 'author' does not support member operation)
1357 [255]
1358 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
1359 hg: parse error: 'a' is not a dictionary
1360 [255]
1361
1362 Test integer literal:
1363
1364 $ hg debugtemplate -v '{(0)}\n'
1365 (template
1366 (group
1367 (integer '0'))
1368 (string '\n'))
1369 * keywords:
1370 * functions:
1371 0
1372 $ hg debugtemplate -v '{(123)}\n'
1373 (template
1374 (group
1375 (integer '123'))
1376 (string '\n'))
1377 * keywords:
1378 * functions:
1379 123
1380 $ hg debugtemplate -v '{(-4)}\n'
1381 (template
1382 (group
1383 (negate
1384 (integer '4')))
1385 (string '\n'))
1386 * keywords:
1387 * functions:
1388 -4
1389 $ hg debugtemplate '{(-)}\n'
1390 hg: parse error at 3: not a prefix: )
1391 ({(-)}\n
1392 ^ here)
1393 [255]
1394 $ hg debugtemplate '{(-a)}\n'
1395 hg: parse error: negation needs an integer argument
1396 [255]
1397
1398 top-level integer literal is interpreted as symbol (i.e. variable name):
1399
1400 $ hg debugtemplate -D 1=one -v '{1}\n'
1401 (template
1402 (integer '1')
1403 (string '\n'))
1404 * keywords:
1405 * functions:
1406 one
1407 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
1408 (template
1409 (func
1410 (symbol 'if')
1411 (list
1412 (string 't')
1413 (template
1414 (integer '1'))))
1415 (string '\n'))
1416 * keywords:
1417 * functions: if
1418 one
1419 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
1420 (template
1421 (|
1422 (integer '1')
1423 (symbol 'stringify'))
1424 (string '\n'))
1425 * keywords:
1426 * functions: stringify
1427 one
1428
1429 unless explicit symbol is expected:
1430
1431 $ hg log -Ra -r0 -T '{desc|1}\n'
1432 hg: parse error: expected a symbol, got 'integer'
1433 [255]
1434 $ hg log -Ra -r0 -T '{1()}\n'
1435 hg: parse error: expected a symbol, got 'integer'
1436 [255]
1437
1438 Test string literal:
1439
1440 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
1441 (template
1442 (string 'string with no template fragment')
1443 (string '\n'))
1444 * keywords:
1445 * functions:
1446 string with no template fragment
1447 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
1448 (template
1449 (template
1450 (string 'template: ')
1451 (symbol 'rev'))
1452 (string '\n'))
1453 * keywords: rev
1454 * functions:
1455 template: 0
1456 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
1457 (template
1458 (string 'rawstring: {rev}')
1459 (string '\n'))
1460 * keywords:
1461 * functions:
1462 rawstring: {rev}
1463 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
1464 (template
1465 (%
1466 (symbol 'files')
1467 (string 'rawstring: {file}'))
1468 (string '\n'))
1469 * keywords: files
1470 * functions:
1471 rawstring: {file}
1472
1473 Test string escaping:
1474
1475 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1476 >
1477 <>\n<[>
1478 <>\n<]>
1479 <>\n<
1480
1481 $ hg log -R latesttag -r 0 \
1482 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1483 >
1484 <>\n<[>
1485 <>\n<]>
1486 <>\n<
1487
1488 $ hg log -R latesttag -r 0 -T esc \
1489 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1490 >
1491 <>\n<[>
1492 <>\n<]>
1493 <>\n<
1494
1495 $ cat <<'EOF' > esctmpl
1496 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1497 > EOF
1498 $ hg log -R latesttag -r 0 --style ./esctmpl
1499 >
1500 <>\n<[>
1501 <>\n<]>
1502 <>\n<
1503
1504 Test string escaping of quotes:
1505
1506 $ hg log -Ra -r0 -T '{"\""}\n'
1507 "
1508 $ hg log -Ra -r0 -T '{"\\\""}\n'
1509 \"
1510 $ hg log -Ra -r0 -T '{r"\""}\n'
1511 \"
1512 $ hg log -Ra -r0 -T '{r"\\\""}\n'
1513 \\\"
1514
1515
1516 $ hg log -Ra -r0 -T '{"\""}\n'
1517 "
1518 $ hg log -Ra -r0 -T '{"\\\""}\n'
1519 \"
1520 $ hg log -Ra -r0 -T '{r"\""}\n'
1521 \"
1522 $ hg log -Ra -r0 -T '{r"\\\""}\n'
1523 \\\"
1524
1525 Test exception in quoted template. single backslash before quotation mark is
1526 stripped before parsing:
1527
1528 $ cat <<'EOF' > escquotetmpl
1529 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
1530 > EOF
1531 $ cd latesttag
1532 $ hg log -r 2 --style ../escquotetmpl
1533 " \" \" \\" head1
1534
1535 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
1536 valid
1537 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
1538 valid
1539
1540 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
1541 _evalifliteral() templates (issue4733):
1542
1543 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
1544 "2
1545 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
1546 "2
1547 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
1548 "2
1549
1550 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
1551 \"
1552 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
1553 \"
1554 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
1555 \"
1556
1557 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
1558 \\\"
1559 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
1560 \\\"
1561 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
1562 \\\"
1563
1564 escaped single quotes and errors:
1565
1566 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
1567 foo
1568 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
1569 foo
1570 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
1571 hg: parse error at 21: unterminated string
1572 ({if(rev, "{if(rev, \")}")}\n
1573 ^ here)
1574 [255]
1575 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
1576 hg: parse error: trailing \ in string
1577 [255]
1578 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
1579 hg: parse error: trailing \ in string
1580 [255]
1581
1582 $ cd ..
1583
1584 Test leading backslashes:
1585
1586 $ cd latesttag
1587 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
1588 {rev} {file}
1589 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
1590 \2 \head1
1591 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
1592 \{rev} \{file}
1593 $ cd ..
1594
1595 Test leading backslashes in "if" expression (issue4714):
1596
1597 $ cd latesttag
1598 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
1599 {rev} \{rev}
1600 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
1601 \2 \\{rev}
1602 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
1603 \{rev} \\\{rev}
1604 $ cd ..
1605
1606 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
1607
1608 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
1609 \x6e
1610 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
1611 \x5c\x786e
1612 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
1613 \x6e
1614 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
1615 \x5c\x786e
1616
1617 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
1618 \x6e
1619 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
1620 \x5c\x786e
1621 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
1622 \x6e
1623 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
1624 \x5c\x786e
1625
1626 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
1627 fourth
1628 second
1629 third
1630 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
1631 fourth\nsecond\nthird
1632
1633 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
1634 <p>
1635 1st
1636 </p>
1637 <p>
1638 2nd
1639 </p>
1640 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
1641 <p>
1642 1st\n\n2nd
1643 </p>
1644 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
1645 1st
1646
1647 2nd
1648
1649 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
1650 o perso
1651 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
1652 no person
1653 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
1654 o perso
1655 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
1656 no perso
1657
1658 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
1659 -o perso-
1660 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
1661 no person
1662 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
1663 \x2do perso\x2d
1664 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
1665 -o perso-
1666 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
1667 \x2do perso\x6e
1668
1669 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
1670 fourth
1671 second
1672 third
1673
1674 Test string escaping in nested expression:
1675
1676 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
1677 fourth\x6esecond\x6ethird
1678 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
1679 fourth\x6esecond\x6ethird
1680
1681 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
1682 fourth\x6esecond\x6ethird
1683 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
1684 fourth\x5c\x786esecond\x5c\x786ethird
1685
1686 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
1687 3:\x6eo user, \x6eo domai\x6e
1688 4:\x5c\x786eew bra\x5c\x786ech
1689
1690 Test quotes in nested expression are evaluated just like a $(command)
1691 substitution in POSIX shells:
1692
1693 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
1694 8:95c24699272e
1695 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
1696 {8} "95c24699272e"
1697
1698 Test recursive evaluation:
934 Set up repository containing template fragments in commit metadata:
1699 935
1700 936 $ hg init r
1701 937 $ cd r
1702 938 $ echo a > a
1703 939 $ hg ci -Am '{rev}'
1704 940 adding a
1705 $ hg log -r 0 --template '{if(rev, desc)}\n'
1706 {rev}
1707 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
1708 test 0
1709 941
1710 942 $ hg branch -q 'text.{rev}'
1711 943 $ echo aa >> aa
1712 944 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
1713 945
1714 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
1715 {node|short}desc to
1716 text.{rev}be wrapped
1717 text.{rev}desc to be
1718 text.{rev}wrapped (no-eol)
1719 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
1720 bcc7ff960b8e:desc to
1721 text.1:be wrapped
1722 text.1:desc to be
1723 text.1:wrapped (no-eol)
1724 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
1725 hg: parse error: fill expects an integer width
1726 [255]
946 Test termwidth:
1727 947
1728 948 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
1729 949 bcc7ff960b8e:desc to be
1730 950 termwidth.1:wrapped desc
1731 951 termwidth.1:to be wrapped (no-eol)
1732 952
1733 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
1734 {node|short} (no-eol)
1735 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
1736 bcc-ff---b-e (no-eol)
1737
1738 $ cat >> .hg/hgrc <<EOF
1739 > [extensions]
1740 > color=
1741 > [color]
1742 > mode=ansi
1743 > text.{rev} = red
1744 > text.1 = green
1745 > EOF
1746 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
1747 \x1b[0;31mtext\x1b[0m (esc)
1748 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
1749 \x1b[0;32mtext\x1b[0m (esc)
1750
1751 953 Just one more commit:
1752 954
1753 955 $ echo b > b
1754 956 $ hg ci -qAm b
1755 957
1756 958 Test 'originalnode'
1757 959
1758 960 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
1759 961 000000000000 bcc7ff960b8e
1760 962 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
1761 963 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
1762 964
1763 965 Test active bookmark templating
1764 966
1765 967 $ hg book foo
1766 968 $ hg book bar
1767 969 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
1768 970 2 bar* foo
1769 971 1
1770 972 0
1771 973 $ hg log --template "{rev} {activebookmark}\n"
1772 974 2 bar
1773 975 1
1774 976 0
1775 977 $ hg bookmarks --inactive bar
1776 978 $ hg log --template "{rev} {activebookmark}\n"
1777 979 2
1778 980 1
1779 981 0
1780 982 $ hg book -r1 baz
1781 983 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
1782 984 2 bar foo
1783 985 1 baz
1784 986 0
1785 987 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
1786 988 2 t
1787 989 1 f
1788 990 0 f
1789 991
1790 992 Test namespaces dict
1791 993
1792 994 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
1793 995 2
1794 996 bookmarks color=bookmark builtin=True
1795 997 bar,foo
1796 998 tags color=tag builtin=True
1797 999 tip
1798 1000 branches color=branch builtin=True
1799 1001 text.{rev}
1800 1002 revnames color=revname builtin=False
1801 1003 r2
1802 1004
1803 1005 1
1804 1006 bookmarks color=bookmark builtin=True
1805 1007 baz
1806 1008 tags color=tag builtin=True
1807 1009
1808 1010 branches color=branch builtin=True
1809 1011 text.{rev}
1810 1012 revnames color=revname builtin=False
1811 1013 r1
1812 1014
1813 1015 0
1814 1016 bookmarks color=bookmark builtin=True
1815 1017
1816 1018 tags color=tag builtin=True
1817 1019
1818 1020 branches color=branch builtin=True
1819 1021 default
1820 1022 revnames color=revname builtin=False
1821 1023 r0
1822 1024
1823 1025 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
1824 1026 bookmarks: bar foo
1825 1027 tags: tip
1826 1028 branches: text.{rev}
1827 1029 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
1828 1030 bookmarks:
1829 1031 bar
1830 1032 foo
1831 1033 tags:
1832 1034 tip
1833 1035 branches:
1834 1036 text.{rev}
1835 1037 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
1836 1038 bar
1837 1039 foo
1838 1040 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
1839 1041 bar
1840 1042 foo
1841 1043
1842 1044 $ cd ..
1843 1045
1844 Test bad template with better error message
1845
1846 $ hg log -Gv -R a --template '{desc|user()}'
1847 hg: parse error: expected a symbol, got 'func'
1848 [255]
1849
1850 Test broken string escapes:
1851
1852 $ hg log -T "bogus\\" -R a
1853 hg: parse error: trailing \ in string
1854 [255]
1855 $ hg log -T "\\xy" -R a
1856 hg: parse error: invalid \x escape* (glob)
1857 [255]
1858
1859 Templater supports aliases of symbol and func() styles:
1860
1861 $ hg clone -q a aliases
1862 $ cd aliases
1863 $ cat <<EOF >> .hg/hgrc
1864 > [templatealias]
1865 > r = rev
1866 > rn = "{r}:{node|short}"
1867 > status(c, files) = files % "{c} {file}\n"
1868 > utcdate(d) = localdate(d, "UTC")
1869 > EOF
1870
1871 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
1872 (template
1873 (symbol 'rn')
1874 (string ' ')
1875 (|
1876 (func
1877 (symbol 'utcdate')
1878 (symbol 'date'))
1879 (symbol 'isodate'))
1880 (string '\n'))
1881 * expanded:
1882 (template
1883 (template
1884 (symbol 'rev')
1885 (string ':')
1886 (|
1887 (symbol 'node')
1888 (symbol 'short')))
1889 (string ' ')
1890 (|
1891 (func
1892 (symbol 'localdate')
1893 (list
1894 (symbol 'date')
1895 (string 'UTC')))
1896 (symbol 'isodate'))
1897 (string '\n'))
1898 * keywords: date, node, rev
1899 * functions: isodate, localdate, short
1900 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
1901
1902 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
1903 (template
1904 (func
1905 (symbol 'status')
1906 (list
1907 (string 'A')
1908 (symbol 'file_adds'))))
1909 * expanded:
1910 (template
1911 (%
1912 (symbol 'file_adds')
1913 (template
1914 (string 'A')
1915 (string ' ')
1916 (symbol 'file')
1917 (string '\n'))))
1918 * keywords: file, file_adds
1919 * functions:
1920 A a
1921
1922 A unary function alias can be called as a filter:
1923
1924 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
1925 (template
1926 (|
1927 (|
1928 (symbol 'date')
1929 (symbol 'utcdate'))
1930 (symbol 'isodate'))
1931 (string '\n'))
1932 * expanded:
1933 (template
1934 (|
1935 (func
1936 (symbol 'localdate')
1937 (list
1938 (symbol 'date')
1939 (string 'UTC')))
1940 (symbol 'isodate'))
1941 (string '\n'))
1942 * keywords: date
1943 * functions: isodate, localdate
1944 1970-01-12 13:46 +0000
1945
1946 Aliases should be applied only to command arguments and templates in hgrc.
1947 Otherwise, our stock styles and web templates could be corrupted:
1948
1949 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
1950 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
1951
1952 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
1953 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
1954
1955 $ cat <<EOF > tmpl
1956 > changeset = 'nothing expanded:{rn}\n'
1957 > EOF
1958 $ hg log -r0 --style ./tmpl
1959 nothing expanded:
1960
1961 Aliases in formatter:
1962
1963 $ hg branches -T '{pad(branch, 7)} {rn}\n'
1964 default 6:d41e714fe50d
1965 foo 4:bbe44766e73d
1966
1967 Aliases should honor HGPLAIN:
1968
1969 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
1970 nothing expanded:
1971 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
1972 0:1e4e1b8f71e0
1973
1974 Unparsable alias:
1975
1976 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
1977 (template
1978 (symbol 'bad'))
1979 abort: bad definition of template alias "bad": at 2: not a prefix: end
1980 [255]
1981 $ hg log --config templatealias.bad='x(' -T '{bad}'
1982 abort: bad definition of template alias "bad": at 2: not a prefix: end
1983 [255]
1984
1985 $ cd ..
1986
1987 Test that template function in extension is registered as expected
1988
1989 $ cd a
1990
1991 $ cat <<EOF > $TESTTMP/customfunc.py
1992 > from mercurial import registrar
1993 >
1994 > templatefunc = registrar.templatefunc()
1995 >
1996 > @templatefunc(b'custom()')
1997 > def custom(context, mapping, args):
1998 > return b'custom'
1999 > EOF
2000 $ cat <<EOF > .hg/hgrc
2001 > [extensions]
2002 > customfunc = $TESTTMP/customfunc.py
2003 > EOF
2004
2005 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
2006 custom
2007
2008 $ cd ..
2009
2010 1046 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
2011 1047 printed graphwidths 3, 5, 7, etc. should all line up in their respective
2012 1048 columns. We don't care about other aspects of the graph rendering here.
2013 1049
2014 1050 $ hg init graphwidth
2015 1051 $ cd graphwidth
2016 1052
2017 1053 $ wrappabletext="a a a a a a a a a a a a"
2018 1054
2019 1055 $ printf "first\n" > file
2020 1056 $ hg add file
2021 1057 $ hg commit -m "$wrappabletext"
2022 1058
2023 1059 $ printf "first\nsecond\n" > file
2024 1060 $ hg commit -m "$wrappabletext"
2025 1061
2026 1062 $ hg checkout 0
2027 1063 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2028 1064 $ printf "third\nfirst\n" > file
2029 1065 $ hg commit -m "$wrappabletext"
2030 1066 created new head
2031 1067
2032 1068 $ hg merge
2033 1069 merging file
2034 1070 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
2035 1071 (branch merge, don't forget to commit)
2036 1072
2037 1073 $ hg log --graph -T "{graphwidth}"
2038 1074 @ 3
2039 1075 |
2040 1076 | @ 5
2041 1077 |/
2042 1078 o 3
2043 1079
2044 1080 $ hg commit -m "$wrappabletext"
2045 1081
2046 1082 $ hg log --graph -T "{graphwidth}"
2047 1083 @ 5
2048 1084 |\
2049 1085 | o 5
2050 1086 | |
2051 1087 o | 5
2052 1088 |/
2053 1089 o 3
2054 1090
2055 1091
2056 1092 $ hg checkout 0
2057 1093 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2058 1094 $ printf "third\nfirst\nsecond\n" > file
2059 1095 $ hg commit -m "$wrappabletext"
2060 1096 created new head
2061 1097
2062 1098 $ hg log --graph -T "{graphwidth}"
2063 1099 @ 3
2064 1100 |
2065 1101 | o 7
2066 1102 | |\
2067 1103 +---o 7
2068 1104 | |
2069 1105 | o 5
2070 1106 |/
2071 1107 o 3
2072 1108
2073 1109
2074 1110 $ hg log --graph -T "{graphwidth}" -r 3
2075 1111 o 5
2076 1112 |\
2077 1113 ~ ~
2078 1114
2079 1115 $ hg log --graph -T "{graphwidth}" -r 1
2080 1116 o 3
2081 1117 |
2082 1118 ~
2083 1119
2084 1120 $ hg merge
2085 1121 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2086 1122 (branch merge, don't forget to commit)
2087 1123 $ hg commit -m "$wrappabletext"
2088 1124
2089 1125 $ printf "seventh\n" >> file
2090 1126 $ hg commit -m "$wrappabletext"
2091 1127
2092 1128 $ hg log --graph -T "{graphwidth}"
2093 1129 @ 3
2094 1130 |
2095 1131 o 5
2096 1132 |\
2097 1133 | o 5
2098 1134 | |
2099 1135 o | 7
2100 1136 |\ \
2101 1137 | o | 7
2102 1138 | |/
2103 1139 o / 5
2104 1140 |/
2105 1141 o 3
2106 1142
2107 1143
2108 1144 The point of graphwidth is to allow wrapping that accounts for the space taken
2109 1145 by the graph.
2110 1146
2111 1147 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
2112 1148 @ a a a a
2113 1149 | a a a a
2114 1150 | a a a a
2115 1151 o a a a
2116 1152 |\ a a a
2117 1153 | | a a a
2118 1154 | | a a a
2119 1155 | o a a a
2120 1156 | | a a a
2121 1157 | | a a a
2122 1158 | | a a a
2123 1159 o | a a
2124 1160 |\ \ a a
2125 1161 | | | a a
2126 1162 | | | a a
2127 1163 | | | a a
2128 1164 | | | a a
2129 1165 | o | a a
2130 1166 | |/ a a
2131 1167 | | a a
2132 1168 | | a a
2133 1169 | | a a
2134 1170 | | a a
2135 1171 o | a a a
2136 1172 |/ a a a
2137 1173 | a a a
2138 1174 | a a a
2139 1175 o a a a a
2140 1176 a a a a
2141 1177 a a a a
2142 1178
2143 1179 Something tricky happens when there are elided nodes; the next drawn row of
2144 1180 edges can be more than one column wider, but the graph width only increases by
2145 1181 one column. The remaining columns are added in between the nodes.
2146 1182
2147 1183 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
2148 1184 o 5
2149 1185 |\
2150 1186 | \
2151 1187 | :\
2152 1188 o : : 7
2153 1189 :/ /
2154 1190 : o 5
2155 1191 :/
2156 1192 o 3
2157 1193
2158 1194
2159 1195 $ cd ..
2160
General Comments 0
You need to be logged in to leave comments. Login now