t / t1000-read-tree-m-3way.shon commit rerere: fix overeager gc (7d7ff15)
   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
 157case which 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-------------------------------------------------------------------
 164  1  missing missing missing   -           must not exist.
 165 ------------------------------------------------------------------
 166  2  missing missing exists    take B*     must match B, if exists.
 167 ------------------------------------------------------------------
 168  3  missing exists  missing   take A*     must match A, if exists.
 169 ------------------------------------------------------------------
 170  4  missing exists  A!=B      no merge    must match A and be
 171                                           up-to-date, if exists.
 172 ------------------------------------------------------------------
 173  5  missing exists  A==B      take A      must match A, if exists.
 174 ------------------------------------------------------------------
 175  6  exists  missing missing   remove      must not exist.
 176 ------------------------------------------------------------------
 177  7  exists  missing O!=B      no merge    must not exist.
 178 ------------------------------------------------------------------
 179  8  exists  missing O==B      remove      must not exist.
 180 ------------------------------------------------------------------
 181  9  exists  O!=A    missing   no merge    must match A and be
 182                                           up-to-date, if exists.
 183 ------------------------------------------------------------------
 184 10  exists  O==A    missing   no merge    must match A
 185 ------------------------------------------------------------------
 186 11  exists  O!=A    O!=B      no merge    must match A and be
 187                     A!=B                  up-to-date, if exists.
 188 ------------------------------------------------------------------
 189 12  exists  O!=A    O!=B      take A      must match A, if exists.
 190                     A==B
 191 ------------------------------------------------------------------
 192 13  exists  O!=A    O==B      take A      must match A, if exists.
 193 ------------------------------------------------------------------
 194 14  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 ------------------------------------------------------------------
 198 15  exists  O==A    O==B      take B      must match A if exists.
 199 ------------------------------------------------------------------
 200 16  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 case 2 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