t / t1000-read-tree-m-3way.shon commit lstat_cache(): print a warning if doing ping-pong between cache types (7734f04)
   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
 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    test_cmp 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
 160case which 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-------------------------------------------------------------------
 167  1  missing missing missing   -           must not exist.
 168 ------------------------------------------------------------------
 169  2  missing missing exists    take B*     must match B, if exists.
 170 ------------------------------------------------------------------
 171  3  missing exists  missing   take A*     must match A, if exists.
 172 ------------------------------------------------------------------
 173  4  missing exists  A!=B      no merge    must match A and be
 174                                           up-to-date, if exists.
 175 ------------------------------------------------------------------
 176  5  missing exists  A==B      take A      must match A, if exists.
 177 ------------------------------------------------------------------
 178  6  exists  missing missing   remove      must not exist.
 179 ------------------------------------------------------------------
 180  7  exists  missing O!=B      no merge    must not exist.
 181 ------------------------------------------------------------------
 182  8  exists  missing O==B      remove      must not exist.
 183 ------------------------------------------------------------------
 184  9  exists  O!=A    missing   no merge    must match A and be
 185                                           up-to-date, if exists.
 186 ------------------------------------------------------------------
 187 10  exists  O==A    missing   no merge    must match A
 188 ------------------------------------------------------------------
 189 11  exists  O!=A    O!=B      no merge    must match A and be
 190                     A!=B                  up-to-date, if exists.
 191 ------------------------------------------------------------------
 192 12  exists  O!=A    O!=B      take A      must match A, if exists.
 193                     A==B
 194 ------------------------------------------------------------------
 195 13  exists  O!=A    O==B      take A      must match A, if exists.
 196 ------------------------------------------------------------------
 197 14  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 ------------------------------------------------------------------
 201 15  exists  O==A    O==B      take B      must match A if exists.
 202 ------------------------------------------------------------------
 203 16  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 case 2 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