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. "$TEST_DIRECTORY"/lib-read-tree.sh 76. "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh 77 78################################################################ 79# Trivial "majority when 3 stages exist" merge plus #2ALT, #3ALT 80# and #5ALT trivial merges. 81 82cat>expected <<\EOF 83100644 X 2 AA 84100644 X 3 AA 85100644 X 0 AN 86100644 X 1 DD 87100644 X 3 DF 88100644 X 2 DF/DF 89100644 X 1 DM 90100644 X 3 DM 91100644 X 1 DN 92100644 X 3 DN 93100644 X 0 LL 94100644 X 1 MD 95100644 X 2 MD 96100644 X 1 MM 97100644 X 2 MM 98100644 X 3 MM 99100644 X 0 MN 100100644 X 0 NA 101100644 X 1 ND 102100644 X 2 ND 103100644 X 0 NM 104100644 X 0 NN 105100644 X 0 SS 106100644 X 1 TT 107100644 X 2 TT 108100644 X 3 TT 109100644 X 2 Z/AA 110100644 X 3 Z/AA 111100644 X 0 Z/AN 112100644 X 1 Z/DD 113100644 X 1 Z/DM 114100644 X 3 Z/DM 115100644 X 1 Z/DN 116100644 X 3 Z/DN 117100644 X 1 Z/MD 118100644 X 2 Z/MD 119100644 X 1 Z/MM 120100644 X 2 Z/MM 121100644 X 3 Z/MM 122100644 X 0 Z/MN 123100644 X 0 Z/NA 124100644 X 1 Z/ND 125100644 X 2 Z/ND 126100644 X 0 Z/NM 127100644 X 0 Z/NN 128EOF 129 130check_result () { 131 git ls-files --stage|sed-e's/ '"$OID_REGEX"' / X /'>current && 132 test_cmp expected current 133} 134 135# This is done on an empty work directory, which is the normal 136# merge person behaviour. 137test_expect_success '3-way merge with git read-tree -m, empty cache'' 138 rm -fr [NDMALTS][NDMALTSF] Z && 139 rm .git/index && 140 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 141 check_result 142' 143 144# This starts out with the first head, which is the normal 145# patch submitter behaviour. 146test_expect_success '3-way merge with git read-tree -m, match H'' 147 rm -fr [NDMALTS][NDMALTSF] Z && 148 rm .git/index && 149 read_tree_must_succeed$tree_A&& 150 git checkout-index -f -u -a && 151 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 152 check_result 153' 154 155: <<\END_OF_CASE_TABLE 156 157We have so far tested only empty index and clean-and-matching-A index 158casewhich are trivial. Make sure index requirements are also 159checked. 160 161"git read-tree -m O A B" 162 163 O A B result index requirements 164------------------------------------------------------------------- 1651 missing missing missing - must not exist. 166------------------------------------------------------------------ 1672 missing missing exists take B* must match B,if exists. 168------------------------------------------------------------------ 1693 missing exists missing take A* must match A,if exists. 170------------------------------------------------------------------ 1714 missing exists A!=B no merge must match A and be 172 up-to-date,if exists. 173------------------------------------------------------------------ 1745 missing exists A==B take A must match A,if exists. 175------------------------------------------------------------------ 1766 exists missing missing remove must not exist. 177------------------------------------------------------------------ 1787 exists missing O!=B no merge must not exist. 179------------------------------------------------------------------ 1808 exists missing O==B remove must not exist. 181------------------------------------------------------------------ 1829 exists O!=A missing no merge must match A and be 183 up-to-date,if exists. 184------------------------------------------------------------------ 18510 exists O==A missing no merge must match A 186------------------------------------------------------------------ 18711 exists O!=A O!=B no merge must match A and be 188 A!=B up-to-date,if exists. 189------------------------------------------------------------------ 19012 exists O!=A O!=B take A must match A,if exists. 191 A==B 192------------------------------------------------------------------ 19313 exists O!=A O==B take A must match A,if exists. 194------------------------------------------------------------------ 19514 exists O==A O!=B take B if exists, must either (1) 196 match A and be up-to-date, 197 or (2) match B. 198------------------------------------------------------------------ 19915 exists O==A O==B take B must match A if exists. 200------------------------------------------------------------------ 20116 exists O==A O==B barf must match A if exists. 202*multi*in one in another 203------------------------------------------------------------------- 204 205Note: we need to be careful in case2 and 3. The tree A may contain 206DF (file) when tree B require DF to be a directory by having DF/DF 207(file). 208 209END_OF_CASE_TABLE 210 211test_expect_success '1 - must not have an entry not in A.'' 212 rm -f .git/index XX && 213 echo XX >XX && 214 git update-index --add XX && 215 read_tree_must_fail -m$tree_O$tree_A$tree_B 216' 217 218test_expect_success '2 - must match B in !O && !A && B case.'' 219 rm -f .git/index NA && 220 cp .orig-B/NA NA && 221 git update-index --add NA && 222 read_tree_must_succeed -m$tree_O$tree_A$tree_B 223' 224 225test_expect_success '2 - matching B alone is OK in !O && !A && B case.'' 226 rm -f .git/index NA && 227 cp .orig-B/NA NA && 228 git update-index --add NA && 229 echo extra >>NA && 230 read_tree_must_succeed -m$tree_O$tree_A$tree_B 231' 232 233test_expect_success '3 - must match A in !O && A && !B case.'' 234 rm -f .git/index AN && 235 cp .orig-A/AN AN && 236 git update-index --add AN && 237 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 238 check_result 239' 240 241test_expect_success '3 - matching A alone is OK in !O && A && !B case.'' 242 rm -f .git/index AN && 243 cp .orig-A/AN AN && 244 git update-index --add AN && 245 echo extra >>AN && 246 read_tree_must_succeed -m$tree_O$tree_A$tree_B 247' 248 249test_expect_success '3 (fail) - must match A in !O && A && !B case.'' 250 rm -f .git/index AN && 251 cp .orig-A/AN AN && 252 echo extra >>AN && 253 git update-index --add AN && 254 read_tree_must_fail -m$tree_O$tree_A$tree_B 255' 256 257test_expect_success '4 - must match and be up-to-date in !O && A && B && A!=B case.'' 258 rm -f .git/index AA && 259 cp .orig-A/AA AA && 260 git update-index --add AA && 261 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 262 check_result 263' 264 265test_expect_success '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.'' 266 rm -f .git/index AA && 267 cp .orig-A/AA AA && 268 git update-index --add AA && 269 echo extra >>AA && 270 read_tree_must_fail -m$tree_O$tree_A$tree_B 271' 272 273test_expect_success '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.'' 274 rm -f .git/index AA && 275 cp .orig-A/AA AA && 276 echo extra >>AA && 277 git update-index --add AA && 278 read_tree_must_fail -m$tree_O$tree_A$tree_B 279' 280 281test_expect_success '5 - must match in !O && A && B && A==B case.'' 282 rm -f .git/index LL && 283 cp .orig-A/LL LL && 284 git update-index --add LL && 285 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 286 check_result 287' 288 289test_expect_success '5 - must match in !O && A && B && A==B case.'' 290 rm -f .git/index LL && 291 cp .orig-A/LL LL && 292 git update-index --add LL && 293 echo extra >>LL && 294 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 295 check_result 296' 297 298test_expect_success '5 (fail) - must match A in !O && A && B && A==B case.'' 299 rm -f .git/index LL && 300 cp .orig-A/LL LL && 301 echo extra >>LL && 302 git update-index --add LL && 303 read_tree_must_fail -m$tree_O$tree_A$tree_B 304' 305 306test_expect_success '6 - must not exist in O && !A && !B case'' 307 rm -f .git/index DD && 308 echo DD >DD && 309 git update-index --add DD && 310 read_tree_must_fail -m$tree_O$tree_A$tree_B 311' 312 313test_expect_success '7 - must not exist in O && !A && B && O!=B case'' 314 rm -f .git/index DM && 315 cp .orig-B/DM DM && 316 git update-index --add DM && 317 read_tree_must_fail -m$tree_O$tree_A$tree_B 318' 319 320test_expect_success '8 - must not exist in O && !A && B && O==B case'' 321 rm -f .git/index DN && 322 cp .orig-B/DN DN && 323 git update-index --add DN && 324 read_tree_must_fail -m$tree_O$tree_A$tree_B 325' 326 327test_expect_success '9 - must match and be up-to-date in O && A && !B && O!=A case'' 328 rm -f .git/index MD && 329 cp .orig-A/MD MD && 330 git update-index --add MD && 331 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 332 check_result 333' 334 335test_expect_success '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case'' 336 rm -f .git/index MD && 337 cp .orig-A/MD MD && 338 git update-index --add MD && 339 echo extra >>MD && 340 read_tree_must_fail -m$tree_O$tree_A$tree_B 341' 342 343test_expect_success '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case'' 344 rm -f .git/index MD && 345 cp .orig-A/MD MD && 346 echo extra >>MD && 347 git update-index --add MD && 348 read_tree_must_fail -m$tree_O$tree_A$tree_B 349' 350 351test_expect_success '10 - must match and be up-to-date in O && A && !B && O==A case'' 352 rm -f .git/index ND && 353 cp .orig-A/ND ND && 354 git update-index --add ND && 355 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 356 check_result 357' 358 359test_expect_success '10 (fail) - must match and be up-to-date in O && A && !B && O==A case'' 360 rm -f .git/index ND && 361 cp .orig-A/ND ND && 362 git update-index --add ND && 363 echo extra >>ND && 364 read_tree_must_fail -m$tree_O$tree_A$tree_B 365' 366 367test_expect_success '10 (fail) - must match and be up-to-date in O && A && !B && O==A case'' 368 rm -f .git/index ND && 369 cp .orig-A/ND ND && 370 echo extra >>ND && 371 git update-index --add ND && 372 read_tree_must_fail -m$tree_O$tree_A$tree_B 373' 374 375test_expect_success '11 - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case'' 376 rm -f .git/index MM && 377 cp .orig-A/MM MM && 378 git update-index --add MM && 379 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 380 check_result 381' 382 383test_expect_success '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case'' 384 rm -f .git/index MM && 385 cp .orig-A/MM MM && 386 git update-index --add MM && 387 echo extra >>MM && 388 read_tree_must_fail -m$tree_O$tree_A$tree_B 389' 390 391test_expect_success '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case'' 392 rm -f .git/index MM && 393 cp .orig-A/MM MM && 394 echo extra >>MM && 395 git update-index --add MM && 396 read_tree_must_fail -m$tree_O$tree_A$tree_B 397' 398 399test_expect_success '12 - must match A in O && A && B && O!=A && A==B case'' 400 rm -f .git/index SS && 401 cp .orig-A/SS SS && 402 git update-index --add SS && 403 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 404 check_result 405' 406 407test_expect_success '12 - must match A in O && A && B && O!=A && A==B case'' 408 rm -f .git/index SS && 409 cp .orig-A/SS SS && 410 git update-index --add SS && 411 echo extra >>SS && 412 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 413 check_result 414' 415 416test_expect_success '12 (fail) - must match A in O && A && B && O!=A && A==B case'' 417 rm -f .git/index SS && 418 cp .orig-A/SS SS && 419 echo extra >>SS && 420 git update-index --add SS && 421 read_tree_must_fail -m$tree_O$tree_A$tree_B 422' 423 424test_expect_success '13 - must match A in O && A && B && O!=A && O==B case'' 425 rm -f .git/index MN && 426 cp .orig-A/MN MN && 427 git update-index --add MN && 428 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 429 check_result 430' 431 432test_expect_success '13 - must match A in O && A && B && O!=A && O==B case'' 433 rm -f .git/index MN && 434 cp .orig-A/MN MN && 435 git update-index --add MN && 436 echo extra >>MN && 437 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 438 check_result 439' 440 441test_expect_success '14 - must match and be up-to-date in O && A && B && O==A && O!=B case'' 442 rm -f .git/index NM && 443 cp .orig-A/NM NM && 444 git update-index --add NM && 445 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 446 check_result 447' 448 449test_expect_success '14 - may match B in O && A && B && O==A && O!=B case'' 450 rm -f .git/index NM && 451 cp .orig-B/NM NM && 452 git update-index --add NM && 453 echo extra >>NM && 454 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 455 check_result 456' 457 458test_expect_success '14 (fail) - 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 echo extra >>NM && 463 read_tree_must_fail -m$tree_O$tree_A$tree_B 464' 465 466test_expect_success '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case'' 467 rm -f .git/index NM && 468 cp .orig-A/NM NM && 469 echo extra >>NM && 470 git update-index --add NM && 471 read_tree_must_fail -m$tree_O$tree_A$tree_B 472' 473 474test_expect_success '15 - must match A in O && A && B && O==A && O==B case'' 475 rm -f .git/index NN && 476 cp .orig-A/NN NN && 477 git update-index --add NN && 478 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 479 check_result 480' 481 482test_expect_success '15 - must match A in O && A && B && O==A && O==B case'' 483 rm -f .git/index NN && 484 cp .orig-A/NN NN && 485 git update-index --add NN && 486 echo extra >>NN && 487 read_tree_must_succeed -m$tree_O$tree_A$tree_B&& 488 check_result 489' 490 491test_expect_success '15 (fail) - must match A in O && A && B && O==A && O==B case'' 492 rm -f .git/index NN && 493 cp .orig-A/NN NN && 494 echo extra >>NN && 495 git update-index --add NN && 496 read_tree_must_fail -m$tree_O$tree_A$tree_B 497' 498 499test_expect_success '16 - A matches in one and B matches in another.'' 500 rm -f .git/index F16 && 501 echo F16 >F16 && 502 git update-index --add F16 && 503 tree0=$(git write-tree)&& 504 echo E16 >F16 && 505 git update-index F16 && 506 tree1=$(git write-tree)&& 507 read_tree_must_succeed -m$tree0$tree1$tree1$tree0&& 508 git ls-files --stage 509' 510 511test_done