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
24 . "$TEST_DIRECTORY"/lib-read-tree.sh
27 git read-tree -m "$1" "$2" && git ls-files --stage
32 -e '/^--- /d; /^+++ /d; /^@@ /d;' \
33 -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /p' \
35 test_cmp expected current
39 clean_if_empty=$(git diff-files -- "$1")
40 case "$clean_if_empty" in
41 '') echo "$1: clean" ;;
42 ?*) echo "$1: dirty" ;;
44 case "$2,$clean_if_empty" in
52 cat >bozbar-old <<\EOF
53 This is a sample file used in two-way fast-forward merge
54 tests. Its second line ends with a magic word bozbar
55 which will be modified by the merged head to gnusto.
56 It has some extra lines so that external tools can
57 successfully merge independent changes made to later
58 lines (such as this one), avoiding line conflicts.
61 sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new
63 test_expect_success 'setup' '
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 test_expect_success '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
94 test_expect_success '4 - carry forward local addition.' '
96 read_tree_must_succeed $treeH &&
97 git checkout-index -u -f -q -a &&
98 git update-index --add yomin &&
99 read_tree_twoway $treeH $treeM &&
100 git ls-files --stage >4.out &&
101 test_must_fail git diff --no-index M.out 4.out >4diff.out &&
102 compare_change 4diff.out expected &&
103 check_cache_at yomin clean
106 test_expect_success '5 - carry forward local addition.' '
108 read_tree_must_succeed $treeH &&
109 git checkout-index -u -f -q -a &&
111 git update-index --add yomin &&
112 echo yomin yomin >yomin &&
113 read_tree_twoway $treeH $treeM &&
114 git ls-files --stage >5.out &&
115 test_must_fail git diff --no-index M.out 5.out >5diff.out &&
116 compare_change 5diff.out expected &&
117 check_cache_at yomin dirty
120 test_expect_success '6 - local addition already has the same.' '
122 read_tree_must_succeed $treeH &&
123 git checkout-index -u -f -q -a &&
124 git update-index --add frotz &&
125 read_tree_twoway $treeH $treeM &&
126 git ls-files --stage >6.out &&
127 test_cmp M.out 6.out &&
128 check_cache_at frotz clean
131 test_expect_success '7 - local addition already has the same.' '
133 read_tree_must_succeed $treeH &&
134 git checkout-index -u -f -q -a &&
136 git update-index --add frotz &&
137 echo frotz frotz >frotz &&
138 read_tree_twoway $treeH $treeM &&
139 git ls-files --stage >7.out &&
140 test_cmp M.out 7.out &&
141 check_cache_at frotz dirty
144 test_expect_success '8 - conflicting addition.' '
146 read_tree_must_succeed $treeH &&
147 git checkout-index -u -f -q -a &&
148 echo frotz frotz >frotz &&
149 git update-index --add frotz &&
150 if read_tree_twoway $treeH $treeM; then false; else :; fi
153 test_expect_success '9 - conflicting addition.' '
155 read_tree_must_succeed $treeH &&
156 git checkout-index -u -f -q -a &&
157 echo frotz frotz >frotz &&
158 git update-index --add frotz &&
160 if read_tree_twoway $treeH $treeM; then false; else :; fi
163 test_expect_success '10 - path removed.' '
165 read_tree_must_succeed $treeH &&
166 git checkout-index -u -f -q -a &&
167 echo rezrov >rezrov &&
168 git update-index --add rezrov &&
169 read_tree_twoway $treeH $treeM &&
170 git ls-files --stage >10.out &&
171 test_cmp M.out 10.out
174 test_expect_success '11 - dirty path removed.' '
176 read_tree_must_succeed $treeH &&
177 git checkout-index -u -f -q -a &&
178 echo rezrov >rezrov &&
179 git update-index --add rezrov &&
180 echo rezrov rezrov >rezrov &&
181 if read_tree_twoway $treeH $treeM; then false; else :; fi
184 test_expect_success '12 - unmatching local changes being removed.' '
186 read_tree_must_succeed $treeH &&
187 git checkout-index -u -f -q -a &&
188 echo rezrov rezrov >rezrov &&
189 git update-index --add rezrov &&
190 if read_tree_twoway $treeH $treeM; then false; else :; fi
193 test_expect_success '13 - unmatching local changes being removed.' '
195 read_tree_must_succeed $treeH &&
196 git checkout-index -u -f -q -a &&
197 echo rezrov rezrov >rezrov &&
198 git update-index --add rezrov &&
199 echo rezrov >rezrov &&
200 if read_tree_twoway $treeH $treeM; then false; else :; fi
208 test_expect_success '14 - unchanged in two heads.' '
210 read_tree_must_succeed $treeH &&
211 git checkout-index -u -f -q -a &&
212 echo nitfol nitfol >nitfol &&
213 git update-index --add nitfol &&
214 read_tree_twoway $treeH $treeM &&
215 git ls-files --stage >14.out &&
216 test_must_fail git diff --no-index M.out 14.out >14diff.out &&
217 compare_change 14diff.out expected &&
218 check_cache_at nitfol clean
221 test_expect_success '15 - unchanged in two heads.' '
223 read_tree_must_succeed $treeH &&
224 git checkout-index -u -f -q -a &&
225 echo nitfol nitfol >nitfol &&
226 git update-index --add nitfol &&
227 echo nitfol nitfol nitfol >nitfol &&
228 read_tree_twoway $treeH $treeM &&
229 git ls-files --stage >15.out &&
230 test_must_fail git diff --no-index M.out 15.out >15diff.out &&
231 compare_change 15diff.out expected &&
232 check_cache_at nitfol dirty
235 test_expect_success '16 - conflicting local change.' '
237 read_tree_must_succeed $treeH &&
238 git checkout-index -u -f -q -a &&
239 echo bozbar bozbar >bozbar &&
240 git update-index --add bozbar &&
241 if read_tree_twoway $treeH $treeM; then false; else :; fi
244 test_expect_success '17 - conflicting local change.' '
246 read_tree_must_succeed $treeH &&
247 git checkout-index -u -f -q -a &&
248 echo bozbar bozbar >bozbar &&
249 git update-index --add bozbar &&
250 echo bozbar bozbar bozbar >bozbar &&
251 if read_tree_twoway $treeH $treeM; then false; else :; fi
254 test_expect_success '18 - local change already having a good result.' '
256 read_tree_must_succeed $treeH &&
257 git checkout-index -u -f -q -a &&
258 cat bozbar-new >bozbar &&
259 git update-index --add bozbar &&
260 read_tree_twoway $treeH $treeM &&
261 git ls-files --stage >18.out &&
262 test_cmp M.out 18.out &&
263 check_cache_at bozbar clean
266 test_expect_success '19 - local change already having a good result, further modified.' '
268 read_tree_must_succeed $treeH &&
269 git checkout-index -u -f -q -a &&
270 cat bozbar-new >bozbar &&
271 git update-index --add bozbar &&
272 echo gnusto gnusto >bozbar &&
273 read_tree_twoway $treeH $treeM &&
274 git ls-files --stage >19.out &&
275 test_cmp M.out 19.out &&
276 check_cache_at bozbar dirty
279 test_expect_success '20 - no local change, use new tree.' '
281 read_tree_must_succeed $treeH &&
282 git checkout-index -u -f -q -a &&
283 cat bozbar-old >bozbar &&
284 git update-index --add bozbar &&
285 read_tree_twoway $treeH $treeM &&
286 git ls-files --stage >20.out &&
287 test_cmp M.out 20.out &&
288 check_cache_at bozbar dirty
291 test_expect_success '21 - no local change, dirty cache.' '
293 read_tree_must_succeed $treeH &&
294 git checkout-index -u -f -q -a &&
295 cat bozbar-old >bozbar &&
296 git update-index --add bozbar &&
297 echo gnusto gnusto >bozbar &&
298 if read_tree_twoway $treeH $treeM; then false; else :; fi
301 # This fails with straight two-way fast-forward.
302 test_expect_success '22 - local change cache updated.' '
304 read_tree_must_succeed $treeH &&
305 git checkout-index -u -f -q -a &&
306 sed -e "s/such as/SUCH AS/" bozbar-old >bozbar &&
307 git update-index --add bozbar &&
308 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 'DF vs DF/DF case setup.' '
315 git update-index --add DF &&
316 treeDF=$(git write-tree) &&
317 echo treeDF $treeDF &&
318 git ls-tree $treeDF &&
323 git update-index --add --remove DF DF/DF &&
324 treeDFDF=$(git write-tree) &&
325 echo treeDFDF $treeDFDF &&
326 git ls-tree $treeDFDF &&
327 git ls-files --stage >DFDF.out
330 test_expect_success 'DF vs DF/DF case test.' '
334 git update-index --add DF &&
335 read_tree_twoway $treeDF $treeDFDF &&
336 git ls-files --stage >DFDFcheck.out &&
337 test_cmp DFDF.out DFDFcheck.out &&
338 check_cache_at DF/DF dirty &&
342 test_expect_success 'a/b (untracked) vs a case setup.' '
345 git update-index --add a &&
346 treeM=$(git write-tree) &&
348 git ls-tree $treeM &&
349 git ls-files --stage >treeM.out &&
352 git update-index --remove a &&
355 treeH=$(git write-tree) &&
360 test_expect_success 'a/b (untracked) vs a, plus c/d case test.' '
361 read_tree_u_must_fail -u -m "$treeH" "$treeM" &&
362 git ls-files --stage &&
366 test_expect_success 'read-tree supports the super-prefix' '
367 cat <<-EOF >expect &&
368 error: Updating '\''fictional/a'\'' would lose untracked files in it
370 test_must_fail git --super-prefix fictional/ read-tree -u -m "$treeH" "$treeM" 2>actual &&
371 test_cmp expect actual
374 test_expect_success 'a/b vs a, plus c/d case setup.' '
380 git update-index --add a c/d &&
381 treeM=$(git write-tree) &&
383 git ls-tree $treeM &&
384 git ls-files --stage >treeM.out &&
389 git update-index --add --remove a a/b &&
390 treeH=$(git write-tree) &&
395 test_expect_success 'a/b vs a, plus c/d case test.' '
396 read_tree_u_must_succeed -u -m "$treeH" "$treeM" &&
397 git ls-files --stage | tee >treeMcheck.out &&
398 test_cmp treeM.out treeMcheck.out
401 test_expect_success '-m references the correct modified tree' '
404 git add file-a file-b &&
405 git commit -a -m "test for correct modified tree" &&
406 git branch initial-mod &&
408 git commit -a -m "B" &&
411 git ls-tree $(git write-tree) file-a >expect &&
412 read_tree_must_succeed -m HEAD initial-mod &&
413 git ls-tree $(git write-tree) file-a >actual &&
414 test_cmp expect actual