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