Commit | Line | Data |
---|---|---|
c8596009 JH |
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 | ||
a75d7b54 | 8 | This test tries two-way merge (aka fast-forward with carry forward). |
c8596009 JH |
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" | |
5be60078 | 14 | rules, found in <Documentation/git read-tree.txt>. |
c8596009 JH |
15 | |
16 | In the test, these paths are used: | |
83587d52 SB |
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 | |
235e8d59 | 21 | yomin - not in H or M |
c8596009 JH |
22 | ' |
23 | . ./test-lib.sh | |
ea5070c9 | 24 | . "$TEST_DIRECTORY"/lib-read-tree.sh |
c8596009 | 25 | |
76bc82ca | 26 | read_tree_twoway () { |
5be60078 | 27 | git read-tree -m "$1" "$2" && git ls-files --stage |
76bc82ca JH |
28 | } |
29 | ||
c8596009 | 30 | compare_change () { |
76bc82ca | 31 | sed -n >current \ |
c8596009 | 32 | -e '/^--- /d; /^+++ /d; /^@@ /d;' \ |
2ece6ad2 | 33 | -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$OID_REGEX"' /\1 X /p' \ |
76bc82ca | 34 | "$1" |
3af82863 | 35 | test_cmp expected current |
c8596009 JH |
36 | } |
37 | ||
38 | check_cache_at () { | |
142efa3e | 39 | clean_if_empty=$(git diff-files -- "$1") |
c8596009 JH |
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 | ||
1abb3f14 | 52 | cat >bozbar-old <<\EOF |
a75d7b54 | 53 | This is a sample file used in two-way fast-forward merge |
1abb3f14 JH |
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 | ||
83587d52 SB |
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 | ' | |
c8596009 | 82 | |
83587d52 SB |
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 | ' | |
c8596009 JH |
92 | echo '+100644 X 0 yomin' >expected |
93 | ||
83587d52 SB |
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 | ' | |
c8596009 JH |
202 | |
203 | cat >expected <<EOF | |
204 | -100644 X 0 nitfol | |
205 | +100644 X 0 nitfol | |
206 | EOF | |
207 | ||
83587d52 SB |
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 | ' | |
c8596009 | 300 | |
a75d7b54 | 301 | # This fails with straight two-way fast-forward. |
83587d52 SB |
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 | ' | |
1abb3f14 | 310 | |
c8596009 | 311 | # Also make sure we did not break DF vs DF/DF case. |
83587d52 SB |
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 | ||
3d415425 SB |
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 | ||
83587d52 SB |
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 | ' | |
837e5fe9 | 400 | |
b1f47514 JH |
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 && | |
a48fcd83 | 405 | git commit -a -m "test for correct modified tree" && |
b1f47514 JH |
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 && | |
ea5070c9 | 412 | read_tree_must_succeed -m HEAD initial-mod && |
b1f47514 JH |
413 | git ls-tree $(git write-tree) file-a >actual && |
414 | test_cmp expect actual | |
415 | ' | |
416 | ||
c8596009 | 417 | test_done |