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 75. ./test-lib.sh 76 77# Original tree. 78mkdir Z 79for a in N D M 80do 81for b in N D M 82do 83 p=$a$b 84echo This is $p from the original tree. >$p 85echo This is Z/$p from the original tree. >Z/$p 86 test_expect_success \ 87"adding test file$pand Z/$p" \ 88'git-update-cache --add$p&& 89 git-update-cache --add Z/$p' 90done 91done 92echo This is SS from the original tree. >SS 93test_expect_success \ 94'adding test file SS' \ 95'git-update-cache --add SS' 96cat>TT <<\EOF 97This is a trivial merge sample text. 98Branch A is expected to upcase this word, here. 99There are some filler lines to avoid diff context 100conflicts here, 101like this one, 102and this one, 103and this one is yet another one of them. 104At the very end, here comes another line, that is 105the word, expected to be upcased by Branch B. 106This concludes the trivial merge sample file. 107EOF 108test_expect_success \ 109'adding test file TT' \ 110'git-update-cache --add TT' 111test_expect_success \ 112'prepare initial tree' \ 113'tree_O=$(git-write-tree)' 114 115test_expect_success \ 116'commit initial tree' \ 117'commit_O=$(echo "Original tree for the merge test." | 118 git-commit-tree$tree_O)' 119echo$commit_O>.git/HEAD-O 120 121################################################################ 122# Branch A and B makes the changes according to the above matrix. 123 124################################################################ 125# Branch A 126 127to_remove=$(echo D? Z/D?) 128rm-f$to_remove 129test_expect_success \ 130'change in branch A (removal)' \ 131'git-update-cache --remove$to_remove' 132 133for p in M? Z/M? 134do 135echo This is modified $pin the branch A. >$p 136 test_expect_success \ 137'change in branch A (modification)' \ 138"git-update-cache$p" 139done 140 141for p in AN AA Z/AN Z/AA 142do 143echo This is added $pin the branch A. >$p 144 test_expect_success \ 145'change in branch A (addition)' \ 146"git-update-cache --add$p" 147done 148 149echo This is SS from the modified tree. >SS 150echo This is LL from the modified tree. >LL 151test_expect_success \ 152'change in branch A (addition)' \ 153'git-update-cache --add LL && 154 git-update-cache SS' 155mv TT TT- 156sed-e'/Branch A/s/word/WORD/g'<TT- >TT 157rm-f TT- 158test_expect_success \ 159'change in branch A (edit)' \ 160'git-update-cache TT' 161 162mkdir DF 163echo Branch A makes a file at DF/DF, creating a directory DF. >DF/DF 164test_expect_success \ 165'change in branch A (change file to directory)' \ 166'git-update-cache --add DF/DF' 167 168test_expect_success \ 169'recording branch A tree' \ 170'tree_A=$(git-write-tree)' 171test_expect_success \ 172'committing branch A changes' \ 173'commit_A=$(echo "Branch A for the merge test." | 174 git-commit-tree$tree_A-p$commit_O)' 175echo$commit_A>.git/HEAD-A 176 177################################################################ 178# Branch B 179# Start from O 180 181rm-rf[NDMASLT][NDMASLT] Z DF 182mkdir Z 183test_expect_success \ 184'reading original tree and checking out' \ 185'git-read-tree$tree_O&& 186 git-checkout-cache -a' 187 188to_remove=$(echo ?D Z/?D) 189rm-f$to_remove 190test_expect_success \ 191'change in branch B (removal)' \ 192"git-update-cache --remove$to_remove" 193 194for p in ?M Z/?M 195do 196echo This is modified $pin the branch B. >$p 197 test_expect_success \ 198'change in branch B (modification)' \ 199"git-update-cache$p" 200done 201 202for p in NA AA Z/NA Z/AA 203do 204echo This is added $pin the branch B. >$p 205 test_expect_success \ 206'change in branch B (addition)' \ 207"git-update-cache --add$p" 208done 209echo This is SS from the modified tree. >SS 210echo This is LL from the modified tree. >LL 211test_expect_success \ 212'change in branch B (addition and modification)' \ 213'git-update-cache --add LL && 214 git-update-cache SS' 215mv TT TT- 216sed-e'/Branch B/s/word/WORD/g'<TT- >TT 217rm-f TT- 218test_expect_success \ 219'change in branch B (modification)' \ 220'git-update-cache TT' 221 222echo Branch B makes a file at DF. >DF 223test_expect_success \ 224'change in branch B (addition of a file to conflict with directory)' \ 225'git-update-cache --add DF' 226 227test_expect_success \ 228'recording branch B tree' \ 229'tree_B=$(git-write-tree)' 230test_expect_success \ 231'committing branch B changes' \ 232'commit_B=$(echo "Branch B for the merge test." | 233 git-commit-tree$tree_B-p$commit_O)' 234echo$commit_B>.git/HEAD-B 235 236################################################################ 237# Done preparation. 238 239test_debug ' 240 for T in O A B 241 do 242 echo "#$T$(eval git-cat-file commit \$commit_$T | sed -e 1q)" 243 done 244' 245 246################################################################ 247# Try merging and showing the various diffs 248 249test_expect_success \ 250'3-way merge with git-read-tree -m' \ 251"git-read-tree -m$tree_O$tree_A$tree_B" 252 253strip_object_id='s/^\([0-7]*\) [0-9a-f]* \([0-3].*\)$/\1 \2/' 254 255test_expect_success \ 256'git-ls-files --stage of the merge result' \ 257'git-ls-files --stage >current- && 258 sed -e "$strip_object_id" <current- >current' 259 260cat>expected <<\EOF 261100644 2 AA 262100644 3 AA 263100644 2 AN 264100644 1 DD 265100644 3 DF 266100644 2 DF/DF 267100644 1 DM 268100644 3 DM 269100644 1 DN 270100644 3 DN 271100644 2 LL 272100644 3 LL 273100644 1 MD 274100644 2 MD 275100644 1 MM 276100644 2 MM 277100644 3 MM 278100644 0 MN 279100644 3 NA 280100644 1 ND 281100644 2 ND 282100644 0 NM 283100644 0 NN 284100644 0 SS 285100644 1 TT 286100644 2 TT 287100644 3 TT 288100644 2 Z/AA 289100644 3 Z/AA 290100644 2 Z/AN 291100644 1 Z/DD 292100644 1 Z/DM 293100644 3 Z/DM 294100644 1 Z/DN 295100644 3 Z/DN 296100644 1 Z/MD 297100644 2 Z/MD 298100644 1 Z/MM 299100644 2 Z/MM 300100644 3 Z/MM 301100644 0 Z/MN 302100644 3 Z/NA 303100644 1 Z/ND 304100644 2 Z/ND 305100644 0 Z/NM 306100644 0 Z/NN 307EOF 308 309test_expect_success \ 310'validate merge result' \ 311'diff current expected' 312 313test_done