Sixth batch
[git/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 . ./test-lib.sh
24 . "$TEST_DIRECTORY"/lib-read-tree.sh
25
26 read_tree_twoway () {
27 git read-tree -m "$1" "$2" && git ls-files --stage
28 }
29
30 compare_change () {
31 sed -n >current \
32 -e '/^--- /d; /^+++ /d; /^@@ /d;' \
33 -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$OID_REGEX"' /\1 X /p' \
34 "$1"
35 test_cmp expected current
36 }
37
38 check_cache_at () {
39 clean_if_empty=$(git diff-files -- "$1")
40 case "$clean_if_empty" in
41 '') echo "$1: clean" ;;
42 ?*) echo "$1: dirty" ;;
43 esac
44 case "$2,$clean_if_empty" in
45 clean,) : ;;
46 clean,?*) false ;;
47 dirty,) false ;;
48 dirty,?*) : ;;
49 esac
50 }
51
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.
59 EOF
60
61 sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new
62
63 test_expect_success 'setup' '
64 echo frotz >frotz &&
65 echo nitfol >nitfol &&
66 cat bozbar-old >bozbar &&
67 echo rezrov >rezrov &&
68 echo yomin >yomin &&
69 git update-index --add nitfol bozbar rezrov &&
70 treeH=$(git write-tree) &&
71 echo treeH $treeH &&
72 git ls-tree $treeH &&
73
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) &&
78 echo treeM $treeM &&
79 git ls-tree $treeM &&
80 git diff-tree $treeH $treeM
81 '
82
83 test_expect_success '1, 2, 3 - no carry forward' '
84 rm -f .git/index &&
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
91 '
92 echo '+100644 X 0 yomin' >expected
93
94 test_expect_success '4 - carry forward local addition.' '
95 rm -f .git/index &&
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
104 '
105
106 test_expect_success '5 - carry forward local addition.' '
107 rm -f .git/index &&
108 read_tree_must_succeed $treeH &&
109 git checkout-index -u -f -q -a &&
110 echo yomin >yomin &&
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
118 '
119
120 test_expect_success '6 - local addition already has the same.' '
121 rm -f .git/index &&
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
129 '
130
131 test_expect_success '7 - local addition already has the same.' '
132 rm -f .git/index &&
133 read_tree_must_succeed $treeH &&
134 git checkout-index -u -f -q -a &&
135 echo frotz >frotz &&
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
142 '
143
144 test_expect_success '8 - conflicting addition.' '
145 rm -f .git/index &&
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
151 '
152
153 test_expect_success '9 - conflicting addition.' '
154 rm -f .git/index &&
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 &&
159 echo frotz >frotz &&
160 if read_tree_twoway $treeH $treeM; then false; else :; fi
161 '
162
163 test_expect_success '10 - path removed.' '
164 rm -f .git/index &&
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
172 '
173
174 test_expect_success '11 - dirty path removed.' '
175 rm -f .git/index &&
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
182 '
183
184 test_expect_success '12 - unmatching local changes being removed.' '
185 rm -f .git/index &&
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
191 '
192
193 test_expect_success '13 - unmatching local changes being removed.' '
194 rm -f .git/index &&
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
201 '
202
203 cat >expected <<EOF
204 -100644 X 0 nitfol
205 +100644 X 0 nitfol
206 EOF
207
208 test_expect_success '14 - unchanged in two heads.' '
209 rm -f .git/index &&
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
219 '
220
221 test_expect_success '15 - unchanged in two heads.' '
222 rm -f .git/index &&
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
233 '
234
235 test_expect_success '16 - conflicting local change.' '
236 rm -f .git/index &&
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
242 '
243
244 test_expect_success '17 - conflicting local change.' '
245 rm -f .git/index &&
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
252 '
253
254 test_expect_success '18 - local change already having a good result.' '
255 rm -f .git/index &&
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
264 '
265
266 test_expect_success '19 - local change already having a good result, further modified.' '
267 rm -f .git/index &&
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
277 '
278
279 test_expect_success '20 - no local change, use new tree.' '
280 rm -f .git/index &&
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
289 '
290
291 test_expect_success '21 - no local change, dirty cache.' '
292 rm -f .git/index &&
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
299 '
300
301 # This fails with straight two-way fast-forward.
302 test_expect_success '22 - local change cache updated.' '
303 rm -f .git/index &&
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
309 '
310
311 # Also make sure we did not break DF vs DF/DF case.
312 test_expect_success 'DF vs DF/DF case setup.' '
313 rm -f .git/index &&
314 echo DF >DF &&
315 git update-index --add DF &&
316 treeDF=$(git write-tree) &&
317 echo treeDF $treeDF &&
318 git ls-tree $treeDF &&
319
320 rm -f DF &&
321 mkdir DF &&
322 echo DF/DF >DF/DF &&
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
328 '
329
330 test_expect_success 'DF vs DF/DF case test.' '
331 rm -f .git/index &&
332 rm -fr DF &&
333 echo DF >DF &&
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 &&
339 :
340 '
341
342 test_expect_success 'a/b (untracked) vs a case setup.' '
343 rm -f .git/index &&
344 : >a &&
345 git update-index --add a &&
346 treeM=$(git write-tree) &&
347 echo treeM $treeM &&
348 git ls-tree $treeM &&
349 git ls-files --stage >treeM.out &&
350
351 rm -f a &&
352 git update-index --remove a &&
353 mkdir a &&
354 : >a/b &&
355 treeH=$(git write-tree) &&
356 echo treeH $treeH &&
357 git ls-tree $treeH
358 '
359
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 &&
363 test -f a/b
364 '
365
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
369 EOF
370 test_must_fail git --super-prefix fictional/ read-tree -u -m "$treeH" "$treeM" 2>actual &&
371 test_cmp expect actual
372 '
373
374 test_expect_success 'a/b vs a, plus c/d case setup.' '
375 rm -f .git/index &&
376 rm -fr a &&
377 : >a &&
378 mkdir c &&
379 : >c/d &&
380 git update-index --add a c/d &&
381 treeM=$(git write-tree) &&
382 echo treeM $treeM &&
383 git ls-tree $treeM &&
384 git ls-files --stage >treeM.out &&
385
386 rm -f a &&
387 mkdir a &&
388 : >a/b &&
389 git update-index --add --remove a a/b &&
390 treeH=$(git write-tree) &&
391 echo treeH $treeH &&
392 git ls-tree $treeH
393 '
394
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
399 '
400
401 test_expect_success '-m references the correct modified tree' '
402 echo >file-a &&
403 echo >file-b &&
404 git add file-a file-b &&
405 git commit -a -m "test for correct modified tree" &&
406 git branch initial-mod &&
407 echo b >file-b &&
408 git commit -a -m "B" &&
409 echo a >file-a &&
410 git add file-a &&
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
415 '
416
417 test_done