tests/test-revset.t
changeset 29390 9349b4073c11
parent 29362 ec75d77df9d7
child 29408 785cadec2091
equal deleted inserted replaced
29389:98e8313dcd9e 29390:9349b4073c11
    29 
    29 
    30   $ log() {
    30   $ log() {
    31   >   hg log --template '{rev}\n' -r "$1"
    31   >   hg log --template '{rev}\n' -r "$1"
    32   > }
    32   > }
    33 
    33 
       
    34 extension to build '_intlist()' and '_hexlist()', which is necessary because
       
    35 these predicates use '\0' as a separator:
       
    36 
       
    37   $ cat <<EOF > debugrevlistspec.py
       
    38   > from __future__ import absolute_import
       
    39   > from mercurial import (
       
    40   >     cmdutil,
       
    41   >     node as nodemod,
       
    42   >     revset,
       
    43   > )
       
    44   > cmdtable = {}
       
    45   > command = cmdutil.command(cmdtable)
       
    46   > @command('debugrevlistspec',
       
    47   >     [('', 'optimize', None, 'print parsed tree after optimizing'),
       
    48   >      ('', 'bin', None, 'unhexlify arguments')])
       
    49   > def debugrevlistspec(ui, repo, fmt, *args, **opts):
       
    50   >     if opts['bin']:
       
    51   >         args = map(nodemod.bin, args)
       
    52   >     expr = revset.formatspec(fmt, list(args))
       
    53   >     if ui.verbose:
       
    54   >         tree = revset.parse(expr, lookup=repo.__contains__)
       
    55   >         ui.note(revset.prettyformat(tree), "\n")
       
    56   >         if opts["optimize"]:
       
    57   >             opttree = revset.optimize(tree)
       
    58   >             ui.note("* optimized:\n", revset.prettyformat(opttree), "\n")
       
    59   >     func = revset.match(ui, expr, repo)
       
    60   >     revs = func(repo)
       
    61   >     if ui.verbose:
       
    62   >         ui.note("* set:\n", revset.prettyformatset(revs), "\n")
       
    63   >     for c in revs:
       
    64   >         ui.write("%s\n" % c)
       
    65   > EOF
       
    66   $ cat <<EOF >> $HGRCPATH
       
    67   > [extensions]
       
    68   > debugrevlistspec = $TESTTMP/debugrevlistspec.py
       
    69   > EOF
       
    70   $ trylist() {
       
    71   >   hg debugrevlistspec --debug "$@"
       
    72   > }
       
    73 
    34   $ hg init repo
    74   $ hg init repo
    35   $ cd repo
    75   $ cd repo
    36 
    76 
    37   $ echo a > a
    77   $ echo a > a
    38   $ hg branch a
    78   $ hg branch a
   899   9
   939   9
   900 
   940 
   901 Test order of revisions in compound expression
   941 Test order of revisions in compound expression
   902 ----------------------------------------------
   942 ----------------------------------------------
   903 
   943 
       
   944 The general rule is that only the outermost (= leftmost) predicate can
       
   945 enforce its ordering requirement. The other predicates should take the
       
   946 ordering defined by it.
       
   947 
   904  'A & B' should follow the order of 'A':
   948  'A & B' should follow the order of 'A':
   905 
   949 
   906   $ log '2:0 & 0::2'
   950   $ log '2:0 & 0::2'
   907   2
   951   2
   908   1
   952   1
   909   0
   953   0
       
   954 
       
   955  'head()' combines sets in wrong order:
       
   956 
       
   957   $ log '2:0 & head()'
       
   958   0
       
   959   1
       
   960   2
       
   961  BROKEN: should be '2 1 0'
       
   962 
       
   963  'a + b', which is optimized to '_list(a b)', should take the ordering of
       
   964  the left expression:
       
   965 
       
   966   $ try --optimize '2:0 & (0 + 1 + 2)'
       
   967   (and
       
   968     (range
       
   969       ('symbol', '2')
       
   970       ('symbol', '0'))
       
   971     (group
       
   972       (or
       
   973         ('symbol', '0')
       
   974         ('symbol', '1')
       
   975         ('symbol', '2'))))
       
   976   * optimized:
       
   977   (and
       
   978     (range
       
   979       ('symbol', '2')
       
   980       ('symbol', '0'))
       
   981     (func
       
   982       ('symbol', '_list')
       
   983       ('string', '0\x001\x002')))
       
   984   * set:
       
   985   <baseset [0, 1, 2]>
       
   986   0
       
   987   1
       
   988   2
       
   989  BROKEN: should be '2 1 0'
       
   990 
       
   991  'A + B' should take the ordering of the left expression:
       
   992 
       
   993   $ try --optimize '2:0 & (0:1 + 2)'
       
   994   (and
       
   995     (range
       
   996       ('symbol', '2')
       
   997       ('symbol', '0'))
       
   998     (group
       
   999       (or
       
  1000         (range
       
  1001           ('symbol', '0')
       
  1002           ('symbol', '1'))
       
  1003         ('symbol', '2'))))
       
  1004   * optimized:
       
  1005   (and
       
  1006     (range
       
  1007       ('symbol', '2')
       
  1008       ('symbol', '0'))
       
  1009     (or
       
  1010       (range
       
  1011         ('symbol', '0')
       
  1012         ('symbol', '1'))
       
  1013       ('symbol', '2')))
       
  1014   * set:
       
  1015   <addset
       
  1016     <filteredset
       
  1017       <spanset+ 0:1>,
       
  1018       <spanset- 0:2>>,
       
  1019     <baseset [2]>>
       
  1020   0
       
  1021   1
       
  1022   2
       
  1023  BROKEN: should be '2 1 0'
       
  1024 
       
  1025  '_intlist(a b)' should behave like 'a + b':
       
  1026 
       
  1027   $ trylist --optimize '2:0 & %ld' 0 1 2
       
  1028   (and
       
  1029     (range
       
  1030       ('symbol', '2')
       
  1031       ('symbol', '0'))
       
  1032     (func
       
  1033       ('symbol', '_intlist')
       
  1034       ('string', '0\x001\x002')))
       
  1035   * optimized:
       
  1036   (and
       
  1037     (func
       
  1038       ('symbol', '_intlist')
       
  1039       ('string', '0\x001\x002'))
       
  1040     (range
       
  1041       ('symbol', '2')
       
  1042       ('symbol', '0')))
       
  1043   * set:
       
  1044   <filteredset
       
  1045     <spanset- 0:2>,
       
  1046     <baseset [0, 1, 2]>>
       
  1047   2
       
  1048   1
       
  1049   0
       
  1050 
       
  1051   $ trylist --optimize '%ld & 2:0' 0 2 1
       
  1052   (and
       
  1053     (func
       
  1054       ('symbol', '_intlist')
       
  1055       ('string', '0\x002\x001'))
       
  1056     (range
       
  1057       ('symbol', '2')
       
  1058       ('symbol', '0')))
       
  1059   * optimized:
       
  1060   (and
       
  1061     (func
       
  1062       ('symbol', '_intlist')
       
  1063       ('string', '0\x002\x001'))
       
  1064     (range
       
  1065       ('symbol', '2')
       
  1066       ('symbol', '0')))
       
  1067   * set:
       
  1068   <filteredset
       
  1069     <spanset- 0:2>,
       
  1070     <baseset [0, 2, 1]>>
       
  1071   2
       
  1072   1
       
  1073   0
       
  1074  BROKEN: should be '0 2 1'
       
  1075 
       
  1076  '_hexlist(a b)' should behave like 'a + b':
       
  1077 
       
  1078   $ trylist --optimize --bin '2:0 & %ln' `hg log -T '{node} ' -r0:2`
       
  1079   (and
       
  1080     (range
       
  1081       ('symbol', '2')
       
  1082       ('symbol', '0'))
       
  1083     (func
       
  1084       ('symbol', '_hexlist')
       
  1085       ('string', '*'))) (glob)
       
  1086   * optimized:
       
  1087   (and
       
  1088     (range
       
  1089       ('symbol', '2')
       
  1090       ('symbol', '0'))
       
  1091     (func
       
  1092       ('symbol', '_hexlist')
       
  1093       ('string', '*'))) (glob)
       
  1094   * set:
       
  1095   <baseset [0, 1, 2]>
       
  1096   0
       
  1097   1
       
  1098   2
       
  1099  BROKEN: should be '2 1 0'
       
  1100 
       
  1101   $ trylist --optimize --bin '%ln & 2:0' `hg log -T '{node} ' -r0+2+1`
       
  1102   (and
       
  1103     (func
       
  1104       ('symbol', '_hexlist')
       
  1105       ('string', '*')) (glob)
       
  1106     (range
       
  1107       ('symbol', '2')
       
  1108       ('symbol', '0')))
       
  1109   * optimized:
       
  1110   (and
       
  1111     (range
       
  1112       ('symbol', '2')
       
  1113       ('symbol', '0'))
       
  1114     (func
       
  1115       ('symbol', '_hexlist')
       
  1116       ('string', '*'))) (glob)
       
  1117   * set:
       
  1118   <baseset [0, 2, 1]>
       
  1119   0
       
  1120   2
       
  1121   1
       
  1122 
       
  1123  'present()' should do nothing other than suppressing an error:
       
  1124 
       
  1125   $ try --optimize '2:0 & present(0 + 1 + 2)'
       
  1126   (and
       
  1127     (range
       
  1128       ('symbol', '2')
       
  1129       ('symbol', '0'))
       
  1130     (func
       
  1131       ('symbol', 'present')
       
  1132       (or
       
  1133         ('symbol', '0')
       
  1134         ('symbol', '1')
       
  1135         ('symbol', '2'))))
       
  1136   * optimized:
       
  1137   (and
       
  1138     (range
       
  1139       ('symbol', '2')
       
  1140       ('symbol', '0'))
       
  1141     (func
       
  1142       ('symbol', 'present')
       
  1143       (func
       
  1144         ('symbol', '_list')
       
  1145         ('string', '0\x001\x002'))))
       
  1146   * set:
       
  1147   <baseset [0, 1, 2]>
       
  1148   0
       
  1149   1
       
  1150   2
       
  1151  BROKEN: should be '2 1 0'
       
  1152 
       
  1153  'reverse()' should take effect only if it is the outermost expression:
       
  1154 
       
  1155   $ try --optimize '0:2 & reverse(all())'
       
  1156   (and
       
  1157     (range
       
  1158       ('symbol', '0')
       
  1159       ('symbol', '2'))
       
  1160     (func
       
  1161       ('symbol', 'reverse')
       
  1162       (func
       
  1163         ('symbol', 'all')
       
  1164         None)))
       
  1165   * optimized:
       
  1166   (and
       
  1167     (range
       
  1168       ('symbol', '0')
       
  1169       ('symbol', '2'))
       
  1170     (func
       
  1171       ('symbol', 'reverse')
       
  1172       (func
       
  1173         ('symbol', 'all')
       
  1174         None)))
       
  1175   * set:
       
  1176   <filteredset
       
  1177     <spanset- 0:2>,
       
  1178     <spanset+ 0:9>>
       
  1179   2
       
  1180   1
       
  1181   0
       
  1182  BROKEN: should be '0 1 2'
       
  1183 
       
  1184  'sort()' should take effect only if it is the outermost expression:
       
  1185 
       
  1186   $ try --optimize '0:2 & sort(all(), -rev)'
       
  1187   (and
       
  1188     (range
       
  1189       ('symbol', '0')
       
  1190       ('symbol', '2'))
       
  1191     (func
       
  1192       ('symbol', 'sort')
       
  1193       (list
       
  1194         (func
       
  1195           ('symbol', 'all')
       
  1196           None)
       
  1197         (negate
       
  1198           ('symbol', 'rev')))))
       
  1199   * optimized:
       
  1200   (and
       
  1201     (range
       
  1202       ('symbol', '0')
       
  1203       ('symbol', '2'))
       
  1204     (func
       
  1205       ('symbol', 'sort')
       
  1206       (list
       
  1207         (func
       
  1208           ('symbol', 'all')
       
  1209           None)
       
  1210         ('string', '-rev'))))
       
  1211   * set:
       
  1212   <filteredset
       
  1213     <spanset- 0:2>,
       
  1214     <spanset+ 0:9>>
       
  1215   2
       
  1216   1
       
  1217   0
       
  1218  BROKEN: should be '0 1 2'
       
  1219 
       
  1220  for 'A & f(B)', 'B' should not be affected by the order of 'A':
       
  1221 
       
  1222   $ try --optimize '2:0 & first(1 + 0 + 2)'
       
  1223   (and
       
  1224     (range
       
  1225       ('symbol', '2')
       
  1226       ('symbol', '0'))
       
  1227     (func
       
  1228       ('symbol', 'first')
       
  1229       (or
       
  1230         ('symbol', '1')
       
  1231         ('symbol', '0')
       
  1232         ('symbol', '2'))))
       
  1233   * optimized:
       
  1234   (and
       
  1235     (range
       
  1236       ('symbol', '2')
       
  1237       ('symbol', '0'))
       
  1238     (func
       
  1239       ('symbol', 'first')
       
  1240       (func
       
  1241         ('symbol', '_list')
       
  1242         ('string', '1\x000\x002'))))
       
  1243   * set:
       
  1244   <baseset
       
  1245     <limit n=1, offset=0,
       
  1246       <spanset- 0:2>,
       
  1247       <baseset [1, 0, 2]>>>
       
  1248   1
       
  1249 
       
  1250   $ try --optimize '2:0 & not last(0 + 2 + 1)'
       
  1251   (and
       
  1252     (range
       
  1253       ('symbol', '2')
       
  1254       ('symbol', '0'))
       
  1255     (not
       
  1256       (func
       
  1257         ('symbol', 'last')
       
  1258         (or
       
  1259           ('symbol', '0')
       
  1260           ('symbol', '2')
       
  1261           ('symbol', '1')))))
       
  1262   * optimized:
       
  1263   (difference
       
  1264     (range
       
  1265       ('symbol', '2')
       
  1266       ('symbol', '0'))
       
  1267     (func
       
  1268       ('symbol', 'last')
       
  1269       (func
       
  1270         ('symbol', '_list')
       
  1271         ('string', '0\x002\x001'))))
       
  1272   * set:
       
  1273   <filteredset
       
  1274     <spanset- 0:2>,
       
  1275     <not
       
  1276       <baseset
       
  1277         <last n=1,
       
  1278           <fullreposet+ 0:9>,
       
  1279           <baseset [1, 2, 0]>>>>>
       
  1280   2
       
  1281   0
       
  1282 
       
  1283  for 'A & (op)(B)', 'B' should not be affected by the order of 'A':
       
  1284 
       
  1285   $ try --optimize '2:0 & (1 + 0 + 2):(0 + 2 + 1)'
       
  1286   (and
       
  1287     (range
       
  1288       ('symbol', '2')
       
  1289       ('symbol', '0'))
       
  1290     (range
       
  1291       (group
       
  1292         (or
       
  1293           ('symbol', '1')
       
  1294           ('symbol', '0')
       
  1295           ('symbol', '2')))
       
  1296       (group
       
  1297         (or
       
  1298           ('symbol', '0')
       
  1299           ('symbol', '2')
       
  1300           ('symbol', '1')))))
       
  1301   * optimized:
       
  1302   (and
       
  1303     (range
       
  1304       ('symbol', '2')
       
  1305       ('symbol', '0'))
       
  1306     (range
       
  1307       (func
       
  1308         ('symbol', '_list')
       
  1309         ('string', '1\x000\x002'))
       
  1310       (func
       
  1311         ('symbol', '_list')
       
  1312         ('string', '0\x002\x001'))))
       
  1313   * set:
       
  1314   <filteredset
       
  1315     <baseset [1]>,
       
  1316     <spanset- 0:2>>
       
  1317   1
       
  1318 
       
  1319  'A & B' can be rewritten as 'B & A' by weight, but the ordering rule should
       
  1320  be determined before the optimization (i.e. 'B' should take the ordering of
       
  1321  'A'):
       
  1322 
       
  1323   $ try --optimize 'contains("glob:*") & (2 + 0 + 1)'
       
  1324   (and
       
  1325     (func
       
  1326       ('symbol', 'contains')
       
  1327       ('string', 'glob:*'))
       
  1328     (group
       
  1329       (or
       
  1330         ('symbol', '2')
       
  1331         ('symbol', '0')
       
  1332         ('symbol', '1'))))
       
  1333   * optimized:
       
  1334   (and
       
  1335     (func
       
  1336       ('symbol', '_list')
       
  1337       ('string', '2\x000\x001'))
       
  1338     (func
       
  1339       ('symbol', 'contains')
       
  1340       ('string', 'glob:*')))
       
  1341   * set:
       
  1342   <filteredset
       
  1343     <baseset [2, 0, 1]>,
       
  1344     <contains 'glob:*'>>
       
  1345   2
       
  1346   0
       
  1347   1
       
  1348  BROKEN: should be '0 1 2'
       
  1349 
       
  1350   $ try --optimize 'reverse(contains("glob:*")) & (0 + 2 + 1)'
       
  1351   (and
       
  1352     (func
       
  1353       ('symbol', 'reverse')
       
  1354       (func
       
  1355         ('symbol', 'contains')
       
  1356         ('string', 'glob:*')))
       
  1357     (group
       
  1358       (or
       
  1359         ('symbol', '0')
       
  1360         ('symbol', '2')
       
  1361         ('symbol', '1'))))
       
  1362   * optimized:
       
  1363   (and
       
  1364     (func
       
  1365       ('symbol', '_list')
       
  1366       ('string', '0\x002\x001'))
       
  1367     (func
       
  1368       ('symbol', 'reverse')
       
  1369       (func
       
  1370         ('symbol', 'contains')
       
  1371         ('string', 'glob:*'))))
       
  1372   * set:
       
  1373   <filteredset
       
  1374     <baseset [1, 2, 0]>,
       
  1375     <contains 'glob:*'>>
       
  1376   1
       
  1377   2
       
  1378   0
       
  1379  BROKEN: should be '2 1 0'
   910 
  1380 
   911 test sort revset
  1381 test sort revset
   912 --------------------------------------------
  1382 --------------------------------------------
   913 
  1383 
   914 test when adding two unordered revsets
  1384 test when adding two unordered revsets