]> git.ipfire.org Git - thirdparty/git.git/blob - t/t1001-read-tree-m-2way.sh
Merge branch 'gc/branch-recurse-submodules-fix'
[thirdparty/git.git] / t / t1001-read-tree-m-2way.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
5
6 test_description='Two way merge with read-tree -m $H $M
7
8 This test tries two-way merge (aka fast-forward with carry forward).
9
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>.
15
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 or M
22 '
23
24 . ./test-lib.sh
25 . "$TEST_DIRECTORY"/lib-read-tree.sh
26
27 read_tree_twoway () {
28 git read-tree -m "$1" "$2" && git ls-files --stage
29 }
30
31 compare_change () {
32 sed -n >current \
33 -e '/^--- /d; /^+++ /d; /^@@ /d;' \
34 -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$OID_REGEX"' /\1 X /p' \
35 "$1"
36 test_cmp expected current
37 }
38
39 check_cache_at () {
40 git diff-files -- "$1" >out &&
41 clean_if_empty=$(cat out) &&
42 case "$clean_if_empty" in
43 '') echo "$1: clean" ;;
44 ?*) echo "$1: dirty" ;;
45 esac &&
46 case "$2,$clean_if_empty" in
47 clean,) : ;;
48 clean,?*) false ;;
49 dirty,) false ;;
50 dirty,?*) : ;;
51 esac
52 }
53
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.
61 EOF
62
63 sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new
64
65 test_expect_success 'setup' '
66 echo frotz >frotz &&
67 echo nitfol >nitfol &&
68 cat bozbar-old >bozbar &&
69 echo rezrov >rezrov &&
70 echo yomin >yomin &&
71 git update-index --add nitfol bozbar rezrov &&
72 treeH=$(git write-tree) &&
73 echo treeH $treeH &&
74 git ls-tree $treeH &&
75
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) &&
80 echo treeM $treeM &&
81 git ls-tree $treeM &&
82 git diff-tree $treeH $treeM
83 '
84
85 test_expect_success '1, 2, 3 - no carry forward' '
86 rm -f .git/index &&
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
93 '
94 echo '+100644 X 0 yomin' >expected
95
96 test_expect_success '4 - carry forward local addition.' '
97 rm -f .git/index &&
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
106 '
107
108 test_expect_success '5 - carry forward local addition.' '
109 rm -f .git/index &&
110 read_tree_must_succeed $treeH &&
111 git checkout-index -u -f -q -a &&
112 echo yomin >yomin &&
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
120 '
121
122 test_expect_success '6 - local addition already has the same.' '
123 rm -f .git/index &&
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
131 '
132
133 test_expect_success '7 - local addition already has the same.' '
134 rm -f .git/index &&
135 read_tree_must_succeed $treeH &&
136 git checkout-index -u -f -q -a &&
137 echo frotz >frotz &&
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
144 '
145
146 test_expect_success '8 - conflicting addition.' '
147 rm -f .git/index &&
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
153 '
154
155 test_expect_success '9 - conflicting addition.' '
156 rm -f .git/index &&
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 &&
161 echo frotz >frotz &&
162 if read_tree_twoway $treeH $treeM; then false; else :; fi
163 '
164
165 test_expect_success '10 - path removed.' '
166 rm -f .git/index &&
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
174 '
175
176 test_expect_success '11 - dirty path removed.' '
177 rm -f .git/index &&
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
184 '
185
186 test_expect_success '12 - unmatching local changes being removed.' '
187 rm -f .git/index &&
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
193 '
194
195 test_expect_success '13 - unmatching local changes being removed.' '
196 rm -f .git/index &&
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
203 '
204
205 cat >expected <<EOF
206 -100644 X 0 nitfol
207 +100644 X 0 nitfol
208 EOF
209
210 test_expect_success '14 - unchanged in two heads.' '
211 rm -f .git/index &&
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
221 '
222
223 test_expect_success '15 - unchanged in two heads.' '
224 rm -f .git/index &&
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
235 '
236
237 test_expect_success '16 - conflicting local change.' '
238 rm -f .git/index &&
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
244 '
245
246 test_expect_success '17 - conflicting local change.' '
247 rm -f .git/index &&
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
254 '
255
256 test_expect_success '18 - local change already having a good result.' '
257 rm -f .git/index &&
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
266 '
267
268 test_expect_success '19 - local change already having a good result, further modified.' '
269 rm -f .git/index &&
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
279 '
280
281 test_expect_success '20 - no local change, use new tree.' '
282 rm -f .git/index &&
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
291 '
292
293 test_expect_success '21 - no local change, dirty cache.' '
294 rm -f .git/index &&
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
301 '
302
303 # This fails with straight two-way fast-forward.
304 test_expect_success '22 - local change cache updated.' '
305 rm -f .git/index &&
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
311 '
312
313 # Also make sure we did not break DF vs DF/DF case.
314 test_expect_success 'DF vs DF/DF case setup.' '
315 rm -f .git/index &&
316 echo DF >DF &&
317 git update-index --add DF &&
318 treeDF=$(git write-tree) &&
319 echo treeDF $treeDF &&
320 git ls-tree $treeDF &&
321
322 rm -f DF &&
323 mkdir DF &&
324 echo DF/DF >DF/DF &&
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
330 '
331
332 test_expect_success 'DF vs DF/DF case test.' '
333 rm -f .git/index &&
334 rm -fr DF &&
335 echo DF >DF &&
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 &&
341 :
342 '
343
344 test_expect_success 'a/b (untracked) vs a case setup.' '
345 rm -f .git/index &&
346 : >a &&
347 git update-index --add a &&
348 treeM=$(git write-tree) &&
349 echo treeM $treeM &&
350 git ls-tree $treeM &&
351 git ls-files --stage >treeM.out &&
352
353 rm -f a &&
354 git update-index --remove a &&
355 mkdir a &&
356 : >a/b &&
357 treeH=$(git write-tree) &&
358 echo treeH $treeH &&
359 git ls-tree $treeH
360 '
361
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 &&
365 test -f a/b
366 '
367
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
371 EOF
372 test_must_fail git --super-prefix fictional/ read-tree -u -m "$treeH" "$treeM" 2>actual &&
373 test_cmp expect actual
374 '
375
376 test_expect_success 'a/b vs a, plus c/d case setup.' '
377 rm -f .git/index &&
378 rm -fr a &&
379 : >a &&
380 mkdir c &&
381 : >c/d &&
382 git update-index --add a c/d &&
383 treeM=$(git write-tree) &&
384 echo treeM $treeM &&
385 git ls-tree $treeM &&
386 git ls-files --stage >treeM.out &&
387
388 rm -f a &&
389 mkdir a &&
390 : >a/b &&
391 git update-index --add --remove a a/b &&
392 treeH=$(git write-tree) &&
393 echo treeH $treeH &&
394 git ls-tree $treeH
395 '
396
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
401 '
402
403 test_expect_success '-m references the correct modified tree' '
404 echo >file-a &&
405 echo >file-b &&
406 git add file-a file-b &&
407 git commit -a -m "test for correct modified tree" &&
408 git branch initial-mod &&
409 echo b >file-b &&
410 git commit -a -m "B" &&
411 echo a >file-a &&
412 git add file-a &&
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
417 '
418
419 test_done