Merge branch 'jc/conflict-marker-size' into maint
[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 nor M
22 '
23 . ./test-lib.sh
24
25 read_tree_twoway () {
26 git read-tree -m "$1" "$2" && git ls-files --stage
27 }
28
29 compare_change () {
30 sed -n >current \
31 -e '/^--- /d; /^+++ /d; /^@@ /d;' \
32 -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /p' \
33 "$1"
34 test_cmp expected current
35 }
36
37 check_cache_at () {
38 clean_if_empty=`git diff-files -- "$1"`
39 case "$clean_if_empty" in
40 '') echo "$1: clean" ;;
41 ?*) echo "$1: dirty" ;;
42 esac
43 case "$2,$clean_if_empty" in
44 clean,) : ;;
45 clean,?*) false ;;
46 dirty,) false ;;
47 dirty,?*) : ;;
48 esac
49 }
50
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.
58 EOF
59
60 sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new
61
62 test_expect_success \
63 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 test_expect_success \
83 '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 \
95 '4 - carry forward local addition.' \
96 'rm -f .git/index &&
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 || return 1
102 git diff --no-index M.out 4.out >4diff.out
103 compare_change 4diff.out expected &&
104 check_cache_at yomin clean'
105
106 test_expect_success \
107 '5 - carry forward local addition.' \
108 'rm -f .git/index &&
109 git read-tree $treeH &&
110 git checkout-index -u -f -q -a &&
111 echo yomin >yomin &&
112 git update-index --add yomin &&
113 echo yomin yomin >yomin &&
114 read_tree_twoway $treeH $treeM &&
115 git ls-files --stage >5.out || return 1
116 git diff --no-index M.out 5.out >5diff.out
117 compare_change 5diff.out expected &&
118 check_cache_at yomin dirty'
119
120 test_expect_success \
121 '6 - local addition already has the same.' \
122 'rm -f .git/index &&
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'
130
131 test_expect_success \
132 '7 - local addition already has the same.' \
133 'rm -f .git/index &&
134 git read-tree $treeH &&
135 git checkout-index -u -f -q -a &&
136 echo frotz >frotz &&
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'
143
144 test_expect_success \
145 '8 - conflicting addition.' \
146 'rm -f .git/index &&
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'
152
153 test_expect_success \
154 '9 - conflicting addition.' \
155 'rm -f .git/index &&
156 git read-tree $treeH &&
157 git checkout-index -u -f -q -a &&
158 echo frotz frotz >frotz &&
159 git update-index --add frotz &&
160 echo frotz >frotz &&
161 if read_tree_twoway $treeH $treeM; then false; else :; fi'
162
163 test_expect_success \
164 '10 - path removed.' \
165 'rm -f .git/index &&
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'
173
174 test_expect_success \
175 '11 - dirty path removed.' \
176 'rm -f .git/index &&
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'
183
184 test_expect_success \
185 '12 - unmatching local changes being removed.' \
186 'rm -f .git/index &&
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'
192
193 test_expect_success \
194 '13 - unmatching local changes being removed.' \
195 'rm -f .git/index &&
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'
202
203 cat >expected <<EOF
204 -100644 X 0 nitfol
205 +100644 X 0 nitfol
206 EOF
207
208 test_expect_success \
209 '14 - unchanged in two heads.' \
210 'rm -f .git/index &&
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 || return 1
217 git diff --no-index M.out 14.out >14diff.out
218 compare_change 14diff.out expected &&
219 check_cache_at nitfol clean'
220
221 test_expect_success \
222 '15 - unchanged in two heads.' \
223 'rm -f .git/index &&
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 || return 1
231 git diff --no-index M.out 15.out >15diff.out
232 compare_change 15diff.out expected &&
233 check_cache_at nitfol dirty'
234
235 test_expect_success \
236 '16 - conflicting local change.' \
237 'rm -f .git/index &&
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'
243
244 test_expect_success \
245 '17 - conflicting local change.' \
246 'rm -f .git/index &&
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'
253
254 test_expect_success \
255 '18 - local change already having a good result.' \
256 'rm -f .git/index &&
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'
265
266 test_expect_success \
267 '19 - local change already having a good result, further modified.' \
268 'rm -f .git/index &&
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'
278
279 test_expect_success \
280 '20 - no local change, use new tree.' \
281 'rm -f .git/index &&
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'
290
291 test_expect_success \
292 '21 - no local change, dirty cache.' \
293 'rm -f .git/index &&
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'
300
301 # This fails with straight two-way fast-forward.
302 test_expect_success \
303 '22 - local change cache updated.' \
304 'rm -f .git/index &&
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'
310
311 # Also make sure we did not break DF vs DF/DF case.
312 test_expect_success \
313 'DF vs DF/DF case setup.' \
314 'rm -f .git/index &&
315 echo DF >DF &&
316 git update-index --add DF &&
317 treeDF=`git write-tree` &&
318 echo treeDF $treeDF &&
319 git ls-tree $treeDF &&
320
321 rm -f DF &&
322 mkdir DF &&
323 echo DF/DF >DF/DF &&
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'
329
330 test_expect_success \
331 'DF vs DF/DF case test.' \
332 'rm -f .git/index &&
333 rm -fr DF &&
334 echo DF >DF &&
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 &&
340 :'
341
342 test_expect_success \
343 'a/b (untracked) vs a case setup.' \
344 'rm -f .git/index &&
345 : >a &&
346 git update-index --add a &&
347 treeM=`git write-tree` &&
348 echo treeM $treeM &&
349 git ls-tree $treeM &&
350 git ls-files --stage >treeM.out &&
351
352 rm -f a &&
353 git update-index --remove a &&
354 mkdir a &&
355 : >a/b &&
356 treeH=`git write-tree` &&
357 echo treeH $treeH &&
358 git ls-tree $treeH'
359
360 test_expect_success \
361 'a/b (untracked) vs a, plus c/d case test.' \
362 '! git read-tree -u -m "$treeH" "$treeM" &&
363 git ls-files --stage &&
364 test -f a/b'
365
366 test_expect_success \
367 'a/b vs a, plus c/d case setup.' \
368 'rm -f .git/index &&
369 rm -fr a &&
370 : >a &&
371 mkdir c &&
372 : >c/d &&
373 git update-index --add a c/d &&
374 treeM=`git write-tree` &&
375 echo treeM $treeM &&
376 git ls-tree $treeM &&
377 git ls-files --stage >treeM.out &&
378
379 rm -f a &&
380 mkdir a
381 : >a/b &&
382 git update-index --add --remove a a/b &&
383 treeH=`git write-tree` &&
384 echo treeH $treeH &&
385 git ls-tree $treeH'
386
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'
392
393 test_done