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_PASSES_SANITIZE_LEAK
=true
26 .
"$TEST_DIRECTORY"/lib-read-tree.sh
29 git read-tree
-m "$1" "$2" && git ls-files
--stage
34 -e '/^--- /d; /^+++ /d; /^@@ /d;' \
35 -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$OID_REGEX"' /\1 X /p' \
37 test_cmp expected current
41 clean_if_empty
=$
(git diff-files
-- "$1")
42 case "$clean_if_empty" in
43 '') echo "$1: clean" ;;
44 ?
*) echo "$1: dirty" ;;
46 case "$2,$clean_if_empty" in
54 cat >bozbar-old
<<\EOF
55 This is a sample
file used
in two-way fast-forward merge
56 tests. Its second line ends with a magic word bozbar
57 which will be modified by the merged
head to gnusto.
58 It has some extra lines so that external tools can
59 successfully merge independent changes made to later
60 lines
(such as this one
), avoiding line conflicts.
63 sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old
>bozbar-new
65 test_expect_success
'setup' '
67 echo nitfol >nitfol &&
68 cat bozbar-old >bozbar &&
69 echo rezrov >rezrov &&
71 git update-index --add nitfol bozbar rezrov &&
72 treeH=$(git write-tree) &&
76 cat bozbar-new >bozbar &&
77 git update-index --add frotz bozbar --force-remove rezrov &&
78 git ls-files --stage >M.out &&
79 treeM=$(git write-tree) &&
82 git diff-tree $treeH $treeM
85 test_expect_success
'1, 2, 3 - no carry forward' '
87 read_tree_twoway $treeH $treeM &&
88 git ls-files --stage >1-3.out &&
89 test_cmp M.out 1-3.out &&
90 check_cache_at bozbar dirty &&
91 check_cache_at frotz dirty &&
92 check_cache_at nitfol dirty
94 echo '+100644 X 0 yomin' >expected
96 test_expect_success
'4 - carry forward local addition.' '
98 read_tree_must_succeed $treeH &&
99 git checkout-index -u -f -q -a &&
100 git update-index --add yomin &&
101 read_tree_twoway $treeH $treeM &&
102 git ls-files --stage >4.out &&
103 test_must_fail git diff --no-index M.out 4.out >4diff.out &&
104 compare_change 4diff.out expected &&
105 check_cache_at yomin clean
108 test_expect_success
'5 - carry forward local addition.' '
110 read_tree_must_succeed $treeH &&
111 git checkout-index -u -f -q -a &&
113 git update-index --add yomin &&
114 echo yomin yomin >yomin &&
115 read_tree_twoway $treeH $treeM &&
116 git ls-files --stage >5.out &&
117 test_must_fail git diff --no-index M.out 5.out >5diff.out &&
118 compare_change 5diff.out expected &&
119 check_cache_at yomin dirty
122 test_expect_success
'6 - local addition already has the same.' '
124 read_tree_must_succeed $treeH &&
125 git checkout-index -u -f -q -a &&
126 git update-index --add frotz &&
127 read_tree_twoway $treeH $treeM &&
128 git ls-files --stage >6.out &&
129 test_cmp M.out 6.out &&
130 check_cache_at frotz clean
133 test_expect_success
'7 - local addition already has the same.' '
135 read_tree_must_succeed $treeH &&
136 git checkout-index -u -f -q -a &&
138 git update-index --add frotz &&
139 echo frotz frotz >frotz &&
140 read_tree_twoway $treeH $treeM &&
141 git ls-files --stage >7.out &&
142 test_cmp M.out 7.out &&
143 check_cache_at frotz dirty
146 test_expect_success
'8 - conflicting addition.' '
148 read_tree_must_succeed $treeH &&
149 git checkout-index -u -f -q -a &&
150 echo frotz frotz >frotz &&
151 git update-index --add frotz &&
152 if read_tree_twoway $treeH $treeM; then false; else :; fi
155 test_expect_success
'9 - conflicting addition.' '
157 read_tree_must_succeed $treeH &&
158 git checkout-index -u -f -q -a &&
159 echo frotz frotz >frotz &&
160 git update-index --add frotz &&
162 if read_tree_twoway $treeH $treeM; then false; else :; fi
165 test_expect_success
'10 - path removed.' '
167 read_tree_must_succeed $treeH &&
168 git checkout-index -u -f -q -a &&
169 echo rezrov >rezrov &&
170 git update-index --add rezrov &&
171 read_tree_twoway $treeH $treeM &&
172 git ls-files --stage >10.out &&
173 test_cmp M.out 10.out
176 test_expect_success
'11 - dirty path removed.' '
178 read_tree_must_succeed $treeH &&
179 git checkout-index -u -f -q -a &&
180 echo rezrov >rezrov &&
181 git update-index --add rezrov &&
182 echo rezrov rezrov >rezrov &&
183 if read_tree_twoway $treeH $treeM; then false; else :; fi
186 test_expect_success
'12 - unmatching local changes being removed.' '
188 read_tree_must_succeed $treeH &&
189 git checkout-index -u -f -q -a &&
190 echo rezrov rezrov >rezrov &&
191 git update-index --add rezrov &&
192 if read_tree_twoway $treeH $treeM; then false; else :; fi
195 test_expect_success
'13 - unmatching local changes being removed.' '
197 read_tree_must_succeed $treeH &&
198 git checkout-index -u -f -q -a &&
199 echo rezrov rezrov >rezrov &&
200 git update-index --add rezrov &&
201 echo rezrov >rezrov &&
202 if read_tree_twoway $treeH $treeM; then false; else :; fi
210 test_expect_success
'14 - unchanged in two heads.' '
212 read_tree_must_succeed $treeH &&
213 git checkout-index -u -f -q -a &&
214 echo nitfol nitfol >nitfol &&
215 git update-index --add nitfol &&
216 read_tree_twoway $treeH $treeM &&
217 git ls-files --stage >14.out &&
218 test_must_fail git diff --no-index M.out 14.out >14diff.out &&
219 compare_change 14diff.out expected &&
220 check_cache_at nitfol clean
223 test_expect_success
'15 - unchanged in two heads.' '
225 read_tree_must_succeed $treeH &&
226 git checkout-index -u -f -q -a &&
227 echo nitfol nitfol >nitfol &&
228 git update-index --add nitfol &&
229 echo nitfol nitfol nitfol >nitfol &&
230 read_tree_twoway $treeH $treeM &&
231 git ls-files --stage >15.out &&
232 test_must_fail git diff --no-index M.out 15.out >15diff.out &&
233 compare_change 15diff.out expected &&
234 check_cache_at nitfol dirty
237 test_expect_success
'16 - conflicting local change.' '
239 read_tree_must_succeed $treeH &&
240 git checkout-index -u -f -q -a &&
241 echo bozbar bozbar >bozbar &&
242 git update-index --add bozbar &&
243 if read_tree_twoway $treeH $treeM; then false; else :; fi
246 test_expect_success
'17 - conflicting local change.' '
248 read_tree_must_succeed $treeH &&
249 git checkout-index -u -f -q -a &&
250 echo bozbar bozbar >bozbar &&
251 git update-index --add bozbar &&
252 echo bozbar bozbar bozbar >bozbar &&
253 if read_tree_twoway $treeH $treeM; then false; else :; fi
256 test_expect_success
'18 - local change already having a good result.' '
258 read_tree_must_succeed $treeH &&
259 git checkout-index -u -f -q -a &&
260 cat bozbar-new >bozbar &&
261 git update-index --add bozbar &&
262 read_tree_twoway $treeH $treeM &&
263 git ls-files --stage >18.out &&
264 test_cmp M.out 18.out &&
265 check_cache_at bozbar clean
268 test_expect_success
'19 - local change already having a good result, further modified.' '
270 read_tree_must_succeed $treeH &&
271 git checkout-index -u -f -q -a &&
272 cat bozbar-new >bozbar &&
273 git update-index --add bozbar &&
274 echo gnusto gnusto >bozbar &&
275 read_tree_twoway $treeH $treeM &&
276 git ls-files --stage >19.out &&
277 test_cmp M.out 19.out &&
278 check_cache_at bozbar dirty
281 test_expect_success
'20 - no local change, use new tree.' '
283 read_tree_must_succeed $treeH &&
284 git checkout-index -u -f -q -a &&
285 cat bozbar-old >bozbar &&
286 git update-index --add bozbar &&
287 read_tree_twoway $treeH $treeM &&
288 git ls-files --stage >20.out &&
289 test_cmp M.out 20.out &&
290 check_cache_at bozbar dirty
293 test_expect_success
'21 - no local change, dirty cache.' '
295 read_tree_must_succeed $treeH &&
296 git checkout-index -u -f -q -a &&
297 cat bozbar-old >bozbar &&
298 git update-index --add bozbar &&
299 echo gnusto gnusto >bozbar &&
300 if read_tree_twoway $treeH $treeM; then false; else :; fi
303 # This fails with straight two-way fast-forward.
304 test_expect_success
'22 - local change cache updated.' '
306 read_tree_must_succeed $treeH &&
307 git checkout-index -u -f -q -a &&
308 sed -e "s/such as/SUCH AS/" bozbar-old >bozbar &&
309 git update-index --add bozbar &&
310 if read_tree_twoway $treeH $treeM; then false; else :; fi
313 # Also make sure we did not break DF vs DF/DF case.
314 test_expect_success
'DF vs DF/DF case setup.' '
317 git update-index --add DF &&
318 treeDF=$(git write-tree) &&
319 echo treeDF $treeDF &&
320 git ls-tree $treeDF &&
325 git update-index --add --remove DF DF/DF &&
326 treeDFDF=$(git write-tree) &&
327 echo treeDFDF $treeDFDF &&
328 git ls-tree $treeDFDF &&
329 git ls-files --stage >DFDF.out
332 test_expect_success
'DF vs DF/DF case test.' '
336 git update-index --add DF &&
337 read_tree_twoway $treeDF $treeDFDF &&
338 git ls-files --stage >DFDFcheck.out &&
339 test_cmp DFDF.out DFDFcheck.out &&
340 check_cache_at DF/DF dirty &&
344 test_expect_success
'a/b (untracked) vs a case setup.' '
347 git update-index --add a &&
348 treeM=$(git write-tree) &&
350 git ls-tree $treeM &&
351 git ls-files --stage >treeM.out &&
354 git update-index --remove a &&
357 treeH=$(git write-tree) &&
362 test_expect_success
'a/b (untracked) vs a, plus c/d case test.' '
363 read_tree_u_must_fail -u -m "$treeH" "$treeM" &&
364 git ls-files --stage &&
368 test_expect_success
'read-tree supports the super-prefix' '
369 cat <<-EOF >expect &&
370 error: Updating '\''fictional/a'\'' would lose untracked files in it
372 test_must_fail git --super-prefix fictional/ read-tree -u -m "$treeH" "$treeM" 2>actual &&
373 test_cmp expect actual
376 test_expect_success
'a/b vs a, plus c/d case setup.' '
382 git update-index --add a c/d &&
383 treeM=$(git write-tree) &&
385 git ls-tree $treeM &&
386 git ls-files --stage >treeM.out &&
391 git update-index --add --remove a a/b &&
392 treeH=$(git write-tree) &&
397 test_expect_success
'a/b vs a, plus c/d case test.' '
398 read_tree_u_must_succeed -u -m "$treeH" "$treeM" &&
399 git ls-files --stage | tee >treeMcheck.out &&
400 test_cmp treeM.out treeMcheck.out
403 test_expect_success
'-m references the correct modified tree' '
406 git add file-a file-b &&
407 git commit -a -m "test for correct modified tree" &&
408 git branch initial-mod &&
410 git commit -a -m "B" &&
413 git ls-tree $(git write-tree) file-a >expect &&
414 read_tree_must_succeed -m HEAD initial-mod &&
415 git ls-tree $(git write-tree) file-a >actual &&
416 test_cmp expect actual