3 # Copyright (c) 2005 Junio C Hamano
6 test_description='Three way merge with read-tree -m
8 This test tries three-way merge with read-tree -m
10 There is one ancestor (called O for Original) and two branches A
11 and B derived from it. We want to do a 3-way merge between A and
12 B, using O as the common ancestor.
16 Decisions are made by comparing contents of O, A and B pathname
17 by pathname. The result is determined by the following guiding
20 - If only A does something to it and B does not touch it, take
23 - If only B does something to it and A does not touch it, take
26 - If both A and B does something but in the same way, take
29 - If A and B does something but different things, we need a
32 - We cannot do anything about the following cases:
34 * O does not have it. A and B both must be adding to the
35 same path independently.
37 * A deletes it. B must be modifying.
39 - Otherwise, A and B are modifying. Run 3-way merge.
41 First, the case matrix.
43 - Vertical axis is for A'\''s actions.
44 - Horizontal axis is for B'\''s actions.
46 .----------------------------------------------------------------.
47 | A B | No Action | Delete | Modify | Add |
48 |------------+------------+------------+------------+------------|
50 | | select O | delete | select B | select B |
52 |------------+------------+------------+------------+------------|
53 | Delete | | | ********** | can |
54 | | delete | delete | merge | not |
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 .----------------------------------------------------------------.
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.
84 echo This is $p from the original tree. >$p
85 echo This is Z/$p from the original tree. >Z/$p
87 "adding test file $p and Z/$p" \
88 'git-update-cache --add $p &&
89 git-update-cache --add Z/$p'
92 echo This is SS from the original tree. >SS
94 'adding test file SS' \
95 'git-update-cache --add SS'
97 This is a trivial merge sample text.
98 Branch A is expected to upcase this word, here.
99 There are some filler lines to avoid diff context
103 and this one is yet another one of them.
104 At the very end, here comes another line, that is
105 the word, expected to be upcased by Branch B.
106 This concludes the trivial merge sample file.
108 test_expect_success \
109 'adding test file TT' \
110 'git-update-cache --add TT'
111 test_expect_success \
112 'prepare initial tree' \
113 'tree_O=$(git-write-tree)'
115 test_expect_success \
116 'commit initial tree' \
117 'commit_O=$(echo "Original tree for the merge test." |
118 git-commit-tree $tree_O)'
119 echo $commit_O >.git/HEAD-O
121 ################################################################
122 # Branch A and B makes the changes according to the above matrix.
124 ################################################################
127 to_remove=$(echo D? Z/D?)
129 test_expect_success \
130 'change in branch A (removal)' \
131 'git-update-cache --remove $to_remove'
135 echo This is modified $p in the branch A. >$p
136 test_expect_success \
137 'change in branch A (modification)' \
138 "git-update-cache $p"
141 for p in AN AA Z/AN Z/AA
143 echo This is added $p in the branch A. >$p
144 test_expect_success \
145 'change in branch A (addition)' \
146 "git-update-cache --add $p"
149 echo This is SS from the modified tree. >SS
150 echo This is LL from the modified tree. >LL
151 test_expect_success \
152 'change in branch A (addition)' \
153 'git-update-cache --add LL &&
156 sed -e '/Branch A/s/word/WORD/g' <TT- >TT
158 test_expect_success \
159 'change in branch A (edit)' \
160 'git-update-cache TT'
163 echo Branch A makes a file at DF/DF, creating a directory DF. >DF/DF
164 test_expect_success \
165 'change in branch A (change file to directory)' \
166 'git-update-cache --add DF/DF'
168 test_expect_success \
169 'recording branch A tree' \
170 'tree_A=$(git-write-tree)'
171 test_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)'
175 echo $commit_A >.git/HEAD-A
177 ################################################################
181 rm -rf [NDMASLT][NDMASLT] Z DF
183 test_expect_success \
184 'reading original tree and checking out' \
185 'git-read-tree $tree_O &&
186 git-checkout-cache -a'
188 to_remove=$(echo ?D Z/?D)
190 test_expect_success \
191 'change in branch B (removal)' \
192 "git-update-cache --remove $to_remove"
196 echo This is modified $p in the branch B. >$p
197 test_expect_success \
198 'change in branch B (modification)' \
199 "git-update-cache $p"
202 for p in NA AA Z/NA Z/AA
204 echo This is added $p in the branch B. >$p
205 test_expect_success \
206 'change in branch B (addition)' \
207 "git-update-cache --add $p"
209 echo This is SS from the modified tree. >SS
210 echo This is LL from the modified tree. >LL
211 test_expect_success \
212 'change in branch B (addition and modification)' \
213 'git-update-cache --add LL &&
216 sed -e '/Branch B/s/word/WORD/g' <TT- >TT
218 test_expect_success \
219 'change in branch B (modification)' \
220 'git-update-cache TT'
222 echo Branch B makes a file at DF. >DF
223 test_expect_success \
224 'change in branch B (addition of a file to conflict with directory)' \
225 'git-update-cache --add DF'
227 test_expect_success \
228 'recording branch B tree' \
229 'tree_B=$(git-write-tree)'
230 test_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)'
234 echo $commit_B >.git/HEAD-B
236 ################################################################
242 echo "# $T $(eval git-cat-file commit \$commit_$T | sed -e 1q)"
246 ################################################################
247 # Try merging and showing the various diffs
249 test_expect_success \
250 '3-way merge with git-read-tree -m' \
251 "git-read-tree -m $tree_O $tree_A $tree_B"
253 strip_object_id='s/^\([0-7]*\) [0-9a-f]* \([0-3].*\)$/\1 \2/'
255 test_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'
309 test_expect_success \
310 'validate merge result' \
311 'diff current expected'