t / t1000-read-tree-m-3way.shon commit Merge my and Petr's git-merge-one-file-script modifications (566487c)
   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# This is the "no trivial merge unless all three exists" table.
  79
  80cat >expected <<\EOF
  81100644 X 2      AA
  82100644 X 3      AA
  83100644 X 2      AN
  84100644 X 1      DD
  85100644 X 3      DF
  86100644 X 2      DF/DF
  87100644 X 1      DM
  88100644 X 3      DM
  89100644 X 1      DN
  90100644 X 3      DN
  91100644 X 2      LL
  92100644 X 3      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 3      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 2      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 3      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    diff -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-cache -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.  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-------------------------------------------------------------------
 168  1  missing missing missing   -           must not exist.
 169 ------------------------------------------------------------------
 170  2  missing missing exists    no merge    must not exist.
 171                               ------------------------------------
 172    (ALT)                      take B*     must match B, if exists.
 173 ------------------------------------------------------------------
 174  3  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 ------------------------------------------------------------------
 179  4  missing exists  A!=B      no merge    must match A and be
 180                                           up-to-date, if exists.
 181 ------------------------------------------------------------------
 182  5  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 ------------------------------------------------------------------
 187  6  exists  missing missing   no merge    must not exist.
 188                               ------------------------------------
 189    (ALT)                      remove      must not exist.
 190 ------------------------------------------------------------------
 191  7  exists  missing O!=B      no merge    must not exist.
 192 ------------------------------------------------------------------
 193  8  exists  missing O==B      no merge    must not exist.
 194                               ------------------------------------
 195    (ALT)                      remove      must not exist.
 196 ------------------------------------------------------------------
 197  9  exists  O!=A    missing   no merge    must match A and be
 198                                           up-to-date, if exists.
 199 ------------------------------------------------------------------
 200 10  exists  O==A    missing   no merge    must match A and be
 201                                           up-to-date, if exists.
 202                               ------------------------------------
 203    (ALT)                      remove      ditto
 204 ------------------------------------------------------------------
 205 11  exists  O!=A    O!=B      no merge    must match A and be
 206                     A!=B                  up-to-date, if exists.
 207 ------------------------------------------------------------------
 208 12  exists  O!=A    O!=B      take A      must match A, if exists.
 209                     A==B
 210 ------------------------------------------------------------------
 211 13  exists  O!=A    O==B      take A      must match A, if exists.
 212 ------------------------------------------------------------------
 213 14  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 ------------------------------------------------------------------
 220 15  exists  O==A    O==B      take B      must match A if exists.
 221-------------------------------------------------------------------
 222
 223Note: if we want to implement 2ALT and 3ALT we need to be careful.
 224The tree A may contain DF (file) when tree B require DF to be a
 225directory by having DF/DF (file).
 226
 227END_OF_CASE_TABLE
 228
 229test_expect_failure \
 230    '1 - must not have an entry not in A.' \
 231    "rm -f .git/index XX &&
 232     echo XX >XX &&
 233     git-update-cache --add XX &&
 234     git-read-tree -m $tree_O $tree_A $tree_B"
 235
 236test_expect_failure \
 237    '2 - must not have an entry not in A.' \
 238    "rm -f .git/index NA &&
 239     cp .orig-B/NA NA &&
 240     git-update-cache --add NA &&
 241     git-read-tree -m $tree_O $tree_A $tree_B"
 242
 243test_expect_success \
 244    '3 - must match and be up-to-date in !O && A && !B case.' \
 245    "rm -f .git/index AN &&
 246     cp .orig-A/AN AN &&
 247     git-update-cache --add AN &&
 248     git-read-tree -m $tree_O $tree_A $tree_B &&
 249     check_result"
 250
 251test_expect_failure \
 252    '3 (fail) - must match and be up-to-date in !O && A && !B case.' \
 253    "rm -f .git/index AN &&
 254     cp .orig-A/AN AN &&
 255     git-update-cache --add AN &&
 256     echo extra >>AN &&
 257     git-read-tree -m $tree_O $tree_A $tree_B"
 258
 259test_expect_failure \
 260    '3 (fail) - must match and be up-to-date in !O && A && !B case.' \
 261    "rm -f .git/index AN &&
 262     cp .orig-A/AN AN &&
 263     echo extra >>AN &&
 264     git-update-cache --add AN &&
 265     git-read-tree -m $tree_O $tree_A $tree_B"
 266
 267test_expect_success \
 268    '4 - must match and be up-to-date in !O && A && B && A!=B case.' \
 269    "rm -f .git/index AA &&
 270     cp .orig-A/AA AA &&
 271     git-update-cache --add AA &&
 272     git-read-tree -m $tree_O $tree_A $tree_B &&
 273     check_result"
 274
 275test_expect_failure \
 276    '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' \
 277    "rm -f .git/index AA &&
 278     cp .orig-A/AA AA &&
 279     git-update-cache --add AA &&
 280     echo extra >>AA &&
 281     git-read-tree -m $tree_O $tree_A $tree_B"
 282
 283test_expect_failure \
 284    '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' \
 285    "rm -f .git/index AA &&
 286     cp .orig-A/AA AA &&
 287     echo extra >>AA &&
 288     git-update-cache --add AA &&
 289     git-read-tree -m $tree_O $tree_A $tree_B"
 290
 291test_expect_success \
 292    '5 - must match and be up-to-date in !O && A && B && A==B case.' \
 293    "rm -f .git/index LL &&
 294     cp .orig-A/LL LL &&
 295     git-update-cache --add LL &&
 296     git-read-tree -m $tree_O $tree_A $tree_B &&
 297     check_result"
 298
 299test_expect_failure \
 300    '5 (fail) - must match and be up-to-date in !O && A && B && A==B case.' \
 301    "rm -f .git/index LL &&
 302     cp .orig-A/LL LL &&
 303     git-update-cache --add LL &&
 304     echo extra >>LL &&
 305     git-read-tree -m $tree_O $tree_A $tree_B"
 306
 307test_expect_failure \
 308    '5 (fail) - must match and be up-to-date in !O && A && B && A==B case.' \
 309    "rm -f .git/index LL &&
 310     cp .orig-A/LL LL &&
 311     echo extra >>LL &&
 312     git-update-cache --add LL &&
 313     git-read-tree -m $tree_O $tree_A $tree_B"
 314
 315test_expect_failure \
 316    '6 - must not exist in O && !A && !B case' \
 317    "rm -f .git/index DD &&
 318     echo DD >DD
 319     git-update-cache --add DD &&
 320     git-read-tree -m $tree_O $tree_A $tree_B"
 321
 322test_expect_failure \
 323    '7 - must not exist in O && !A && B && O!=B case' \
 324    "rm -f .git/index DM &&
 325     cp .orig-B/DM DM &&
 326     git-update-cache --add DM &&
 327     git-read-tree -m $tree_O $tree_A $tree_B"
 328
 329test_expect_failure \
 330    '8 - must not exist in O && !A && B && O==B case' \
 331    "rm -f .git/index DN &&
 332     cp .orig-B/DN DN &&
 333     git-update-cache --add DN &&
 334     git-read-tree -m $tree_O $tree_A $tree_B"
 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-cache --add MD &&
 341     git-read-tree -m $tree_O $tree_A $tree_B &&
 342     check_result"
 343
 344test_expect_failure \
 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-cache --add MD &&
 349     echo extra >>MD &&
 350     git-read-tree -m $tree_O $tree_A $tree_B"
 351
 352test_expect_failure \
 353    '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' \
 354    "rm -f .git/index MD &&
 355     cp .orig-A/MD MD &&
 356     echo extra >>MD &&
 357     git-update-cache --add MD &&
 358     git-read-tree -m $tree_O $tree_A $tree_B"
 359
 360test_expect_success \
 361    '10 - must match and be up-to-date in O && A && !B && O==A case' \
 362    "rm -f .git/index ND &&
 363     cp .orig-A/ND ND &&
 364     git-update-cache --add ND &&
 365     git-read-tree -m $tree_O $tree_A $tree_B &&
 366     check_result"
 367
 368test_expect_failure \
 369    '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' \
 370    "rm -f .git/index ND &&
 371     cp .orig-A/ND ND &&
 372     git-update-cache --add ND &&
 373     echo extra >>ND &&
 374     git-read-tree -m $tree_O $tree_A $tree_B"
 375
 376test_expect_failure \
 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-cache --add ND &&
 382     git-read-tree -m $tree_O $tree_A $tree_B"
 383
 384test_expect_success \
 385    '11 - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \
 386    "rm -f .git/index MM &&
 387     cp .orig-A/MM MM &&
 388     git-update-cache --add MM &&
 389     git-read-tree -m $tree_O $tree_A $tree_B &&
 390     check_result"
 391
 392test_expect_failure \
 393    '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \
 394    "rm -f .git/index MM &&
 395     cp .orig-A/MM MM &&
 396     git-update-cache --add MM &&
 397     echo extra >>MM &&
 398     git-read-tree -m $tree_O $tree_A $tree_B"
 399
 400test_expect_failure \
 401    '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \
 402    "rm -f .git/index MM &&
 403     cp .orig-A/MM MM &&
 404     echo extra >>MM &&
 405     git-update-cache --add MM &&
 406     git-read-tree -m $tree_O $tree_A $tree_B"
 407
 408test_expect_success \
 409    '12 - must match A in O && A && B && O!=A && A==B case' \
 410    "rm -f .git/index SS &&
 411     cp .orig-A/SS SS &&
 412     git-update-cache --add SS &&
 413     git-read-tree -m $tree_O $tree_A $tree_B &&
 414     check_result"
 415
 416test_expect_success \
 417    '12 - must match A in O && A && B && O!=A && A==B case' \
 418    "rm -f .git/index SS &&
 419     cp .orig-A/SS SS &&
 420     git-update-cache --add SS &&
 421     echo extra >>SS &&
 422     git-read-tree -m $tree_O $tree_A $tree_B &&
 423     check_result"
 424
 425test_expect_failure \
 426    '12 (fail) - must match A in O && A && B && O!=A && A==B case' \
 427    "rm -f .git/index SS &&
 428     cp .orig-A/SS SS &&
 429     echo extra >>SS &&
 430     git-update-cache --add SS &&
 431     git-read-tree -m $tree_O $tree_A $tree_B"
 432
 433test_expect_success \
 434    '13 - must match A in O && A && B && O!=A && O==B case' \
 435    "rm -f .git/index MN &&
 436     cp .orig-A/MN MN &&
 437     git-update-cache --add MN &&
 438     git-read-tree -m $tree_O $tree_A $tree_B &&
 439     check_result"
 440
 441test_expect_success \
 442    '13 - must match A in O && A && B && O!=A && O==B case' \
 443    "rm -f .git/index MN &&
 444     cp .orig-A/MN MN &&
 445     git-update-cache --add MN &&
 446     echo extra >>MN &&
 447     git-read-tree -m $tree_O $tree_A $tree_B &&
 448     check_result"
 449
 450test_expect_success \
 451    '14 - must match and be up-to-date in O && A && B && O==A && O!=B case' \
 452    "rm -f .git/index NM &&
 453     cp .orig-A/NM NM &&
 454     git-update-cache --add NM &&
 455     git-read-tree -m $tree_O $tree_A $tree_B &&
 456     check_result"
 457
 458test_expect_failure \
 459    '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' \
 460    "rm -f .git/index NM &&
 461     cp .orig-A/NM NM &&
 462     git-update-cache --add NM &&
 463     echo extra >>NM &&
 464     git-read-tree -m $tree_O $tree_A $tree_B"
 465
 466test_expect_failure \
 467    '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' \
 468    "rm -f .git/index NM &&
 469     cp .orig-A/NM NM &&
 470     echo extra >>NM &&
 471     git-update-cache --add NM &&
 472     git-read-tree -m $tree_O $tree_A $tree_B"
 473
 474test_expect_success \
 475    '15 - must match A in O && A && B && O==A && O==B case' \
 476    "rm -f .git/index NN &&
 477     cp .orig-A/NN NN &&
 478     git-update-cache --add NN &&
 479     git-read-tree -m $tree_O $tree_A $tree_B &&
 480     check_result"
 481
 482test_expect_success \
 483    '15 - must match A in O && A && B && O==A && O==B case' \
 484    "rm -f .git/index NN &&
 485     cp .orig-A/NN NN &&
 486     git-update-cache --add NN &&
 487     echo extra >>NN &&
 488     git-read-tree -m $tree_O $tree_A $tree_B &&
 489     check_result"
 490
 491test_expect_failure \
 492    '15 (fail) - must match A in O && A && B && O==A && O==B case' \
 493    "rm -f .git/index NN &&
 494     cp .orig-A/NN NN &&
 495     echo extra >>NN &&
 496     git-update-cache --add NN &&
 497     git-read-tree -m $tree_O $tree_A $tree_B"
 498
 499test_done