1#!/bin/sh 2# 3# Copyright (c) 2005 Junio C Hamano 4# 5 6test_description='Three way merge with read-tree -m 7 8This test tries three-way merge with read-tree -m 9 10There is one ancestor (called O for Original) and two branches A 11and B derived from it. We want to do a 3-way merge between A and 12B, using O as the common ancestor. 13 14 merge A O B 15 16Decisions are made by comparing contents of O, A and B pathname 17by pathname. The result is determined by the following guiding 18principle: 19 20 - If only A does something to it and B does not touch it, take 21 whatever A does. 22 23 - If only B does something to it and A does not touch it, take 24 whatever B does. 25 26 - If both A and B does something but in the same way, take 27 whatever they do. 28 29 - If A and B does something but different things, we need a 30 3-way merge: 31 32 - We cannot do anything about the following cases: 33 34 * O does not have it. A and B both must be adding to the 35 same path independently. 36 37 * A deletes it. B must be modifying. 38 39 - Otherwise, A and B are modifying. Run 3-way merge. 40 41First, the case matrix. 42 43 - Vertical axis is for A'\''s actions. 44 - Horizontal axis is for B'\''s actions. 45 46.----------------------------------------------------------------. 47| A B | No Action | Delete | Modify | Add | 48|------------+------------+------------+------------+------------| 49| No Action | | | | | 50| | select O | delete | select B | select B | 51| | | | | | 52|------------+------------+------------+------------+------------| 53| Delete | | | ********** | can | 54| | delete | delete | merge | not | 55| | | | | happen | 56|------------+------------+------------+------------+------------| 57| Modify | | ********** | ?????????? | can | 58| | select A | merge | select A=B | not | 59| | | | merge | happen | 60|------------+------------+------------+------------+------------| 61| Add | | can | can | ?????????? | 62| | select A | not | not | select A=B | 63| | | happen | happen | merge | 64.----------------------------------------------------------------. 65 66In addition: 67 68 SS: a special case of MM, where A and B makes the same modification. 69 LL: a special case of AA, where A and B creates the same file. 70 TT: a special case of MM, where A and B makes mergeable changes. 71 DF: a special case, where A makes a directory and B makes a file. 72 73' 74. ./test-lib.sh 75. ../lib-read-tree-m-3way.sh 76 77################################################################ 78# Trivial "majority when 3 stages exist" merge plus #2ALT, #3ALT 79# and #5ALT trivial merges. 80 81cat>expected <<\EOF 82100644 X 2 AA 83100644 X 3 AA 84100644 X 0 AN 85100644 X 1 DD 86100644 X 3 DF 87100644 X 2 DF/DF 88100644 X 1 DM 89100644 X 3 DM 90100644 X 1 DN 91100644 X 3 DN 92100644 X 0 LL 93100644 X 1 MD 94100644 X 2 MD 95100644 X 1 MM 96100644 X 2 MM 97100644 X 3 MM 98100644 X 0 MN 99100644 X 0 NA 100100644 X 1 ND 101100644 X 2 ND 102100644 X 0 NM 103100644 X 0 NN 104100644 X 0 SS 105100644 X 1 TT 106100644 X 2 TT 107100644 X 3 TT 108100644 X 2 Z/AA 109100644 X 3 Z/AA 110100644 X 0 Z/AN 111100644 X 1 Z/DD 112100644 X 1 Z/DM 113100644 X 3 Z/DM 114100644 X 1 Z/DN 115100644 X 3 Z/DN 116100644 X 1 Z/MD 117100644 X 2 Z/MD 118100644 X 1 Z/MM 119100644 X 2 Z/MM 120100644 X 3 Z/MM 121100644 X 0 Z/MN 122100644 X 0 Z/NA 123100644 X 1 Z/ND 124100644 X 2 Z/ND 125100644 X 0 Z/NM 126100644 X 0 Z/NN 127EOF 128 129_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' 130_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" 131 132check_result () { 133 git ls-files --stage|sed-e's/ '"$_x40"' / X /'>current && 134 git diff expected current 135} 136 137# This is done on an empty work directory, which is the normal 138# merge person behaviour. 139test_expect_success \ 140'3-way merge with git read-tree -m, empty cache' \ 141"rm -fr [NDMALTS][NDMALTSF] Z && 142 rm .git/index && 143 git read-tree -m$tree_O$tree_A$tree_B&& 144 check_result" 145 146# This starts out with the first head, which is the normal 147# patch submitter behaviour. 148test_expect_success \ 149'3-way merge with git read-tree -m, match H' \ 150"rm -fr [NDMALTS][NDMALTSF] Z && 151 rm .git/index && 152 git read-tree$tree_A&& 153 git checkout-index -f -u -a && 154 git read-tree -m$tree_O$tree_A$tree_B&& 155 check_result" 156 157: <<\END_OF_CASE_TABLE 158 159We have so far tested only empty index and clean-and-matching-A index 160casewhich are trivial. Make sure index requirements are also 161checked. 162 163"git read-tree -m O A B" 164 165 O A B result index requirements 166------------------------------------------------------------------- 1671 missing missing missing - must not exist. 168------------------------------------------------------------------ 1692 missing missing exists take B* must match B,if exists. 170------------------------------------------------------------------ 1713 missing exists missing take A* must match A,if exists. 172------------------------------------------------------------------ 1734 missing exists A!=B no merge must match A and be 174 up-to-date,if exists. 175------------------------------------------------------------------ 1765 missing exists A==B take A must match A,if exists. 177------------------------------------------------------------------ 1786 exists missing missing remove must not exist. 179------------------------------------------------------------------ 1807 exists missing O!=B no merge must not exist. 181------------------------------------------------------------------ 1828 exists missing O==B remove must not exist. 183------------------------------------------------------------------ 1849 exists O!=A missing no merge must match A and be 185 up-to-date,if exists. 186------------------------------------------------------------------ 18710 exists O==A missing no merge must match A 188------------------------------------------------------------------ 18911 exists O!=A O!=B no merge must match A and be 190 A!=B up-to-date,if exists. 191------------------------------------------------------------------ 19212 exists O!=A O!=B take A must match A,if exists. 193 A==B 194------------------------------------------------------------------ 19513 exists O!=A O==B take A must match A,if exists. 196------------------------------------------------------------------ 19714 exists O==A O!=B take B if exists, must either (1) 198 match A and be up-to-date, 199 or (2) match B. 200------------------------------------------------------------------ 20115 exists O==A O==B take B must match A if exists. 202------------------------------------------------------------------ 20316 exists O==A O==B barf must match A if exists. 204*multi*in one in another 205------------------------------------------------------------------- 206 207Note: we need to be careful in case2 and 3. The tree A may contain 208DF (file) when tree B require DF to be a directory by having DF/DF 209(file). 210 211END_OF_CASE_TABLE 212 213test_expect_success '1 - must not have an entry not in A.'" 214 rm -f .git/index XX && 215 echo XX >XX && 216 git update-index --add XX && 217 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 218" 219 220test_expect_success \ 221'2 - must match B in !O && !A && B case.' \ 222"rm -f .git/index NA && 223 cp .orig-B/NA NA && 224 git update-index --add NA && 225 git read-tree -m$tree_O$tree_A$tree_B" 226 227test_expect_success \ 228'2 - matching B alone is OK in !O && !A && B case.' \ 229"rm -f .git/index NA && 230 cp .orig-B/NA NA && 231 git update-index --add NA && 232 echo extra >>NA && 233 git read-tree -m$tree_O$tree_A$tree_B" 234 235test_expect_success \ 236'3 - must match A in !O && A && !B case.' \ 237"rm -f .git/index AN && 238 cp .orig-A/AN AN && 239 git update-index --add AN && 240 git read-tree -m$tree_O$tree_A$tree_B&& 241 check_result" 242 243test_expect_success \ 244'3 - matching A alone is OK in !O && A && !B case.' \ 245"rm -f .git/index AN && 246 cp .orig-A/AN AN && 247 git update-index --add AN && 248 echo extra >>AN && 249 git read-tree -m$tree_O$tree_A$tree_B" 250 251test_expect_success \ 252'3 (fail) - must match A in !O && A && !B case.'" 253 rm -f .git/index AN && 254 cp .orig-A/AN AN && 255 echo extra >>AN && 256 git update-index --add AN && 257 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 258" 259 260test_expect_success \ 261'4 - must match and be up-to-date in !O && A && B && A!=B case.' \ 262"rm -f .git/index AA && 263 cp .orig-A/AA AA && 264 git update-index --add AA && 265 git read-tree -m$tree_O$tree_A$tree_B&& 266 check_result" 267 268test_expect_success \ 269'4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.'" 270 rm -f .git/index AA && 271 cp .orig-A/AA AA && 272 git update-index --add AA && 273 echo extra >>AA && 274 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 275" 276 277test_expect_success \ 278'4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.'" 279 rm -f .git/index AA && 280 cp .orig-A/AA AA && 281 echo extra >>AA && 282 git update-index --add AA && 283 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 284" 285 286test_expect_success \ 287'5 - must match in !O && A && B && A==B case.' \ 288"rm -f .git/index LL && 289 cp .orig-A/LL LL && 290 git update-index --add LL && 291 git read-tree -m$tree_O$tree_A$tree_B&& 292 check_result" 293 294test_expect_success \ 295'5 - must match in !O && A && B && A==B case.' \ 296"rm -f .git/index LL && 297 cp .orig-A/LL LL && 298 git update-index --add LL && 299 echo extra >>LL && 300 git read-tree -m$tree_O$tree_A$tree_B&& 301 check_result" 302 303test_expect_success \ 304'5 (fail) - must match A in !O && A && B && A==B case.'" 305 rm -f .git/index LL && 306 cp .orig-A/LL LL && 307 echo extra >>LL && 308 git update-index --add LL && 309 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 310" 311 312test_expect_success \ 313'6 - must not exist in O && !A && !B case'" 314 rm -f .git/index DD && 315 echo DD >DD 316 git update-index --add DD && 317 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 318" 319 320test_expect_success \ 321'7 - must not exist in O && !A && B && O!=B case'" 322 rm -f .git/index DM && 323 cp .orig-B/DM DM && 324 git update-index --add DM && 325 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 326" 327 328test_expect_success \ 329'8 - must not exist in O && !A && B && O==B case'" 330 rm -f .git/index DN && 331 cp .orig-B/DN DN && 332 git update-index --add DN && 333 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 334" 335 336test_expect_success \ 337'9 - must match and be up-to-date in O && A && !B && O!=A case' \ 338"rm -f .git/index MD && 339 cp .orig-A/MD MD && 340 git update-index --add MD && 341 git read-tree -m$tree_O$tree_A$tree_B&& 342 check_result" 343 344test_expect_success \ 345'9 (fail) - must match and be up-to-date in O && A && !B && O!=A case'" 346 rm -f .git/index MD && 347 cp .orig-A/MD MD && 348 git update-index --add MD && 349 echo extra >>MD && 350 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 351" 352 353test_expect_success \ 354'9 (fail) - must match and be up-to-date in O && A && !B && O!=A case'" 355 rm -f .git/index MD && 356 cp .orig-A/MD MD && 357 echo extra >>MD && 358 git update-index --add MD && 359 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 360" 361 362test_expect_success \ 363'10 - must match and be up-to-date in O && A && !B && O==A case' \ 364"rm -f .git/index ND && 365 cp .orig-A/ND ND && 366 git update-index --add ND && 367 git read-tree -m$tree_O$tree_A$tree_B&& 368 check_result" 369 370test_expect_success \ 371'10 (fail) - must match and be up-to-date in O && A && !B && O==A case'" 372 rm -f .git/index ND && 373 cp .orig-A/ND ND && 374 git update-index --add ND && 375 echo extra >>ND && 376 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 377" 378 379test_expect_success \ 380'10 (fail) - must match and be up-to-date in O && A && !B && O==A case'" 381 rm -f .git/index ND && 382 cp .orig-A/ND ND && 383 echo extra >>ND && 384 git update-index --add ND && 385 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 386" 387 388test_expect_success \ 389'11 - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \ 390"rm -f .git/index MM && 391 cp .orig-A/MM MM && 392 git update-index --add MM && 393 git read-tree -m$tree_O$tree_A$tree_B&& 394 check_result" 395 396test_expect_success \ 397'11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case'" 398 rm -f .git/index MM && 399 cp .orig-A/MM MM && 400 git update-index --add MM && 401 echo extra >>MM && 402 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 403" 404 405test_expect_success \ 406'11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case'" 407 rm -f .git/index MM && 408 cp .orig-A/MM MM && 409 echo extra >>MM && 410 git update-index --add MM && 411 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 412" 413 414test_expect_success \ 415'12 - must match A in O && A && B && O!=A && A==B case' \ 416"rm -f .git/index SS && 417 cp .orig-A/SS SS && 418 git update-index --add SS && 419 git read-tree -m$tree_O$tree_A$tree_B&& 420 check_result" 421 422test_expect_success \ 423'12 - must match A in O && A && B && O!=A && A==B case' \ 424"rm -f .git/index SS && 425 cp .orig-A/SS SS && 426 git update-index --add SS && 427 echo extra >>SS && 428 git read-tree -m$tree_O$tree_A$tree_B&& 429 check_result" 430 431test_expect_success \ 432'12 (fail) - must match A in O && A && B && O!=A && A==B case'" 433 rm -f .git/index SS && 434 cp .orig-A/SS SS && 435 echo extra >>SS && 436 git update-index --add SS && 437 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 438" 439 440test_expect_success \ 441'13 - must match A in O && A && B && O!=A && O==B case' \ 442"rm -f .git/index MN && 443 cp .orig-A/MN MN && 444 git update-index --add MN && 445 git read-tree -m$tree_O$tree_A$tree_B&& 446 check_result" 447 448test_expect_success \ 449'13 - must match A in O && A && B && O!=A && O==B case' \ 450"rm -f .git/index MN && 451 cp .orig-A/MN MN && 452 git update-index --add MN && 453 echo extra >>MN && 454 git read-tree -m$tree_O$tree_A$tree_B&& 455 check_result" 456 457test_expect_success \ 458'14 - must match and be up-to-date in O && A && B && O==A && O!=B case' \ 459"rm -f .git/index NM && 460 cp .orig-A/NM NM && 461 git update-index --add NM && 462 git read-tree -m$tree_O$tree_A$tree_B&& 463 check_result" 464 465test_expect_success \ 466'14 - may match B in O && A && B && O==A && O!=B case' \ 467"rm -f .git/index NM && 468 cp .orig-B/NM NM && 469 git update-index --add NM && 470 echo extra >>NM && 471 git read-tree -m$tree_O$tree_A$tree_B&& 472 check_result" 473 474test_expect_success \ 475'14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case'" 476 rm -f .git/index NM && 477 cp .orig-A/NM NM && 478 git update-index --add NM && 479 echo extra >>NM && 480 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 481" 482 483test_expect_success \ 484'14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case'" 485 rm -f .git/index NM && 486 cp .orig-A/NM NM && 487 echo extra >>NM && 488 git update-index --add NM && 489 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 490" 491 492test_expect_success \ 493'15 - must match A in O && A && B && O==A && O==B case' \ 494"rm -f .git/index NN && 495 cp .orig-A/NN NN && 496 git update-index --add NN && 497 git read-tree -m$tree_O$tree_A$tree_B&& 498 check_result" 499 500test_expect_success \ 501'15 - must match A in O && A && B && O==A && O==B case' \ 502"rm -f .git/index NN && 503 cp .orig-A/NN NN && 504 git update-index --add NN && 505 echo extra >>NN && 506 git read-tree -m$tree_O$tree_A$tree_B&& 507 check_result" 508 509test_expect_success \ 510'15 (fail) - must match A in O && A && B && O==A && O==B case'" 511 rm -f .git/index NN && 512 cp .orig-A/NN NN && 513 echo extra >>NN && 514 git update-index --add NN && 515 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 516" 517 518# #16 519test_expect_success \ 520'16 - A matches in one and B matches in another.' \ 521'rm -f .git/index F16 && 522 echo F16 >F16 && 523 git update-index --add F16 && 524 tree0=`git write-tree` && 525 echo E16 >F16 && 526 git update-index F16 && 527 tree1=`git write-tree` && 528 git read-tree -m$tree0$tree1$tree1$tree0&& 529 git ls-files --stage' 530 531test_done