3 # Copyright (c) 2005 Junio C Hamano
6 test_description='Two way merge with read-tree -m $H $M
8 This test tries two-way merge (aka fast-forward with carry forward).
10 There is the head (called H) and another commit (called M), which is
11 simply ahead of H. The index and the work tree contains a state that
12 is derived from H, but may also have local changes. This test checks
13 all the combinations described in the two-tree merge "carry forward"
14 rules, found in <Documentation/git read-tree.txt>.
16 In the test, these paths are used:
17 bozbar - in H, stays in M, modified from bozbar to gnusto
18 frotz - not in H added in M
19 nitfol - in H, stays in M unmodified
20 rezrov - in H, deleted in M
21 yomin - not in H nor M
26 git read-tree -m "$1" "$2" && git ls-files --stage
31 -e '/^--- /d; /^+++ /d; /^@@ /d;' \
32 -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /p' \
34 test_cmp expected current
38 clean_if_empty=`git diff-files -- "$1"`
39 case "$clean_if_empty" in
40 '') echo "$1: clean" ;;
41 ?*) echo "$1: dirty" ;;
43 case "$2,$clean_if_empty" in
51 cat >bozbar-old <<\EOF
52 This is a sample file used in two-way fast-forward merge
53 tests. Its second line ends with a magic word bozbar
54 which will be modified by the merged head to gnusto.
55 It has some extra lines so that external tools can
56 successfully merge independent changes made to later
57 lines (such as this one), avoiding line conflicts.
60 sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new
65 echo nitfol >nitfol &&
66 cat bozbar-old >bozbar &&
67 echo rezrov >rezrov &&
69 git update-index --add nitfol bozbar rezrov &&
70 treeH=`git write-tree` &&
74 cat bozbar-new >bozbar &&
75 git update-index --add frotz bozbar --force-remove rezrov &&
76 git ls-files --stage >M.out &&
77 treeM=`git write-tree` &&
80 git diff-tree $treeH $treeM'
83 '1, 2, 3 - no carry forward' \
85 read_tree_twoway $treeH $treeM &&
86 git ls-files --stage >1-3.out &&
87 test_cmp M.out 1-3.out &&
88 check_cache_at bozbar dirty &&
89 check_cache_at frotz dirty &&
90 check_cache_at nitfol dirty'
92 echo '+100644 X 0 yomin' >expected
95 '4 - carry forward local addition.' \
97 git read-tree $treeH &&
98 git checkout-index -u -f -q -a &&
99 git update-index --add yomin &&
100 read_tree_twoway $treeH $treeM &&
101 git ls-files --stage >4.out &&
102 test_must_fail git diff --no-index M.out 4.out >4diff.out &&
103 compare_change 4diff.out expected &&
104 check_cache_at yomin clean'
106 test_expect_success \
107 '5 - carry forward local addition.' \
109 git read-tree $treeH &&
110 git checkout-index -u -f -q -a &&
112 git update-index --add yomin &&
113 echo yomin yomin >yomin &&
114 read_tree_twoway $treeH $treeM &&
115 git ls-files --stage >5.out &&
116 test_must_fail git diff --no-index M.out 5.out >5diff.out &&
117 compare_change 5diff.out expected &&
118 check_cache_at yomin dirty'
120 test_expect_success \
121 '6 - local addition already has the same.' \
123 git read-tree $treeH &&
124 git checkout-index -u -f -q -a &&
125 git update-index --add frotz &&
126 read_tree_twoway $treeH $treeM &&
127 git ls-files --stage >6.out &&
128 test_cmp M.out 6.out &&
129 check_cache_at frotz clean'
131 test_expect_success \
132 '7 - local addition already has the same.' \
134 git read-tree $treeH &&
135 git checkout-index -u -f -q -a &&
137 git update-index --add frotz &&
138 echo frotz frotz >frotz &&
139 read_tree_twoway $treeH $treeM &&
140 git ls-files --stage >7.out &&
141 test_cmp M.out 7.out &&
142 check_cache_at frotz dirty'
144 test_expect_success \
145 '8 - conflicting addition.' \
147 git read-tree $treeH &&
148 git checkout-index -u -f -q -a &&
149 echo frotz frotz >frotz &&
150 git update-index --add frotz &&
151 if read_tree_twoway $treeH $treeM; then false; else :; fi'
153 test_expect_success \
154 '9 - conflicting addition.' \
156 git read-tree $treeH &&
157 git checkout-index -u -f -q -a &&
158 echo frotz frotz >frotz &&
159 git update-index --add frotz &&
161 if read_tree_twoway $treeH $treeM; then false; else :; fi'
163 test_expect_success \
164 '10 - path removed.' \
166 git read-tree $treeH &&
167 git checkout-index -u -f -q -a &&
168 echo rezrov >rezrov &&
169 git update-index --add rezrov &&
170 read_tree_twoway $treeH $treeM &&
171 git ls-files --stage >10.out &&
172 test_cmp M.out 10.out'
174 test_expect_success \
175 '11 - dirty path removed.' \
177 git read-tree $treeH &&
178 git checkout-index -u -f -q -a &&
179 echo rezrov >rezrov &&
180 git update-index --add rezrov &&
181 echo rezrov rezrov >rezrov &&
182 if read_tree_twoway $treeH $treeM; then false; else :; fi'
184 test_expect_success \
185 '12 - unmatching local changes being removed.' \
187 git read-tree $treeH &&
188 git checkout-index -u -f -q -a &&
189 echo rezrov rezrov >rezrov &&
190 git update-index --add rezrov &&
191 if read_tree_twoway $treeH $treeM; then false; else :; fi'
193 test_expect_success \
194 '13 - unmatching local changes being removed.' \
196 git read-tree $treeH &&
197 git checkout-index -u -f -q -a &&
198 echo rezrov rezrov >rezrov &&
199 git update-index --add rezrov &&
200 echo rezrov >rezrov &&
201 if read_tree_twoway $treeH $treeM; then false; else :; fi'
208 test_expect_success \
209 '14 - unchanged in two heads.' \
211 git read-tree $treeH &&
212 git checkout-index -u -f -q -a &&
213 echo nitfol nitfol >nitfol &&
214 git update-index --add nitfol &&
215 read_tree_twoway $treeH $treeM &&
216 git ls-files --stage >14.out &&
217 test_must_fail git diff --no-index M.out 14.out >14diff.out &&
218 compare_change 14diff.out expected &&
219 check_cache_at nitfol clean'
221 test_expect_success \
222 '15 - unchanged in two heads.' \
224 git read-tree $treeH &&
225 git checkout-index -u -f -q -a &&
226 echo nitfol nitfol >nitfol &&
227 git update-index --add nitfol &&
228 echo nitfol nitfol nitfol >nitfol &&
229 read_tree_twoway $treeH $treeM &&
230 git ls-files --stage >15.out &&
231 test_must_fail git diff --no-index M.out 15.out >15diff.out &&
232 compare_change 15diff.out expected &&
233 check_cache_at nitfol dirty'
235 test_expect_success \
236 '16 - conflicting local change.' \
238 git read-tree $treeH &&
239 git checkout-index -u -f -q -a &&
240 echo bozbar bozbar >bozbar &&
241 git update-index --add bozbar &&
242 if read_tree_twoway $treeH $treeM; then false; else :; fi'
244 test_expect_success \
245 '17 - conflicting local change.' \
247 git read-tree $treeH &&
248 git checkout-index -u -f -q -a &&
249 echo bozbar bozbar >bozbar &&
250 git update-index --add bozbar &&
251 echo bozbar bozbar bozbar >bozbar &&
252 if read_tree_twoway $treeH $treeM; then false; else :; fi'
254 test_expect_success \
255 '18 - local change already having a good result.' \
257 git read-tree $treeH &&
258 git checkout-index -u -f -q -a &&
259 cat bozbar-new >bozbar &&
260 git update-index --add bozbar &&
261 read_tree_twoway $treeH $treeM &&
262 git ls-files --stage >18.out &&
263 test_cmp M.out 18.out &&
264 check_cache_at bozbar clean'
266 test_expect_success \
267 '19 - local change already having a good result, further modified.' \
269 git read-tree $treeH &&
270 git checkout-index -u -f -q -a &&
271 cat bozbar-new >bozbar &&
272 git update-index --add bozbar &&
273 echo gnusto gnusto >bozbar &&
274 read_tree_twoway $treeH $treeM &&
275 git ls-files --stage >19.out &&
276 test_cmp M.out 19.out &&
277 check_cache_at bozbar dirty'
279 test_expect_success \
280 '20 - no local change, use new tree.' \
282 git read-tree $treeH &&
283 git checkout-index -u -f -q -a &&
284 cat bozbar-old >bozbar &&
285 git update-index --add bozbar &&
286 read_tree_twoway $treeH $treeM &&
287 git ls-files --stage >20.out &&
288 test_cmp M.out 20.out &&
289 check_cache_at bozbar dirty'
291 test_expect_success \
292 '21 - no local change, dirty cache.' \
294 git read-tree $treeH &&
295 git checkout-index -u -f -q -a &&
296 cat bozbar-old >bozbar &&
297 git update-index --add bozbar &&
298 echo gnusto gnusto >bozbar &&
299 if read_tree_twoway $treeH $treeM; then false; else :; fi'
301 # This fails with straight two-way fast-forward.
302 test_expect_success \
303 '22 - local change cache updated.' \
305 git read-tree $treeH &&
306 git checkout-index -u -f -q -a &&
307 sed -e "s/such as/SUCH AS/" bozbar-old >bozbar &&
308 git update-index --add bozbar &&
309 if read_tree_twoway $treeH $treeM; then false; else :; fi'
311 # Also make sure we did not break DF vs DF/DF case.
312 test_expect_success \
313 'DF vs DF/DF case setup.' \
316 git update-index --add DF &&
317 treeDF=`git write-tree` &&
318 echo treeDF $treeDF &&
319 git ls-tree $treeDF &&
324 git update-index --add --remove DF DF/DF &&
325 treeDFDF=`git write-tree` &&
326 echo treeDFDF $treeDFDF &&
327 git ls-tree $treeDFDF &&
328 git ls-files --stage >DFDF.out'
330 test_expect_success \
331 'DF vs DF/DF case test.' \
335 git update-index --add DF &&
336 read_tree_twoway $treeDF $treeDFDF &&
337 git ls-files --stage >DFDFcheck.out &&
338 test_cmp DFDF.out DFDFcheck.out &&
339 check_cache_at DF/DF dirty &&
342 test_expect_success \
343 'a/b (untracked) vs a case setup.' \
346 git update-index --add a &&
347 treeM=`git write-tree` &&
349 git ls-tree $treeM &&
350 git ls-files --stage >treeM.out &&
353 git update-index --remove a &&
356 treeH=`git write-tree` &&
360 test_expect_success \
361 'a/b (untracked) vs a, plus c/d case test.' \
362 'test_must_fail git read-tree -u -m "$treeH" "$treeM" &&
363 git ls-files --stage &&
366 test_expect_success \
367 'a/b vs a, plus c/d case setup.' \
373 git update-index --add a c/d &&
374 treeM=`git write-tree` &&
376 git ls-tree $treeM &&
377 git ls-files --stage >treeM.out &&
382 git update-index --add --remove a a/b &&
383 treeH=`git write-tree` &&
387 test_expect_success \
388 'a/b vs a, plus c/d case test.' \
389 'git read-tree -u -m "$treeH" "$treeM" &&
390 git ls-files --stage | tee >treeMcheck.out &&
391 test_cmp treeM.out treeMcheck.out'
393 test_expect_success '-m references the correct modified tree' '
396 git add file-a file-b &&
397 git commit -a -m "test for correct modified tree" &&
398 git branch initial-mod &&
400 git commit -a -m "B" &&
403 git ls-tree $(git write-tree) file-a >expect &&
404 git read-tree -m HEAD initial-mod &&
405 git ls-tree $(git write-tree) file-a >actual &&
406 test_cmp expect actual