]>
Commit | Line | Data |
---|---|---|
c94736a2 JH |
1 | #!/bin/sh |
2 | ||
695576fd | 3 | test_description='recursive merge corner cases involving criss-cross merges' |
c94736a2 JH |
4 | |
5 | . ./test-lib.sh | |
f06481f1 | 6 | . "$TEST_DIRECTORY"/lib-merge.sh |
c94736a2 JH |
7 | |
8 | # | |
9 | # L1 L2 | |
10 | # o---o | |
11 | # / \ / \ | |
12 | # o X ? | |
13 | # \ / \ / | |
14 | # o---o | |
15 | # R1 R2 | |
16 | # | |
17 | ||
c976260d | 18 | test_expect_success 'setup basic criss-cross + rename with no modifications' ' |
2a4c19ef EN |
19 | test_create_repo basic-rename && |
20 | ( | |
21 | cd basic-rename && | |
22 | ||
23 | ten="0 1 2 3 4 5 6 7 8 9" && | |
24 | for i in $ten | |
25 | do | |
26 | echo line $i in a sample file | |
27 | done >one && | |
28 | for i in $ten | |
29 | do | |
30 | echo line $i in another sample file | |
31 | done >two && | |
32 | git add one two && | |
33 | test_tick && git commit -m initial && | |
34 | ||
35 | git branch L1 && | |
36 | git checkout -b R1 && | |
37 | git mv one three && | |
38 | test_tick && git commit -m R1 && | |
39 | ||
40 | git checkout L1 && | |
41 | git mv two three && | |
42 | test_tick && git commit -m L1 && | |
43 | ||
44 | git checkout L1^0 && | |
45 | test_tick && git merge -s ours R1 && | |
46 | git tag L2 && | |
47 | ||
48 | git checkout R1^0 && | |
49 | test_tick && git merge -s ours L1 && | |
50 | git tag R2 | |
51 | ) | |
c94736a2 JH |
52 | ' |
53 | ||
c976260d | 54 | test_expect_success 'merge simple rename+criss-cross with no modifications' ' |
2a4c19ef EN |
55 | ( |
56 | cd basic-rename && | |
57 | ||
58 | git reset --hard && | |
59 | git checkout L2^0 && | |
c94736a2 | 60 | |
2a4c19ef | 61 | test_must_fail git merge -s recursive R2^0 && |
c976260d | 62 | |
0cdabc10 | 63 | git ls-files -s >out && |
80205040 | 64 | test_line_count = 5 out && |
0cdabc10 | 65 | git ls-files -u >out && |
80205040 | 66 | test_line_count = 3 out && |
0cdabc10 | 67 | git ls-files -o >out && |
bbafc9c4 | 68 | test_line_count = 1 out && |
c976260d | 69 | |
6ac767e5 | 70 | git rev-parse >expect \ |
6ac767e5 EN |
71 | L2:three R2:three && |
72 | git rev-parse >actual \ | |
73 | :2:three :3:three && | |
6ac767e5 | 74 | test_cmp expect actual |
2a4c19ef | 75 | ) |
c94736a2 JH |
76 | ' |
77 | ||
583942df EN |
78 | # |
79 | # Same as before, but modify L1 slightly: | |
80 | # | |
81 | # L1m L2 | |
82 | # o---o | |
83 | # / \ / \ | |
84 | # o X ? | |
85 | # \ / \ / | |
86 | # o---o | |
87 | # R1 R2 | |
88 | # | |
89 | ||
90 | test_expect_success 'setup criss-cross + rename merges with basic modification' ' | |
2a4c19ef EN |
91 | test_create_repo rename-modify && |
92 | ( | |
93 | cd rename-modify && | |
94 | ||
95 | ten="0 1 2 3 4 5 6 7 8 9" && | |
96 | for i in $ten | |
97 | do | |
98 | echo line $i in a sample file | |
99 | done >one && | |
100 | for i in $ten | |
101 | do | |
102 | echo line $i in another sample file | |
103 | done >two && | |
104 | git add one two && | |
105 | test_tick && git commit -m initial && | |
106 | ||
107 | git branch L1 && | |
108 | git checkout -b R1 && | |
109 | git mv one three && | |
110 | echo more >>two && | |
111 | git add two && | |
112 | test_tick && git commit -m R1 && | |
113 | ||
114 | git checkout L1 && | |
115 | git mv two three && | |
116 | test_tick && git commit -m L1 && | |
117 | ||
118 | git checkout L1^0 && | |
119 | test_tick && git merge -s ours R1 && | |
120 | git tag L2 && | |
121 | ||
122 | git checkout R1^0 && | |
123 | test_tick && git merge -s ours L1 && | |
124 | git tag R2 | |
125 | ) | |
583942df EN |
126 | ' |
127 | ||
2a669c34 | 128 | test_expect_success 'merge criss-cross + rename merges with basic modification' ' |
2a4c19ef EN |
129 | ( |
130 | cd rename-modify && | |
131 | ||
132 | git checkout L2^0 && | |
583942df | 133 | |
2a4c19ef | 134 | test_must_fail git merge -s recursive R2^0 && |
583942df | 135 | |
0cdabc10 | 136 | git ls-files -s >out && |
80205040 | 137 | test_line_count = 5 out && |
0cdabc10 | 138 | git ls-files -u >out && |
80205040 | 139 | test_line_count = 3 out && |
0cdabc10 | 140 | git ls-files -o >out && |
bbafc9c4 | 141 | test_line_count = 1 out && |
583942df | 142 | |
6ac767e5 | 143 | git rev-parse >expect \ |
6ac767e5 EN |
144 | L2:three R2:three && |
145 | git rev-parse >actual \ | |
146 | :2:three :3:three && | |
6ac767e5 | 147 | test_cmp expect actual |
2a4c19ef | 148 | ) |
583942df EN |
149 | ' |
150 | ||
f63622c0 EN |
151 | # |
152 | # For the next test, we start with three commits in two lines of development | |
153 | # which setup a rename/add conflict: | |
154 | # Commit A: File 'a' exists | |
155 | # Commit B: Rename 'a' -> 'new_a' | |
156 | # Commit C: Modify 'a', create different 'new_a' | |
157 | # Later, two different people merge and resolve differently: | |
158 | # Commit D: Merge B & C, ignoring separately created 'new_a' | |
159 | # Commit E: Merge B & C making use of some piece of secondary 'new_a' | |
160 | # Finally, someone goes to merge D & E. Does git detect the conflict? | |
161 | # | |
162 | # B D | |
163 | # o---o | |
164 | # / \ / \ | |
165 | # A o X ? F | |
166 | # \ / \ / | |
167 | # o---o | |
168 | # C E | |
169 | # | |
170 | ||
171 | test_expect_success 'setup differently handled merges of rename/add conflict' ' | |
2a4c19ef EN |
172 | test_create_repo rename-add && |
173 | ( | |
174 | cd rename-add && | |
175 | ||
176 | printf "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n" >a && | |
177 | git add a && | |
178 | test_tick && git commit -m A && | |
179 | ||
180 | git branch B && | |
181 | git checkout -b C && | |
182 | echo 10 >>a && | |
7f867165 | 183 | test_write_lines 0 1 2 3 4 5 6 7 foobar >new_a && |
2a4c19ef EN |
184 | git add a new_a && |
185 | test_tick && git commit -m C && | |
186 | ||
187 | git checkout B && | |
188 | git mv a new_a && | |
189 | test_tick && git commit -m B && | |
190 | ||
191 | git checkout B^0 && | |
192 | test_must_fail git merge C && | |
7f867165 EN |
193 | git show :2:new_a >new_a && |
194 | git add new_a && | |
2a4c19ef EN |
195 | test_tick && git commit -m D && |
196 | git tag D && | |
197 | ||
198 | git checkout C^0 && | |
199 | test_must_fail git merge B && | |
7f867165 | 200 | test_write_lines 0 1 2 3 4 5 6 7 bad_merge >new_a && |
2a4c19ef EN |
201 | git add -u && |
202 | test_tick && git commit -m E && | |
203 | git tag E | |
204 | ) | |
f63622c0 EN |
205 | ' |
206 | ||
2a669c34 | 207 | test_expect_success 'git detects differently handled merges conflict' ' |
2a4c19ef EN |
208 | ( |
209 | cd rename-add && | |
210 | ||
211 | git checkout D^0 && | |
212 | ||
213 | test_must_fail git merge -s recursive E^0 && | |
214 | ||
0cdabc10 EN |
215 | git ls-files -s >out && |
216 | test_line_count = 3 out && | |
217 | git ls-files -u >out && | |
218 | test_line_count = 3 out && | |
219 | git ls-files -o >out && | |
220 | test_line_count = 1 out && | |
2a4c19ef | 221 | |
80205040 EN |
222 | git cat-file -p C:new_a >ours && |
223 | git cat-file -p C:a >theirs && | |
224 | >empty && | |
225 | test_must_fail git merge-file \ | |
226 | -L "Temporary merge branch 1" \ | |
227 | -L "" \ | |
228 | -L "Temporary merge branch 2" \ | |
229 | ours empty theirs && | |
230 | sed -e "s/^\([<=>]\)/\1\1\1/" ours >ours-tweaked && | |
231 | git hash-object ours-tweaked >expect && | |
232 | git rev-parse >>expect \ | |
233 | D:new_a E:new_a && | |
6ac767e5 | 234 | git rev-parse >actual \ |
7f867165 | 235 | :1:new_a :2:new_a :3:new_a && |
c8ce3763 | 236 | test_cmp expect actual && |
2a4c19ef | 237 | |
7f867165 EN |
238 | # Test that the two-way merge in new_a is as expected |
239 | git cat-file -p D:new_a >ours && | |
240 | git cat-file -p E:new_a >theirs && | |
2a4c19ef EN |
241 | >empty && |
242 | test_must_fail git merge-file \ | |
7f867165 | 243 | -L "HEAD" \ |
4f445453 | 244 | -L "" \ |
7f867165 | 245 | -L "E^0" \ |
6ac767e5 EN |
246 | ours empty theirs && |
247 | sed -e "s/^\([<=>]\)/\1\1\1/" ours >expect && | |
7f867165 EN |
248 | git hash-object new_a >actual && |
249 | git hash-object ours >expect && | |
6ac767e5 | 250 | test_cmp expect actual |
2a4c19ef | 251 | ) |
c94736a2 JH |
252 | ' |
253 | ||
b8cd1bb7 EN |
254 | # Repeat the above testcase with precisely the same setup, other than with |
255 | # the two merge bases having different orderings of commit timestamps so | |
256 | # that they are reversed in the order they are provided to merge-recursive, | |
257 | # so that we can improve code coverage. | |
258 | test_expect_success 'git detects differently handled merges conflict, swapped' ' | |
259 | ( | |
260 | cd rename-add && | |
261 | ||
262 | # Difference #1: Do cleanup from previous testrun | |
263 | git reset --hard && | |
264 | git clean -fdqx && | |
265 | ||
266 | # Difference #2: Change commit timestamps | |
267 | btime=$(git log --no-walk --date=raw --format=%cd B | awk "{print \$1}") && | |
268 | ctime=$(git log --no-walk --date=raw --format=%cd C | awk "{print \$1}") && | |
269 | newctime=$(($btime+1)) && | |
270 | git fast-export --no-data --all | sed -e s/$ctime/$newctime/ | git fast-import --force --quiet && | |
80205040 EN |
271 | # End of most differences; rest is copy-paste of last test, |
272 | # other than swapping C:a and C:new_a due to order switch | |
b8cd1bb7 EN |
273 | |
274 | git checkout D^0 && | |
275 | test_must_fail git merge -s recursive E^0 && | |
276 | ||
277 | git ls-files -s >out && | |
278 | test_line_count = 3 out && | |
279 | git ls-files -u >out && | |
280 | test_line_count = 3 out && | |
281 | git ls-files -o >out && | |
282 | test_line_count = 1 out && | |
283 | ||
80205040 EN |
284 | git cat-file -p C:a >ours && |
285 | git cat-file -p C:new_a >theirs && | |
286 | >empty && | |
287 | test_must_fail git merge-file \ | |
288 | -L "Temporary merge branch 1" \ | |
289 | -L "" \ | |
290 | -L "Temporary merge branch 2" \ | |
291 | ours empty theirs && | |
292 | sed -e "s/^\([<=>]\)/\1\1\1/" ours >ours-tweaked && | |
293 | git hash-object ours-tweaked >expect && | |
294 | git rev-parse >>expect \ | |
295 | D:new_a E:new_a && | |
b8cd1bb7 EN |
296 | git rev-parse >actual \ |
297 | :1:new_a :2:new_a :3:new_a && | |
298 | test_cmp expect actual && | |
299 | ||
300 | # Test that the two-way merge in new_a is as expected | |
301 | git cat-file -p D:new_a >ours && | |
302 | git cat-file -p E:new_a >theirs && | |
303 | >empty && | |
304 | test_must_fail git merge-file \ | |
305 | -L "HEAD" \ | |
306 | -L "" \ | |
307 | -L "E^0" \ | |
308 | ours empty theirs && | |
309 | sed -e "s/^\([<=>]\)/\1\1\1/" ours >expect && | |
310 | git hash-object new_a >actual && | |
311 | git hash-object ours >expect && | |
312 | test_cmp expect actual | |
313 | ) | |
314 | ' | |
315 | ||
fe7e9c23 EN |
316 | # |
317 | # criss-cross + modify/delete: | |
318 | # | |
319 | # B D | |
320 | # o---o | |
321 | # / \ / \ | |
322 | # A o X ? F | |
323 | # \ / \ / | |
324 | # o---o | |
325 | # C E | |
326 | # | |
327 | # Commit A: file with contents 'A\n' | |
328 | # Commit B: file with contents 'B\n' | |
329 | # Commit C: file not present | |
330 | # Commit D: file with contents 'B\n' | |
331 | # Commit E: file not present | |
332 | # | |
333 | # Merging commits D & E should result in modify/delete conflict. | |
334 | ||
335 | test_expect_success 'setup criss-cross + modify/delete resolved differently' ' | |
2a4c19ef EN |
336 | test_create_repo modify-delete && |
337 | ( | |
338 | cd modify-delete && | |
339 | ||
340 | echo A >file && | |
341 | git add file && | |
342 | test_tick && | |
343 | git commit -m A && | |
344 | ||
345 | git branch B && | |
346 | git checkout -b C && | |
347 | git rm file && | |
348 | test_tick && | |
349 | git commit -m C && | |
350 | ||
351 | git checkout B && | |
352 | echo B >file && | |
353 | git add file && | |
354 | test_tick && | |
355 | git commit -m B && | |
356 | ||
357 | git checkout B^0 && | |
358 | test_must_fail git merge C && | |
359 | echo B >file && | |
360 | git add file && | |
361 | test_tick && | |
362 | git commit -m D && | |
363 | git tag D && | |
364 | ||
365 | git checkout C^0 && | |
366 | test_must_fail git merge B && | |
367 | git rm file && | |
368 | test_tick && | |
369 | git commit -m E && | |
370 | git tag E | |
371 | ) | |
fe7e9c23 EN |
372 | ' |
373 | ||
ec61d149 | 374 | test_expect_success 'git detects conflict merging criss-cross+modify/delete' ' |
2a4c19ef EN |
375 | ( |
376 | cd modify-delete && | |
377 | ||
378 | git checkout D^0 && | |
fe7e9c23 | 379 | |
2a4c19ef | 380 | test_must_fail git merge -s recursive E^0 && |
fe7e9c23 | 381 | |
0cdabc10 EN |
382 | git ls-files -s >out && |
383 | test_line_count = 2 out && | |
384 | git ls-files -u >out && | |
385 | test_line_count = 2 out && | |
fe7e9c23 | 386 | |
6ac767e5 EN |
387 | git rev-parse >expect \ |
388 | master:file B:file && | |
389 | git rev-parse >actual \ | |
390 | :1:file :2:file && | |
391 | test_cmp expect actual | |
2a4c19ef | 392 | ) |
fe7e9c23 EN |
393 | ' |
394 | ||
ec61d149 | 395 | test_expect_success 'git detects conflict merging criss-cross+modify/delete, reverse direction' ' |
2a4c19ef EN |
396 | ( |
397 | cd modify-delete && | |
398 | ||
399 | git reset --hard && | |
400 | git checkout E^0 && | |
fe7e9c23 | 401 | |
2a4c19ef | 402 | test_must_fail git merge -s recursive D^0 && |
fe7e9c23 | 403 | |
0cdabc10 EN |
404 | git ls-files -s >out && |
405 | test_line_count = 2 out && | |
406 | git ls-files -u >out && | |
407 | test_line_count = 2 out && | |
fe7e9c23 | 408 | |
6ac767e5 EN |
409 | git rev-parse >expect \ |
410 | master:file B:file && | |
411 | git rev-parse >actual \ | |
412 | :1:file :3:file && | |
413 | test_cmp expect actual | |
2a4c19ef | 414 | ) |
fe7e9c23 EN |
415 | ' |
416 | ||
327ac9cb | 417 | # SORRY FOR THE SUPER LONG DESCRIPTION, BUT THIS NEXT ONE IS HAIRY |
827f2b7d EN |
418 | # |
419 | # criss-cross + d/f conflict via add/add: | |
235e8d59 | 420 | # Commit A: Neither file 'a' nor directory 'a/' exists. |
827f2b7d EN |
421 | # Commit B: Introduce 'a' |
422 | # Commit C: Introduce 'a/file' | |
327ac9cb | 423 | # Commit D1: Merge B & C, keeping 'a' and deleting 'a/' |
827f2b7d | 424 | # Commit E1: Merge B & C, deleting 'a' but keeping 'a/file' |
827f2b7d | 425 | # |
327ac9cb | 426 | # B D1 or D2 |
827f2b7d EN |
427 | # o---o |
428 | # / \ / \ | |
429 | # A o X ? F | |
430 | # \ / \ / | |
431 | # o---o | |
327ac9cb EN |
432 | # C E1 or E2 or E3 |
433 | # | |
434 | # I'll describe D2, E2, & E3 (which are alternatives for D1 & E1) more below... | |
435 | # | |
436 | # Merging D1 & E1 requires we first create a virtual merge base X from | |
437 | # merging A & B in memory. There are several possibilities for the merge-base: | |
438 | # 1: Keep both 'a' and 'a/file' (assuming crazy filesystem allowing a tree | |
439 | # with a directory and file at same path): results in merge of D1 & E1 | |
440 | # being clean with both files deleted. Bad (no conflict detected). | |
441 | # 2: Keep 'a' but not 'a/file': Merging D1 & E1 is clean and matches E1. Bad. | |
442 | # 3: Keep 'a/file' but not 'a': Merging D1 & E1 is clean and matches D1. Bad. | |
443 | # 4: Keep neither file: Merging D1 & E1 reports the D/F add/add conflict. | |
444 | # | |
445 | # So 4 sounds good for this case, but if we were to merge D1 & E3, where E3 | |
446 | # is defined as: | |
447 | # Commit E3: Merge B & C, keeping modified a, and deleting a/ | |
448 | # then we'd get an add/add conflict for 'a', which seems suboptimal. A little | |
449 | # creativity leads us to an alternate choice: | |
450 | # 5: Keep 'a' as 'a~$UNIQUE' and a/file; results: | |
451 | # Merge D1 & E1: rename/delete conflict for 'a'; a/file silently deleted | |
452 | # Merge D1 & E3 is clean, as expected. | |
453 | # | |
454 | # So choice 5 at least provides some kind of conflict for the original case, | |
455 | # and can merge cleanly as expected with D1 and E3. It also made things just | |
6c74948f | 456 | # slightly funny for merging D1 and E4, where E4 is defined as: |
327ac9cb EN |
457 | # Commit E4: Merge B & C, modifying 'a' and renaming to 'a2', and deleting 'a/' |
458 | # in this case, we'll get a rename/rename(1to2) conflict because a~$UNIQUE | |
459 | # gets renamed to 'a' in D1 and to 'a2' in E4. But that's better than having | |
460 | # two files (both 'a' and 'a2') sitting around without the user being notified | |
461 | # that we could detect they were related and need to be merged. Also, choice | |
462 | # 5 makes the handling of 'a/file' seem suboptimal. What if we were to merge | |
463 | # D2 and E4, where D2 is: | |
464 | # Commit D2: Merge B & C, renaming 'a'->'a2', keeping 'a/file' | |
465 | # This would result in a clean merge with 'a2' having three-way merged | |
466 | # contents (good), and deleting 'a/' (bad) -- it doesn't detect the | |
467 | # conflict in how the different sides treated a/file differently. | |
468 | # Continuing down the creative route: | |
469 | # 6: Keep 'a' as 'a~$UNIQUE1' and keep 'a/' as 'a~$UNIQUE2/'; results: | |
470 | # Merge D1 & E1: rename/delete conflict for 'a' and each path under 'a/'. | |
471 | # Merge D1 & E3: clean, as expected. | |
472 | # Merge D1 & E4: rename/rename(1to2) conflict on 'a' vs 'a2'. | |
473 | # Merge D2 & E4: clean for 'a2', rename/delete for a/file | |
827f2b7d | 474 | # |
327ac9cb EN |
475 | # Choice 6 could cause rename detection to take longer (providing more targets |
476 | # that need to be searched). Also, the conflict message for each path under | |
477 | # 'a/' might be annoying unless we can detect it at the directory level, print | |
478 | # it once, and then suppress it for individual filepaths underneath. | |
827f2b7d | 479 | # |
827f2b7d | 480 | # |
327ac9cb EN |
481 | # As of time of writing, git uses choice 5. Directory rename detection and |
482 | # rename detection performance improvements might make choice 6 a desirable | |
483 | # improvement. But we can at least document where we fall short for now... | |
484 | # | |
485 | # | |
486 | # Historically, this testcase also used: | |
487 | # Commit E2: Merge B & C, deleting 'a' but keeping slightly modified 'a/file' | |
488 | # The merge of D1 & E2 is very similar to D1 & E1 -- it has similar issues for | |
489 | # path 'a', but should always result in a modify/delete conflict for path | |
490 | # 'a/file'. These tests ran the two merges | |
491 | # D1 & E1 | |
492 | # D1 & E2 | |
493 | # in both directions, to check for directional issues with D/F conflict | |
494 | # handling. Later we added | |
495 | # D1 & E3 | |
496 | # D1 & E4 | |
497 | # D2 & E4 | |
498 | # for good measure, though we only ran those one way because we had pretty | |
499 | # good confidence in merge-recursive's directional handling of D/F issues. | |
500 | # | |
501 | # Just to summarize all the intermediate merge commits: | |
502 | # Commit D1: Merge B & C, keeping a and deleting a/ | |
503 | # Commit D2: Merge B & C, renaming a->a2, keeping a/file | |
504 | # Commit E1: Merge B & C, deleting a but keeping a/file | |
505 | # Commit E2: Merge B & C, deleting a but keeping slightly modified a/file | |
506 | # Commit E3: Merge B & C, keeping modified a, and deleting a/ | |
507 | # Commit E4: Merge B & C, modifying 'a' and renaming to 'a2', and deleting 'a/' | |
827f2b7d EN |
508 | # |
509 | ||
510 | test_expect_success 'setup differently handled merges of directory/file conflict' ' | |
2a4c19ef EN |
511 | test_create_repo directory-file && |
512 | ( | |
513 | cd directory-file && | |
514 | ||
515 | >ignore-me && | |
516 | git add ignore-me && | |
517 | test_tick && | |
518 | git commit -m A && | |
519 | git tag A && | |
520 | ||
521 | git branch B && | |
522 | git checkout -b C && | |
523 | mkdir a && | |
327ac9cb | 524 | test_write_lines a b c d e f g >a/file && |
2a4c19ef EN |
525 | git add a/file && |
526 | test_tick && | |
527 | git commit -m C && | |
528 | ||
529 | git checkout B && | |
327ac9cb | 530 | test_write_lines 1 2 3 4 5 6 7 >a && |
2a4c19ef EN |
531 | git add a && |
532 | test_tick && | |
533 | git commit -m B && | |
534 | ||
535 | git checkout B^0 && | |
327ac9cb EN |
536 | git merge -s ours -m D1 C^0 && |
537 | git tag D1 && | |
538 | ||
539 | git checkout B^0 && | |
540 | test_must_fail git merge C^0 && | |
ef527787 EN |
541 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort |
542 | then | |
543 | git rm -rf a/ && | |
544 | git rm a~HEAD | |
545 | else | |
546 | git clean -fd && | |
547 | git rm -rf a/ && | |
548 | git rm a | |
549 | fi && | |
327ac9cb EN |
550 | git cat-file -p B:a >a2 && |
551 | git add a2 && | |
552 | git commit -m D2 && | |
553 | git tag D2 && | |
2a4c19ef EN |
554 | |
555 | git checkout C^0 && | |
327ac9cb | 556 | git merge -s ours -m E1 B^0 && |
2a4c19ef EN |
557 | git tag E1 && |
558 | ||
559 | git checkout C^0 && | |
327ac9cb EN |
560 | git merge -s ours -m E2 B^0 && |
561 | test_write_lines a b c d e f g h >a/file && | |
2a4c19ef | 562 | git add a/file && |
327ac9cb EN |
563 | git commit --amend -C HEAD && |
564 | git tag E2 && | |
565 | ||
566 | git checkout C^0 && | |
567 | test_must_fail git merge B^0 && | |
ef527787 EN |
568 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort |
569 | then | |
570 | git rm a~B^0 | |
571 | else | |
572 | git clean -fd | |
573 | fi && | |
327ac9cb EN |
574 | git rm -rf a/ && |
575 | test_write_lines 1 2 3 4 5 6 7 8 >a && | |
576 | git add a && | |
577 | git commit -m E3 && | |
6b82db9b | 578 | git tag E3 && |
327ac9cb EN |
579 | |
580 | git checkout C^0 && | |
581 | test_must_fail git merge B^0 && | |
ef527787 EN |
582 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort |
583 | then | |
584 | git rm -rf a/ && | |
585 | git rm a~B^0 | |
586 | else | |
587 | git clean -fd && | |
588 | git rm -rf a/ && | |
589 | git rm a | |
590 | fi && | |
327ac9cb EN |
591 | test_write_lines 1 2 3 4 5 6 7 8 >a2 && |
592 | git add a2 && | |
593 | git commit -m E4 && | |
594 | git tag E4 | |
2a4c19ef | 595 | ) |
827f2b7d EN |
596 | ' |
597 | ||
327ac9cb | 598 | test_expect_success 'merge of D1 & E1 fails but has appropriate contents' ' |
d43eba0a EN |
599 | test_when_finished "git -C directory-file reset --hard" && |
600 | test_when_finished "git -C directory-file clean -fdqx" && | |
2a4c19ef EN |
601 | ( |
602 | cd directory-file && | |
827f2b7d | 603 | |
327ac9cb | 604 | git checkout D1^0 && |
827f2b7d | 605 | |
2a4c19ef | 606 | test_must_fail git merge -s recursive E1^0 && |
827f2b7d | 607 | |
ef527787 EN |
608 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort |
609 | then | |
610 | git ls-files -s >out && | |
611 | test_line_count = 3 out && | |
612 | git ls-files -u >out && | |
613 | test_line_count = 2 out && | |
614 | git ls-files -o >out && | |
615 | test_line_count = 1 out && | |
616 | ||
617 | git rev-parse >expect \ | |
618 | A:ignore-me B:a D1:a && | |
619 | git rev-parse >actual \ | |
620 | :0:ignore-me :1:a :2:a && | |
621 | test_cmp expect actual | |
622 | else | |
623 | git ls-files -s >out && | |
624 | test_line_count = 2 out && | |
625 | git ls-files -u >out && | |
626 | test_line_count = 1 out && | |
627 | git ls-files -o >out && | |
628 | test_line_count = 1 out && | |
629 | ||
630 | git rev-parse >expect \ | |
631 | A:ignore-me B:a && | |
632 | git rev-parse >actual \ | |
633 | :0:ignore-me :2:a && | |
634 | test_cmp expect actual | |
635 | fi | |
2a4c19ef | 636 | ) |
827f2b7d EN |
637 | ' |
638 | ||
327ac9cb | 639 | test_expect_success 'merge of E1 & D1 fails but has appropriate contents' ' |
d43eba0a EN |
640 | test_when_finished "git -C directory-file reset --hard" && |
641 | test_when_finished "git -C directory-file clean -fdqx" && | |
2a4c19ef EN |
642 | ( |
643 | cd directory-file && | |
644 | ||
d43eba0a | 645 | git checkout E1^0 && |
827f2b7d | 646 | |
327ac9cb | 647 | test_must_fail git merge -s recursive D1^0 && |
827f2b7d | 648 | |
ef527787 EN |
649 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort |
650 | then | |
651 | git ls-files -s >out && | |
652 | test_line_count = 3 out && | |
653 | git ls-files -u >out && | |
654 | test_line_count = 2 out && | |
655 | git ls-files -o >out && | |
656 | test_line_count = 1 out && | |
657 | ||
658 | git rev-parse >expect \ | |
659 | A:ignore-me B:a D1:a && | |
660 | git rev-parse >actual \ | |
661 | :0:ignore-me :1:a :3:a && | |
662 | test_cmp expect actual | |
663 | else | |
664 | git ls-files -s >out && | |
665 | test_line_count = 2 out && | |
666 | git ls-files -u >out && | |
667 | test_line_count = 1 out && | |
668 | git ls-files -o >out && | |
669 | test_line_count = 1 out && | |
670 | ||
671 | git rev-parse >expect \ | |
672 | A:ignore-me B:a && | |
673 | git rev-parse >actual \ | |
674 | :0:ignore-me :3:a && | |
675 | test_cmp expect actual | |
676 | fi | |
2a4c19ef | 677 | ) |
827f2b7d EN |
678 | ' |
679 | ||
327ac9cb | 680 | test_expect_success 'merge of D1 & E2 fails but has appropriate contents' ' |
d43eba0a EN |
681 | test_when_finished "git -C directory-file reset --hard" && |
682 | test_when_finished "git -C directory-file clean -fdqx" && | |
2a4c19ef EN |
683 | ( |
684 | cd directory-file && | |
685 | ||
327ac9cb | 686 | git checkout D1^0 && |
827f2b7d | 687 | |
2a4c19ef | 688 | test_must_fail git merge -s recursive E2^0 && |
827f2b7d | 689 | |
ef527787 EN |
690 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort |
691 | then | |
692 | git ls-files -s >out && | |
693 | test_line_count = 5 out && | |
694 | git ls-files -u >out && | |
695 | test_line_count = 4 out && | |
696 | git ls-files -o >out && | |
697 | test_line_count = 1 out && | |
698 | ||
699 | git rev-parse >expect \ | |
700 | B:a D1:a E2:a/file C:a/file A:ignore-me && | |
701 | git rev-parse >actual \ | |
702 | :1:a~HEAD :2:a~HEAD :3:a/file :1:a/file :0:ignore-me | |
703 | else | |
704 | git ls-files -s >out && | |
705 | test_line_count = 4 out && | |
706 | git ls-files -u >out && | |
707 | test_line_count = 3 out && | |
708 | git ls-files -o >out && | |
709 | test_line_count = 2 out && | |
710 | ||
711 | git rev-parse >expect \ | |
712 | B:a E2:a/file C:a/file A:ignore-me && | |
713 | git rev-parse >actual \ | |
714 | :2:a :3:a/file :1:a/file :0:ignore-me | |
715 | fi && | |
f1e12398 | 716 | test_cmp expect actual && |
827f2b7d | 717 | |
5b0b9712 | 718 | test_path_is_file a~HEAD |
2a4c19ef | 719 | ) |
827f2b7d EN |
720 | ' |
721 | ||
327ac9cb | 722 | test_expect_success 'merge of E2 & D1 fails but has appropriate contents' ' |
d43eba0a EN |
723 | test_when_finished "git -C directory-file reset --hard" && |
724 | test_when_finished "git -C directory-file clean -fdqx" && | |
2a4c19ef EN |
725 | ( |
726 | cd directory-file && | |
827f2b7d | 727 | |
d43eba0a | 728 | git checkout E2^0 && |
827f2b7d | 729 | |
327ac9cb | 730 | test_must_fail git merge -s recursive D1^0 && |
827f2b7d | 731 | |
ef527787 EN |
732 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort |
733 | then | |
734 | git ls-files -s >out && | |
735 | test_line_count = 5 out && | |
736 | git ls-files -u >out && | |
737 | test_line_count = 4 out && | |
738 | git ls-files -o >out && | |
739 | test_line_count = 1 out && | |
740 | ||
741 | git rev-parse >expect \ | |
742 | B:a D1:a E2:a/file C:a/file A:ignore-me && | |
743 | git rev-parse >actual \ | |
744 | :1:a~D1^0 :3:a~D1^0 :2:a/file :1:a/file :0:ignore-me | |
745 | else | |
746 | git ls-files -s >out && | |
747 | test_line_count = 4 out && | |
748 | git ls-files -u >out && | |
749 | test_line_count = 3 out && | |
750 | git ls-files -o >out && | |
751 | test_line_count = 2 out && | |
752 | ||
753 | git rev-parse >expect \ | |
754 | B:a E2:a/file C:a/file A:ignore-me && | |
755 | git rev-parse >actual \ | |
756 | :3:a :2:a/file :1:a/file :0:ignore-me | |
757 | fi && | |
f1e12398 | 758 | test_cmp expect actual && |
2a4c19ef | 759 | |
327ac9cb EN |
760 | test_path_is_file a~D1^0 |
761 | ) | |
762 | ' | |
763 | ||
764 | test_expect_success 'merge of D1 & E3 succeeds' ' | |
765 | test_when_finished "git -C directory-file reset --hard" && | |
766 | test_when_finished "git -C directory-file clean -fdqx" && | |
767 | ( | |
768 | cd directory-file && | |
769 | ||
770 | git checkout D1^0 && | |
771 | ||
772 | git merge -s recursive E3^0 && | |
773 | ||
774 | git ls-files -s >out && | |
775 | test_line_count = 2 out && | |
776 | git ls-files -u >out && | |
777 | test_line_count = 0 out && | |
778 | git ls-files -o >out && | |
779 | test_line_count = 1 out && | |
780 | ||
781 | git rev-parse >expect \ | |
782 | A:ignore-me E3:a && | |
783 | git rev-parse >actual \ | |
784 | :0:ignore-me :0:a && | |
785 | test_cmp expect actual | |
786 | ) | |
787 | ' | |
788 | ||
489c85ff | 789 | test_expect_merge_algorithm failure success 'merge of D1 & E4 puts merge of a and a2 in both a and a2' ' |
327ac9cb EN |
790 | test_when_finished "git -C directory-file reset --hard" && |
791 | test_when_finished "git -C directory-file clean -fdqx" && | |
792 | ( | |
793 | cd directory-file && | |
794 | ||
795 | git checkout D1^0 && | |
796 | ||
797 | test_must_fail git merge -s recursive E4^0 && | |
798 | ||
799 | git ls-files -s >out && | |
800 | test_line_count = 4 out && | |
801 | git ls-files -u >out && | |
802 | test_line_count = 3 out && | |
803 | git ls-files -o >out && | |
804 | test_line_count = 1 out && | |
805 | ||
806 | git rev-parse >expect \ | |
489c85ff | 807 | A:ignore-me B:a E4:a2 E4:a2 && |
327ac9cb EN |
808 | git rev-parse >actual \ |
809 | :0:ignore-me :1:a~Temporary\ merge\ branch\ 2 :2:a :3:a2 && | |
810 | test_cmp expect actual | |
811 | ) | |
812 | ' | |
813 | ||
814 | test_expect_failure 'merge of D2 & E4 merges a2s & reports conflict for a/file' ' | |
815 | test_when_finished "git -C directory-file reset --hard" && | |
816 | test_when_finished "git -C directory-file clean -fdqx" && | |
817 | ( | |
818 | cd directory-file && | |
819 | ||
820 | git checkout D2^0 && | |
821 | ||
822 | test_must_fail git merge -s recursive E4^0 && | |
823 | ||
824 | git ls-files -s >out && | |
825 | test_line_count = 3 out && | |
826 | git ls-files -u >out && | |
827 | test_line_count = 1 out && | |
828 | git ls-files -o >out && | |
829 | test_line_count = 1 out && | |
830 | ||
831 | git rev-parse >expect \ | |
832 | A:ignore-me E4:a2 D2:a/file && | |
833 | git rev-parse >actual \ | |
834 | :0:ignore-me :0:a2 :2:a/file && | |
835 | test_cmp expect actual | |
2a4c19ef | 836 | ) |
827f2b7d EN |
837 | ' |
838 | ||
a0d33116 EN |
839 | # |
840 | # criss-cross with rename/rename(1to2)/modify followed by | |
841 | # rename/rename(2to1)/modify: | |
842 | # | |
843 | # B D | |
844 | # o---o | |
845 | # / \ / \ | |
846 | # A o X ? F | |
847 | # \ / \ / | |
848 | # o---o | |
849 | # C E | |
850 | # | |
851 | # Commit A: new file: a | |
852 | # Commit B: rename a->b, modifying by adding a line | |
853 | # Commit C: rename a->c | |
854 | # Commit D: merge B&C, resolving conflict by keeping contents in newname | |
855 | # Commit E: merge B&C, resolving conflict similar to D but adding another line | |
856 | # | |
857 | # There is a conflict merging B & C, but one of filename not of file | |
858 | # content. Whoever created D and E chose specific resolutions for that | |
859 | # conflict resolution. Now, since: (1) there is no content conflict | |
860 | # merging B & C, (2) D does not modify that merged content further, and (3) | |
861 | # both D & E resolve the name conflict in the same way, the modification to | |
862 | # newname in E should not cause any conflicts when it is merged with D. | |
863 | # (Note that this can be accomplished by having the virtual merge base have | |
864 | # the merged contents of b and c stored in a file named a, which seems like | |
865 | # the most logical choice anyway.) | |
866 | # | |
867 | # Comment from Junio: I do not necessarily agree with the choice "a", but | |
868 | # it feels sound to say "B and C do not agree what the final pathname | |
869 | # should be, but we know this content was derived from the common A:a so we | |
870 | # use one path whose name is arbitrary in the virtual merge base X between | |
871 | # D and E" and then further let the rename detection to notice that that | |
872 | # arbitrary path gets renamed between X-D to "newname" and X-E also to | |
873 | # "newname" to resolve it as both sides renaming it to the same new | |
874 | # name. It is akin to what we do at the content level, i.e. "B and C do not | |
875 | # agree what the final contents should be, so we leave the conflict marker | |
876 | # but that may cancel out at the final merge stage". | |
877 | ||
878 | test_expect_success 'setup rename/rename(1to2)/modify followed by what looks like rename/rename(2to1)/modify' ' | |
2a4c19ef EN |
879 | test_create_repo rename-squared-squared && |
880 | ( | |
881 | cd rename-squared-squared && | |
882 | ||
883 | printf "1\n2\n3\n4\n5\n6\n" >a && | |
884 | git add a && | |
885 | git commit -m A && | |
886 | git tag A && | |
887 | ||
888 | git checkout -b B A && | |
889 | git mv a b && | |
890 | echo 7 >>b && | |
891 | git add -u && | |
892 | git commit -m B && | |
893 | ||
894 | git checkout -b C A && | |
895 | git mv a c && | |
896 | git commit -m C && | |
897 | ||
898 | git checkout -q B^0 && | |
899 | git merge --no-commit -s ours C^0 && | |
900 | git mv b newname && | |
901 | git commit -m "Merge commit C^0 into HEAD" && | |
902 | git tag D && | |
903 | ||
904 | git checkout -q C^0 && | |
905 | git merge --no-commit -s ours B^0 && | |
906 | git mv c newname && | |
907 | printf "7\n8\n" >>newname && | |
908 | git add -u && | |
909 | git commit -m "Merge commit B^0 into HEAD" && | |
910 | git tag E | |
911 | ) | |
a0d33116 EN |
912 | ' |
913 | ||
c52ff85d | 914 | test_expect_success 'handle rename/rename(1to2)/modify followed by what looks like rename/rename(2to1)/modify' ' |
2a4c19ef EN |
915 | ( |
916 | cd rename-squared-squared && | |
a0d33116 | 917 | |
2a4c19ef | 918 | git checkout D^0 && |
a0d33116 | 919 | |
2a4c19ef | 920 | git merge -s recursive E^0 && |
a0d33116 | 921 | |
0cdabc10 EN |
922 | git ls-files -s >out && |
923 | test_line_count = 1 out && | |
924 | git ls-files -u >out && | |
925 | test_line_count = 0 out && | |
926 | git ls-files -o >out && | |
927 | test_line_count = 1 out && | |
2a4c19ef EN |
928 | |
929 | test $(git rev-parse HEAD:newname) = $(git rev-parse E:newname) | |
930 | ) | |
a0d33116 EN |
931 | ' |
932 | ||
0b35deb3 EN |
933 | # |
934 | # criss-cross with rename/rename(1to2)/add-source + resolvable modify/modify: | |
935 | # | |
936 | # B D | |
937 | # o---o | |
938 | # / \ / \ | |
939 | # A o X ? F | |
940 | # \ / \ / | |
941 | # o---o | |
942 | # C E | |
943 | # | |
944 | # Commit A: new file: a | |
945 | # Commit B: rename a->b | |
946 | # Commit C: rename a->c, add different a | |
947 | # Commit D: merge B&C, keeping b&c and (new) a modified at beginning | |
948 | # Commit E: merge B&C, keeping b&c and (new) a modified at end | |
949 | # | |
950 | # Merging commits D & E should result in no conflict; doing so correctly | |
951 | # requires getting the virtual merge base (from merging B&C) right, handling | |
952 | # renaming carefully (both in the virtual merge base and later), and getting | |
953 | # content merge handled. | |
954 | ||
2a4c19ef EN |
955 | test_expect_success 'setup criss-cross + rename/rename/add-source + modify/modify' ' |
956 | test_create_repo rename-rename-add-source && | |
957 | ( | |
958 | cd rename-rename-add-source && | |
959 | ||
960 | printf "lots\nof\nwords\nand\ncontent\n" >a && | |
961 | git add a && | |
962 | git commit -m A && | |
963 | git tag A && | |
964 | ||
965 | git checkout -b B A && | |
966 | git mv a b && | |
967 | git commit -m B && | |
968 | ||
969 | git checkout -b C A && | |
970 | git mv a c && | |
971 | printf "2\n3\n4\n5\n6\n7\n" >a && | |
972 | git add a && | |
973 | git commit -m C && | |
974 | ||
975 | git checkout B^0 && | |
976 | git merge --no-commit -s ours C^0 && | |
977 | git checkout C -- a c && | |
978 | mv a old_a && | |
979 | echo 1 >a && | |
980 | cat old_a >>a && | |
981 | rm old_a && | |
982 | git add -u && | |
983 | git commit -m "Merge commit C^0 into HEAD" && | |
984 | git tag D && | |
985 | ||
986 | git checkout C^0 && | |
987 | git merge --no-commit -s ours B^0 && | |
988 | git checkout B -- b && | |
989 | echo 8 >>a && | |
990 | git add -u && | |
991 | git commit -m "Merge commit B^0 into HEAD" && | |
992 | git tag E | |
993 | ) | |
0b35deb3 EN |
994 | ' |
995 | ||
996 | test_expect_failure 'detect rename/rename/add-source for virtual merge-base' ' | |
2a4c19ef EN |
997 | ( |
998 | cd rename-rename-add-source && | |
999 | ||
1000 | git checkout D^0 && | |
0b35deb3 | 1001 | |
2a4c19ef | 1002 | git merge -s recursive E^0 && |
0b35deb3 | 1003 | |
0cdabc10 EN |
1004 | git ls-files -s >out && |
1005 | test_line_count = 3 out && | |
1006 | git ls-files -u >out && | |
1007 | test_line_count = 0 out && | |
1008 | git ls-files -o >out && | |
1009 | test_line_count = 1 out && | |
0b35deb3 | 1010 | |
6ac767e5 EN |
1011 | printf "1\n2\n3\n4\n5\n6\n7\n8\n" >correct && |
1012 | git rev-parse >expect \ | |
1013 | A:a A:a \ | |
1014 | correct && | |
1015 | git rev-parse >actual \ | |
1016 | :0:b :0:c && | |
1017 | git hash-object >>actual \ | |
1018 | a && | |
1019 | test_cmp expect actual | |
2a4c19ef | 1020 | ) |
0b35deb3 EN |
1021 | ' |
1022 | ||
b630b814 EN |
1023 | # |
1024 | # criss-cross with rename/rename(1to2)/add-dest + simple modify: | |
1025 | # | |
1026 | # B D | |
1027 | # o---o | |
1028 | # / \ / \ | |
1029 | # A o X ? F | |
1030 | # \ / \ / | |
1031 | # o---o | |
1032 | # C E | |
1033 | # | |
1034 | # Commit A: new file: a | |
1035 | # Commit B: rename a->b, add c | |
1036 | # Commit C: rename a->c | |
1037 | # Commit D: merge B&C, keeping A:a and B:c | |
1038 | # Commit E: merge B&C, keeping A:a and slightly modified c from B | |
1039 | # | |
1040 | # Merging commits D & E should result in no conflict. The virtual merge | |
1041 | # base of B & C needs to not delete B:c for that to work, though... | |
1042 | ||
1043 | test_expect_success 'setup criss-cross+rename/rename/add-dest + simple modify' ' | |
2a4c19ef EN |
1044 | test_create_repo rename-rename-add-dest && |
1045 | ( | |
1046 | cd rename-rename-add-dest && | |
1047 | ||
1048 | >a && | |
1049 | git add a && | |
1050 | git commit -m A && | |
1051 | git tag A && | |
1052 | ||
1053 | git checkout -b B A && | |
1054 | git mv a b && | |
1055 | printf "1\n2\n3\n4\n5\n6\n7\n" >c && | |
1056 | git add c && | |
1057 | git commit -m B && | |
1058 | ||
1059 | git checkout -b C A && | |
1060 | git mv a c && | |
1061 | git commit -m C && | |
1062 | ||
1063 | git checkout B^0 && | |
1064 | git merge --no-commit -s ours C^0 && | |
1065 | git mv b a && | |
1066 | git commit -m "D is like B but renames b back to a" && | |
1067 | git tag D && | |
1068 | ||
1069 | git checkout B^0 && | |
1070 | git merge --no-commit -s ours C^0 && | |
1071 | git mv b a && | |
1072 | echo 8 >>c && | |
1073 | git add c && | |
1074 | git commit -m "E like D but has mod in c" && | |
1075 | git tag E | |
1076 | ) | |
b630b814 EN |
1077 | ' |
1078 | ||
6d63070c | 1079 | test_expect_success 'virtual merge base handles rename/rename(1to2)/add-dest' ' |
2a4c19ef EN |
1080 | ( |
1081 | cd rename-rename-add-dest && | |
1082 | ||
1083 | git checkout D^0 && | |
b630b814 | 1084 | |
2a4c19ef | 1085 | git merge -s recursive E^0 && |
b630b814 | 1086 | |
0cdabc10 EN |
1087 | git ls-files -s >out && |
1088 | test_line_count = 2 out && | |
1089 | git ls-files -u >out && | |
1090 | test_line_count = 0 out && | |
1091 | git ls-files -o >out && | |
1092 | test_line_count = 1 out && | |
b630b814 | 1093 | |
6ac767e5 EN |
1094 | git rev-parse >expect \ |
1095 | A:a E:c && | |
1096 | git rev-parse >actual \ | |
1097 | :0:a :0:c && | |
1098 | test_cmp expect actual | |
2a4c19ef | 1099 | ) |
b630b814 EN |
1100 | ' |
1101 | ||
c6d3dd5d EN |
1102 | # |
1103 | # criss-cross with modify/modify on a symlink: | |
1104 | # | |
1105 | # B D | |
1106 | # o---o | |
1107 | # / \ / \ | |
1108 | # A o X ? F | |
1109 | # \ / \ / | |
1110 | # o---o | |
1111 | # C E | |
1112 | # | |
1113 | # Commit A: simple simlink fickle->lagoon | |
1114 | # Commit B: redirect fickle->disneyland | |
1115 | # Commit C: redirect fickle->home | |
1116 | # Commit D: merge B&C, resolving in favor of B | |
1117 | # Commit E: merge B&C, resolving in favor of C | |
1118 | # | |
1119 | # This is an obvious modify/modify conflict for the symlink 'fickle'. Can | |
1120 | # git detect it? | |
1121 | ||
1122 | test_expect_success 'setup symlink modify/modify' ' | |
1123 | test_create_repo symlink-modify-modify && | |
1124 | ( | |
1125 | cd symlink-modify-modify && | |
1126 | ||
1127 | test_ln_s_add lagoon fickle && | |
1128 | git commit -m A && | |
1129 | git tag A && | |
1130 | ||
1131 | git checkout -b B A && | |
1132 | git rm fickle && | |
1133 | test_ln_s_add disneyland fickle && | |
1134 | git commit -m B && | |
1135 | ||
1136 | git checkout -b C A && | |
1137 | git rm fickle && | |
1138 | test_ln_s_add home fickle && | |
1139 | git add fickle && | |
1140 | git commit -m C && | |
1141 | ||
1142 | git checkout -q B^0 && | |
1143 | git merge -s ours -m D C^0 && | |
1144 | git tag D && | |
1145 | ||
1146 | git checkout -q C^0 && | |
1147 | git merge -s ours -m E B^0 && | |
1148 | git tag E | |
1149 | ) | |
1150 | ' | |
1151 | ||
f06481f1 | 1152 | test_expect_merge_algorithm failure success 'check symlink modify/modify' ' |
c6d3dd5d EN |
1153 | ( |
1154 | cd symlink-modify-modify && | |
1155 | ||
1156 | git checkout D^0 && | |
1157 | ||
1158 | test_must_fail git merge -s recursive E^0 && | |
1159 | ||
1160 | git ls-files -s >out && | |
1161 | test_line_count = 3 out && | |
1162 | git ls-files -u >out && | |
1163 | test_line_count = 3 out && | |
1164 | git ls-files -o >out && | |
1165 | test_line_count = 1 out | |
1166 | ) | |
1167 | ' | |
1168 | ||
81f5a2ce EN |
1169 | # |
1170 | # criss-cross with add/add of a symlink: | |
1171 | # | |
1172 | # B D | |
1173 | # o---o | |
1174 | # / \ / \ | |
1175 | # A o X ? F | |
1176 | # \ / \ / | |
1177 | # o---o | |
1178 | # C E | |
1179 | # | |
1180 | # Commit A: No symlink or path exists yet | |
1181 | # Commit B: set up symlink: fickle->disneyland | |
1182 | # Commit C: set up symlink: fickle->home | |
1183 | # Commit D: merge B&C, resolving in favor of B | |
1184 | # Commit E: merge B&C, resolving in favor of C | |
1185 | # | |
1186 | # This is an obvious add/add conflict for the symlink 'fickle'. Can | |
1187 | # git detect it? | |
1188 | ||
1189 | test_expect_success 'setup symlink add/add' ' | |
1190 | test_create_repo symlink-add-add && | |
1191 | ( | |
1192 | cd symlink-add-add && | |
1193 | ||
1194 | touch ignoreme && | |
1195 | git add ignoreme && | |
1196 | git commit -m A && | |
1197 | git tag A && | |
1198 | ||
1199 | git checkout -b B A && | |
1200 | test_ln_s_add disneyland fickle && | |
1201 | git commit -m B && | |
1202 | ||
1203 | git checkout -b C A && | |
1204 | test_ln_s_add home fickle && | |
1205 | git add fickle && | |
1206 | git commit -m C && | |
1207 | ||
1208 | git checkout -q B^0 && | |
1209 | git merge -s ours -m D C^0 && | |
1210 | git tag D && | |
1211 | ||
1212 | git checkout -q C^0 && | |
1213 | git merge -s ours -m E B^0 && | |
1214 | git tag E | |
1215 | ) | |
1216 | ' | |
1217 | ||
f06481f1 | 1218 | test_expect_merge_algorithm failure success 'check symlink add/add' ' |
81f5a2ce EN |
1219 | ( |
1220 | cd symlink-add-add && | |
1221 | ||
1222 | git checkout D^0 && | |
1223 | ||
1224 | test_must_fail git merge -s recursive E^0 && | |
1225 | ||
1226 | git ls-files -s >out && | |
3df4e3bb | 1227 | test_line_count = 3 out && |
81f5a2ce EN |
1228 | git ls-files -u >out && |
1229 | test_line_count = 2 out && | |
1230 | git ls-files -o >out && | |
1231 | test_line_count = 1 out | |
1232 | ) | |
1233 | ' | |
1234 | ||
d4d17180 EN |
1235 | # |
1236 | # criss-cross with modify/modify on a submodule: | |
1237 | # | |
1238 | # B D | |
1239 | # o---o | |
1240 | # / \ / \ | |
1241 | # A o X ? F | |
1242 | # \ / \ / | |
1243 | # o---o | |
1244 | # C E | |
1245 | # | |
1246 | # Commit A: simple submodule repo | |
1247 | # Commit B: update repo | |
1248 | # Commit C: update repo differently | |
1249 | # Commit D: merge B&C, resolving in favor of B | |
1250 | # Commit E: merge B&C, resolving in favor of C | |
1251 | # | |
1252 | # This is an obvious modify/modify conflict for the submodule 'repo'. Can | |
1253 | # git detect it? | |
1254 | ||
1255 | test_expect_success 'setup submodule modify/modify' ' | |
1256 | test_create_repo submodule-modify-modify && | |
1257 | ( | |
1258 | cd submodule-modify-modify && | |
1259 | ||
1260 | test_create_repo submod && | |
1261 | ( | |
1262 | cd submod && | |
1263 | touch file-A && | |
1264 | git add file-A && | |
1265 | git commit -m A && | |
1266 | git tag A && | |
1267 | ||
1268 | git checkout -b B A && | |
1269 | touch file-B && | |
1270 | git add file-B && | |
1271 | git commit -m B && | |
1272 | git tag B && | |
1273 | ||
1274 | git checkout -b C A && | |
1275 | touch file-C && | |
1276 | git add file-C && | |
1277 | git commit -m C && | |
1278 | git tag C | |
1279 | ) && | |
1280 | ||
1281 | git -C submod reset --hard A && | |
1282 | git add submod && | |
1283 | git commit -m A && | |
1284 | git tag A && | |
1285 | ||
1286 | git checkout -b B A && | |
1287 | git -C submod reset --hard B && | |
1288 | git add submod && | |
1289 | git commit -m B && | |
1290 | ||
1291 | git checkout -b C A && | |
1292 | git -C submod reset --hard C && | |
1293 | git add submod && | |
1294 | git commit -m C && | |
1295 | ||
1296 | git checkout -q B^0 && | |
1297 | git merge -s ours -m D C^0 && | |
1298 | git tag D && | |
1299 | ||
1300 | git checkout -q C^0 && | |
1301 | git merge -s ours -m E B^0 && | |
1302 | git tag E | |
1303 | ) | |
1304 | ' | |
1305 | ||
f06481f1 | 1306 | test_expect_merge_algorithm failure success 'check submodule modify/modify' ' |
d4d17180 EN |
1307 | ( |
1308 | cd submodule-modify-modify && | |
1309 | ||
1310 | git checkout D^0 && | |
1311 | ||
1312 | test_must_fail git merge -s recursive E^0 && | |
1313 | ||
1314 | git ls-files -s >out && | |
1315 | test_line_count = 3 out && | |
1316 | git ls-files -u >out && | |
1317 | test_line_count = 3 out && | |
1318 | git ls-files -o >out && | |
1319 | test_line_count = 1 out | |
1320 | ) | |
1321 | ' | |
1322 | ||
a79968be EN |
1323 | # |
1324 | # criss-cross with add/add on a submodule: | |
1325 | # | |
1326 | # B D | |
1327 | # o---o | |
1328 | # / \ / \ | |
1329 | # A o X ? F | |
1330 | # \ / \ / | |
1331 | # o---o | |
1332 | # C E | |
1333 | # | |
1334 | # Commit A: nothing of note | |
1335 | # Commit B: introduce submodule repo | |
1336 | # Commit C: introduce submodule repo at different commit | |
1337 | # Commit D: merge B&C, resolving in favor of B | |
1338 | # Commit E: merge B&C, resolving in favor of C | |
1339 | # | |
1340 | # This is an obvious add/add conflict for the submodule 'repo'. Can | |
1341 | # git detect it? | |
1342 | ||
1343 | test_expect_success 'setup submodule add/add' ' | |
1344 | test_create_repo submodule-add-add && | |
1345 | ( | |
1346 | cd submodule-add-add && | |
1347 | ||
1348 | test_create_repo submod && | |
1349 | ( | |
1350 | cd submod && | |
1351 | touch file-A && | |
1352 | git add file-A && | |
1353 | git commit -m A && | |
1354 | git tag A && | |
1355 | ||
1356 | git checkout -b B A && | |
1357 | touch file-B && | |
1358 | git add file-B && | |
1359 | git commit -m B && | |
1360 | git tag B && | |
1361 | ||
1362 | git checkout -b C A && | |
1363 | touch file-C && | |
1364 | git add file-C && | |
1365 | git commit -m C && | |
1366 | git tag C | |
1367 | ) && | |
1368 | ||
1369 | touch irrelevant-file && | |
1370 | git add irrelevant-file && | |
1371 | git commit -m A && | |
1372 | git tag A && | |
1373 | ||
1374 | git checkout -b B A && | |
1375 | git -C submod reset --hard B && | |
1376 | git add submod && | |
1377 | git commit -m B && | |
1378 | ||
1379 | git checkout -b C A && | |
1380 | git -C submod reset --hard C && | |
1381 | git add submod && | |
1382 | git commit -m C && | |
1383 | ||
1384 | git checkout -q B^0 && | |
1385 | git merge -s ours -m D C^0 && | |
1386 | git tag D && | |
1387 | ||
1388 | git checkout -q C^0 && | |
1389 | git merge -s ours -m E B^0 && | |
1390 | git tag E | |
1391 | ) | |
1392 | ' | |
1393 | ||
f06481f1 | 1394 | test_expect_merge_algorithm failure success 'check submodule add/add' ' |
a79968be EN |
1395 | ( |
1396 | cd submodule-add-add && | |
1397 | ||
1398 | git checkout D^0 && | |
1399 | ||
1400 | test_must_fail git merge -s recursive E^0 && | |
1401 | ||
1402 | git ls-files -s >out && | |
1403 | test_line_count = 3 out && | |
1404 | git ls-files -u >out && | |
1405 | test_line_count = 2 out && | |
1406 | git ls-files -o >out && | |
1407 | test_line_count = 1 out | |
1408 | ) | |
1409 | ' | |
1410 | ||
451a3abc EN |
1411 | # |
1412 | # criss-cross with conflicting entry types: | |
1413 | # | |
1414 | # B D | |
1415 | # o---o | |
1416 | # / \ / \ | |
1417 | # A o X ? F | |
1418 | # \ / \ / | |
1419 | # o---o | |
1420 | # C E | |
1421 | # | |
1422 | # Commit A: nothing of note | |
1423 | # Commit B: introduce submodule 'path' | |
1424 | # Commit C: introduce symlink 'path' | |
1425 | # Commit D: merge B&C, resolving in favor of B | |
1426 | # Commit E: merge B&C, resolving in favor of C | |
1427 | # | |
1428 | # This is an obvious add/add conflict for 'path'. Can git detect it? | |
1429 | ||
1430 | test_expect_success 'setup conflicting entry types (submodule vs symlink)' ' | |
1431 | test_create_repo submodule-symlink-add-add && | |
1432 | ( | |
1433 | cd submodule-symlink-add-add && | |
1434 | ||
1435 | test_create_repo path && | |
1436 | ( | |
1437 | cd path && | |
1438 | touch file-B && | |
1439 | git add file-B && | |
1440 | git commit -m B && | |
1441 | git tag B | |
1442 | ) && | |
1443 | ||
1444 | touch irrelevant-file && | |
1445 | git add irrelevant-file && | |
1446 | git commit -m A && | |
1447 | git tag A && | |
1448 | ||
1449 | git checkout -b B A && | |
1450 | git -C path reset --hard B && | |
1451 | git add path && | |
1452 | git commit -m B && | |
1453 | ||
1454 | git checkout -b C A && | |
1455 | rm -rf path/ && | |
1456 | test_ln_s_add irrelevant-file path && | |
1457 | git commit -m C && | |
1458 | ||
1459 | git checkout -q B^0 && | |
1460 | git merge -s ours -m D C^0 && | |
1461 | git tag D && | |
1462 | ||
1463 | git checkout -q C^0 && | |
1464 | git merge -s ours -m E B^0 && | |
1465 | git tag E | |
1466 | ) | |
1467 | ' | |
1468 | ||
f06481f1 | 1469 | test_expect_merge_algorithm failure success 'check conflicting entry types (submodule vs symlink)' ' |
451a3abc EN |
1470 | ( |
1471 | cd submodule-symlink-add-add && | |
1472 | ||
1473 | git checkout D^0 && | |
1474 | ||
1475 | test_must_fail git merge -s recursive E^0 && | |
1476 | ||
1477 | git ls-files -s >out && | |
1478 | test_line_count = 3 out && | |
1479 | git ls-files -u >out && | |
1480 | test_line_count = 2 out && | |
1481 | git ls-files -o >out && | |
1482 | test_line_count = 1 out | |
1483 | ) | |
1484 | ' | |
1485 | ||
5d1daf30 EN |
1486 | # |
1487 | # criss-cross with regular files that have conflicting modes: | |
1488 | # | |
1489 | # B D | |
1490 | # o---o | |
1491 | # / \ / \ | |
1492 | # A o X ? F | |
1493 | # \ / \ / | |
1494 | # o---o | |
1495 | # C E | |
1496 | # | |
1497 | # Commit A: nothing of note | |
1498 | # Commit B: introduce file source_me.bash, not executable | |
1499 | # Commit C: introduce file source_me.bash, executable | |
1500 | # Commit D: merge B&C, resolving in favor of B | |
1501 | # Commit E: merge B&C, resolving in favor of C | |
1502 | # | |
1503 | # This is an obvious add/add mode conflict. Can git detect it? | |
1504 | ||
1505 | test_expect_success 'setup conflicting modes for regular file' ' | |
1506 | test_create_repo regular-file-mode-conflict && | |
1507 | ( | |
1508 | cd regular-file-mode-conflict && | |
1509 | ||
1510 | touch irrelevant-file && | |
1511 | git add irrelevant-file && | |
1512 | git commit -m A && | |
1513 | git tag A && | |
1514 | ||
1515 | git checkout -b B A && | |
1516 | echo "command_to_run" >source_me.bash && | |
1517 | git add source_me.bash && | |
1518 | git commit -m B && | |
1519 | ||
1520 | git checkout -b C A && | |
1521 | echo "command_to_run" >source_me.bash && | |
1522 | git add source_me.bash && | |
1523 | test_chmod +x source_me.bash && | |
1524 | git commit -m C && | |
1525 | ||
1526 | git checkout -q B^0 && | |
1527 | git merge -s ours -m D C^0 && | |
1528 | git tag D && | |
1529 | ||
1530 | git checkout -q C^0 && | |
1531 | git merge -s ours -m E B^0 && | |
1532 | git tag E | |
1533 | ) | |
1534 | ' | |
1535 | ||
1536 | test_expect_failure 'check conflicting modes for regular file' ' | |
1537 | ( | |
1538 | cd regular-file-mode-conflict && | |
1539 | ||
1540 | git checkout D^0 && | |
1541 | ||
1542 | test_must_fail git merge -s recursive E^0 && | |
1543 | ||
1544 | git ls-files -s >out && | |
1545 | test_line_count = 3 out && | |
1546 | git ls-files -u >out && | |
1547 | test_line_count = 2 out && | |
1548 | git ls-files -o >out && | |
1549 | test_line_count = 1 out | |
1550 | ) | |
1551 | ' | |
1552 | ||
b28eeb30 EN |
1553 | # Setup: |
1554 | # L1---L2 | |
1555 | # / \ / \ | |
1556 | # master X ? | |
1557 | # \ / \ / | |
1558 | # R1---R2 | |
1559 | # | |
1560 | # Where: | |
1561 | # master has two files, named 'b' and 'a' | |
1562 | # branches L1 and R1 both modify each of the two files in conflicting ways | |
1563 | # | |
1564 | # L2 is a merge of R1 into L1; more on it later. | |
1565 | # R2 is a merge of L1 into R1; more on it later. | |
1566 | # | |
1567 | # X is an auto-generated merge-base used when merging L2 and R2. | |
1568 | # since X is a merge of L1 and R1, it has conflicting versions of each file | |
1569 | # | |
1570 | # More about L2 and R2: | |
1571 | # - both resolve the conflicts in 'b' and 'a' differently | |
1572 | # - L2 renames 'b' to 'm' | |
1573 | # - R2 renames 'a' to 'm' | |
1574 | # | |
1575 | # In the end, in file 'm' we have four different conflicting files (from | |
1576 | # two versions of 'b' and two of 'a'). In addition, if | |
1577 | # merge.conflictstyle is diff3, then the base version also has | |
1578 | # conflict markers of its own, leading to a total of three levels of | |
1579 | # conflict markers. This is a pretty weird corner case, but we just want | |
1580 | # to ensure that we handle it as well as practical. | |
1581 | ||
1582 | test_expect_success 'setup nested conflicts' ' | |
1583 | test_create_repo nested_conflicts && | |
1584 | ( | |
1585 | cd nested_conflicts && | |
1586 | ||
1587 | # Create some related files now | |
1588 | for i in $(test_seq 1 10) | |
1589 | do | |
1590 | echo Random base content line $i | |
1591 | done >initial && | |
1592 | ||
1593 | cp initial b_L1 && | |
1594 | cp initial b_R1 && | |
1595 | cp initial b_L2 && | |
1596 | cp initial b_R2 && | |
1597 | cp initial a_L1 && | |
1598 | cp initial a_R1 && | |
1599 | cp initial a_L2 && | |
1600 | cp initial a_R2 && | |
1601 | ||
1602 | test_write_lines b b_L1 >>b_L1 && | |
1603 | test_write_lines b b_R1 >>b_R1 && | |
1604 | test_write_lines b b_L2 >>b_L2 && | |
1605 | test_write_lines b b_R2 >>b_R2 && | |
1606 | test_write_lines a a_L1 >>a_L1 && | |
1607 | test_write_lines a a_R1 >>a_R1 && | |
1608 | test_write_lines a a_L2 >>a_L2 && | |
1609 | test_write_lines a a_R2 >>a_R2 && | |
1610 | ||
1611 | # Setup original commit (or merge-base), consisting of | |
1612 | # files named "b" and "a" | |
1613 | cp initial b && | |
1614 | cp initial a && | |
1615 | echo b >>b && | |
1616 | echo a >>a && | |
1617 | git add b a && | |
1618 | test_tick && git commit -m initial && | |
1619 | ||
1620 | git branch L && | |
1621 | git branch R && | |
1622 | ||
1623 | # Handle the left side | |
1624 | git checkout L && | |
1625 | mv -f b_L1 b && | |
1626 | mv -f a_L1 a && | |
1627 | git add b a && | |
1628 | test_tick && git commit -m "version L1 of files" && | |
1629 | git tag L1 && | |
1630 | ||
1631 | # Handle the right side | |
1632 | git checkout R && | |
1633 | mv -f b_R1 b && | |
1634 | mv -f a_R1 a && | |
1635 | git add b a && | |
aa74be31 | 1636 | test_tick && git commit -m "version R1 of files" && |
b28eeb30 EN |
1637 | git tag R1 && |
1638 | ||
1639 | # Create first merge on left side | |
1640 | git checkout L && | |
1641 | test_must_fail git merge R1 && | |
1642 | mv -f b_L2 b && | |
1643 | mv -f a_L2 a && | |
1644 | git add b a && | |
1645 | git mv b m && | |
1646 | test_tick && git commit -m "left merge, rename b->m" && | |
1647 | git tag L2 && | |
1648 | ||
1649 | # Create first merge on right side | |
1650 | git checkout R && | |
1651 | test_must_fail git merge L1 && | |
1652 | mv -f b_R2 b && | |
1653 | mv -f a_R2 a && | |
1654 | git add b a && | |
1655 | git mv a m && | |
1656 | test_tick && git commit -m "right merge, rename a->m" && | |
1657 | git tag R2 | |
1658 | ) | |
1659 | ' | |
1660 | ||
bbafc9c4 | 1661 | test_expect_success 'check nested conflicts' ' |
b28eeb30 EN |
1662 | ( |
1663 | cd nested_conflicts && | |
1664 | ||
1665 | git clean -f && | |
743474cb | 1666 | MASTER=$(git rev-parse --short master) && |
b28eeb30 EN |
1667 | git checkout L2^0 && |
1668 | ||
1669 | # Merge must fail; there is a conflict | |
1670 | test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R2^0 && | |
1671 | ||
1672 | # Make sure the index has the right number of entries | |
1673 | git ls-files -s >out && | |
1674 | test_line_count = 2 out && | |
1675 | git ls-files -u >out && | |
1676 | test_line_count = 2 out && | |
1677 | # Ensure we have the correct number of untracked files | |
1678 | git ls-files -o >out && | |
1679 | test_line_count = 1 out && | |
1680 | ||
1681 | # Create a and b from virtual merge base X | |
1682 | git cat-file -p master:a >base && | |
1683 | git cat-file -p L1:a >ours && | |
1684 | git cat-file -p R1:a >theirs && | |
1685 | test_must_fail git merge-file --diff3 \ | |
1686 | -L "Temporary merge branch 1" \ | |
743474cb | 1687 | -L "$MASTER" \ |
b28eeb30 EN |
1688 | -L "Temporary merge branch 2" \ |
1689 | ours \ | |
1690 | base \ | |
1691 | theirs && | |
1692 | sed -e "s/^\([<|=>]\)/\1\1/" ours >vmb_a && | |
1693 | ||
1694 | git cat-file -p master:b >base && | |
1695 | git cat-file -p L1:b >ours && | |
1696 | git cat-file -p R1:b >theirs && | |
1697 | test_must_fail git merge-file --diff3 \ | |
1698 | -L "Temporary merge branch 1" \ | |
743474cb | 1699 | -L "$MASTER" \ |
b28eeb30 EN |
1700 | -L "Temporary merge branch 2" \ |
1701 | ours \ | |
1702 | base \ | |
1703 | theirs && | |
1704 | sed -e "s/^\([<|=>]\)/\1\1/" ours >vmb_b && | |
1705 | ||
1706 | # Compare :2:m to expected values | |
1707 | git cat-file -p L2:m >ours && | |
1708 | git cat-file -p R2:b >theirs && | |
1709 | test_must_fail git merge-file --diff3 \ | |
1710 | -L "HEAD:m" \ | |
1711 | -L "merged common ancestors:b" \ | |
1712 | -L "R2^0:b" \ | |
1713 | ours \ | |
1714 | vmb_b \ | |
1715 | theirs && | |
1716 | sed -e "s/^\([<|=>]\)/\1\1/" ours >m_stage_2 && | |
1717 | git cat-file -p :2:m >actual && | |
1718 | test_cmp m_stage_2 actual && | |
1719 | ||
1720 | # Compare :3:m to expected values | |
1721 | git cat-file -p L2:a >ours && | |
1722 | git cat-file -p R2:m >theirs && | |
1723 | test_must_fail git merge-file --diff3 \ | |
1724 | -L "HEAD:a" \ | |
1725 | -L "merged common ancestors:a" \ | |
1726 | -L "R2^0:m" \ | |
1727 | ours \ | |
1728 | vmb_a \ | |
1729 | theirs && | |
1730 | sed -e "s/^\([<|=>]\)/\1\1/" ours >m_stage_3 && | |
1731 | git cat-file -p :3:m >actual && | |
1732 | test_cmp m_stage_3 actual && | |
1733 | ||
1734 | # Compare m to expected contents | |
1735 | >empty && | |
cc4cb090 | 1736 | cp m_stage_2 expected_final_m && |
b28eeb30 EN |
1737 | test_must_fail git merge-file --diff3 \ |
1738 | -L "HEAD" \ | |
1739 | -L "merged common ancestors" \ | |
1740 | -L "R2^0" \ | |
1741 | expected_final_m \ | |
1742 | empty \ | |
1743 | m_stage_3 && | |
1744 | test_cmp expected_final_m m | |
1745 | ) | |
1746 | ' | |
1747 | ||
b2a7942b EN |
1748 | # Setup: |
1749 | # L1---L2---L3 | |
1750 | # / \ / \ / \ | |
1751 | # master X1 X2 ? | |
1752 | # \ / \ / \ / | |
1753 | # R1---R2---R3 | |
1754 | # | |
1755 | # Where: | |
1756 | # master has one file named 'content' | |
1757 | # branches L1 and R1 both modify each of the two files in conflicting ways | |
1758 | # | |
1759 | # L<n> (n>1) is a merge of R<n-1> into L<n-1> | |
1760 | # R<n> (n>1) is a merge of L<n-1> into R<n-1> | |
1761 | # L<n> and R<n> resolve the conflicts differently. | |
1762 | # | |
1763 | # X<n> is an auto-generated merge-base used when merging L<n+1> and R<n+1>. | |
1764 | # By construction, X1 has conflict markers due to conflicting versions. | |
1765 | # X2, due to using merge.conflictstyle=3, has nested conflict markers. | |
1766 | # | |
1767 | # So, merging R3 into L3 using merge.conflictstyle=3 should show the | |
1768 | # nested conflict markers from X2 in the base version -- that means we | |
1769 | # have three levels of conflict markers. Can we distinguish all three? | |
1770 | ||
1771 | test_expect_success 'setup virtual merge base with nested conflicts' ' | |
1772 | test_create_repo virtual_merge_base_has_nested_conflicts && | |
1773 | ( | |
1774 | cd virtual_merge_base_has_nested_conflicts && | |
1775 | ||
1776 | # Create some related files now | |
1777 | for i in $(test_seq 1 10) | |
1778 | do | |
1779 | echo Random base content line $i | |
1780 | done >content && | |
1781 | ||
1782 | # Setup original commit | |
1783 | git add content && | |
1784 | test_tick && git commit -m initial && | |
1785 | ||
1786 | git branch L && | |
1787 | git branch R && | |
1788 | ||
1789 | # Create L1 | |
1790 | git checkout L && | |
1791 | echo left >>content && | |
1792 | git add content && | |
1793 | test_tick && git commit -m "version L1 of content" && | |
1794 | git tag L1 && | |
1795 | ||
1796 | # Create R1 | |
1797 | git checkout R && | |
1798 | echo right >>content && | |
1799 | git add content && | |
aa74be31 | 1800 | test_tick && git commit -m "version R1 of content" && |
b2a7942b EN |
1801 | git tag R1 && |
1802 | ||
1803 | # Create L2 | |
1804 | git checkout L && | |
1805 | test_must_fail git -c merge.conflictstyle=diff3 merge R1 && | |
1806 | git checkout L1 content && | |
1807 | test_tick && git commit -m "version L2 of content" && | |
1808 | git tag L2 && | |
1809 | ||
1810 | # Create R2 | |
1811 | git checkout R && | |
1812 | test_must_fail git -c merge.conflictstyle=diff3 merge L1 && | |
1813 | git checkout R1 content && | |
1814 | test_tick && git commit -m "version R2 of content" && | |
1815 | git tag R2 && | |
1816 | ||
1817 | # Create L3 | |
1818 | git checkout L && | |
1819 | test_must_fail git -c merge.conflictstyle=diff3 merge R2 && | |
1820 | git checkout L1 content && | |
1821 | test_tick && git commit -m "version L3 of content" && | |
1822 | git tag L3 && | |
1823 | ||
1824 | # Create R3 | |
1825 | git checkout R && | |
1826 | test_must_fail git -c merge.conflictstyle=diff3 merge L2 && | |
1827 | git checkout R1 content && | |
1828 | test_tick && git commit -m "version R3 of content" && | |
1829 | git tag R3 | |
1830 | ) | |
1831 | ' | |
1832 | ||
1833 | test_expect_success 'check virtual merge base with nested conflicts' ' | |
1834 | ( | |
1835 | cd virtual_merge_base_has_nested_conflicts && | |
1836 | ||
743474cb | 1837 | MASTER=$(git rev-parse --short master) && |
b2a7942b EN |
1838 | git checkout L3^0 && |
1839 | ||
1840 | # Merge must fail; there is a conflict | |
1841 | test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R3^0 && | |
1842 | ||
1843 | # Make sure the index has the right number of entries | |
1844 | git ls-files -s >out && | |
1845 | test_line_count = 3 out && | |
1846 | git ls-files -u >out && | |
1847 | test_line_count = 3 out && | |
1848 | # Ensure we have the correct number of untracked files | |
1849 | git ls-files -o >out && | |
1850 | test_line_count = 1 out && | |
1851 | ||
1852 | # Compare :[23]:content to expected values | |
1853 | git rev-parse L1:content R1:content >expect && | |
1854 | git rev-parse :2:content :3:content >actual && | |
1855 | test_cmp expect actual && | |
1856 | ||
1857 | # Imitate X1 merge base, except without long enough conflict | |
1858 | # markers because a subsequent sed will modify them. Put | |
1859 | # result into vmb. | |
1860 | git cat-file -p master:content >base && | |
1861 | git cat-file -p L:content >left && | |
1862 | git cat-file -p R:content >right && | |
1863 | cp left merged-once && | |
1864 | test_must_fail git merge-file --diff3 \ | |
1865 | -L "Temporary merge branch 1" \ | |
743474cb | 1866 | -L "$MASTER" \ |
b2a7942b EN |
1867 | -L "Temporary merge branch 2" \ |
1868 | merged-once \ | |
1869 | base \ | |
1870 | right && | |
1871 | sed -e "s/^\([<|=>]\)/\1\1\1/" merged-once >vmb && | |
1872 | ||
1873 | # Imitate X2 merge base, overwriting vmb. Note that we | |
1874 | # extend both sets of conflict markers to make them longer | |
1875 | # with the sed command. | |
1876 | cp left merged-twice && | |
1877 | test_must_fail git merge-file --diff3 \ | |
1878 | -L "Temporary merge branch 1" \ | |
1879 | -L "merged common ancestors" \ | |
1880 | -L "Temporary merge branch 2" \ | |
1881 | merged-twice \ | |
1882 | vmb \ | |
1883 | right && | |
1884 | sed -e "s/^\([<|=>]\)/\1\1\1/" merged-twice >vmb && | |
1885 | ||
1886 | # Compare :1:content to expected value | |
1887 | git cat-file -p :1:content >actual && | |
1888 | test_cmp vmb actual && | |
1889 | ||
1890 | # Determine expected content in final outer merge, compare to | |
1891 | # what the merge generated. | |
1892 | cp -f left expect && | |
1893 | test_must_fail git merge-file --diff3 \ | |
1894 | -L "HEAD" -L "merged common ancestors" -L "R3^0" \ | |
1895 | expect vmb right && | |
1896 | test_cmp expect content | |
1897 | ) | |
1898 | ' | |
1899 | ||
c94736a2 | 1900 | test_done |