directory rename detection: testcases checking which side did the rename

Reviewed-by: Stefan Beller <sbeller@google.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Apr 19, 2018 at 10:57 UTC f34998768824dd64dd68635e7d0ac93275ebede8
1 file changed +336
t/t6043-merge-rename-directories.sh
+336
@@ -1180,4 +1180,340 @@ test_expect_failure '5d-check: Directory/file/file conflict due to directory ren
1180 # back to old handling. But, sadly, see testcases 8a and 8b.
1181 ###########################################################################
1182
1183 +
1184 +###########################################################################
1185 +# SECTION 6: Same side of the merge was the one that did the rename
1186 +#
1187 +# It may sound obvious that you only want to apply implicit directory
1188 +# renames to directories if the _other_ side of history did the renaming.
1189 +# If you did make an implementation that didn't explicitly enforce this
1190 +# rule, the majority of cases that would fall under this section would
1191 +# also be solved by following the rules from the above sections. But
1192 +# there are still a few that stick out, so this section covers them just
1193 +# to make sure we also get them right.
1194 +###########################################################################
1195 +
1196 +# Testcase 6a, Tricky rename/delete
1197 +# Commit O: z/{b,c,d}
1198 +# Commit A: z/b
1199 +# Commit B: y/{b,c}, z/d
1200 +# Expected: y/b, CONFLICT(rename/delete, z/c -> y/c vs. NULL)
1201 +# Note: We're just checking here that the rename of z/b and z/c to put
1202 +# them under y/ doesn't accidentally catch z/d and make it look like
1203 +# it is also involved in a rename/delete conflict.
1204 +
1205 +test_expect_success '6a-setup: Tricky rename/delete' '
1206 + test_create_repo 6a &&
1207 + (
1208 + cd 6a &&
1209 +
1210 + mkdir z &&
1211 + echo b >z/b &&
1212 + echo c >z/c &&
1213 + echo d >z/d &&
1214 + git add z &&
1215 + test_tick &&
1216 + git commit -m "O" &&
1217 +
1218 + git branch O &&
1219 + git branch A &&
1220 + git branch B &&
1221 +
1222 + git checkout A &&
1223 + git rm z/c &&
1224 + git rm z/d &&
1225 + test_tick &&
1226 + git commit -m "A" &&
1227 +
1228 + git checkout B &&
1229 + mkdir y &&
1230 + git mv z/b y/ &&
1231 + git mv z/c y/ &&
1232 + test_tick &&
1233 + git commit -m "B"
1234 + )
1235 +'
1236 +
1237 +test_expect_success '6a-check: Tricky rename/delete' '
1238 + (
1239 + cd 6a &&
1240 +
1241 + git checkout A^0 &&
1242 +
1243 + test_must_fail git merge -s recursive B^0 >out &&
1244 + test_i18ngrep "CONFLICT (rename/delete).*z/c.*y/c" out &&
1245 +
1246 + git ls-files -s >out &&
1247 + test_line_count = 2 out &&
1248 + git ls-files -u >out &&
1249 + test_line_count = 1 out &&
1250 + git ls-files -o >out &&
1251 + test_line_count = 1 out &&
1252 +
1253 + git rev-parse >actual \
1254 + :0:y/b :3:y/c &&
1255 + git rev-parse >expect \
1256 + O:z/b O:z/c &&
1257 + test_cmp expect actual
1258 + )
1259 +'
1260 +
1261 +# Testcase 6b, Same rename done on both sides
1262 +# (Related to testcases 6c and 8e)
1263 +# Commit O: z/{b,c}
1264 +# Commit A: y/{b,c}
1265 +# Commit B: y/{b,c}, z/d
1266 +# Expected: y/{b,c}, z/d
1267 +# Note: If we did directory rename detection here, we'd move z/d into y/,
1268 +# but B did that rename and still decided to put the file into z/,
1269 +# so we probably shouldn't apply directory rename detection for it.
1270 +
1271 +test_expect_success '6b-setup: Same rename done on both sides' '
1272 + test_create_repo 6b &&
1273 + (
1274 + cd 6b &&
1275 +
1276 + mkdir z &&
1277 + echo b >z/b &&
1278 + echo c >z/c &&
1279 + git add z &&
1280 + test_tick &&
1281 + git commit -m "O" &&
1282 +
1283 + git branch O &&
1284 + git branch A &&
1285 + git branch B &&
1286 +
1287 + git checkout A &&
1288 + git mv z y &&
1289 + test_tick &&
1290 + git commit -m "A" &&
1291 +
1292 + git checkout B &&
1293 + git mv z y &&
1294 + mkdir z &&
1295 + echo d >z/d &&
1296 + git add z/d &&
1297 + test_tick &&
1298 + git commit -m "B"
1299 + )
1300 +'
1301 +
1302 +test_expect_success '6b-check: Same rename done on both sides' '
1303 + (
1304 + cd 6b &&
1305 +
1306 + git checkout A^0 &&
1307 +
1308 + git merge -s recursive B^0 &&
1309 +
1310 + git ls-files -s >out &&
1311 + test_line_count = 3 out &&
1312 + git ls-files -u >out &&
1313 + test_line_count = 0 out &&
1314 + git ls-files -o >out &&
1315 + test_line_count = 1 out &&
1316 +
1317 + git rev-parse >actual \
1318 + HEAD:y/b HEAD:y/c HEAD:z/d &&
1319 + git rev-parse >expect \
1320 + O:z/b O:z/c B:z/d &&
1321 + test_cmp expect actual
1322 + )
1323 +'
1324 +
1325 +# Testcase 6c, Rename only done on same side
1326 +# (Related to testcases 6b and 8e)
1327 +# Commit O: z/{b,c}
1328 +# Commit A: z/{b,c} (no change)
1329 +# Commit B: y/{b,c}, z/d
1330 +# Expected: y/{b,c}, z/d
1331 +# NOTE: Seems obvious, but just checking that the implementation doesn't
1332 +# "accidentally detect a rename" and give us y/{b,c,d}.
1333 +
1334 +test_expect_success '6c-setup: Rename only done on same side' '
1335 + test_create_repo 6c &&
1336 + (
1337 + cd 6c &&
1338 +
1339 + mkdir z &&
1340 + echo b >z/b &&
1341 + echo c >z/c &&
1342 + git add z &&
1343 + test_tick &&
1344 + git commit -m "O" &&
1345 +
1346 + git branch O &&
1347 + git branch A &&
1348 + git branch B &&
1349 +
1350 + git checkout A &&
1351 + test_tick &&
1352 + git commit --allow-empty -m "A" &&
1353 +
1354 + git checkout B &&
1355 + git mv z y &&
1356 + mkdir z &&
1357 + echo d >z/d &&
1358 + git add z/d &&
1359 + test_tick &&
1360 + git commit -m "B"
1361 + )
1362 +'
1363 +
1364 +test_expect_success '6c-check: Rename only done on same side' '
1365 + (
1366 + cd 6c &&
1367 +
1368 + git checkout A^0 &&
1369 +
1370 + git merge -s recursive B^0 &&
1371 +
1372 + git ls-files -s >out &&
1373 + test_line_count = 3 out &&
1374 + git ls-files -u >out &&
1375 + test_line_count = 0 out &&
1376 + git ls-files -o >out &&
1377 + test_line_count = 1 out &&
1378 +
1379 + git rev-parse >actual \
1380 + HEAD:y/b HEAD:y/c HEAD:z/d &&
1381 + git rev-parse >expect \
1382 + O:z/b O:z/c B:z/d &&
1383 + test_cmp expect actual
1384 + )
1385 +'
1386 +
1387 +# Testcase 6d, We don't always want transitive renaming
1388 +# (Related to testcase 1c)
1389 +# Commit O: z/{b,c}, x/d
1390 +# Commit A: z/{b,c}, x/d (no change)
1391 +# Commit B: y/{b,c}, z/d
1392 +# Expected: y/{b,c}, z/d
1393 +# NOTE: Again, this seems obvious but just checking that the implementation
1394 +# doesn't "accidentally detect a rename" and give us y/{b,c,d}.
1395 +
1396 +test_expect_success '6d-setup: We do not always want transitive renaming' '
1397 + test_create_repo 6d &&
1398 + (
1399 + cd 6d &&
1400 +
1401 + mkdir z &&
1402 + echo b >z/b &&
1403 + echo c >z/c &&
1404 + mkdir x &&
1405 + echo d >x/d &&
1406 + git add z x &&
1407 + test_tick &&
1408 + git commit -m "O" &&
1409 +
1410 + git branch O &&
1411 + git branch A &&
1412 + git branch B &&
1413 +
1414 + git checkout A &&
1415 + test_tick &&
1416 + git commit --allow-empty -m "A" &&
1417 +
1418 + git checkout B &&
1419 + git mv z y &&
1420 + git mv x z &&
1421 + test_tick &&
1422 + git commit -m "B"
1423 + )
1424 +'
1425 +
1426 +test_expect_success '6d-check: We do not always want transitive renaming' '
1427 + (
1428 + cd 6d &&
1429 +
1430 + git checkout A^0 &&
1431 +
1432 + git merge -s recursive B^0 &&
1433 +
1434 + git ls-files -s >out &&
1435 + test_line_count = 3 out &&
1436 + git ls-files -u >out &&
1437 + test_line_count = 0 out &&
1438 + git ls-files -o >out &&
1439 + test_line_count = 1 out &&
1440 +
1441 + git rev-parse >actual \
1442 + HEAD:y/b HEAD:y/c HEAD:z/d &&
1443 + git rev-parse >expect \
1444 + O:z/b O:z/c O:x/d &&
1445 + test_cmp expect actual
1446 + )
1447 +'
1448 +
1449 +# Testcase 6e, Add/add from one-side
1450 +# Commit O: z/{b,c}
1451 +# Commit A: z/{b,c} (no change)
1452 +# Commit B: y/{b,c,d_1}, z/d_2
1453 +# Expected: y/{b,c,d_1}, z/d_2
1454 +# NOTE: Again, this seems obvious but just checking that the implementation
1455 +# doesn't "accidentally detect a rename" and give us y/{b,c} +
1456 +# add/add conflict on y/d_1 vs y/d_2.
1457 +
1458 +test_expect_success '6e-setup: Add/add from one side' '
1459 + test_create_repo 6e &&
1460 + (
1461 + cd 6e &&
1462 +
1463 + mkdir z &&
1464 + echo b >z/b &&
1465 + echo c >z/c &&
1466 + git add z &&
1467 + test_tick &&
1468 + git commit -m "O" &&
1469 +
1470 + git branch O &&
1471 + git branch A &&
1472 + git branch B &&
1473 +
1474 + git checkout A &&
1475 + test_tick &&
1476 + git commit --allow-empty -m "A" &&
1477 +
1478 + git checkout B &&
1479 + git mv z y &&
1480 + echo d1 > y/d &&
1481 + mkdir z &&
1482 + echo d2 > z/d &&
1483 + git add y/d z/d &&
1484 + test_tick &&
1485 + git commit -m "B"
1486 + )
1487 +'
1488 +
1489 +test_expect_success '6e-check: Add/add from one side' '
1490 + (
1491 + cd 6e &&
1492 +
1493 + git checkout A^0 &&
1494 +
1495 + git merge -s recursive B^0 &&
1496 +
1497 + git ls-files -s >out &&
1498 + test_line_count = 4 out &&
1499 + git ls-files -u >out &&
1500 + test_line_count = 0 out &&
1501 + git ls-files -o >out &&
1502 + test_line_count = 1 out &&
1503 +
1504 + git rev-parse >actual \
1505 + HEAD:y/b HEAD:y/c HEAD:y/d HEAD:z/d &&
1506 + git rev-parse >expect \
1507 + O:z/b O:z/c B:y/d B:z/d &&
1508 + test_cmp expect actual
1509 + )
1510 +'
1511 +
1512 +###########################################################################
1513 +# Rules suggested by section 6:
1514 +#
1515 +# Only apply implicit directory renames to directories if the other
1516 +# side of history is the one doing the renaming.
1517 +###########################################################################
1518 +
1519 test_done