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 && 134diff-u 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. The table also lists alternative semantics which is not 162currently implemented. 163 164"git-diff-tree -m O A B" 165 166 O A B result index requirements 167------------------------------------------------------------------- 1681 missing missing missing - must not exist. 169------------------------------------------------------------------ 1702 missing missing exists no merge must not exist. 171------------------------------------ 172(ALT) take B* must match B,if exists. 173------------------------------------------------------------------ 1743 missing exists missing no merge must match A and be 175 up-to-date,if exists. 176------------------------------------ 177(ALT) take A* must match A,if exists. 178------------------------------------------------------------------ 1794 missing exists A!=B no merge must match A and be 180 up-to-date,if exists. 181------------------------------------------------------------------ 1825 missing exists A==B no merge must match A and be 183 up-to-date,if exists. 184------------------------------------ 185(ALT) take A must match A,if exists. 186------------------------------------------------------------------ 1876 exists missing missing no merge must not exist. 188------------------------------------ 189(ALT) remove must not exist. 190------------------------------------------------------------------ 1917 exists missing O!=B no merge must not exist. 192------------------------------------------------------------------ 1938 exists missing O==B no merge must not exist. 194------------------------------------ 195(ALT) remove must not exist. 196------------------------------------------------------------------ 1979 exists O!=A missing no merge must match A and be 198 up-to-date,if exists. 199------------------------------------------------------------------ 20010 exists O==A missing no merge must match A and be 201 up-to-date,if exists. 202------------------------------------ 203(ALT) remove ditto 204------------------------------------------------------------------ 20511 exists O!=A O!=B no merge must match A and be 206 A!=B up-to-date,if exists. 207------------------------------------------------------------------ 20812 exists O!=A O!=B take A must match A,if exists. 209 A==B 210------------------------------------------------------------------ 21113 exists O!=A O==B take A must match A,if exists. 212------------------------------------------------------------------ 21314 exists O==A O!=B take B must match A and be 214 be up-to-date,if exists. 215------------------------------------ 216(ALT) take B if exists, must either (1) 217 match A and be up-to-date, 218 or (2) match B. 219------------------------------------------------------------------ 22015 exists O==A O==B take B must match A if exists. 221------------------------------------------------------------------ 22216 exists O==A O==B barf must match A if exists. 223*multi*in one in another 224------------------------------------------------------------------- 225 226Note:if we want to implement 2ALT and 3ALT we need to be careful. 227The tree A may contain DF (file) when tree B require DF to be a 228directory by having DF/DF (file). 229 230END_OF_CASE_TABLE 231 232test_expect_failure \ 233'1 - must not have an entry not in A.' \ 234"rm -f .git/index XX && 235 echo XX >XX && 236 git-update-index --add XX && 237 git-read-tree -m$tree_O$tree_A$tree_B" 238 239test_expect_success \ 240'2 - must match B in !O && !A && B case.' \ 241"rm -f .git/index NA && 242 cp .orig-B/NA NA && 243 git-update-index --add NA && 244 git-read-tree -m$tree_O$tree_A$tree_B" 245 246test_expect_success \ 247'2 - matching B alone is OK in !O && !A && B case.' \ 248"rm -f .git/index NA && 249 cp .orig-B/NA NA && 250 git-update-index --add NA && 251 echo extra >>NA && 252 git-read-tree -m$tree_O$tree_A$tree_B" 253 254test_expect_success \ 255'3 - must match A in !O && A && !B case.' \ 256"rm -f .git/index AN && 257 cp .orig-A/AN AN && 258 git-update-index --add AN && 259 git-read-tree -m$tree_O$tree_A$tree_B&& 260 check_result" 261 262test_expect_success \ 263'3 - matching A alone is OK in !O && A && !B case.' \ 264"rm -f .git/index AN && 265 cp .orig-A/AN AN && 266 git-update-index --add AN && 267 echo extra >>AN && 268 git-read-tree -m$tree_O$tree_A$tree_B" 269 270test_expect_failure \ 271'3 (fail) - must match A in !O && A && !B case.' \ 272"rm -f .git/index AN && 273 cp .orig-A/AN AN && 274 echo extra >>AN && 275 git-update-index --add AN && 276 git-read-tree -m$tree_O$tree_A$tree_B" 277 278test_expect_success \ 279'4 - must match and be up-to-date in !O && A && B && A!=B case.' \ 280"rm -f .git/index AA && 281 cp .orig-A/AA AA && 282 git-update-index --add AA && 283 git-read-tree -m$tree_O$tree_A$tree_B&& 284 check_result" 285 286test_expect_failure \ 287'4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' \ 288"rm -f .git/index AA && 289 cp .orig-A/AA AA && 290 git-update-index --add AA && 291 echo extra >>AA && 292 git-read-tree -m$tree_O$tree_A$tree_B" 293 294test_expect_failure \ 295'4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' \ 296"rm -f .git/index AA && 297 cp .orig-A/AA AA && 298 echo extra >>AA && 299 git-update-index --add AA && 300 git-read-tree -m$tree_O$tree_A$tree_B" 301 302test_expect_success \ 303'5 - must match in !O && A && B && A==B case.' \ 304"rm -f .git/index LL && 305 cp .orig-A/LL LL && 306 git-update-index --add LL && 307 git-read-tree -m$tree_O$tree_A$tree_B&& 308 check_result" 309 310test_expect_success \ 311'5 - must match in !O && A && B && A==B case.' \ 312"rm -f .git/index LL && 313 cp .orig-A/LL LL && 314 git-update-index --add LL && 315 echo extra >>LL && 316 git-read-tree -m$tree_O$tree_A$tree_B&& 317 check_result" 318 319test_expect_failure \ 320'5 (fail) - must match A in !O && A && B && A==B case.' \ 321"rm -f .git/index LL && 322 cp .orig-A/LL LL && 323 echo extra >>LL && 324 git-update-index --add LL && 325 git-read-tree -m$tree_O$tree_A$tree_B" 326 327test_expect_failure \ 328'6 - must not exist in O && !A && !B case' \ 329"rm -f .git/index DD && 330 echo DD >DD 331 git-update-index --add DD && 332 git-read-tree -m$tree_O$tree_A$tree_B" 333 334test_expect_failure \ 335'7 - must not exist in O && !A && B && O!=B case' \ 336"rm -f .git/index DM && 337 cp .orig-B/DM DM && 338 git-update-index --add DM && 339 git-read-tree -m$tree_O$tree_A$tree_B" 340 341test_expect_failure \ 342'8 - must not exist in O && !A && B && O==B case' \ 343"rm -f .git/index DN && 344 cp .orig-B/DN DN && 345 git-update-index --add DN && 346 git-read-tree -m$tree_O$tree_A$tree_B" 347 348test_expect_success \ 349'9 - must match and be up-to-date in O && A && !B && O!=A case' \ 350"rm -f .git/index MD && 351 cp .orig-A/MD MD && 352 git-update-index --add MD && 353 git-read-tree -m$tree_O$tree_A$tree_B&& 354 check_result" 355 356test_expect_failure \ 357'9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' \ 358"rm -f .git/index MD && 359 cp .orig-A/MD MD && 360 git-update-index --add MD && 361 echo extra >>MD && 362 git-read-tree -m$tree_O$tree_A$tree_B" 363 364test_expect_failure \ 365'9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' \ 366"rm -f .git/index MD && 367 cp .orig-A/MD MD && 368 echo extra >>MD && 369 git-update-index --add MD && 370 git-read-tree -m$tree_O$tree_A$tree_B" 371 372test_expect_success \ 373'10 - must match and be up-to-date in O && A && !B && O==A case' \ 374"rm -f .git/index ND && 375 cp .orig-A/ND ND && 376 git-update-index --add ND && 377 git-read-tree -m$tree_O$tree_A$tree_B&& 378 check_result" 379 380test_expect_failure \ 381'10 (fail) - must match and be up-to-date in O && A && !B && O==A case' \ 382"rm -f .git/index ND && 383 cp .orig-A/ND ND && 384 git-update-index --add ND && 385 echo extra >>ND && 386 git-read-tree -m$tree_O$tree_A$tree_B" 387 388test_expect_failure \ 389'10 (fail) - must match and be up-to-date in O && A && !B && O==A case' \ 390"rm -f .git/index ND && 391 cp .orig-A/ND ND && 392 echo extra >>ND && 393 git-update-index --add ND && 394 git-read-tree -m$tree_O$tree_A$tree_B" 395 396test_expect_success \ 397'11 - 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 git-read-tree -m$tree_O$tree_A$tree_B&& 402 check_result" 403 404test_expect_failure \ 405'11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \ 406"rm -f .git/index MM && 407 cp .orig-A/MM MM && 408 git-update-index --add MM && 409 echo extra >>MM && 410 git-read-tree -m$tree_O$tree_A$tree_B" 411 412test_expect_failure \ 413'11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \ 414"rm -f .git/index MM && 415 cp .orig-A/MM MM && 416 echo extra >>MM && 417 git-update-index --add MM && 418 git-read-tree -m$tree_O$tree_A$tree_B" 419 420test_expect_success \ 421'12 - must match A in O && A && B && O!=A && A==B case' \ 422"rm -f .git/index SS && 423 cp .orig-A/SS SS && 424 git-update-index --add SS && 425 git-read-tree -m$tree_O$tree_A$tree_B&& 426 check_result" 427 428test_expect_success \ 429'12 - must match A in O && A && B && O!=A && A==B case' \ 430"rm -f .git/index SS && 431 cp .orig-A/SS SS && 432 git-update-index --add SS && 433 echo extra >>SS && 434 git-read-tree -m$tree_O$tree_A$tree_B&& 435 check_result" 436 437test_expect_failure \ 438'12 (fail) - must match A in O && A && B && O!=A && A==B case' \ 439"rm -f .git/index SS && 440 cp .orig-A/SS SS && 441 echo extra >>SS && 442 git-update-index --add SS && 443 git-read-tree -m$tree_O$tree_A$tree_B" 444 445test_expect_success \ 446'13 - must match A in O && A && B && O!=A && O==B case' \ 447"rm -f .git/index MN && 448 cp .orig-A/MN MN && 449 git-update-index --add MN && 450 git-read-tree -m$tree_O$tree_A$tree_B&& 451 check_result" 452 453test_expect_success \ 454'13 - must match A in O && A && B && O!=A && O==B case' \ 455"rm -f .git/index MN && 456 cp .orig-A/MN MN && 457 git-update-index --add MN && 458 echo extra >>MN && 459 git-read-tree -m$tree_O$tree_A$tree_B&& 460 check_result" 461 462test_expect_success \ 463'14 - must match and be up-to-date in O && A && B && O==A && O!=B case' \ 464"rm -f .git/index NM && 465 cp .orig-A/NM NM && 466 git-update-index --add NM && 467 git-read-tree -m$tree_O$tree_A$tree_B&& 468 check_result" 469 470test_expect_success \ 471'14 - may match B in O && A && B && O==A && O!=B case' \ 472"rm -f .git/index NM && 473 cp .orig-B/NM NM && 474 git-update-index --add NM && 475 echo extra >>NM && 476 git-read-tree -m$tree_O$tree_A$tree_B&& 477 check_result" 478 479test_expect_failure \ 480'14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' \ 481"rm -f .git/index NM && 482 cp .orig-A/NM NM && 483 git-update-index --add NM && 484 echo extra >>NM && 485 git-read-tree -m$tree_O$tree_A$tree_B" 486 487test_expect_failure \ 488'14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' \ 489"rm -f .git/index NM && 490 cp .orig-A/NM NM && 491 echo extra >>NM && 492 git-update-index --add NM && 493 git-read-tree -m$tree_O$tree_A$tree_B" 494 495test_expect_success \ 496'15 - must match A in O && A && B && O==A && O==B case' \ 497"rm -f .git/index NN && 498 cp .orig-A/NN NN && 499 git-update-index --add NN && 500 git-read-tree -m$tree_O$tree_A$tree_B&& 501 check_result" 502 503test_expect_success \ 504'15 - must match A in O && A && B && O==A && O==B case' \ 505"rm -f .git/index NN && 506 cp .orig-A/NN NN && 507 git-update-index --add NN && 508 echo extra >>NN && 509 git-read-tree -m$tree_O$tree_A$tree_B&& 510 check_result" 511 512test_expect_failure \ 513'15 (fail) - must match A in O && A && B && O==A && O==B case' \ 514"rm -f .git/index NN && 515 cp .orig-A/NN NN && 516 echo extra >>NN && 517 git-update-index --add NN && 518 git-read-tree -m$tree_O$tree_A$tree_B" 519 520# #16 521test_expect_success \ 522'16 - A matches in one and B matches in another.' \ 523'rm -f .git/index F16 && 524 echo F16 >F16 && 525 git-update-index --add F16 && 526 tree0=`git-write-tree` && 527 echo E16 >F16 && 528 git-update-index F16 && 529 tree1=`git-write-tree` && 530 git-read-tree -m$tree0$tree1$tree1$tree0&& 531 git-ls-files --stage' 532 533test_done