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