]>
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 | 22 | ' |
e5a917fc | 23 | |
6ab75ac8 | 24 | TEST_PASSES_SANITIZE_LEAK=true |
c8596009 | 25 | . ./test-lib.sh |
ea5070c9 | 26 | . "$TEST_DIRECTORY"/lib-read-tree.sh |
c8596009 | 27 | |
76bc82ca | 28 | read_tree_twoway () { |
58db6e45 | 29 | git read-tree -m "$1" "$2" && git ls-files --stage |
76bc82ca JH |
30 | } |
31 | ||
c8596009 | 32 | compare_change () { |
76bc82ca | 33 | sed -n >current \ |
c8596009 | 34 | -e '/^--- /d; /^+++ /d; /^@@ /d;' \ |
2ece6ad2 | 35 | -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$OID_REGEX"' /\1 X /p' \ |
76bc82ca | 36 | "$1" |
3af82863 | 37 | test_cmp expected current |
c8596009 JH |
38 | } |
39 | ||
40 | check_cache_at () { | |
277ce796 ÆAB |
41 | git diff-files -- "$1" >out && |
42 | clean_if_empty=$(cat out) && | |
c8596009 JH |
43 | case "$clean_if_empty" in |
44 | '') echo "$1: clean" ;; | |
45 | ?*) echo "$1: dirty" ;; | |
277ce796 | 46 | esac && |
c8596009 JH |
47 | case "$2,$clean_if_empty" in |
48 | clean,) : ;; | |
49 | clean,?*) false ;; | |
50 | dirty,) false ;; | |
51 | dirty,?*) : ;; | |
52 | esac | |
53 | } | |
54 | ||
1abb3f14 | 55 | cat >bozbar-old <<\EOF |
a75d7b54 | 56 | This is a sample file used in two-way fast-forward merge |
1abb3f14 JH |
57 | tests. Its second line ends with a magic word bozbar |
58 | which will be modified by the merged head to gnusto. | |
59 | It has some extra lines so that external tools can | |
60 | successfully merge independent changes made to later | |
61 | lines (such as this one), avoiding line conflicts. | |
62 | EOF | |
63 | ||
64 | sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new | |
65 | ||
83587d52 SB |
66 | test_expect_success 'setup' ' |
67 | echo frotz >frotz && | |
68 | echo nitfol >nitfol && | |
69 | cat bozbar-old >bozbar && | |
70 | echo rezrov >rezrov && | |
71 | echo yomin >yomin && | |
72 | git update-index --add nitfol bozbar rezrov && | |
73 | treeH=$(git write-tree) && | |
74 | echo treeH $treeH && | |
75 | git ls-tree $treeH && | |
76 | ||
77 | cat bozbar-new >bozbar && | |
78 | git update-index --add frotz bozbar --force-remove rezrov && | |
79 | git ls-files --stage >M.out && | |
80 | treeM=$(git write-tree) && | |
81 | echo treeM $treeM && | |
82 | git ls-tree $treeM && | |
83 | git diff-tree $treeH $treeM | |
84 | ' | |
c8596009 | 85 | |
83587d52 SB |
86 | test_expect_success '1, 2, 3 - no carry forward' ' |
87 | rm -f .git/index && | |
88 | read_tree_twoway $treeH $treeM && | |
89 | git ls-files --stage >1-3.out && | |
90 | test_cmp M.out 1-3.out && | |
91 | check_cache_at bozbar dirty && | |
92 | check_cache_at frotz dirty && | |
93 | check_cache_at nitfol dirty | |
94 | ' | |
c8596009 JH |
95 | echo '+100644 X 0 yomin' >expected |
96 | ||
83587d52 SB |
97 | test_expect_success '4 - carry forward local addition.' ' |
98 | rm -f .git/index && | |
99 | read_tree_must_succeed $treeH && | |
100 | git checkout-index -u -f -q -a && | |
101 | git update-index --add yomin && | |
102 | read_tree_twoway $treeH $treeM && | |
103 | git ls-files --stage >4.out && | |
104 | test_must_fail git diff --no-index M.out 4.out >4diff.out && | |
105 | compare_change 4diff.out expected && | |
106 | check_cache_at yomin clean | |
107 | ' | |
108 | ||
109 | test_expect_success '5 - carry forward local addition.' ' | |
110 | rm -f .git/index && | |
111 | read_tree_must_succeed $treeH && | |
112 | git checkout-index -u -f -q -a && | |
113 | echo yomin >yomin && | |
114 | git update-index --add yomin && | |
115 | echo yomin yomin >yomin && | |
116 | read_tree_twoway $treeH $treeM && | |
117 | git ls-files --stage >5.out && | |
118 | test_must_fail git diff --no-index M.out 5.out >5diff.out && | |
119 | compare_change 5diff.out expected && | |
120 | check_cache_at yomin dirty | |
121 | ' | |
122 | ||
123 | test_expect_success '6 - local addition already has the same.' ' | |
124 | rm -f .git/index && | |
125 | read_tree_must_succeed $treeH && | |
126 | git checkout-index -u -f -q -a && | |
127 | git update-index --add frotz && | |
128 | read_tree_twoway $treeH $treeM && | |
129 | git ls-files --stage >6.out && | |
130 | test_cmp M.out 6.out && | |
131 | check_cache_at frotz clean | |
132 | ' | |
133 | ||
134 | test_expect_success '7 - local addition already has the same.' ' | |
135 | rm -f .git/index && | |
136 | read_tree_must_succeed $treeH && | |
137 | git checkout-index -u -f -q -a && | |
138 | echo frotz >frotz && | |
139 | git update-index --add frotz && | |
140 | echo frotz frotz >frotz && | |
141 | read_tree_twoway $treeH $treeM && | |
142 | git ls-files --stage >7.out && | |
143 | test_cmp M.out 7.out && | |
144 | check_cache_at frotz dirty | |
145 | ' | |
146 | ||
147 | test_expect_success '8 - conflicting addition.' ' | |
148 | rm -f .git/index && | |
149 | read_tree_must_succeed $treeH && | |
150 | git checkout-index -u -f -q -a && | |
151 | echo frotz frotz >frotz && | |
152 | git update-index --add frotz && | |
153 | if read_tree_twoway $treeH $treeM; then false; else :; fi | |
154 | ' | |
155 | ||
156 | test_expect_success '9 - conflicting addition.' ' | |
157 | rm -f .git/index && | |
158 | read_tree_must_succeed $treeH && | |
159 | git checkout-index -u -f -q -a && | |
160 | echo frotz frotz >frotz && | |
161 | git update-index --add frotz && | |
162 | echo frotz >frotz && | |
163 | if read_tree_twoway $treeH $treeM; then false; else :; fi | |
164 | ' | |
165 | ||
166 | test_expect_success '10 - path removed.' ' | |
167 | rm -f .git/index && | |
168 | read_tree_must_succeed $treeH && | |
169 | git checkout-index -u -f -q -a && | |
170 | echo rezrov >rezrov && | |
171 | git update-index --add rezrov && | |
172 | read_tree_twoway $treeH $treeM && | |
173 | git ls-files --stage >10.out && | |
174 | test_cmp M.out 10.out | |
175 | ' | |
176 | ||
177 | test_expect_success '11 - dirty path removed.' ' | |
178 | rm -f .git/index && | |
179 | read_tree_must_succeed $treeH && | |
180 | git checkout-index -u -f -q -a && | |
181 | echo rezrov >rezrov && | |
182 | git update-index --add rezrov && | |
183 | echo rezrov rezrov >rezrov && | |
184 | if read_tree_twoway $treeH $treeM; then false; else :; fi | |
185 | ' | |
186 | ||
187 | test_expect_success '12 - unmatching local changes being removed.' ' | |
188 | rm -f .git/index && | |
189 | read_tree_must_succeed $treeH && | |
190 | git checkout-index -u -f -q -a && | |
191 | echo rezrov rezrov >rezrov && | |
192 | git update-index --add rezrov && | |
193 | if read_tree_twoway $treeH $treeM; then false; else :; fi | |
194 | ' | |
195 | ||
196 | test_expect_success '13 - unmatching local changes being removed.' ' | |
197 | rm -f .git/index && | |
198 | read_tree_must_succeed $treeH && | |
199 | git checkout-index -u -f -q -a && | |
200 | echo rezrov rezrov >rezrov && | |
201 | git update-index --add rezrov && | |
202 | echo rezrov >rezrov && | |
203 | if read_tree_twoway $treeH $treeM; then false; else :; fi | |
204 | ' | |
c8596009 JH |
205 | |
206 | cat >expected <<EOF | |
207 | -100644 X 0 nitfol | |
208 | +100644 X 0 nitfol | |
209 | EOF | |
210 | ||
83587d52 SB |
211 | test_expect_success '14 - unchanged in two heads.' ' |
212 | rm -f .git/index && | |
213 | read_tree_must_succeed $treeH && | |
214 | git checkout-index -u -f -q -a && | |
215 | echo nitfol nitfol >nitfol && | |
216 | git update-index --add nitfol && | |
217 | read_tree_twoway $treeH $treeM && | |
218 | git ls-files --stage >14.out && | |
219 | test_must_fail git diff --no-index M.out 14.out >14diff.out && | |
220 | compare_change 14diff.out expected && | |
221 | check_cache_at nitfol clean | |
222 | ' | |
223 | ||
224 | test_expect_success '15 - unchanged in two heads.' ' | |
225 | rm -f .git/index && | |
226 | read_tree_must_succeed $treeH && | |
227 | git checkout-index -u -f -q -a && | |
228 | echo nitfol nitfol >nitfol && | |
229 | git update-index --add nitfol && | |
230 | echo nitfol nitfol nitfol >nitfol && | |
231 | read_tree_twoway $treeH $treeM && | |
232 | git ls-files --stage >15.out && | |
233 | test_must_fail git diff --no-index M.out 15.out >15diff.out && | |
234 | compare_change 15diff.out expected && | |
235 | check_cache_at nitfol dirty | |
236 | ' | |
237 | ||
238 | test_expect_success '16 - conflicting local change.' ' | |
239 | rm -f .git/index && | |
240 | read_tree_must_succeed $treeH && | |
241 | git checkout-index -u -f -q -a && | |
242 | echo bozbar bozbar >bozbar && | |
243 | git update-index --add bozbar && | |
244 | if read_tree_twoway $treeH $treeM; then false; else :; fi | |
245 | ' | |
246 | ||
247 | test_expect_success '17 - conflicting local change.' ' | |
248 | rm -f .git/index && | |
249 | read_tree_must_succeed $treeH && | |
250 | git checkout-index -u -f -q -a && | |
251 | echo bozbar bozbar >bozbar && | |
252 | git update-index --add bozbar && | |
253 | echo bozbar bozbar bozbar >bozbar && | |
254 | if read_tree_twoway $treeH $treeM; then false; else :; fi | |
255 | ' | |
256 | ||
257 | test_expect_success '18 - local change already having a good result.' ' | |
258 | rm -f .git/index && | |
259 | read_tree_must_succeed $treeH && | |
260 | git checkout-index -u -f -q -a && | |
261 | cat bozbar-new >bozbar && | |
262 | git update-index --add bozbar && | |
263 | read_tree_twoway $treeH $treeM && | |
264 | git ls-files --stage >18.out && | |
265 | test_cmp M.out 18.out && | |
266 | check_cache_at bozbar clean | |
267 | ' | |
268 | ||
269 | test_expect_success '19 - local change already having a good result, further modified.' ' | |
270 | rm -f .git/index && | |
271 | read_tree_must_succeed $treeH && | |
272 | git checkout-index -u -f -q -a && | |
273 | cat bozbar-new >bozbar && | |
274 | git update-index --add bozbar && | |
275 | echo gnusto gnusto >bozbar && | |
276 | read_tree_twoway $treeH $treeM && | |
277 | git ls-files --stage >19.out && | |
278 | test_cmp M.out 19.out && | |
279 | check_cache_at bozbar dirty | |
280 | ' | |
281 | ||
282 | test_expect_success '20 - no local change, use new tree.' ' | |
283 | rm -f .git/index && | |
284 | read_tree_must_succeed $treeH && | |
285 | git checkout-index -u -f -q -a && | |
286 | cat bozbar-old >bozbar && | |
287 | git update-index --add bozbar && | |
288 | read_tree_twoway $treeH $treeM && | |
289 | git ls-files --stage >20.out && | |
290 | test_cmp M.out 20.out && | |
291 | check_cache_at bozbar dirty | |
292 | ' | |
293 | ||
294 | test_expect_success '21 - no local change, dirty cache.' ' | |
295 | rm -f .git/index && | |
296 | read_tree_must_succeed $treeH && | |
297 | git checkout-index -u -f -q -a && | |
298 | cat bozbar-old >bozbar && | |
299 | git update-index --add bozbar && | |
300 | echo gnusto gnusto >bozbar && | |
301 | if read_tree_twoway $treeH $treeM; then false; else :; fi | |
302 | ' | |
c8596009 | 303 | |
a75d7b54 | 304 | # This fails with straight two-way fast-forward. |
83587d52 SB |
305 | test_expect_success '22 - local change cache updated.' ' |
306 | rm -f .git/index && | |
307 | read_tree_must_succeed $treeH && | |
308 | git checkout-index -u -f -q -a && | |
309 | sed -e "s/such as/SUCH AS/" bozbar-old >bozbar && | |
310 | git update-index --add bozbar && | |
311 | if read_tree_twoway $treeH $treeM; then false; else :; fi | |
312 | ' | |
1abb3f14 | 313 | |
c8596009 | 314 | # Also make sure we did not break DF vs DF/DF case. |
83587d52 SB |
315 | test_expect_success 'DF vs DF/DF case setup.' ' |
316 | rm -f .git/index && | |
317 | echo DF >DF && | |
318 | git update-index --add DF && | |
319 | treeDF=$(git write-tree) && | |
320 | echo treeDF $treeDF && | |
321 | git ls-tree $treeDF && | |
322 | ||
323 | rm -f DF && | |
324 | mkdir DF && | |
325 | echo DF/DF >DF/DF && | |
326 | git update-index --add --remove DF DF/DF && | |
327 | treeDFDF=$(git write-tree) && | |
328 | echo treeDFDF $treeDFDF && | |
329 | git ls-tree $treeDFDF && | |
330 | git ls-files --stage >DFDF.out | |
331 | ' | |
332 | ||
333 | test_expect_success 'DF vs DF/DF case test.' ' | |
334 | rm -f .git/index && | |
335 | rm -fr DF && | |
336 | echo DF >DF && | |
337 | git update-index --add DF && | |
338 | read_tree_twoway $treeDF $treeDFDF && | |
339 | git ls-files --stage >DFDFcheck.out && | |
340 | test_cmp DFDF.out DFDFcheck.out && | |
341 | check_cache_at DF/DF dirty && | |
342 | : | |
343 | ' | |
344 | ||
345 | test_expect_success 'a/b (untracked) vs a case setup.' ' | |
346 | rm -f .git/index && | |
347 | : >a && | |
348 | git update-index --add a && | |
349 | treeM=$(git write-tree) && | |
350 | echo treeM $treeM && | |
351 | git ls-tree $treeM && | |
352 | git ls-files --stage >treeM.out && | |
353 | ||
354 | rm -f a && | |
355 | git update-index --remove a && | |
356 | mkdir a && | |
357 | : >a/b && | |
358 | treeH=$(git write-tree) && | |
359 | echo treeH $treeH && | |
360 | git ls-tree $treeH | |
361 | ' | |
362 | ||
363 | test_expect_success 'a/b (untracked) vs a, plus c/d case test.' ' | |
364 | read_tree_u_must_fail -u -m "$treeH" "$treeM" && | |
365 | git ls-files --stage && | |
366 | test -f a/b | |
367 | ' | |
368 | ||
3d415425 SB |
369 | test_expect_success 'read-tree supports the super-prefix' ' |
370 | cat <<-EOF >expect && | |
371 | error: Updating '\''fictional/a'\'' would lose untracked files in it | |
372 | EOF | |
4002ec3d | 373 | test_must_fail git read-tree --super-prefix fictional/ -u -m "$treeH" "$treeM" 2>actual && |
3d415425 SB |
374 | test_cmp expect actual |
375 | ' | |
376 | ||
83587d52 SB |
377 | test_expect_success 'a/b vs a, plus c/d case setup.' ' |
378 | rm -f .git/index && | |
379 | rm -fr a && | |
380 | : >a && | |
381 | mkdir c && | |
382 | : >c/d && | |
383 | git update-index --add a c/d && | |
384 | treeM=$(git write-tree) && | |
385 | echo treeM $treeM && | |
386 | git ls-tree $treeM && | |
387 | git ls-files --stage >treeM.out && | |
388 | ||
389 | rm -f a && | |
390 | mkdir a && | |
391 | : >a/b && | |
392 | git update-index --add --remove a a/b && | |
393 | treeH=$(git write-tree) && | |
394 | echo treeH $treeH && | |
395 | git ls-tree $treeH | |
396 | ' | |
397 | ||
398 | test_expect_success 'a/b vs a, plus c/d case test.' ' | |
399 | read_tree_u_must_succeed -u -m "$treeH" "$treeM" && | |
400 | git ls-files --stage | tee >treeMcheck.out && | |
401 | test_cmp treeM.out treeMcheck.out | |
402 | ' | |
837e5fe9 | 403 | |
b1f47514 JH |
404 | test_expect_success '-m references the correct modified tree' ' |
405 | echo >file-a && | |
406 | echo >file-b && | |
407 | git add file-a file-b && | |
a48fcd83 | 408 | git commit -a -m "test for correct modified tree" && |
b1f47514 JH |
409 | git branch initial-mod && |
410 | echo b >file-b && | |
411 | git commit -a -m "B" && | |
412 | echo a >file-a && | |
413 | git add file-a && | |
414 | git ls-tree $(git write-tree) file-a >expect && | |
ea5070c9 | 415 | read_tree_must_succeed -m HEAD initial-mod && |
b1f47514 JH |
416 | git ls-tree $(git write-tree) file-a >actual && |
417 | test_cmp expect actual | |
418 | ' | |
419 | ||
c8596009 | 420 | test_done |