##// END OF EJS Templates
tests: extract test-template-functions.t from test-command-template.t...
Yuya Nishihara -
r38453:70f551a3 default
parent child Browse files
Show More
@@ -490,6 +490,7 b' test-symlinks.t'
490 test-tag.t
490 test-tag.t
491 test-tags.t
491 test-tags.t
492 test-template-filters.t
492 test-template-filters.t
493 test-template-functions.t
493 test-template-map.t
494 test-template-map.t
494 test-transplant.t
495 test-transplant.t
495 test-treemanifest.t
496 test-treemanifest.t
This diff has been collapsed as it changes many lines, (1231 lines changed) Show them Hide them
@@ -929,225 +929,12 b' Keys work:'
929 p2node--debug: 0000000000000000000000000000000000000000
929 p2node--debug: 0000000000000000000000000000000000000000
930 p2node--debug: 0000000000000000000000000000000000000000
930 p2node--debug: 0000000000000000000000000000000000000000
931
931
932 Filters work:
933
934 $ hg log --template '{author|domain}\n'
935
936 hostname
937
938
939
940
941 place
942 place
943 hostname
944
945 $ hg log --template '{author|person}\n'
946 test
947 User Name
948 person
949 person
950 person
951 person
952 other
953 A. N. Other
954 User Name
955
956 $ hg log --template '{author|user}\n'
957 test
958 user
959 person
960 person
961 person
962 person
963 other
964 other
965 user
966
967 $ hg log --template '{date|date}\n'
968 Wed Jan 01 10:01:00 2020 +0000
969 Mon Jan 12 13:46:40 1970 +0000
970 Sun Jan 18 08:40:01 1970 +0000
971 Sun Jan 18 08:40:00 1970 +0000
972 Sat Jan 17 04:53:20 1970 +0000
973 Fri Jan 16 01:06:40 1970 +0000
974 Wed Jan 14 21:20:00 1970 +0000
975 Tue Jan 13 17:33:20 1970 +0000
976 Mon Jan 12 13:46:40 1970 +0000
977
978 $ hg log --template '{date|isodate}\n'
979 2020-01-01 10:01 +0000
980 1970-01-12 13:46 +0000
981 1970-01-18 08:40 +0000
982 1970-01-18 08:40 +0000
983 1970-01-17 04:53 +0000
984 1970-01-16 01:06 +0000
985 1970-01-14 21:20 +0000
986 1970-01-13 17:33 +0000
987 1970-01-12 13:46 +0000
988
989 $ hg log --template '{date|isodatesec}\n'
990 2020-01-01 10:01:00 +0000
991 1970-01-12 13:46:40 +0000
992 1970-01-18 08:40:01 +0000
993 1970-01-18 08:40:00 +0000
994 1970-01-17 04:53:20 +0000
995 1970-01-16 01:06:40 +0000
996 1970-01-14 21:20:00 +0000
997 1970-01-13 17:33:20 +0000
998 1970-01-12 13:46:40 +0000
999
1000 $ hg log --template '{date|rfc822date}\n'
1001 Wed, 01 Jan 2020 10:01:00 +0000
1002 Mon, 12 Jan 1970 13:46:40 +0000
1003 Sun, 18 Jan 1970 08:40:01 +0000
1004 Sun, 18 Jan 1970 08:40:00 +0000
1005 Sat, 17 Jan 1970 04:53:20 +0000
1006 Fri, 16 Jan 1970 01:06:40 +0000
1007 Wed, 14 Jan 1970 21:20:00 +0000
1008 Tue, 13 Jan 1970 17:33:20 +0000
1009 Mon, 12 Jan 1970 13:46:40 +0000
1010
1011 $ hg log --template '{desc|firstline}\n'
1012 third
1013 second
1014 merge
1015 new head
1016 new branch
1017 no user, no domain
1018 no person
1019 other 1
1020 line 1
1021
1022 $ hg log --template '{node|short}\n'
1023 95c24699272e
1024 29114dbae42b
1025 d41e714fe50d
1026 13207e5a10d9
1027 bbe44766e73d
1028 10e46f2dcbf4
1029 97054abb4ab8
1030 b608e9d1a3f0
1031 1e4e1b8f71e0
1032
1033 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1034 <changeset author="test"/>
1035 <changeset author="User Name &lt;user@hostname&gt;"/>
1036 <changeset author="person"/>
1037 <changeset author="person"/>
1038 <changeset author="person"/>
1039 <changeset author="person"/>
1040 <changeset author="other@place"/>
1041 <changeset author="A. N. Other &lt;other@place&gt;"/>
1042 <changeset author="User Name &lt;user@hostname&gt;"/>
1043
1044 $ hg log --template '{rev}: {children}\n'
1045 8:
1046 7: 8:95c24699272e
1047 6:
1048 5: 6:d41e714fe50d
1049 4: 6:d41e714fe50d
1050 3: 4:bbe44766e73d 5:13207e5a10d9
1051 2: 3:10e46f2dcbf4
1052 1: 2:97054abb4ab8
1053 0: 1:b608e9d1a3f0
1054
1055 Formatnode filter works:
1056
1057 $ hg -q log -r 0 --template '{node|formatnode}\n'
1058 1e4e1b8f71e0
1059
1060 $ hg log -r 0 --template '{node|formatnode}\n'
1061 1e4e1b8f71e0
1062
1063 $ hg -v log -r 0 --template '{node|formatnode}\n'
1064 1e4e1b8f71e0
1065
1066 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1067 1e4e1b8f71e05681d422154f5421e385fec3454f
1068
1069 Age filter:
1070
1071 $ hg init unstable-hash
1072 $ cd unstable-hash
1073 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1074
1075 >>> from __future__ import absolute_import
1076 >>> import datetime
1077 >>> fp = open('a', 'wb')
1078 >>> n = datetime.datetime.now() + datetime.timedelta(366 * 7)
1079 >>> fp.write(b'%d-%d-%d 00:00' % (n.year, n.month, n.day)) and None
1080 >>> fp.close()
1081 $ hg add a
1082 $ hg commit -m future -d "`cat a`"
1083
1084 $ hg log -l1 --template '{date|age}\n'
1085 7 years from now
1086
1087 $ cd ..
1088 $ rm -rf unstable-hash
1089
1090 Filename filters:
1091
1092 $ hg debugtemplate '{"foo/bar"|basename}|{"foo/"|basename}|{"foo"|basename}|\n'
1093 bar||foo|
1094 $ hg debugtemplate '{"foo/bar"|dirname}|{"foo/"|dirname}|{"foo"|dirname}|\n'
1095 foo|foo||
1096 $ hg debugtemplate '{"foo/bar"|stripdir}|{"foo/"|stripdir}|{"foo"|stripdir}|\n'
1097 foo|foo|foo|
1098
1099 Add a dummy commit to make up for the instability of the above:
932 Add a dummy commit to make up for the instability of the above:
1100
933
1101 $ echo a > a
934 $ echo a > a
1102 $ hg add a
935 $ hg add a
1103 $ hg ci -m future
936 $ hg ci -m future
1104
937
1105 Count filter:
1106
1107 $ hg log -l1 --template '{node|count} {node|short|count}\n'
1108 40 12
1109
1110 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
1111 0 1 4
1112
1113 $ hg log -G --template '{rev}: children: {children|count}, \
1114 > tags: {tags|count}, file_adds: {file_adds|count}, \
1115 > ancestors: {revset("ancestors(%s)", rev)|count}'
1116 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
1117 |
1118 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
1119 |
1120 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
1121
1122 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
1123 |\
1124 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
1125 | |
1126 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
1127 |/
1128 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
1129 |
1130 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
1131 |
1132 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
1133 |
1134 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
1135
1136
1137 $ hg log -l1 -T '{termwidth|count}\n'
1138 hg: parse error: not countable
1139 (template filter 'count' is not compatible with keyword 'termwidth')
1140 [255]
1141
1142 Upper/lower filters:
1143
1144 $ hg log -r0 --template '{branch|upper}\n'
1145 DEFAULT
1146 $ hg log -r0 --template '{author|lower}\n'
1147 user name <user@hostname>
1148 $ hg log -r0 --template '{date|upper}\n'
1149 1000000.00
1150
1151 Add a commit that does all possible modifications at once
938 Add a commit that does all possible modifications at once
1152
939
1153 $ echo modify >> third
940 $ echo modify >> third
@@ -1266,11 +1053,6 b' Thrown an error if a template function d'
1266 hg: parse error: unknown function 'foo'
1053 hg: parse error: unknown function 'foo'
1267 [255]
1054 [255]
1268
1055
1269 Pass generator object created by template function to filter
1270
1271 $ hg log -l 1 --template '{if(author, author)|user}\n'
1272 test
1273
1274 Test index keyword:
1056 Test index keyword:
1275
1057
1276 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
1058 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
@@ -1281,68 +1063,6 b' Test index keyword:'
1281 0 default
1063 0 default
1282 1 foo
1064 1 foo
1283
1065
1284 Test diff function:
1285
1286 $ hg diff -c 8
1287 diff -r 29114dbae42b -r 95c24699272e fourth
1288 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1289 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
1290 @@ -0,0 +1,1 @@
1291 +second
1292 diff -r 29114dbae42b -r 95c24699272e second
1293 --- a/second Mon Jan 12 13:46:40 1970 +0000
1294 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1295 @@ -1,1 +0,0 @@
1296 -second
1297 diff -r 29114dbae42b -r 95c24699272e third
1298 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1299 +++ b/third Wed Jan 01 10:01:00 2020 +0000
1300 @@ -0,0 +1,1 @@
1301 +third
1302
1303 $ hg log -r 8 -T "{diff()}"
1304 diff -r 29114dbae42b -r 95c24699272e fourth
1305 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1306 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
1307 @@ -0,0 +1,1 @@
1308 +second
1309 diff -r 29114dbae42b -r 95c24699272e second
1310 --- a/second Mon Jan 12 13:46:40 1970 +0000
1311 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1312 @@ -1,1 +0,0 @@
1313 -second
1314 diff -r 29114dbae42b -r 95c24699272e third
1315 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1316 +++ b/third Wed Jan 01 10:01:00 2020 +0000
1317 @@ -0,0 +1,1 @@
1318 +third
1319
1320 $ hg log -r 8 -T "{diff('glob:f*')}"
1321 diff -r 29114dbae42b -r 95c24699272e fourth
1322 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1323 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
1324 @@ -0,0 +1,1 @@
1325 +second
1326
1327 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
1328 diff -r 29114dbae42b -r 95c24699272e second
1329 --- a/second Mon Jan 12 13:46:40 1970 +0000
1330 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1331 @@ -1,1 +0,0 @@
1332 -second
1333 diff -r 29114dbae42b -r 95c24699272e third
1334 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1335 +++ b/third Wed Jan 01 10:01:00 2020 +0000
1336 @@ -0,0 +1,1 @@
1337 +third
1338
1339 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
1340 diff -r 29114dbae42b -r 95c24699272e fourth
1341 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1342 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
1343 @@ -0,0 +1,1 @@
1344 +second
1345
1346 ui verbosity:
1066 ui verbosity:
1347
1067
1348 $ hg log -l1 -T '{verbosity}\n'
1068 $ hg log -l1 -T '{verbosity}\n'
@@ -1545,32 +1265,6 b' Merged tag overrides:'
1545 o 0: null+1,1
1265 o 0: null+1,1
1546
1266
1547
1267
1548 $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
1549 @ 11: t3, C: 9, D: 8
1550 |
1551 o 10: t3, C: 8, D: 7
1552 |
1553 o 9: t3, C: 7, D: 6
1554 |
1555 o 8: t3, C: 6, D: 5
1556 |
1557 o 7: t3, C: 5, D: 4
1558 |
1559 o 6: t3, C: 4, D: 3
1560 |
1561 o 5: t3, C: 3, D: 2
1562 |\
1563 | o 4: t3, C: 1, D: 1
1564 | |
1565 | o 3: t3, C: 0, D: 0
1566 | |
1567 o | 2: t1, C: 1, D: 1
1568 |/
1569 o 1: t1, C: 0, D: 0
1570 |
1571 o 0: null, C: 1, D: 1
1572
1573
1574 $ cd ..
1268 $ cd ..
1575
1269
1576 Test new-style inline templating:
1270 Test new-style inline templating:
@@ -1611,122 +1305,6 b' Test new-style inline templating of non-'
1611 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
1305 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
1612 9:fbc7cd862e9c
1306 9:fbc7cd862e9c
1613
1307
1614 Test manifest/get() can be join()-ed as string, though it's silly:
1615
1616 $ hg log -R latesttag -r tip -T '{join(manifest, ".")}\n'
1617 1.1.:.2.b.c.6.e.9.0.0.6.c.e.2
1618 $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), ".")}\n'
1619 d.e.f.a.u.l.t
1620
1621 Test join() over string
1622
1623 $ hg log -R latesttag -r tip -T '{join(rev|stringify, ".")}\n'
1624 1.1
1625
1626 Test join() over uniterable
1627
1628 $ hg log -R latesttag -r tip -T '{join(rev, "")}\n'
1629 hg: parse error: 11 is not iterable
1630 [255]
1631
1632 Test min/max of integers
1633
1634 $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'
1635 9
1636 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
1637 10
1638
1639 Test min/max over map operation:
1640
1641 $ hg log -R latesttag -r3 -T '{min(tags % "{tag}")}\n'
1642 at3
1643 $ hg log -R latesttag -r3 -T '{max(tags % "{tag}")}\n'
1644 t3
1645
1646 Test min/max of strings:
1647
1648 $ hg log -R latesttag -l1 -T '{min(desc)}\n'
1649 3
1650 $ hg log -R latesttag -l1 -T '{max(desc)}\n'
1651 t
1652
1653 Test min/max of non-iterable:
1654
1655 $ hg debugtemplate '{min(1)}'
1656 hg: parse error: 1 is not iterable
1657 (min first argument should be an iterable)
1658 [255]
1659 $ hg debugtemplate '{max(2)}'
1660 hg: parse error: 2 is not iterable
1661 (max first argument should be an iterable)
1662 [255]
1663
1664 $ hg log -R latesttag -l1 -T '{min(date)}'
1665 hg: parse error: date is not iterable
1666 (min first argument should be an iterable)
1667 [255]
1668 $ hg log -R latesttag -l1 -T '{max(date)}'
1669 hg: parse error: date is not iterable
1670 (max first argument should be an iterable)
1671 [255]
1672
1673 Test min/max of empty sequence:
1674
1675 $ hg debugtemplate '{min("")}'
1676 hg: parse error: empty string
1677 (min first argument should be an iterable)
1678 [255]
1679 $ hg debugtemplate '{max("")}'
1680 hg: parse error: empty string
1681 (max first argument should be an iterable)
1682 [255]
1683 $ hg debugtemplate '{min(dict())}'
1684 hg: parse error: empty sequence
1685 (min first argument should be an iterable)
1686 [255]
1687 $ hg debugtemplate '{max(dict())}'
1688 hg: parse error: empty sequence
1689 (max first argument should be an iterable)
1690 [255]
1691 $ hg debugtemplate '{min(dict() % "")}'
1692 hg: parse error: empty sequence
1693 (min first argument should be an iterable)
1694 [255]
1695 $ hg debugtemplate '{max(dict() % "")}'
1696 hg: parse error: empty sequence
1697 (max first argument should be an iterable)
1698 [255]
1699
1700 Test min/max of if() result
1701
1702 $ cd latesttag
1703 $ hg log -l1 -T '{min(if(true, revset("9:10"), ""))}\n'
1704 9
1705 $ hg log -l1 -T '{max(if(false, "", revset("9:10")))}\n'
1706 10
1707 $ hg log -l1 -T '{min(ifcontains("a", "aa", revset("9:10"), ""))}\n'
1708 9
1709 $ hg log -l1 -T '{max(ifcontains("a", "bb", "", revset("9:10")))}\n'
1710 10
1711 $ hg log -l1 -T '{min(ifeq(0, 0, revset("9:10"), ""))}\n'
1712 9
1713 $ hg log -l1 -T '{max(ifeq(0, 1, "", revset("9:10")))}\n'
1714 10
1715 $ cd ..
1716
1717 Test laziness of if() then/else clause
1718
1719 $ hg debugtemplate '{count(0)}'
1720 hg: parse error: not countable
1721 (incompatible use of template filter 'count')
1722 [255]
1723 $ hg debugtemplate '{if(true, "", count(0))}'
1724 $ hg debugtemplate '{if(false, count(0), "")}'
1725 $ hg debugtemplate '{ifcontains("a", "aa", "", count(0))}'
1726 $ hg debugtemplate '{ifcontains("a", "bb", count(0), "")}'
1727 $ hg debugtemplate '{ifeq(0, 0, "", count(0))}'
1728 $ hg debugtemplate '{ifeq(0, 1, count(0), "")}'
1729
1730 Test dot operator precedence:
1308 Test dot operator precedence:
1731
1309
1732 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
1310 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
@@ -1781,70 +1359,6 b' Test evaluation of dot operator:'
1781 hg: parse error: 'a' is not a dictionary
1359 hg: parse error: 'a' is not a dictionary
1782 [255]
1360 [255]
1783
1361
1784 Test the sub function of templating for expansion:
1785
1786 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
1787 xx
1788
1789 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
1790 hg: parse error: sub got an invalid pattern: [
1791 [255]
1792 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
1793 hg: parse error: sub got an invalid replacement: \1
1794 [255]
1795
1796 Test the strip function with chars specified:
1797
1798 $ hg log -R latesttag --template '{desc}\n'
1799 at3
1800 t5
1801 t4
1802 t3
1803 t2
1804 t1
1805 merge
1806 h2e
1807 h2d
1808 h1c
1809 b
1810 a
1811
1812 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
1813 at3
1814 5
1815 4
1816 3
1817 2
1818 1
1819 merg
1820 h2
1821 h2d
1822 h1c
1823 b
1824 a
1825
1826 Test date format:
1827
1828 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
1829 date: 70 01 01 10 +0000
1830 date: 70 01 01 09 +0000
1831 date: 70 01 01 04 +0000
1832 date: 70 01 01 08 +0000
1833 date: 70 01 01 07 +0000
1834 date: 70 01 01 06 +0000
1835 date: 70 01 01 05 +0100
1836 date: 70 01 01 04 +0000
1837 date: 70 01 01 03 +0000
1838 date: 70 01 01 02 +0000
1839 date: 70 01 01 01 +0000
1840 date: 70 01 01 00 +0000
1841
1842 Test invalid date:
1843
1844 $ hg log -R latesttag -T '{date(rev)}\n'
1845 hg: parse error: date expects a date information
1846 [255]
1847
1848 Test integer literal:
1362 Test integer literal:
1849
1363
1850 $ hg debugtemplate -v '{(0)}\n'
1364 $ hg debugtemplate -v '{(0)}\n'
@@ -2234,498 +1748,10 b' Test recursive evaluation:'
2234 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
1748 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
2235 \x1b[0;32mtext\x1b[0m (esc)
1749 \x1b[0;32mtext\x1b[0m (esc)
2236
1750
2237 color effect can be specified without quoting:
1751 Just one more commit:
2238
2239 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
2240 \x1b[0;31mtext\x1b[0m (esc)
2241
2242 color effects can be nested (issue5413)
2243
2244 $ hg debugtemplate --color=always \
2245 > '{label(red, "red{label(magenta, "ma{label(cyan, "cyan")}{label(yellow, "yellow")}genta")}")}\n'
2246 \x1b[0;31mred\x1b[0;35mma\x1b[0;36mcyan\x1b[0m\x1b[0;31m\x1b[0;35m\x1b[0;33myellow\x1b[0m\x1b[0;31m\x1b[0;35mgenta\x1b[0m (esc)
2247
2248 pad() should interact well with color codes (issue5416)
2249
2250 $ hg debugtemplate --color=always \
2251 > '{pad(label(red, "red"), 5, label(cyan, "-"))}\n'
2252 \x1b[0;31mred\x1b[0m\x1b[0;36m-\x1b[0m\x1b[0;36m-\x1b[0m (esc)
2253
2254 label should be no-op if color is disabled:
2255
2256 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
2257 text
2258 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
2259 text
2260
2261 Test branches inside if statement:
2262
2263 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
2264 no
2265
2266 Test dict constructor:
2267
2268 $ hg log -r 0 -T '{dict(y=node|short, x=rev)}\n'
2269 y=f7769ec2ab97 x=0
2270 $ hg log -r 0 -T '{dict(x=rev, y=node|short) % "{key}={value}\n"}'
2271 x=0
2272 y=f7769ec2ab97
2273 $ hg log -r 0 -T '{dict(x=rev, y=node|short)|json}\n'
2274 {"x": 0, "y": "f7769ec2ab97"}
2275 $ hg log -r 0 -T '{dict()|json}\n'
2276 {}
2277
2278 $ hg log -r 0 -T '{dict(rev, node=node|short)}\n'
2279 rev=0 node=f7769ec2ab97
2280 $ hg log -r 0 -T '{dict(rev, node|short)}\n'
2281 rev=0 node=f7769ec2ab97
2282
2283 $ hg log -r 0 -T '{dict(rev, rev=rev)}\n'
2284 hg: parse error: duplicated dict key 'rev' inferred
2285 [255]
2286 $ hg log -r 0 -T '{dict(node, node|short)}\n'
2287 hg: parse error: duplicated dict key 'node' inferred
2288 [255]
2289 $ hg log -r 0 -T '{dict(1 + 2)}'
2290 hg: parse error: dict key cannot be inferred
2291 [255]
2292
2293 $ hg log -r 0 -T '{dict(x=rev, x=node)}'
2294 hg: parse error: dict got multiple values for keyword argument 'x'
2295 [255]
2296
2297 Test get function:
2298
2299 $ hg log -r 0 --template '{get(extras, "branch")}\n'
2300 default
2301 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
2302 default
2303 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
2304 hg: parse error: not a dictionary
2305 (get() expects a dict as first argument)
2306 [255]
2307
2308 Test json filter applied to wrapped object:
2309
2310 $ hg log -r0 -T '{files|json}\n'
2311 ["a"]
2312 $ hg log -r0 -T '{extras|json}\n'
2313 {"branch": "default"}
2314 $ hg log -r0 -T '{date|json}\n'
2315 [0, 0]
2316
2317 Test json filter applied to map result:
2318
2319 $ hg log -r0 -T '{json(extras % "{key}")}\n'
2320 ["branch"]
2321
2322 Test localdate(date, tz) function:
2323
2324 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
2325 1970-01-01 09:00 +0900
2326 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
2327 1970-01-01 00:00 +0000
2328 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "blahUTC")|isodate}\n'
2329 hg: parse error: localdate expects a timezone
2330 [255]
2331 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
2332 1970-01-01 02:00 +0200
2333 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
2334 1970-01-01 00:00 +0000
2335 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
2336 1970-01-01 00:00 +0000
2337 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
2338 hg: parse error: localdate expects a timezone
2339 [255]
2340 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
2341 hg: parse error: localdate expects a timezone
2342 [255]
2343
2344 Test shortest(node) function:
2345
1752
2346 $ echo b > b
1753 $ echo b > b
2347 $ hg ci -qAm b
1754 $ hg ci -qAm b
2348 $ hg log --template '{shortest(node)}\n'
2349 e777
2350 bcc7
2351 f776
2352 $ hg log --template '{shortest(node, 10)}\n'
2353 e777603221
2354 bcc7ff960b
2355 f7769ec2ab
2356 $ hg log --template '{node|shortest}\n' -l1
2357 e777
2358
2359 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
2360 f7769ec2ab
2361 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
2362 hg: parse error: shortest() expects an integer minlength
2363 [255]
2364
2365 $ hg log -r 'wdir()' -T '{node|shortest}\n'
2366 ffff
2367
2368 $ hg log --template '{shortest("f")}\n' -l1
2369 f
2370
2371 $ hg log --template '{shortest("0123456789012345678901234567890123456789")}\n' -l1
2372 0123456789012345678901234567890123456789
2373
2374 $ hg log --template '{shortest("01234567890123456789012345678901234567890123456789")}\n' -l1
2375 01234567890123456789012345678901234567890123456789
2376
2377 $ hg log --template '{shortest("not a hex string")}\n' -l1
2378 not a hex string
2379
2380 $ hg log --template '{shortest("not a hex string, but it'\''s 40 bytes long")}\n' -l1
2381 not a hex string, but it's 40 bytes long
2382
2383 $ hg log --template '{shortest("ffffffffffffffffffffffffffffffffffffffff")}\n' -l1
2384 ffff
2385
2386 $ hg log --template '{shortest("fffffff")}\n' -l1
2387 ffff
2388
2389 $ hg log --template '{shortest("ff")}\n' -l1
2390 ffff
2391
2392 $ cd ..
2393
2394 Test shortest(node) with the repo having short hash collision:
2395
2396 $ hg init hashcollision
2397 $ cd hashcollision
2398 $ cat <<EOF >> .hg/hgrc
2399 > [experimental]
2400 > evolution.createmarkers=True
2401 > EOF
2402 $ echo 0 > a
2403 $ hg ci -qAm 0
2404 $ for i in 17 129 248 242 480 580 617 1057 2857 4025; do
2405 > hg up -q 0
2406 > echo $i > a
2407 > hg ci -qm $i
2408 > done
2409 $ hg up -q null
2410 $ hg log -r0: -T '{rev}:{node}\n'
2411 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
2412 1:11424df6dc1dd4ea255eae2b58eaca7831973bbc
2413 2:11407b3f1b9c3e76a79c1ec5373924df096f0499
2414 3:11dd92fe0f39dfdaacdaa5f3997edc533875cfc4
2415 4:10776689e627b465361ad5c296a20a487e153ca4
2416 5:a00be79088084cb3aff086ab799f8790e01a976b
2417 6:a0b0acd79b4498d0052993d35a6a748dd51d13e6
2418 7:a0457b3450b8e1b778f1163b31a435802987fe5d
2419 8:c56256a09cd28e5764f32e8e2810d0f01e2e357a
2420 9:c5623987d205cd6d9d8389bfc40fff9dbb670b48
2421 10:c562ddd9c94164376c20b86b0b4991636a3bf84f
2422 $ hg debugobsolete a00be79088084cb3aff086ab799f8790e01a976b
2423 obsoleted 1 changesets
2424 $ hg debugobsolete c5623987d205cd6d9d8389bfc40fff9dbb670b48
2425 obsoleted 1 changesets
2426 $ hg debugobsolete c562ddd9c94164376c20b86b0b4991636a3bf84f
2427 obsoleted 1 changesets
2428
2429 nodes starting with '11' (we don't have the revision number '11' though)
2430
2431 $ hg log -r 1:3 -T '{rev}:{shortest(node, 0)}\n'
2432 1:1142
2433 2:1140
2434 3:11d
2435
2436 '5:a00' is hidden, but still we have two nodes starting with 'a0'
2437
2438 $ hg log -r 6:7 -T '{rev}:{shortest(node, 0)}\n'
2439 6:a0b
2440 7:a04
2441
2442 node '10' conflicts with the revision number '10' even if it is hidden
2443 (we could exclude hidden revision numbers, but currently we don't)
2444
2445 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n'
2446 4:107
2447 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden
2448 4:107
2449
2450 node 'c562' should be unique if the other 'c562' nodes are hidden
2451 (but we don't try the slow path to filter out hidden nodes for now)
2452
2453 $ hg log -r 8 -T '{rev}:{node|shortest}\n'
2454 8:c5625
2455 $ hg log -r 8:10 -T '{rev}:{node|shortest}\n' --hidden
2456 8:c5625
2457 9:c5623
2458 10:c562d
2459
2460 $ cd ..
2461
2462 Test pad function
2463
2464 $ cd r
2465
2466 $ hg log --template '{pad(rev, 20)} {author|user}\n'
2467 2 test
2468 1 {node|short}
2469 0 test
2470
2471 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
2472 2 test
2473 1 {node|short}
2474 0 test
2475
2476 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
2477 2------------------- test
2478 1------------------- {node|short}
2479 0------------------- test
2480
2481 Test template string in pad function
2482
2483 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
2484 {0} test
2485
2486 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
2487 \{rev} test
2488
2489 Test width argument passed to pad function
2490
2491 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
2492 0 test
2493 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
2494 hg: parse error: pad() expects an integer width
2495 [255]
2496
2497 Test invalid fillchar passed to pad function
2498
2499 $ hg log -r 0 -T '{pad(rev, 10, "")}\n'
2500 hg: parse error: pad() expects a single fill character
2501 [255]
2502 $ hg log -r 0 -T '{pad(rev, 10, "--")}\n'
2503 hg: parse error: pad() expects a single fill character
2504 [255]
2505
2506 Test boolean argument passed to pad function
2507
2508 no crash
2509
2510 $ hg log -r 0 -T '{pad(rev, 10, "-", "f{"oo"}")}\n'
2511 ---------0
2512
2513 string/literal
2514
2515 $ hg log -r 0 -T '{pad(rev, 10, "-", "false")}\n'
2516 ---------0
2517 $ hg log -r 0 -T '{pad(rev, 10, "-", false)}\n'
2518 0---------
2519 $ hg log -r 0 -T '{pad(rev, 10, "-", "")}\n'
2520 0---------
2521
2522 unknown keyword is evaluated to ''
2523
2524 $ hg log -r 0 -T '{pad(rev, 10, "-", unknownkeyword)}\n'
2525 0---------
2526
2527 Test separate function
2528
2529 $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
2530 a-b-c
2531 $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
2532 0:f7769ec2ab97 test default
2533 $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
2534 a \x1b[0;31mb\x1b[0m c d (esc)
2535
2536 Test boolean expression/literal passed to if function
2537
2538 $ hg log -r 0 -T '{if(rev, "rev 0 is True")}\n'
2539 rev 0 is True
2540 $ hg log -r 0 -T '{if(0, "literal 0 is True as well")}\n'
2541 literal 0 is True as well
2542 $ hg log -r 0 -T '{if("", "", "empty string is False")}\n'
2543 empty string is False
2544 $ hg log -r 0 -T '{if(revset(r"0 - 0"), "", "empty list is False")}\n'
2545 empty list is False
2546 $ hg log -r 0 -T '{if(revset(r"0"), "non-empty list is True")}\n'
2547 non-empty list is True
2548 $ hg log -r 0 -T '{if(revset(r"0") % "", "list of empty strings is True")}\n'
2549 list of empty strings is True
2550 $ hg log -r 0 -T '{if(true, "true is True")}\n'
2551 true is True
2552 $ hg log -r 0 -T '{if(false, "", "false is False")}\n'
2553 false is False
2554 $ hg log -r 0 -T '{if("false", "non-empty string is True")}\n'
2555 non-empty string is True
2556
2557 Test ifcontains function
2558
2559 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
2560 2 is in the string
2561 1 is not
2562 0 is in the string
2563
2564 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
2565 2 is in the string
2566 1 is not
2567 0 is in the string
2568
2569 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
2570 2 did not add a
2571 1 did not add a
2572 0 added a
2573
2574 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
2575 2 is parent of 1
2576 1
2577 0
2578
2579 $ hg log -l1 -T '{ifcontains("branch", extras, "t", "f")}\n'
2580 t
2581 $ hg log -l1 -T '{ifcontains("branch", extras % "{key}", "t", "f")}\n'
2582 t
2583 $ hg log -l1 -T '{ifcontains("branc", extras % "{key}", "t", "f")}\n'
2584 f
2585 $ hg log -l1 -T '{ifcontains("branc", stringify(extras % "{key}"), "t", "f")}\n'
2586 t
2587
2588 Test revset function
2589
2590 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
2591 2 current rev
2592 1 not current rev
2593 0 not current rev
2594
2595 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
2596 2 match rev
2597 1 match rev
2598 0 not match rev
2599
2600 $ hg log -T '{ifcontains(desc, revset(":"), "", "type not match")}\n' -l1
2601 type not match
2602
2603 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
2604 2 Parents: 1
2605 1 Parents: 0
2606 0 Parents:
2607
2608 $ cat >> .hg/hgrc <<EOF
2609 > [revsetalias]
2610 > myparents(\$1) = parents(\$1)
2611 > EOF
2612 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
2613 2 Parents: 1
2614 1 Parents: 0
2615 0 Parents:
2616
2617 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
2618 Rev: 2
2619 Ancestor: 0
2620 Ancestor: 1
2621 Ancestor: 2
2622
2623 Rev: 1
2624 Ancestor: 0
2625 Ancestor: 1
2626
2627 Rev: 0
2628 Ancestor: 0
2629
2630 $ hg log --template '{revset("TIP"|lower)}\n' -l1
2631 2
2632
2633 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
2634 2
2635
2636 a list template is evaluated for each item of revset/parents
2637
2638 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
2639 2 p: 1:bcc7ff960b8e
2640 1 p: 0:f7769ec2ab97
2641 0 p:
2642
2643 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
2644 2 p: 1:bcc7ff960b8e -1:000000000000
2645 1 p: 0:f7769ec2ab97 -1:000000000000
2646 0 p: -1:000000000000 -1:000000000000
2647
2648 therefore, 'revcache' should be recreated for each rev
2649
2650 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
2651 2 aa b
2652 p
2653 1
2654 p a
2655 0 a
2656 p
2657
2658 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
2659 2 aa b
2660 p
2661 1
2662 p a
2663 0 a
2664 p
2665
2666 a revset item must be evaluated as an integer revision, not an offset from tip
2667
2668 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
2669 -1:000000000000
2670 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
2671 -1:000000000000
2672
2673 join() should pick '{rev}' from revset items:
2674
2675 $ hg log -R ../a -T '{join(revset("parents(%d)", rev), ", ")}\n' -r6
2676 4, 5
2677
2678 on the other hand, parents are formatted as '{rev}:{node|formatnode}' by
2679 default. join() should agree with the default formatting:
2680
2681 $ hg log -R ../a -T '{join(parents, ", ")}\n' -r6
2682 5:13207e5a10d9, 4:bbe44766e73d
2683
2684 $ hg log -R ../a -T '{join(parents, ",\n")}\n' -r6 --debug
2685 5:13207e5a10d9fd28ec424934298e176197f2c67f,
2686 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2687
2688 Invalid arguments passed to revset()
2689
2690 $ hg log -T '{revset("%whatever", 0)}\n'
2691 hg: parse error: unexpected revspec format character w
2692 [255]
2693 $ hg log -T '{revset("%lwhatever", files)}\n'
2694 hg: parse error: unexpected revspec format character w
2695 [255]
2696 $ hg log -T '{revset("%s %s", 0)}\n'
2697 hg: parse error: missing argument for revspec
2698 [255]
2699 $ hg log -T '{revset("", 0)}\n'
2700 hg: parse error: too many revspec arguments specified
2701 [255]
2702 $ hg log -T '{revset("%s", 0, 1)}\n'
2703 hg: parse error: too many revspec arguments specified
2704 [255]
2705 $ hg log -T '{revset("%", 0)}\n'
2706 hg: parse error: incomplete revspec format character
2707 [255]
2708 $ hg log -T '{revset("%l", 0)}\n'
2709 hg: parse error: incomplete revspec format character
2710 [255]
2711 $ hg log -T '{revset("%d", 'foo')}\n'
2712 hg: parse error: invalid argument for revspec
2713 [255]
2714 $ hg log -T '{revset("%ld", files)}\n'
2715 hg: parse error: invalid argument for revspec
2716 [255]
2717 $ hg log -T '{revset("%ls", 0)}\n'
2718 hg: parse error: invalid argument for revspec
2719 [255]
2720 $ hg log -T '{revset("%b", 'foo')}\n'
2721 hg: parse error: invalid argument for revspec
2722 [255]
2723 $ hg log -T '{revset("%lb", files)}\n'
2724 hg: parse error: invalid argument for revspec
2725 [255]
2726 $ hg log -T '{revset("%r", 0)}\n'
2727 hg: parse error: invalid argument for revspec
2728 [255]
2729
1755
2730 Test 'originalnode'
1756 Test 'originalnode'
2731
1757
@@ -2734,41 +1760,6 b" Test 'originalnode'"
2734 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
1760 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
2735 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
1761 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
2736
1762
2737 Test files function
2738
2739 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
2740 2
2741 a
2742 aa
2743 b
2744 1
2745 a
2746 0
2747 a
2748
2749 $ hg log -T "{rev}\n{join(files('aa'), '\n')}\n"
2750 2
2751 aa
2752 1
2753
2754 0
2755
2756 $ hg rm a
2757 $ hg log -r "wdir()" -T "{rev}\n{join(files('*'), '\n')}\n"
2758 2147483647
2759 aa
2760 b
2761 $ hg revert a
2762
2763 Test relpath function
2764
2765 $ hg log -r0 -T '{files % "{file|relpath}\n"}'
2766 a
2767 $ cd ..
2768 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
2769 r/a
2770 $ cd r
2771
2772 Test active bookmark templating
1763 Test active bookmark templating
2773
1764
2774 $ hg book foo
1765 $ hg book foo
@@ -2848,75 +1839,7 b' Test namespaces dict'
2848 bar
1839 bar
2849 foo
1840 foo
2850
1841
2851 Test stringify on sub expressions
2852
2853 $ cd ..
1842 $ cd ..
2854 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
2855 fourth, second, third
2856 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
2857 abc
2858
2859 Test splitlines
2860
2861 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
2862 @ foo Modify, add, remove, rename
2863 |
2864 o foo future
2865 |
2866 o foo third
2867 |
2868 o foo second
2869
2870 o foo merge
2871 |\
2872 | o foo new head
2873 | |
2874 o | foo new branch
2875 |/
2876 o foo no user, no domain
2877 |
2878 o foo no person
2879 |
2880 o foo other 1
2881 | foo other 2
2882 | foo
2883 | foo other 3
2884 o foo line 1
2885 foo line 2
2886
2887 $ hg log -R a -r0 -T '{desc|splitlines}\n'
2888 line 1 line 2
2889 $ hg log -R a -r0 -T '{join(desc|splitlines, "|")}\n'
2890 line 1|line 2
2891
2892 Test startswith
2893 $ hg log -Gv -R a --template "{startswith(desc)}"
2894 hg: parse error: startswith expects two arguments
2895 [255]
2896
2897 $ hg log -Gv -R a --template "{startswith('line', desc)}"
2898 @
2899 |
2900 o
2901 |
2902 o
2903 |
2904 o
2905
2906 o
2907 |\
2908 | o
2909 | |
2910 o |
2911 |/
2912 o
2913 |
2914 o
2915 |
2916 o
2917 |
2918 o line 1
2919 line 2
2920
1843
2921 Test bad template with better error message
1844 Test bad template with better error message
2922
1845
@@ -2924,102 +1847,6 b' Test bad template with better error mess'
2924 hg: parse error: expected a symbol, got 'func'
1847 hg: parse error: expected a symbol, got 'func'
2925 [255]
1848 [255]
2926
1849
2927 Test word function (including index out of bounds graceful failure)
2928
2929 $ hg log -Gv -R a --template "{word('1', desc)}"
2930 @ add,
2931 |
2932 o
2933 |
2934 o
2935 |
2936 o
2937
2938 o
2939 |\
2940 | o head
2941 | |
2942 o | branch
2943 |/
2944 o user,
2945 |
2946 o person
2947 |
2948 o 1
2949 |
2950 o 1
2951
2952
2953 Test word third parameter used as splitter
2954
2955 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
2956 @ M
2957 |
2958 o future
2959 |
2960 o third
2961 |
2962 o sec
2963
2964 o merge
2965 |\
2966 | o new head
2967 | |
2968 o | new branch
2969 |/
2970 o n
2971 |
2972 o n
2973 |
2974 o
2975 |
2976 o line 1
2977 line 2
2978
2979 Test word error messages for not enough and too many arguments
2980
2981 $ hg log -Gv -R a --template "{word('0')}"
2982 hg: parse error: word expects two or three arguments, got 1
2983 [255]
2984
2985 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
2986 hg: parse error: word expects two or three arguments, got 7
2987 [255]
2988
2989 Test word for integer literal
2990
2991 $ hg log -R a --template "{word(2, desc)}\n" -r0
2992 line
2993
2994 Test word for invalid numbers
2995
2996 $ hg log -Gv -R a --template "{word('a', desc)}"
2997 hg: parse error: word expects an integer index
2998 [255]
2999
3000 Test word for out of range
3001
3002 $ hg log -R a --template "{word(10000, desc)}"
3003 $ hg log -R a --template "{word(-10000, desc)}"
3004
3005 Test indent and not adding to empty lines
3006
3007 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
3008 -----
3009 > line 1
3010 >> line 2
3011 -----
3012 > other 1
3013 >> other 2
3014
3015 >> other 3
3016
3017 Test with non-strings like dates
3018
3019 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3020 1200000.00
3021 1300000.00
3022
3023 Test broken string escapes:
1850 Test broken string escapes:
3024
1851
3025 $ hg log -T "bogus\\" -R a
1852 $ hg log -T "bogus\\" -R a
@@ -3029,11 +1856,6 b' Test broken string escapes:'
3029 hg: parse error: invalid \x escape* (glob)
1856 hg: parse error: invalid \x escape* (glob)
3030 [255]
1857 [255]
3031
1858
3032 json filter should escape HTML tags so that the output can be embedded in hgweb:
3033
3034 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
3035 "\u003cfoo@example.org\u003e"
3036
3037 Templater supports aliases of symbol and func() styles:
1859 Templater supports aliases of symbol and func() styles:
3038
1860
3039 $ hg clone -q a aliases
1861 $ hg clone -q a aliases
@@ -3162,57 +1984,6 b' Unparsable alias:'
3162
1984
3163 $ cd ..
1985 $ cd ..
3164
1986
3165 Set up repository for non-ascii encoding tests:
3166
3167 $ hg init nonascii
3168 $ cd nonascii
3169 $ $PYTHON <<EOF
3170 > open('latin1', 'wb').write(b'\xe9')
3171 > open('utf-8', 'wb').write(b'\xc3\xa9')
3172 > EOF
3173 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
3174 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
3175
3176 json filter should try round-trip conversion to utf-8:
3177
3178 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
3179 "\u00e9"
3180 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
3181 "non-ascii branch: \u00e9"
3182
3183 json filter should take input as utf-8 if it was converted from utf-8:
3184
3185 $ HGENCODING=latin-1 hg log -T "{branch|json}\n" -r0
3186 "\u00e9"
3187 $ HGENCODING=latin-1 hg log -T "{desc|json}\n" -r0
3188 "non-ascii branch: \u00e9"
3189
3190 json filter takes input as utf-8b:
3191
3192 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
3193 "\u00e9"
3194 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
3195 "\udce9"
3196
3197 utf8 filter:
3198
3199 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
3200 round-trip: c3a9
3201 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
3202 decoded: c3a9
3203 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
3204 abort: decoding near * (glob)
3205 [255]
3206 $ hg log -T "coerced to string: {rev|utf8}\n" -r0
3207 coerced to string: 0
3208
3209 pad width:
3210
3211 $ HGENCODING=utf-8 hg debugtemplate "{pad('`cat utf-8`', 2, '-')}\n"
3212 \xc3\xa9- (esc)
3213
3214 $ cd ..
3215
3216 Test that template function in extension is registered as expected
1987 Test that template function in extension is registered as expected
3217
1988
3218 $ cd a
1989 $ cd a
This diff has been collapsed as it changes many lines, (2049 lines changed) Show them Hide them
@@ -1,3 +1,6 b''
1 Test template filters and functions
2 ===================================
3
1 $ hg init a
4 $ hg init a
2 $ cd a
5 $ cd a
3 $ echo a > a
6 $ echo a > a
@@ -29,165 +32,6 b''
29 $ hg merge -q foo
32 $ hg merge -q foo
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
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 Second branch starting at nullrev:
35 Second branch starting at nullrev:
192
36
193 $ hg update null
37 $ hg update null
@@ -202,732 +46,8 b' Second branch starting at nullrev:'
202 $ hg mv second fourth
46 $ hg mv second fourth
203 $ hg commit -m third -d "2020-01-01 10:01"
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 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 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 Check that {phase} works correctly on parents:
288
289 $ cat << EOF > parentphase
290 > changeset_debug = '{rev} ({phase}):{parents}\n'
291 > parent = ' {rev} ({phase})'
292 > EOF
293 $ hg phase -r 5 --public
49 $ hg phase -r 5 --public
294 $ hg phase -r 7 --secret --force
50 $ 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
51
932 Filters work:
52 Filters work:
933
53
@@ -1157,130 +277,11 b' Add a commit that does all possible modi'
1157 $ hg rm a
277 $ hg rm a
1158 $ hg ci -m "Modify, add, remove, rename"
278 $ hg ci -m "Modify, add, remove, rename"
1159
279
1160 Error on syntax:
1161
1162 $ cat <<EOF > t
1163 > changeset = '{c}'
1164 > c = q
1165 > x = "f
1166 > EOF
1167 $ echo '[ui]' > .hg/hgrc
1168 $ echo 'style = t' >> .hg/hgrc
1169 $ hg log
1170 hg: parse error at t:3: unmatched quotes
1171 [255]
1172
1173 $ hg log -T '{date'
1174 hg: parse error at 1: unterminated template expansion
1175 ({date
1176 ^ here)
1177 [255]
1178 $ hg log -T '{date(}'
1179 hg: parse error at 6: not a prefix: end
1180 ({date(}
1181 ^ here)
1182 [255]
1183 $ hg log -T '{date)}'
1184 hg: parse error at 5: invalid token
1185 ({date)}
1186 ^ here)
1187 [255]
1188 $ hg log -T '{date date}'
1189 hg: parse error at 6: invalid token
1190 ({date date}
1191 ^ here)
1192 [255]
1193
1194 $ hg log -T '{}'
1195 hg: parse error at 1: not a prefix: end
1196 ({}
1197 ^ here)
1198 [255]
1199 $ hg debugtemplate -v '{()}'
1200 (template
1201 (group
1202 None))
1203 * keywords:
1204 * functions:
1205 hg: parse error: missing argument
1206 [255]
1207
1208 Behind the scenes, this would throw TypeError without intype=bytes
1209
1210 $ hg log -l 3 --template '{date|obfuscate}\n'
1211 &#48;&#46;&#48;&#48;
1212 &#48;&#46;&#48;&#48;
1213 &#49;&#53;&#55;&#55;&#56;&#55;&#50;&#56;&#54;&#48;&#46;&#48;&#48;
1214
1215 Behind the scenes, this will throw a ValueError
1216
1217 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1218 hg: parse error: invalid date: 'Modify, add, remove, rename'
1219 (template filter 'shortdate' is not compatible with keyword 'desc')
1220 [255]
1221
1222 Behind the scenes, this would throw AttributeError without intype=bytes
1223
1224 $ hg log -l 3 --template 'line: {date|escape}\n'
1225 line: 0.00
1226 line: 0.00
1227 line: 1577872860.00
1228
1229 $ hg log -l 3 --template 'line: {extras|localdate}\n'
1230 hg: parse error: localdate expects a date information
1231 [255]
1232
1233 Behind the scenes, this will throw ValueError
1234
1235 $ hg tip --template '{author|email|date}\n'
1236 hg: parse error: date expects a date information
1237 [255]
1238
1239 $ hg tip -T '{author|email|shortdate}\n'
1240 hg: parse error: invalid date: 'test'
1241 (template filter 'shortdate' is not compatible with keyword 'author')
1242 [255]
1243
1244 $ hg tip -T '{get(extras, "branch")|shortdate}\n'
1245 hg: parse error: invalid date: 'default'
1246 (incompatible use of template filter 'shortdate')
1247 [255]
1248
1249 Error in nested template:
1250
1251 $ hg log -T '{"date'
1252 hg: parse error at 2: unterminated string
1253 ({"date
1254 ^ here)
1255 [255]
1256
1257 $ hg log -T '{"foo{date|?}"}'
1258 hg: parse error at 11: syntax error
1259 ({"foo{date|?}"}
1260 ^ here)
1261 [255]
1262
1263 Thrown an error if a template function doesn't exist
1264
1265 $ hg tip --template '{foo()}\n'
1266 hg: parse error: unknown function 'foo'
1267 [255]
1268
1269 Pass generator object created by template function to filter
280 Pass generator object created by template function to filter
1270
281
1271 $ hg log -l 1 --template '{if(author, author)|user}\n'
282 $ hg log -l 1 --template '{if(author, author)|user}\n'
1272 test
283 test
1273
284
1274 Test index keyword:
1275
1276 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
1277 10 0:a 1:b 2:fifth 3:fourth 4:third
1278 11 0:a
1279
1280 $ hg branches -T '{index} {branch}\n'
1281 0 default
1282 1 foo
1283
1284 Test diff function:
285 Test diff function:
1285
286
1286 $ hg diff -c 8
287 $ hg diff -c 8
@@ -1343,21 +344,9 b' Test diff function:'
1343 @@ -0,0 +1,1 @@
344 @@ -0,0 +1,1 @@
1344 +second
345 +second
1345
346
1346 ui verbosity:
1347
1348 $ hg log -l1 -T '{verbosity}\n'
1349
1350 $ hg log -l1 -T '{verbosity}\n' --debug
1351 debug
1352 $ hg log -l1 -T '{verbosity}\n' --quiet
1353 quiet
1354 $ hg log -l1 -T '{verbosity}\n' --verbose
1355 verbose
1356
1357 $ cd ..
347 $ cd ..
1358
348
1359
349 latesttag() function:
1360 latesttag:
1361
350
1362 $ hg init latesttag
351 $ hg init latesttag
1363 $ cd latesttag
352 $ cd latesttag
@@ -1385,165 +374,12 b' latesttag:'
1385 $ hg merge -q
374 $ hg merge -q
1386 $ hg ci -m merge -d '5 -3600'
375 $ hg ci -m merge -d '5 -3600'
1387
376
1388 No tag set:
1389
1390 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1391 @ 5: null+5
1392 |\
1393 | o 4: null+4
1394 | |
1395 | o 3: null+3
1396 | |
1397 o | 2: null+3
1398 |/
1399 o 1: null+2
1400 |
1401 o 0: null+1
1402
1403
1404 One common tag: longest path wins for {latesttagdistance}:
1405
1406 $ hg tag -r 1 -m t1 -d '6 0' t1
377 $ hg tag -r 1 -m t1 -d '6 0' t1
1407 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1408 @ 6: t1+4
1409 |
1410 o 5: t1+3
1411 |\
1412 | o 4: t1+2
1413 | |
1414 | o 3: t1+1
1415 | |
1416 o | 2: t1+1
1417 |/
1418 o 1: t1+0
1419 |
1420 o 0: null+1
1421
1422
1423 One ancestor tag: closest wins:
1424
1425 $ hg tag -r 2 -m t2 -d '7 0' t2
378 $ hg tag -r 2 -m t2 -d '7 0' t2
1426 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1427 @ 7: t2+3
1428 |
1429 o 6: t2+2
1430 |
1431 o 5: t2+1
1432 |\
1433 | o 4: t1+2
1434 | |
1435 | o 3: t1+1
1436 | |
1437 o | 2: t2+0
1438 |/
1439 o 1: t1+0
1440 |
1441 o 0: null+1
1442
1443
1444 Two branch tags: more recent wins if same number of changes:
1445
1446 $ hg tag -r 3 -m t3 -d '8 0' t3
379 $ hg tag -r 3 -m t3 -d '8 0' t3
1447 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1448 @ 8: t3+5
1449 |
1450 o 7: t3+4
1451 |
1452 o 6: t3+3
1453 |
1454 o 5: t3+2
1455 |\
1456 | o 4: t3+1
1457 | |
1458 | o 3: t3+0
1459 | |
1460 o | 2: t2+0
1461 |/
1462 o 1: t1+0
1463 |
1464 o 0: null+1
1465
1466
1467 Two branch tags: fewest changes wins:
1468
1469 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
380 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
1470 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1471 @ 9: t4+5,6
1472 |
1473 o 8: t4+4,5
1474 |
1475 o 7: t4+3,4
1476 |
1477 o 6: t4+2,3
1478 |
1479 o 5: t4+1,2
1480 |\
1481 | o 4: t4+0,0
1482 | |
1483 | o 3: t3+0,0
1484 | |
1485 o | 2: t2+0,0
1486 |/
1487 o 1: t1+0,0
1488 |
1489 o 0: null+1,1
1490
1491
1492 Merged tag overrides:
1493
1494 $ hg tag -r 5 -m t5 -d '9 0' t5
381 $ hg tag -r 5 -m t5 -d '9 0' t5
1495 $ hg tag -r 3 -m at3 -d '10 0' at3
382 $ hg tag -r 3 -m at3 -d '10 0' at3
1496 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
1497 @ 11: t5+6
1498 |
1499 o 10: t5+5
1500 |
1501 o 9: t5+4
1502 |
1503 o 8: t5+3
1504 |
1505 o 7: t5+2
1506 |
1507 o 6: t5+1
1508 |
1509 o 5: t5+0
1510 |\
1511 | o 4: t4+0
1512 | |
1513 | o 3: at3:t3+0
1514 | |
1515 o | 2: t2+0
1516 |/
1517 o 1: t1+0
1518 |
1519 o 0: null+1
1520
1521
1522 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
1523 @ 11: t5+6,6
1524 |
1525 o 10: t5+5,5
1526 |
1527 o 9: t5+4,4
1528 |
1529 o 8: t5+3,3
1530 |
1531 o 7: t5+2,2
1532 |
1533 o 6: t5+1,1
1534 |
1535 o 5: t5+0,0
1536 |\
1537 | o 4: t4+0,0
1538 | |
1539 | o 3: at3+0,0 t3+0,0
1540 | |
1541 o | 2: t2+0,0
1542 |/
1543 o 1: t1+0,0
1544 |
1545 o 0: null+1,1
1546
1547
383
1548 $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
384 $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
1549 @ 11: t3, C: 9, D: 8
385 @ 11: t3, C: 9, D: 8
@@ -1573,44 +409,6 b' Merged tag overrides:'
1573
409
1574 $ cd ..
410 $ cd ..
1575
411
1576 Test new-style inline templating:
1577
1578 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1579 modified files: .hgtags
1580
1581
1582 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
1583 hg: parse error: 11 is not iterable of mappings
1584 (keyword 'rev' does not support map operation)
1585 [255]
1586 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
1587 hg: parse error: None is not iterable of mappings
1588 [255]
1589 $ hg log -R latesttag -r tip -T '{extras % "{key}\n" % "{key}\n"}'
1590 hg: parse error: list of strings is not mappable
1591 [255]
1592
1593 Test new-style inline templating of non-list/dict type:
1594
1595 $ hg log -R latesttag -r tip -T '{manifest}\n'
1596 11:2bc6e9006ce2
1597 $ hg log -R latesttag -r tip -T 'string length: {manifest|count}\n'
1598 string length: 15
1599 $ hg log -R latesttag -r tip -T '{manifest % "{rev}:{node}"}\n'
1600 11:2bc6e9006ce29882383a22d39fd1f4e66dd3e2fc
1601
1602 $ hg log -R latesttag -r tip -T '{get(extras, "branch") % "{key}: {value}\n"}'
1603 branch: default
1604 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "{key}\n"}'
1605 hg: parse error: None is not iterable of mappings
1606 [255]
1607 $ hg log -R latesttag -r tip -T '{min(extras) % "{key}: {value}\n"}'
1608 branch: default
1609 $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}'
1610 0:ce3cec86e6c2
1611 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
1612 9:fbc7cd862e9c
1613
1614 Test manifest/get() can be join()-ed as string, though it's silly:
412 Test manifest/get() can be join()-ed as string, though it's silly:
1615
413
1616 $ hg log -R latesttag -r tip -T '{join(manifest, ".")}\n'
414 $ hg log -R latesttag -r tip -T '{join(manifest, ".")}\n'
@@ -1727,60 +525,6 b' Test laziness of if() then/else clause'
1727 $ hg debugtemplate '{ifeq(0, 0, "", count(0))}'
525 $ hg debugtemplate '{ifeq(0, 0, "", count(0))}'
1728 $ hg debugtemplate '{ifeq(0, 1, count(0), "")}'
526 $ hg debugtemplate '{ifeq(0, 1, count(0), "")}'
1729
527
1730 Test dot operator precedence:
1731
1732 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
1733 (template
1734 (|
1735 (.
1736 (symbol 'manifest')
1737 (symbol 'node'))
1738 (symbol 'short'))
1739 (string '\n'))
1740 * keywords: manifest, node, rev
1741 * functions: formatnode, short
1742 89f4071fec70
1743
1744 (the following examples are invalid, but seem natural in parsing POV)
1745
1746 $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null
1747 (template
1748 (|
1749 (symbol 'foo')
1750 (.
1751 (symbol 'bar')
1752 (symbol 'baz')))
1753 (string '\n'))
1754 [255]
1755 $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null
1756 (template
1757 (.
1758 (symbol 'foo')
1759 (func
1760 (symbol 'bar')
1761 None))
1762 (string '\n'))
1763 * keywords: foo
1764 * functions: bar
1765 [255]
1766
1767 Test evaluation of dot operator:
1768
1769 $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n'
1770 ce3cec86e6c26bd9bdfc590a6b92abc9680f1796
1771 $ hg log -R latesttag -r0 -T '{extras.branch}\n'
1772 default
1773 $ hg log -R latesttag -r0 -T '{date.unixtime} {localdate(date, "+0200").tzoffset}\n'
1774 0 -7200
1775
1776 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
1777 hg: parse error: 'test' is not a dictionary
1778 (keyword 'author' does not support member operation)
1779 [255]
1780 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
1781 hg: parse error: 'a' is not a dictionary
1782 [255]
1783
1784 Test the sub function of templating for expansion:
528 Test the sub function of templating for expansion:
1785
529
1786 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
530 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
@@ -1845,395 +589,18 b' Test invalid date:'
1845 hg: parse error: date expects a date information
589 hg: parse error: date expects a date information
1846 [255]
590 [255]
1847
591
1848 Test integer literal:
592 Set up repository containing template fragments in commit metadata:
1849
1850 $ hg debugtemplate -v '{(0)}\n'
1851 (template
1852 (group
1853 (integer '0'))
1854 (string '\n'))
1855 * keywords:
1856 * functions:
1857 0
1858 $ hg debugtemplate -v '{(123)}\n'
1859 (template
1860 (group
1861 (integer '123'))
1862 (string '\n'))
1863 * keywords:
1864 * functions:
1865 123
1866 $ hg debugtemplate -v '{(-4)}\n'
1867 (template
1868 (group
1869 (negate
1870 (integer '4')))
1871 (string '\n'))
1872 * keywords:
1873 * functions:
1874 -4
1875 $ hg debugtemplate '{(-)}\n'
1876 hg: parse error at 3: not a prefix: )
1877 ({(-)}\n
1878 ^ here)
1879 [255]
1880 $ hg debugtemplate '{(-a)}\n'
1881 hg: parse error: negation needs an integer argument
1882 [255]
1883
1884 top-level integer literal is interpreted as symbol (i.e. variable name):
1885
1886 $ hg debugtemplate -D 1=one -v '{1}\n'
1887 (template
1888 (integer '1')
1889 (string '\n'))
1890 * keywords:
1891 * functions:
1892 one
1893 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
1894 (template
1895 (func
1896 (symbol 'if')
1897 (list
1898 (string 't')
1899 (template
1900 (integer '1'))))
1901 (string '\n'))
1902 * keywords:
1903 * functions: if
1904 one
1905 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
1906 (template
1907 (|
1908 (integer '1')
1909 (symbol 'stringify'))
1910 (string '\n'))
1911 * keywords:
1912 * functions: stringify
1913 one
1914
1915 unless explicit symbol is expected:
1916
1917 $ hg log -Ra -r0 -T '{desc|1}\n'
1918 hg: parse error: expected a symbol, got 'integer'
1919 [255]
1920 $ hg log -Ra -r0 -T '{1()}\n'
1921 hg: parse error: expected a symbol, got 'integer'
1922 [255]
1923
1924 Test string literal:
1925
1926 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
1927 (template
1928 (string 'string with no template fragment')
1929 (string '\n'))
1930 * keywords:
1931 * functions:
1932 string with no template fragment
1933 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
1934 (template
1935 (template
1936 (string 'template: ')
1937 (symbol 'rev'))
1938 (string '\n'))
1939 * keywords: rev
1940 * functions:
1941 template: 0
1942 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
1943 (template
1944 (string 'rawstring: {rev}')
1945 (string '\n'))
1946 * keywords:
1947 * functions:
1948 rawstring: {rev}
1949 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
1950 (template
1951 (%
1952 (symbol 'files')
1953 (string 'rawstring: {file}'))
1954 (string '\n'))
1955 * keywords: files
1956 * functions:
1957 rawstring: {file}
1958
1959 Test string escaping:
1960
1961 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1962 >
1963 <>\n<[>
1964 <>\n<]>
1965 <>\n<
1966
1967 $ hg log -R latesttag -r 0 \
1968 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1969 >
1970 <>\n<[>
1971 <>\n<]>
1972 <>\n<
1973
1974 $ hg log -R latesttag -r 0 -T esc \
1975 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1976 >
1977 <>\n<[>
1978 <>\n<]>
1979 <>\n<
1980
1981 $ cat <<'EOF' > esctmpl
1982 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1983 > EOF
1984 $ hg log -R latesttag -r 0 --style ./esctmpl
1985 >
1986 <>\n<[>
1987 <>\n<]>
1988 <>\n<
1989
1990 Test string escaping of quotes:
1991
1992 $ hg log -Ra -r0 -T '{"\""}\n'
1993 "
1994 $ hg log -Ra -r0 -T '{"\\\""}\n'
1995 \"
1996 $ hg log -Ra -r0 -T '{r"\""}\n'
1997 \"
1998 $ hg log -Ra -r0 -T '{r"\\\""}\n'
1999 \\\"
2000
2001
2002 $ hg log -Ra -r0 -T '{"\""}\n'
2003 "
2004 $ hg log -Ra -r0 -T '{"\\\""}\n'
2005 \"
2006 $ hg log -Ra -r0 -T '{r"\""}\n'
2007 \"
2008 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2009 \\\"
2010
2011 Test exception in quoted template. single backslash before quotation mark is
2012 stripped before parsing:
2013
2014 $ cat <<'EOF' > escquotetmpl
2015 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
2016 > EOF
2017 $ cd latesttag
2018 $ hg log -r 2 --style ../escquotetmpl
2019 " \" \" \\" head1
2020
2021 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
2022 valid
2023 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
2024 valid
2025
2026 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
2027 _evalifliteral() templates (issue4733):
2028
2029 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
2030 "2
2031 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
2032 "2
2033 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
2034 "2
2035
2036 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
2037 \"
2038 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
2039 \"
2040 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2041 \"
2042
2043 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
2044 \\\"
2045 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
2046 \\\"
2047 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
2048 \\\"
2049
2050 escaped single quotes and errors:
2051
2052 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
2053 foo
2054 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
2055 foo
2056 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
2057 hg: parse error at 21: unterminated string
2058 ({if(rev, "{if(rev, \")}")}\n
2059 ^ here)
2060 [255]
2061 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
2062 hg: parse error: trailing \ in string
2063 [255]
2064 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
2065 hg: parse error: trailing \ in string
2066 [255]
2067
2068 $ cd ..
2069
2070 Test leading backslashes:
2071
2072 $ cd latesttag
2073 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
2074 {rev} {file}
2075 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
2076 \2 \head1
2077 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
2078 \{rev} \{file}
2079 $ cd ..
2080
2081 Test leading backslashes in "if" expression (issue4714):
2082
2083 $ cd latesttag
2084 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
2085 {rev} \{rev}
2086 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
2087 \2 \\{rev}
2088 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
2089 \{rev} \\\{rev}
2090 $ cd ..
2091
2092 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
2093
2094 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
2095 \x6e
2096 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
2097 \x5c\x786e
2098 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
2099 \x6e
2100 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
2101 \x5c\x786e
2102
2103 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
2104 \x6e
2105 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
2106 \x5c\x786e
2107 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
2108 \x6e
2109 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
2110 \x5c\x786e
2111
2112 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
2113 fourth
2114 second
2115 third
2116 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
2117 fourth\nsecond\nthird
2118
2119 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
2120 <p>
2121 1st
2122 </p>
2123 <p>
2124 2nd
2125 </p>
2126 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
2127 <p>
2128 1st\n\n2nd
2129 </p>
2130 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
2131 1st
2132
2133 2nd
2134
2135 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
2136 o perso
2137 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
2138 no person
2139 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
2140 o perso
2141 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
2142 no perso
2143
2144 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
2145 -o perso-
2146 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
2147 no person
2148 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
2149 \x2do perso\x2d
2150 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
2151 -o perso-
2152 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
2153 \x2do perso\x6e
2154
2155 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
2156 fourth
2157 second
2158 third
2159
2160 Test string escaping in nested expression:
2161
2162 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
2163 fourth\x6esecond\x6ethird
2164 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
2165 fourth\x6esecond\x6ethird
2166
2167 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
2168 fourth\x6esecond\x6ethird
2169 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
2170 fourth\x5c\x786esecond\x5c\x786ethird
2171
2172 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
2173 3:\x6eo user, \x6eo domai\x6e
2174 4:\x5c\x786eew bra\x5c\x786ech
2175
2176 Test quotes in nested expression are evaluated just like a $(command)
2177 substitution in POSIX shells:
2178
2179 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
2180 8:95c24699272e
2181 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
2182 {8} "95c24699272e"
2183
2184 Test recursive evaluation:
2185
593
2186 $ hg init r
594 $ hg init r
2187 $ cd r
595 $ cd r
2188 $ echo a > a
596 $ echo a > a
2189 $ hg ci -Am '{rev}'
597 $ hg ci -Am '{rev}'
2190 adding a
598 adding a
2191 $ hg log -r 0 --template '{if(rev, desc)}\n'
2192 {rev}
2193 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
2194 test 0
2195
599
2196 $ hg branch -q 'text.{rev}'
600 $ hg branch -q 'text.{rev}'
2197 $ echo aa >> aa
601 $ echo aa >> aa
2198 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
602 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
2199
603
2200 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
2201 {node|short}desc to
2202 text.{rev}be wrapped
2203 text.{rev}desc to be
2204 text.{rev}wrapped (no-eol)
2205 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
2206 bcc7ff960b8e:desc to
2207 text.1:be wrapped
2208 text.1:desc to be
2209 text.1:wrapped (no-eol)
2210 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
2211 hg: parse error: fill expects an integer width
2212 [255]
2213
2214 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
2215 bcc7ff960b8e:desc to be
2216 termwidth.1:wrapped desc
2217 termwidth.1:to be wrapped (no-eol)
2218
2219 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
2220 {node|short} (no-eol)
2221 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
2222 bcc-ff---b-e (no-eol)
2223
2224 $ cat >> .hg/hgrc <<EOF
2225 > [extensions]
2226 > color=
2227 > [color]
2228 > mode=ansi
2229 > text.{rev} = red
2230 > text.1 = green
2231 > EOF
2232 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
2233 \x1b[0;31mtext\x1b[0m (esc)
2234 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
2235 \x1b[0;32mtext\x1b[0m (esc)
2236
2237 color effect can be specified without quoting:
604 color effect can be specified without quoting:
2238
605
2239 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
606 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
@@ -2727,13 +1094,6 b' Invalid arguments passed to revset()'
2727 hg: parse error: invalid argument for revspec
1094 hg: parse error: invalid argument for revspec
2728 [255]
1095 [255]
2729
1096
2730 Test 'originalnode'
2731
2732 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
2733 000000000000 bcc7ff960b8e
2734 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
2735 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
2736
2737 Test files function
1097 Test files function
2738
1098
2739 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
1099 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
@@ -2767,90 +1127,9 b' Test relpath function'
2767 $ cd ..
1127 $ cd ..
2768 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
1128 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
2769 r/a
1129 r/a
2770 $ cd r
2771
2772 Test active bookmark templating
2773
2774 $ hg book foo
2775 $ hg book bar
2776 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
2777 2 bar* foo
2778 1
2779 0
2780 $ hg log --template "{rev} {activebookmark}\n"
2781 2 bar
2782 1
2783 0
2784 $ hg bookmarks --inactive bar
2785 $ hg log --template "{rev} {activebookmark}\n"
2786 2
2787 1
2788 0
2789 $ hg book -r1 baz
2790 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
2791 2 bar foo
2792 1 baz
2793 0
2794 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
2795 2 t
2796 1 f
2797 0 f
2798
2799 Test namespaces dict
2800
2801 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
2802 2
2803 bookmarks color=bookmark builtin=True
2804 bar,foo
2805 tags color=tag builtin=True
2806 tip
2807 branches color=branch builtin=True
2808 text.{rev}
2809 revnames color=revname builtin=False
2810 r2
2811
2812 1
2813 bookmarks color=bookmark builtin=True
2814 baz
2815 tags color=tag builtin=True
2816
2817 branches color=branch builtin=True
2818 text.{rev}
2819 revnames color=revname builtin=False
2820 r1
2821
2822 0
2823 bookmarks color=bookmark builtin=True
2824
2825 tags color=tag builtin=True
2826
2827 branches color=branch builtin=True
2828 default
2829 revnames color=revname builtin=False
2830 r0
2831
2832 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
2833 bookmarks: bar foo
2834 tags: tip
2835 branches: text.{rev}
2836 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
2837 bookmarks:
2838 bar
2839 foo
2840 tags:
2841 tip
2842 branches:
2843 text.{rev}
2844 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
2845 bar
2846 foo
2847 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
2848 bar
2849 foo
2850
1130
2851 Test stringify on sub expressions
1131 Test stringify on sub expressions
2852
1132
2853 $ cd ..
2854 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
1133 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
2855 fourth, second, third
1134 fourth, second, third
2856 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
1135 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
@@ -2918,12 +1197,6 b' Test startswith'
2918 o line 1
1197 o line 1
2919 line 2
1198 line 2
2920
1199
2921 Test bad template with better error message
2922
2923 $ hg log -Gv -R a --template '{desc|user()}'
2924 hg: parse error: expected a symbol, got 'func'
2925 [255]
2926
2927 Test word function (including index out of bounds graceful failure)
1200 Test word function (including index out of bounds graceful failure)
2928
1201
2929 $ hg log -Gv -R a --template "{word('1', desc)}"
1202 $ hg log -Gv -R a --template "{word('1', desc)}"
@@ -3020,148 +1293,11 b' Test with non-strings like dates'
3020 1200000.00
1293 1200000.00
3021 1300000.00
1294 1300000.00
3022
1295
3023 Test broken string escapes:
3024
3025 $ hg log -T "bogus\\" -R a
3026 hg: parse error: trailing \ in string
3027 [255]
3028 $ hg log -T "\\xy" -R a
3029 hg: parse error: invalid \x escape* (glob)
3030 [255]
3031
3032 json filter should escape HTML tags so that the output can be embedded in hgweb:
1296 json filter should escape HTML tags so that the output can be embedded in hgweb:
3033
1297
3034 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
1298 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
3035 "\u003cfoo@example.org\u003e"
1299 "\u003cfoo@example.org\u003e"
3036
1300
3037 Templater supports aliases of symbol and func() styles:
3038
3039 $ hg clone -q a aliases
3040 $ cd aliases
3041 $ cat <<EOF >> .hg/hgrc
3042 > [templatealias]
3043 > r = rev
3044 > rn = "{r}:{node|short}"
3045 > status(c, files) = files % "{c} {file}\n"
3046 > utcdate(d) = localdate(d, "UTC")
3047 > EOF
3048
3049 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
3050 (template
3051 (symbol 'rn')
3052 (string ' ')
3053 (|
3054 (func
3055 (symbol 'utcdate')
3056 (symbol 'date'))
3057 (symbol 'isodate'))
3058 (string '\n'))
3059 * expanded:
3060 (template
3061 (template
3062 (symbol 'rev')
3063 (string ':')
3064 (|
3065 (symbol 'node')
3066 (symbol 'short')))
3067 (string ' ')
3068 (|
3069 (func
3070 (symbol 'localdate')
3071 (list
3072 (symbol 'date')
3073 (string 'UTC')))
3074 (symbol 'isodate'))
3075 (string '\n'))
3076 * keywords: date, node, rev
3077 * functions: isodate, localdate, short
3078 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3079
3080 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
3081 (template
3082 (func
3083 (symbol 'status')
3084 (list
3085 (string 'A')
3086 (symbol 'file_adds'))))
3087 * expanded:
3088 (template
3089 (%
3090 (symbol 'file_adds')
3091 (template
3092 (string 'A')
3093 (string ' ')
3094 (symbol 'file')
3095 (string '\n'))))
3096 * keywords: file, file_adds
3097 * functions:
3098 A a
3099
3100 A unary function alias can be called as a filter:
3101
3102 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
3103 (template
3104 (|
3105 (|
3106 (symbol 'date')
3107 (symbol 'utcdate'))
3108 (symbol 'isodate'))
3109 (string '\n'))
3110 * expanded:
3111 (template
3112 (|
3113 (func
3114 (symbol 'localdate')
3115 (list
3116 (symbol 'date')
3117 (string 'UTC')))
3118 (symbol 'isodate'))
3119 (string '\n'))
3120 * keywords: date
3121 * functions: isodate, localdate
3122 1970-01-12 13:46 +0000
3123
3124 Aliases should be applied only to command arguments and templates in hgrc.
3125 Otherwise, our stock styles and web templates could be corrupted:
3126
3127 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
3128 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3129
3130 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
3131 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3132
3133 $ cat <<EOF > tmpl
3134 > changeset = 'nothing expanded:{rn}\n'
3135 > EOF
3136 $ hg log -r0 --style ./tmpl
3137 nothing expanded:
3138
3139 Aliases in formatter:
3140
3141 $ hg branches -T '{pad(branch, 7)} {rn}\n'
3142 default 6:d41e714fe50d
3143 foo 4:bbe44766e73d
3144
3145 Aliases should honor HGPLAIN:
3146
3147 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
3148 nothing expanded:
3149 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
3150 0:1e4e1b8f71e0
3151
3152 Unparsable alias:
3153
3154 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
3155 (template
3156 (symbol 'bad'))
3157 abort: bad definition of template alias "bad": at 2: not a prefix: end
3158 [255]
3159 $ hg log --config templatealias.bad='x(' -T '{bad}'
3160 abort: bad definition of template alias "bad": at 2: not a prefix: end
3161 [255]
3162
3163 $ cd ..
3164
3165 Set up repository for non-ascii encoding tests:
1301 Set up repository for non-ascii encoding tests:
3166
1302
3167 $ hg init nonascii
1303 $ hg init nonascii
@@ -3212,178 +1348,3 b' pad width:'
3212 \xc3\xa9- (esc)
1348 \xc3\xa9- (esc)
3213
1349
3214 $ cd ..
1350 $ cd ..
3215
3216 Test that template function in extension is registered as expected
3217
3218 $ cd a
3219
3220 $ cat <<EOF > $TESTTMP/customfunc.py
3221 > from mercurial import registrar
3222 >
3223 > templatefunc = registrar.templatefunc()
3224 >
3225 > @templatefunc(b'custom()')
3226 > def custom(context, mapping, args):
3227 > return b'custom'
3228 > EOF
3229 $ cat <<EOF > .hg/hgrc
3230 > [extensions]
3231 > customfunc = $TESTTMP/customfunc.py
3232 > EOF
3233
3234 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
3235 custom
3236
3237 $ cd ..
3238
3239 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
3240 printed graphwidths 3, 5, 7, etc. should all line up in their respective
3241 columns. We don't care about other aspects of the graph rendering here.
3242
3243 $ hg init graphwidth
3244 $ cd graphwidth
3245
3246 $ wrappabletext="a a a a a a a a a a a a"
3247
3248 $ printf "first\n" > file
3249 $ hg add file
3250 $ hg commit -m "$wrappabletext"
3251
3252 $ printf "first\nsecond\n" > file
3253 $ hg commit -m "$wrappabletext"
3254
3255 $ hg checkout 0
3256 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
3257 $ printf "third\nfirst\n" > file
3258 $ hg commit -m "$wrappabletext"
3259 created new head
3260
3261 $ hg merge
3262 merging file
3263 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
3264 (branch merge, don't forget to commit)
3265
3266 $ hg log --graph -T "{graphwidth}"
3267 @ 3
3268 |
3269 | @ 5
3270 |/
3271 o 3
3272
3273 $ hg commit -m "$wrappabletext"
3274
3275 $ hg log --graph -T "{graphwidth}"
3276 @ 5
3277 |\
3278 | o 5
3279 | |
3280 o | 5
3281 |/
3282 o 3
3283
3284
3285 $ hg checkout 0
3286 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
3287 $ printf "third\nfirst\nsecond\n" > file
3288 $ hg commit -m "$wrappabletext"
3289 created new head
3290
3291 $ hg log --graph -T "{graphwidth}"
3292 @ 3
3293 |
3294 | o 7
3295 | |\
3296 +---o 7
3297 | |
3298 | o 5
3299 |/
3300 o 3
3301
3302
3303 $ hg log --graph -T "{graphwidth}" -r 3
3304 o 5
3305 |\
3306 ~ ~
3307
3308 $ hg log --graph -T "{graphwidth}" -r 1
3309 o 3
3310 |
3311 ~
3312
3313 $ hg merge
3314 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
3315 (branch merge, don't forget to commit)
3316 $ hg commit -m "$wrappabletext"
3317
3318 $ printf "seventh\n" >> file
3319 $ hg commit -m "$wrappabletext"
3320
3321 $ hg log --graph -T "{graphwidth}"
3322 @ 3
3323 |
3324 o 5
3325 |\
3326 | o 5
3327 | |
3328 o | 7
3329 |\ \
3330 | o | 7
3331 | |/
3332 o / 5
3333 |/
3334 o 3
3335
3336
3337 The point of graphwidth is to allow wrapping that accounts for the space taken
3338 by the graph.
3339
3340 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
3341 @ a a a a
3342 | a a a a
3343 | a a a a
3344 o a a a
3345 |\ a a a
3346 | | a a a
3347 | | a a a
3348 | o a a a
3349 | | a a a
3350 | | a a a
3351 | | a a a
3352 o | a a
3353 |\ \ a a
3354 | | | a a
3355 | | | a a
3356 | | | a a
3357 | | | a a
3358 | o | a a
3359 | |/ a a
3360 | | a a
3361 | | a a
3362 | | a a
3363 | | a a
3364 o | a a a
3365 |/ a a a
3366 | a a a
3367 | a a a
3368 o a a a a
3369 a a a a
3370 a a a a
3371
3372 Something tricky happens when there are elided nodes; the next drawn row of
3373 edges can be more than one column wider, but the graph width only increases by
3374 one column. The remaining columns are added in between the nodes.
3375
3376 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
3377 o 5
3378 |\
3379 | \
3380 | :\
3381 o : : 7
3382 :/ /
3383 : o 5
3384 :/
3385 o 3
3386
3387
3388 $ cd ..
3389
General Comments 0
You need to be logged in to leave comments. Login now