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-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 129check_result () { 130 git ls-files --stage|sed-e's/ '"$_x40"' / X /'>current && 131 test_cmp expected current 132} 133 134# This is done on an empty work directory, which is the normal 135# merge person behaviour. 136test_expect_success \ 137'3-way merge with git read-tree -m, empty cache' \ 138"rm -fr [NDMALTS][NDMALTSF] Z && 139 rm .git/index && 140 git read-tree -m$tree_O$tree_A$tree_B&& 141 check_result" 142 143# This starts out with the first head, which is the normal 144# patch submitter behaviour. 145test_expect_success \ 146'3-way merge with git read-tree -m, match H' \ 147"rm -fr [NDMALTS][NDMALTSF] Z && 148 rm .git/index && 149 git read-tree$tree_A&& 150 git checkout-index -f -u -a && 151 git read-tree -m$tree_O$tree_A$tree_B&& 152 check_result" 153 154: <<\END_OF_CASE_TABLE 155 156We have so far tested only empty index and clean-and-matching-A index 157casewhich are trivial. Make sure index requirements are also 158checked. 159 160"git read-tree -m O A B" 161 162 O A B result index requirements 163------------------------------------------------------------------- 1641 missing missing missing - must not exist. 165------------------------------------------------------------------ 1662 missing missing exists take B* must match B,if exists. 167------------------------------------------------------------------ 1683 missing exists missing take A* must match A,if exists. 169------------------------------------------------------------------ 1704 missing exists A!=B no merge must match A and be 171 up-to-date,if exists. 172------------------------------------------------------------------ 1735 missing exists A==B take A must match A,if exists. 174------------------------------------------------------------------ 1756 exists missing missing remove must not exist. 176------------------------------------------------------------------ 1777 exists missing O!=B no merge must not exist. 178------------------------------------------------------------------ 1798 exists missing O==B remove must not exist. 180------------------------------------------------------------------ 1819 exists O!=A missing no merge must match A and be 182 up-to-date,if exists. 183------------------------------------------------------------------ 18410 exists O==A missing no merge must match A 185------------------------------------------------------------------ 18611 exists O!=A O!=B no merge must match A and be 187 A!=B up-to-date,if exists. 188------------------------------------------------------------------ 18912 exists O!=A O!=B take A must match A,if exists. 190 A==B 191------------------------------------------------------------------ 19213 exists O!=A O==B take A must match A,if exists. 193------------------------------------------------------------------ 19414 exists O==A O!=B take B if exists, must either (1) 195 match A and be up-to-date, 196 or (2) match B. 197------------------------------------------------------------------ 19815 exists O==A O==B take B must match A if exists. 199------------------------------------------------------------------ 20016 exists O==A O==B barf must match A if exists. 201*multi*in one in another 202------------------------------------------------------------------- 203 204Note: we need to be careful in case2 and 3. The tree A may contain 205DF (file) when tree B require DF to be a directory by having DF/DF 206(file). 207 208END_OF_CASE_TABLE 209 210test_expect_success '1 - must not have an entry not in A.'" 211 rm -f .git/index XX && 212 echo XX >XX && 213 git update-index --add XX && 214 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 215" 216 217test_expect_success \ 218'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 git read-tree -m$tree_O$tree_A$tree_B" 223 224test_expect_success \ 225'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 git read-tree -m$tree_O$tree_A$tree_B" 231 232test_expect_success \ 233'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 git read-tree -m$tree_O$tree_A$tree_B&& 238 check_result" 239 240test_expect_success \ 241'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 git read-tree -m$tree_O$tree_A$tree_B" 247 248test_expect_success \ 249'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 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 255" 256 257test_expect_success \ 258'4 - must match and be up-to-date in !O && A && B && A!=B case.' \ 259"rm -f .git/index AA && 260 cp .orig-A/AA AA && 261 git update-index --add AA && 262 git read-tree -m$tree_O$tree_A$tree_B&& 263 check_result" 264 265test_expect_success \ 266'4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.'" 267 rm -f .git/index AA && 268 cp .orig-A/AA AA && 269 git update-index --add AA && 270 echo extra >>AA && 271 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 272" 273 274test_expect_success \ 275'4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.'" 276 rm -f .git/index AA && 277 cp .orig-A/AA AA && 278 echo extra >>AA && 279 git update-index --add AA && 280 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 281" 282 283test_expect_success \ 284'5 - must match in !O && A && B && A==B case.' \ 285"rm -f .git/index LL && 286 cp .orig-A/LL LL && 287 git update-index --add LL && 288 git read-tree -m$tree_O$tree_A$tree_B&& 289 check_result" 290 291test_expect_success \ 292'5 - must match in !O && A && B && A==B case.' \ 293"rm -f .git/index LL && 294 cp .orig-A/LL LL && 295 git update-index --add LL && 296 echo extra >>LL && 297 git read-tree -m$tree_O$tree_A$tree_B&& 298 check_result" 299 300test_expect_success \ 301'5 (fail) - must match A in !O && A && B && A==B case.'" 302 rm -f .git/index LL && 303 cp .orig-A/LL LL && 304 echo extra >>LL && 305 git update-index --add LL && 306 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 307" 308 309test_expect_success \ 310'6 - must not exist in O && !A && !B case'" 311 rm -f .git/index DD && 312 echo DD >DD && 313 git update-index --add DD && 314 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 315" 316 317test_expect_success \ 318'7 - must not exist in O && !A && B && O!=B case'" 319 rm -f .git/index DM && 320 cp .orig-B/DM DM && 321 git update-index --add DM && 322 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 323" 324 325test_expect_success \ 326'8 - must not exist in O && !A && B && O==B case'" 327 rm -f .git/index DN && 328 cp .orig-B/DN DN && 329 git update-index --add DN && 330 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 331" 332 333test_expect_success \ 334'9 - must match and be up-to-date in O && A && !B && O!=A case' \ 335"rm -f .git/index MD && 336 cp .orig-A/MD MD && 337 git update-index --add MD && 338 git read-tree -m$tree_O$tree_A$tree_B&& 339 check_result" 340 341test_expect_success \ 342'9 (fail) - must match and be up-to-date in O && A && !B && O!=A case'" 343 rm -f .git/index MD && 344 cp .orig-A/MD MD && 345 git update-index --add MD && 346 echo extra >>MD && 347 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 348" 349 350test_expect_success \ 351'9 (fail) - must match and be up-to-date in O && A && !B && O!=A case'" 352 rm -f .git/index MD && 353 cp .orig-A/MD MD && 354 echo extra >>MD && 355 git update-index --add MD && 356 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 357" 358 359test_expect_success \ 360'10 - must match and be up-to-date in O && A && !B && O==A case' \ 361"rm -f .git/index ND && 362 cp .orig-A/ND ND && 363 git update-index --add ND && 364 git read-tree -m$tree_O$tree_A$tree_B&& 365 check_result" 366 367test_expect_success \ 368'10 (fail) - must match and be up-to-date in O && A && !B && O==A case'" 369 rm -f .git/index ND && 370 cp .orig-A/ND ND && 371 git update-index --add ND && 372 echo extra >>ND && 373 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 374" 375 376test_expect_success \ 377'10 (fail) - must match and be up-to-date in O && A && !B && O==A case'" 378 rm -f .git/index ND && 379 cp .orig-A/ND ND && 380 echo extra >>ND && 381 git update-index --add ND && 382 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 383" 384 385test_expect_success \ 386'11 - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \ 387"rm -f .git/index MM && 388 cp .orig-A/MM MM && 389 git update-index --add MM && 390 git read-tree -m$tree_O$tree_A$tree_B&& 391 check_result" 392 393test_expect_success \ 394'11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case'" 395 rm -f .git/index MM && 396 cp .orig-A/MM MM && 397 git update-index --add MM && 398 echo extra >>MM && 399 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 400" 401 402test_expect_success \ 403'11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case'" 404 rm -f .git/index MM && 405 cp .orig-A/MM MM && 406 echo extra >>MM && 407 git update-index --add MM && 408 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 409" 410 411test_expect_success \ 412'12 - must match A in O && A && B && O!=A && A==B case' \ 413"rm -f .git/index SS && 414 cp .orig-A/SS SS && 415 git update-index --add SS && 416 git read-tree -m$tree_O$tree_A$tree_B&& 417 check_result" 418 419test_expect_success \ 420'12 - must match A in O && A && B && O!=A && A==B case' \ 421"rm -f .git/index SS && 422 cp .orig-A/SS SS && 423 git update-index --add SS && 424 echo extra >>SS && 425 git read-tree -m$tree_O$tree_A$tree_B&& 426 check_result" 427 428test_expect_success \ 429'12 (fail) - 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 echo extra >>SS && 433 git update-index --add SS && 434 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 435" 436 437test_expect_success \ 438'13 - must match A in O && A && B && O!=A && O==B case' \ 439"rm -f .git/index MN && 440 cp .orig-A/MN MN && 441 git update-index --add MN && 442 git read-tree -m$tree_O$tree_A$tree_B&& 443 check_result" 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 echo extra >>MN && 451 git read-tree -m$tree_O$tree_A$tree_B&& 452 check_result" 453 454test_expect_success \ 455'14 - must match and be up-to-date in O && A && B && O==A && O!=B case' \ 456"rm -f .git/index NM && 457 cp .orig-A/NM NM && 458 git update-index --add NM && 459 git read-tree -m$tree_O$tree_A$tree_B&& 460 check_result" 461 462test_expect_success \ 463'14 - may match B in O && A && B && O==A && O!=B case' \ 464"rm -f .git/index NM && 465 cp .orig-B/NM NM && 466 git update-index --add NM && 467 echo extra >>NM && 468 git read-tree -m$tree_O$tree_A$tree_B&& 469 check_result" 470 471test_expect_success \ 472'14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case'" 473 rm -f .git/index NM && 474 cp .orig-A/NM NM && 475 git update-index --add NM && 476 echo extra >>NM && 477 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 478" 479 480test_expect_success \ 481'14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case'" 482 rm -f .git/index NM && 483 cp .orig-A/NM NM && 484 echo extra >>NM && 485 git update-index --add NM && 486 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 487" 488 489test_expect_success \ 490'15 - must match A in O && A && B && O==A && O==B case' \ 491"rm -f .git/index NN && 492 cp .orig-A/NN NN && 493 git update-index --add NN && 494 git read-tree -m$tree_O$tree_A$tree_B&& 495 check_result" 496 497test_expect_success \ 498'15 - must match A in O && A && B && O==A && O==B case' \ 499"rm -f .git/index NN && 500 cp .orig-A/NN NN && 501 git update-index --add NN && 502 echo extra >>NN && 503 git read-tree -m$tree_O$tree_A$tree_B&& 504 check_result" 505 506test_expect_success \ 507'15 (fail) - must match A in O && A && B && O==A && O==B case'" 508 rm -f .git/index NN && 509 cp .orig-A/NN NN && 510 echo extra >>NN && 511 git update-index --add NN && 512 test_must_fail git read-tree -m$tree_O$tree_A$tree_B 513" 514 515# #16 516test_expect_success \ 517'16 - A matches in one and B matches in another.' \ 518'rm -f .git/index F16 && 519 echo F16 >F16 && 520 git update-index --add F16 && 521 tree0=`git write-tree` && 522 echo E16 >F16 && 523 git update-index F16 && 524 tree1=`git write-tree` && 525 git read-tree -m$tree0$tree1$tree1$tree0&& 526 git ls-files --stage' 527 528test_done