515 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			515 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
| #!/bin/sh
 | |
| #
 | |
| # Copyright (c) 2005 Junio C Hamano
 | |
| #
 | |
| 
 | |
| test_description='Three way merge with read-tree -m
 | |
| 
 | |
| This test tries three-way merge with read-tree -m
 | |
| 
 | |
| There is one ancestor (called O for Original) and two branches A
 | |
| and B derived from it.  We want to do a 3-way merge between A and
 | |
| B, using O as the common ancestor.
 | |
| 
 | |
|     merge A O B
 | |
| 
 | |
| Decisions are made by comparing contents of O, A and B pathname
 | |
| by pathname.  The result is determined by the following guiding
 | |
| principle:
 | |
| 
 | |
|  - If only A does something to it and B does not touch it, take
 | |
|    whatever A does.
 | |
| 
 | |
|  - If only B does something to it and A does not touch it, take
 | |
|    whatever B does.
 | |
| 
 | |
|  - If both A and B does something but in the same way, take
 | |
|    whatever they do.
 | |
| 
 | |
|  - If A and B does something but different things, we need a
 | |
|    3-way merge:
 | |
| 
 | |
|    - We cannot do anything about the following cases:
 | |
| 
 | |
|      * O does not have it.  A and B both must be adding to the
 | |
|        same path independently.
 | |
| 
 | |
|      * A deletes it.  B must be modifying.
 | |
| 
 | |
|    - Otherwise, A and B are modifying.  Run 3-way merge.
 | |
| 
 | |
| First, the case matrix.
 | |
| 
 | |
|  - Vertical axis is for A'\''s actions.
 | |
|  - Horizontal axis is for B'\''s actions.
 | |
| 
 | |
| .----------------------------------------------------------------.
 | |
| | A        B | No Action  |   Delete   |   Modify   |    Add     |
 | |
| |------------+------------+------------+------------+------------|
 | |
| | No Action  |            |            |            |            |
 | |
| |            | select O   | delete     | select B   | select B   |
 | |
| |            |            |            |            |            |
 | |
| |------------+------------+------------+------------+------------|
 | |
| | Delete     |            |            | ********** |    can     |
 | |
| |            | delete     | delete     | merge      |    not     |
 | |
| |            |            |            |            |  happen    |
 | |
| |------------+------------+------------+------------+------------|
 | |
| | Modify     |            | ********** | ?????????? |    can     |
 | |
| |            | select A   | merge      | select A=B |    not     |
 | |
| |            |            |            | merge      |  happen    |
 | |
| |------------+------------+------------+------------+------------|
 | |
| | Add        |            |    can     |    can     | ?????????? |
 | |
| |            | select A   |    not     |    not     | select A=B |
 | |
| |            |            |  happen    |  happen    | merge      |
 | |
| .----------------------------------------------------------------.
 | |
| 
 | |
| In addition:
 | |
| 
 | |
|  SS: a special case of MM, where A and B makes the same modification.
 | |
|  LL: a special case of AA, where A and B creates the same file.
 | |
|  TT: a special case of MM, where A and B makes mergeable changes.
 | |
|  DF: a special case, where A makes a directory and B makes a file.
 | |
| 
 | |
| '
 | |
| . ./test-lib.sh
 | |
| . ../lib-read-tree-m-3way.sh
 | |
| 
 | |
| ################################################################
 | |
| # Trivial "majority when 3 stages exist" merge plus #2ALT, #3ALT
 | |
| # and #5ALT trivial merges.
 | |
| 
 | |
| cat >expected <<\EOF
 | |
| 100644 X 2	AA
 | |
| 100644 X 3	AA
 | |
| 100644 X 0	AN
 | |
| 100644 X 1	DD
 | |
| 100644 X 3	DF
 | |
| 100644 X 2	DF/DF
 | |
| 100644 X 1	DM
 | |
| 100644 X 3	DM
 | |
| 100644 X 1	DN
 | |
| 100644 X 3	DN
 | |
| 100644 X 0	LL
 | |
| 100644 X 1	MD
 | |
| 100644 X 2	MD
 | |
| 100644 X 1	MM
 | |
| 100644 X 2	MM
 | |
| 100644 X 3	MM
 | |
| 100644 X 0	MN
 | |
| 100644 X 0	NA
 | |
| 100644 X 1	ND
 | |
| 100644 X 2	ND
 | |
| 100644 X 0	NM
 | |
| 100644 X 0	NN
 | |
| 100644 X 0	SS
 | |
| 100644 X 1	TT
 | |
| 100644 X 2	TT
 | |
| 100644 X 3	TT
 | |
| 100644 X 2	Z/AA
 | |
| 100644 X 3	Z/AA
 | |
| 100644 X 0	Z/AN
 | |
| 100644 X 1	Z/DD
 | |
| 100644 X 1	Z/DM
 | |
| 100644 X 3	Z/DM
 | |
| 100644 X 1	Z/DN
 | |
| 100644 X 3	Z/DN
 | |
| 100644 X 1	Z/MD
 | |
| 100644 X 2	Z/MD
 | |
| 100644 X 1	Z/MM
 | |
| 100644 X 2	Z/MM
 | |
| 100644 X 3	Z/MM
 | |
| 100644 X 0	Z/MN
 | |
| 100644 X 0	Z/NA
 | |
| 100644 X 1	Z/ND
 | |
| 100644 X 2	Z/ND
 | |
| 100644 X 0	Z/NM
 | |
| 100644 X 0	Z/NN
 | |
| EOF
 | |
| 
 | |
| _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
 | |
| _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
 | |
| 
 | |
| check_result () {
 | |
|     git-ls-files --stage | sed -e 's/ '"$_x40"' / X /' >current &&
 | |
|     diff -u expected current
 | |
| }
 | |
| 
 | |
| # This is done on an empty work directory, which is the normal
 | |
| # merge person behaviour.
 | |
| test_expect_success \
 | |
|     '3-way merge with git-read-tree -m, empty cache' \
 | |
|     "rm -fr [NDMALTS][NDMALTSF] Z &&
 | |
|      rm .git/index &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| # This starts out with the first head, which is the normal
 | |
| # patch submitter behaviour.
 | |
| test_expect_success \
 | |
|     '3-way merge with git-read-tree -m, match H' \
 | |
|     "rm -fr [NDMALTS][NDMALTSF] Z &&
 | |
|      rm .git/index &&
 | |
|      git-read-tree $tree_A &&
 | |
|      git-checkout-index -f -u -a &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| : <<\END_OF_CASE_TABLE
 | |
| 
 | |
| We have so far tested only empty index and clean-and-matching-A index
 | |
| case which are trivial.  Make sure index requirements are also
 | |
| checked.
 | |
| 
 | |
| "git-read-tree -m O A B"
 | |
| 
 | |
|      O       A       B         result      index requirements
 | |
| -------------------------------------------------------------------
 | |
|   1  missing missing missing   -           must not exist.
 | |
|  ------------------------------------------------------------------
 | |
|   2  missing missing exists    take B*     must match B, if exists.
 | |
|  ------------------------------------------------------------------
 | |
|   3  missing exists  missing   take A*     must match A, if exists.
 | |
|  ------------------------------------------------------------------
 | |
|   4  missing exists  A!=B      no merge    must match A and be
 | |
|                                            up-to-date, if exists.
 | |
|  ------------------------------------------------------------------
 | |
|   5  missing exists  A==B      take A      must match A, if exists.
 | |
|  ------------------------------------------------------------------
 | |
|   6  exists  missing missing   remove      must not exist.
 | |
|  ------------------------------------------------------------------
 | |
|   7  exists  missing O!=B      no merge    must not exist.
 | |
|  ------------------------------------------------------------------
 | |
|   8  exists  missing O==B      remove      must not exist.
 | |
|  ------------------------------------------------------------------
 | |
|   9  exists  O!=A    missing   no merge    must match A and be
 | |
|                                            up-to-date, if exists.
 | |
|  ------------------------------------------------------------------
 | |
|  10  exists  O==A    missing   remove      ditto
 | |
|  ------------------------------------------------------------------
 | |
|  11  exists  O!=A    O!=B      no merge    must match A and be
 | |
|                      A!=B                  up-to-date, if exists.
 | |
|  ------------------------------------------------------------------
 | |
|  12  exists  O!=A    O!=B      take A      must match A, if exists.
 | |
|                      A==B
 | |
|  ------------------------------------------------------------------
 | |
|  13  exists  O!=A    O==B      take A      must match A, if exists.
 | |
|  ------------------------------------------------------------------
 | |
|  14  exists  O==A    O!=B      take B      if exists, must either (1)
 | |
|                                            match A and be up-to-date,
 | |
|                                            or (2) match B.
 | |
|  ------------------------------------------------------------------
 | |
|  15  exists  O==A    O==B      take B      must match A if exists.
 | |
|  ------------------------------------------------------------------
 | |
|  16  exists  O==A    O==B      barf        must match A if exists.
 | |
|      *multi* in one  in another
 | |
| -------------------------------------------------------------------
 | |
| 
 | |
| Note: we need to be careful in case 2 and 3.  The tree A may contain
 | |
| DF (file) when tree B require DF to be a directory by having DF/DF
 | |
| (file).
 | |
| 
 | |
| END_OF_CASE_TABLE
 | |
| 
 | |
| test_expect_failure \
 | |
|     '1 - must not have an entry not in A.' \
 | |
|     "rm -f .git/index XX &&
 | |
|      echo XX >XX &&
 | |
|      git-update-index --add XX &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_success \
 | |
|     '2 - must match B in !O && !A && B case.' \
 | |
|     "rm -f .git/index NA &&
 | |
|      cp .orig-B/NA NA &&
 | |
|      git-update-index --add NA &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_success \
 | |
|     '2 - matching B alone is OK in !O && !A && B case.' \
 | |
|     "rm -f .git/index NA &&
 | |
|      cp .orig-B/NA NA &&
 | |
|      git-update-index --add NA &&
 | |
|      echo extra >>NA &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_success \
 | |
|     '3 - must match A in !O && A && !B case.' \
 | |
|     "rm -f .git/index AN &&
 | |
|      cp .orig-A/AN AN &&
 | |
|      git-update-index --add AN &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_success \
 | |
|     '3 - matching A alone is OK in !O && A && !B case.' \
 | |
|     "rm -f .git/index AN &&
 | |
|      cp .orig-A/AN AN &&
 | |
|      git-update-index --add AN &&
 | |
|      echo extra >>AN &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '3 (fail) - must match A in !O && A && !B case.' \
 | |
|     "rm -f .git/index AN &&
 | |
|      cp .orig-A/AN AN &&
 | |
|      echo extra >>AN &&
 | |
|      git-update-index --add AN &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_success \
 | |
|     '4 - must match and be up-to-date in !O && A && B && A!=B case.' \
 | |
|     "rm -f .git/index AA &&
 | |
|      cp .orig-A/AA AA &&
 | |
|      git-update-index --add AA &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' \
 | |
|     "rm -f .git/index AA &&
 | |
|      cp .orig-A/AA AA &&
 | |
|      git-update-index --add AA &&
 | |
|      echo extra >>AA &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' \
 | |
|     "rm -f .git/index AA &&
 | |
|      cp .orig-A/AA AA &&
 | |
|      echo extra >>AA &&
 | |
|      git-update-index --add AA &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_success \
 | |
|     '5 - must match in !O && A && B && A==B case.' \
 | |
|     "rm -f .git/index LL &&
 | |
|      cp .orig-A/LL LL &&
 | |
|      git-update-index --add LL &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_success \
 | |
|     '5 - must match in !O && A && B && A==B case.' \
 | |
|     "rm -f .git/index LL &&
 | |
|      cp .orig-A/LL LL &&
 | |
|      git-update-index --add LL &&
 | |
|      echo extra >>LL &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '5 (fail) - must match A in !O && A && B && A==B case.' \
 | |
|     "rm -f .git/index LL &&
 | |
|      cp .orig-A/LL LL &&
 | |
|      echo extra >>LL &&
 | |
|      git-update-index --add LL &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '6 - must not exist in O && !A && !B case' \
 | |
|     "rm -f .git/index DD &&
 | |
|      echo DD >DD
 | |
|      git-update-index --add DD &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '7 - must not exist in O && !A && B && O!=B case' \
 | |
|     "rm -f .git/index DM &&
 | |
|      cp .orig-B/DM DM &&
 | |
|      git-update-index --add DM &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '8 - must not exist in O && !A && B && O==B case' \
 | |
|     "rm -f .git/index DN &&
 | |
|      cp .orig-B/DN DN &&
 | |
|      git-update-index --add DN &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_success \
 | |
|     '9 - must match and be up-to-date in O && A && !B && O!=A case' \
 | |
|     "rm -f .git/index MD &&
 | |
|      cp .orig-A/MD MD &&
 | |
|      git-update-index --add MD &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' \
 | |
|     "rm -f .git/index MD &&
 | |
|      cp .orig-A/MD MD &&
 | |
|      git-update-index --add MD &&
 | |
|      echo extra >>MD &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' \
 | |
|     "rm -f .git/index MD &&
 | |
|      cp .orig-A/MD MD &&
 | |
|      echo extra >>MD &&
 | |
|      git-update-index --add MD &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_success \
 | |
|     '10 - must match and be up-to-date in O && A && !B && O==A case' \
 | |
|     "rm -f .git/index ND &&
 | |
|      cp .orig-A/ND ND &&
 | |
|      git-update-index --add ND &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' \
 | |
|     "rm -f .git/index ND &&
 | |
|      cp .orig-A/ND ND &&
 | |
|      git-update-index --add ND &&
 | |
|      echo extra >>ND &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' \
 | |
|     "rm -f .git/index ND &&
 | |
|      cp .orig-A/ND ND &&
 | |
|      echo extra >>ND &&
 | |
|      git-update-index --add ND &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_success \
 | |
|     '11 - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \
 | |
|     "rm -f .git/index MM &&
 | |
|      cp .orig-A/MM MM &&
 | |
|      git-update-index --add MM &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \
 | |
|     "rm -f .git/index MM &&
 | |
|      cp .orig-A/MM MM &&
 | |
|      git-update-index --add MM &&
 | |
|      echo extra >>MM &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \
 | |
|     "rm -f .git/index MM &&
 | |
|      cp .orig-A/MM MM &&
 | |
|      echo extra >>MM &&
 | |
|      git-update-index --add MM &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_success \
 | |
|     '12 - must match A in O && A && B && O!=A && A==B case' \
 | |
|     "rm -f .git/index SS &&
 | |
|      cp .orig-A/SS SS &&
 | |
|      git-update-index --add SS &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_success \
 | |
|     '12 - must match A in O && A && B && O!=A && A==B case' \
 | |
|     "rm -f .git/index SS &&
 | |
|      cp .orig-A/SS SS &&
 | |
|      git-update-index --add SS &&
 | |
|      echo extra >>SS &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '12 (fail) - must match A in O && A && B && O!=A && A==B case' \
 | |
|     "rm -f .git/index SS &&
 | |
|      cp .orig-A/SS SS &&
 | |
|      echo extra >>SS &&
 | |
|      git-update-index --add SS &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_success \
 | |
|     '13 - must match A in O && A && B && O!=A && O==B case' \
 | |
|     "rm -f .git/index MN &&
 | |
|      cp .orig-A/MN MN &&
 | |
|      git-update-index --add MN &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_success \
 | |
|     '13 - must match A in O && A && B && O!=A && O==B case' \
 | |
|     "rm -f .git/index MN &&
 | |
|      cp .orig-A/MN MN &&
 | |
|      git-update-index --add MN &&
 | |
|      echo extra >>MN &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_success \
 | |
|     '14 - must match and be up-to-date in O && A && B && O==A && O!=B case' \
 | |
|     "rm -f .git/index NM &&
 | |
|      cp .orig-A/NM NM &&
 | |
|      git-update-index --add NM &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_success \
 | |
|     '14 - may match B in O && A && B && O==A && O!=B case' \
 | |
|     "rm -f .git/index NM &&
 | |
|      cp .orig-B/NM NM &&
 | |
|      git-update-index --add NM &&
 | |
|      echo extra >>NM &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' \
 | |
|     "rm -f .git/index NM &&
 | |
|      cp .orig-A/NM NM &&
 | |
|      git-update-index --add NM &&
 | |
|      echo extra >>NM &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' \
 | |
|     "rm -f .git/index NM &&
 | |
|      cp .orig-A/NM NM &&
 | |
|      echo extra >>NM &&
 | |
|      git-update-index --add NM &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| test_expect_success \
 | |
|     '15 - must match A in O && A && B && O==A && O==B case' \
 | |
|     "rm -f .git/index NN &&
 | |
|      cp .orig-A/NN NN &&
 | |
|      git-update-index --add NN &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_success \
 | |
|     '15 - must match A in O && A && B && O==A && O==B case' \
 | |
|     "rm -f .git/index NN &&
 | |
|      cp .orig-A/NN NN &&
 | |
|      git-update-index --add NN &&
 | |
|      echo extra >>NN &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B &&
 | |
|      check_result"
 | |
| 
 | |
| test_expect_failure \
 | |
|     '15 (fail) - must match A in O && A && B && O==A && O==B case' \
 | |
|     "rm -f .git/index NN &&
 | |
|      cp .orig-A/NN NN &&
 | |
|      echo extra >>NN &&
 | |
|      git-update-index --add NN &&
 | |
|      git-read-tree -m $tree_O $tree_A $tree_B"
 | |
| 
 | |
| # #16
 | |
| test_expect_success \
 | |
|     '16 - A matches in one and B matches in another.' \
 | |
|     'rm -f .git/index F16 &&
 | |
|     echo F16 >F16 &&
 | |
|     git-update-index --add F16 &&
 | |
|     tree0=`git-write-tree` &&
 | |
|     echo E16 >F16 &&
 | |
|     git-update-index F16 &&
 | |
|     tree1=`git-write-tree` &&
 | |
|     git-read-tree -m $tree0 $tree1 $tree1 $tree0 &&
 | |
|     git-ls-files --stage'
 | |
| 
 | |
| test_done
 |