]> git.ipfire.org Git - thirdparty/git.git/blame - t/t6042-merge-rename-corner-cases.sh
merge-recursive: use handle_file_collision for add/add conflicts
[thirdparty/git.git] / t / t6042-merge-rename-corner-cases.sh
CommitLineData
695576fd
EN
1#!/bin/sh
2
3test_description="recursive merge corner cases w/ renames but not criss-crosses"
4# t6036 has corner cases that involve both criss-cross merges and renames
5
6. ./test-lib.sh
7
8test_expect_success 'setup rename/delete + untracked file' '
2a4c19ef
EN
9 test_create_repo rename-delete-untracked &&
10 (
11 cd rename-delete-untracked &&
12
13 echo "A pretty inscription" >ring &&
14 git add ring &&
15 test_tick &&
16 git commit -m beginning &&
17
18 git branch people &&
19 git checkout -b rename-the-ring &&
20 git mv ring one-ring-to-rule-them-all &&
21 test_tick &&
22 git commit -m fullname &&
23
24 git checkout people &&
25 git rm ring &&
26 echo gollum >owner &&
27 git add owner &&
28 test_tick &&
29 git commit -m track-people-instead-of-objects &&
30 echo "Myyy PRECIOUSSS" >ring
31 )
695576fd
EN
32'
33
531357a4 34test_expect_success "Does git preserve Gollum's precious artifact?" '
2a4c19ef
EN
35 (
36 cd rename-delete-untracked &&
695576fd 37
2a4c19ef
EN
38 test_must_fail git merge -s recursive rename-the-ring &&
39
40 # Make sure git did not delete an untracked file
5b0b9712 41 test_path_is_file ring
2a4c19ef 42 )
695576fd
EN
43'
44
58040239
EN
45# Testcase setup for rename/modify/add-source:
46# Commit A: new file: a
47# Commit B: modify a slightly
48# Commit C: rename a->b, add completely different a
49#
50# We should be able to merge B & C cleanly
51
52test_expect_success 'setup rename/modify/add-source conflict' '
2a4c19ef
EN
53 test_create_repo rename-modify-add-source &&
54 (
55 cd rename-modify-add-source &&
56
57 printf "1\n2\n3\n4\n5\n6\n7\n" >a &&
58 git add a &&
59 git commit -m A &&
60 git tag A &&
61
62 git checkout -b B A &&
63 echo 8 >>a &&
64 git add a &&
65 git commit -m B &&
66
67 git checkout -b C A &&
68 git mv a b &&
69 echo something completely different >a &&
70 git add a &&
71 git commit -m C
72 )
58040239
EN
73'
74
75test_expect_failure 'rename/modify/add-source conflict resolvable' '
2a4c19ef
EN
76 (
77 cd rename-modify-add-source &&
78
79 git checkout B^0 &&
58040239 80
2a4c19ef 81 git merge -s recursive C^0 &&
58040239 82
6ac767e5
EN
83 git rev-parse >expect \
84 B:a C:a &&
85 git rev-parse >actual \
86 b c &&
87 test_cmp expect actual
2a4c19ef 88 )
58040239
EN
89'
90
7b4ed594 91test_expect_success 'setup resolvable conflict missed if rename missed' '
2a4c19ef
EN
92 test_create_repo break-detection-1 &&
93 (
94 cd break-detection-1 &&
95
96 printf "1\n2\n3\n4\n5\n" >a &&
97 echo foo >b &&
98 git add a b &&
99 git commit -m A &&
100 git tag A &&
101
102 git checkout -b B A &&
103 git mv a c &&
104 echo "Completely different content" >a &&
105 git add a &&
106 git commit -m B &&
107
108 git checkout -b C A &&
109 echo 6 >>a &&
110 git add a &&
111 git commit -m C
112 )
7b4ed594
EN
113'
114
115test_expect_failure 'conflict caused if rename not detected' '
2a4c19ef
EN
116 (
117 cd break-detection-1 &&
118
119 git checkout -q C^0 &&
120 git merge -s recursive B^0 &&
7b4ed594 121
0cdabc10
EN
122 git ls-files -s >out &&
123 test_line_count = 3 out &&
124 git ls-files -u >out &&
125 test_line_count = 0 out &&
126 git ls-files -o >out &&
127 test_line_count = 1 out &&
7b4ed594 128
2a4c19ef 129 test_line_count = 6 c &&
6ac767e5
EN
130 git rev-parse >expect \
131 B:a A:b &&
132 git rev-parse >actual \
133 :0:a :0:b &&
134 test_cmp expect actual
2a4c19ef 135 )
7b4ed594
EN
136'
137
138test_expect_success 'setup conflict resolved wrong if rename missed' '
2a4c19ef
EN
139 test_create_repo break-detection-2 &&
140 (
141 cd break-detection-2 &&
142
143 printf "1\n2\n3\n4\n5\n" >a &&
144 echo foo >b &&
145 git add a b &&
146 git commit -m A &&
147 git tag A &&
148
149 git checkout -b D A &&
150 echo 7 >>a &&
151 git add a &&
152 git mv a c &&
153 echo "Completely different content" >a &&
154 git add a &&
155 git commit -m D &&
156
157 git checkout -b E A &&
158 git rm a &&
159 echo "Completely different content" >>a &&
160 git add a &&
161 git commit -m E
162 )
7b4ed594
EN
163'
164
165test_expect_failure 'missed conflict if rename not detected' '
2a4c19ef
EN
166 (
167 cd break-detection-2 &&
168
169 git checkout -q E^0 &&
170 test_must_fail git merge -s recursive D^0
171 )
7b4ed594
EN
172'
173
a0551f21
EN
174# Tests for undetected rename/add-source causing a file to erroneously be
175# deleted (and for mishandled rename/rename(1to1) causing the same issue).
176#
177# This test uses a rename/rename(1to1)+add-source conflict (1to1 means the
178# same file is renamed on both sides to the same thing; it should trigger
179# the 1to2 logic, which it would do if the add-source didn't cause issues
180# for git's rename detection):
181# Commit A: new file: a
182# Commit B: rename a->b
183# Commit C: rename a->b, add unrelated a
184
185test_expect_success 'setup undetected rename/add-source causes data loss' '
2a4c19ef
EN
186 test_create_repo break-detection-3 &&
187 (
188 cd break-detection-3 &&
189
190 printf "1\n2\n3\n4\n5\n" >a &&
191 git add a &&
192 git commit -m A &&
193 git tag A &&
194
195 git checkout -b B A &&
196 git mv a b &&
197 git commit -m B &&
198
199 git checkout -b C A &&
200 git mv a b &&
201 echo foobar >a &&
202 git add a &&
203 git commit -m C
204 )
a0551f21
EN
205'
206
207test_expect_failure 'detect rename/add-source and preserve all data' '
2a4c19ef
EN
208 (
209 cd break-detection-3 &&
210
211 git checkout B^0 &&
a0551f21 212
2a4c19ef 213 git merge -s recursive C^0 &&
a0551f21 214
0cdabc10
EN
215 git ls-files -s >out &&
216 test_line_count = 2 out &&
217 git ls-files -u >out &&
218 test_line_count = 2 out &&
219 git ls-files -o >out &&
220 test_line_count = 1 out &&
a0551f21 221
5b0b9712
EN
222 test_path_is_file a &&
223 test_path_is_file b &&
a0551f21 224
6ac767e5
EN
225 git rev-parse >expect \
226 A:a C:a &&
227 git rev-parse >actual \
228 :0:b :0:a &&
229 test_cmp expect actual
2a4c19ef 230 )
a0551f21
EN
231'
232
233test_expect_failure 'detect rename/add-source and preserve all data, merge other way' '
2a4c19ef
EN
234 (
235 cd break-detection-3 &&
a0551f21 236
2a4c19ef 237 git checkout C^0 &&
a0551f21 238
2a4c19ef 239 git merge -s recursive B^0 &&
a0551f21 240
0cdabc10
EN
241 git ls-files -s >out &&
242 test_line_count = 2 out &&
243 git ls-files -u >out &&
244 test_line_count = 2 out &&
245 git ls-files -o >out &&
246 test_line_count = 1 out &&
a0551f21 247
5b0b9712
EN
248 test_path_is_file a &&
249 test_path_is_file b &&
2a4c19ef 250
6ac767e5
EN
251 git rev-parse >expect \
252 A:a C:a &&
253 git rev-parse >actual \
254 :0:b :0:a &&
255 test_cmp expect actual
2a4c19ef 256 )
a0551f21
EN
257'
258
ac6e8392 259test_expect_success 'setup content merge + rename/directory conflict' '
2a4c19ef
EN
260 test_create_repo rename-directory-1 &&
261 (
262 cd rename-directory-1 &&
263
264 printf "1\n2\n3\n4\n5\n6\n" >file &&
265 git add file &&
266 test_tick &&
267 git commit -m base &&
268 git tag base &&
269
270 git checkout -b right &&
271 echo 7 >>file &&
272 mkdir newfile &&
273 echo junk >newfile/realfile &&
274 git add file newfile/realfile &&
275 test_tick &&
276 git commit -m right &&
277
278 git checkout -b left-conflict base &&
279 echo 8 >>file &&
280 git add file &&
281 git mv file newfile &&
282 test_tick &&
283 git commit -m left &&
284
285 git checkout -b left-clean base &&
286 echo 0 >newfile &&
287 cat file >>newfile &&
288 git add newfile &&
289 git rm file &&
290 test_tick &&
291 git commit -m left
292 )
ac6e8392
EN
293'
294
51931bf0 295test_expect_success 'rename/directory conflict + clean content merge' '
2a4c19ef
EN
296 (
297 cd rename-directory-1 &&
ac6e8392 298
2a4c19ef 299 git checkout left-clean^0 &&
ac6e8392 300
2a4c19ef 301 test_must_fail git merge -s recursive right^0 &&
ac6e8392 302
0cdabc10
EN
303 git ls-files -s >out &&
304 test_line_count = 2 out &&
305 git ls-files -u >out &&
306 test_line_count = 1 out &&
307 git ls-files -o >out &&
308 test_line_count = 2 out &&
ac6e8392 309
2a4c19ef
EN
310 echo 0 >expect &&
311 git cat-file -p base:file >>expect &&
312 echo 7 >>expect &&
313 test_cmp expect newfile~HEAD &&
ac6e8392 314
2a4c19ef 315 test $(git rev-parse :2:newfile) = $(git hash-object expect) &&
ac6e8392 316
5b0b9712
EN
317 test_path_is_file newfile/realfile &&
318 test_path_is_file newfile~HEAD
2a4c19ef 319 )
ac6e8392
EN
320'
321
3c217c07 322test_expect_success 'rename/directory conflict + content merge conflict' '
2a4c19ef
EN
323 (
324 cd rename-directory-1 &&
325
2a4c19ef
EN
326 git reset --hard &&
327 git clean -fdqx &&
328
329 git checkout left-conflict^0 &&
330
331 test_must_fail git merge -s recursive right^0 &&
332
0cdabc10
EN
333 git ls-files -s >out &&
334 test_line_count = 4 out &&
335 git ls-files -u >out &&
336 test_line_count = 3 out &&
337 git ls-files -o >out &&
338 test_line_count = 2 out &&
2a4c19ef
EN
339
340 git cat-file -p left-conflict:newfile >left &&
341 git cat-file -p base:file >base &&
342 git cat-file -p right:file >right &&
343 test_must_fail git merge-file \
344 -L "HEAD:newfile" \
345 -L "" \
346 -L "right^0:file" \
347 left base right &&
348 test_cmp left newfile~HEAD &&
349
6ac767e5
EN
350 git rev-parse >expect \
351 base:file left-conflict:newfile right:file &&
352 git rev-parse >actual \
353 :1:newfile :2:newfile :3:newfile &&
c8ce3763 354 test_cmp expect actual &&
2a4c19ef 355
5b0b9712
EN
356 test_path_is_file newfile/realfile &&
357 test_path_is_file newfile~HEAD
2a4c19ef 358 )
ac6e8392
EN
359'
360
361test_expect_success 'setup content merge + rename/directory conflict w/ disappearing dir' '
2a4c19ef
EN
362 test_create_repo rename-directory-2 &&
363 (
364 cd rename-directory-2 &&
365
366 mkdir sub &&
367 printf "1\n2\n3\n4\n5\n6\n" >sub/file &&
368 git add sub/file &&
369 test_tick &&
370 git commit -m base &&
371 git tag base &&
372
373 git checkout -b right &&
374 echo 7 >>sub/file &&
375 git add sub/file &&
376 test_tick &&
377 git commit -m right &&
378
379 git checkout -b left base &&
380 echo 0 >newfile &&
381 cat sub/file >>newfile &&
382 git rm sub/file &&
383 mv newfile sub &&
384 git add sub &&
385 test_tick &&
386 git commit -m left
387 )
ac6e8392
EN
388'
389
390test_expect_success 'disappearing dir in rename/directory conflict handled' '
2a4c19ef
EN
391 (
392 cd rename-directory-2 &&
ac6e8392 393
2a4c19ef 394 git checkout left^0 &&
ac6e8392 395
2a4c19ef 396 git merge -s recursive right^0 &&
ac6e8392 397
0cdabc10
EN
398 git ls-files -s >out &&
399 test_line_count = 1 out &&
400 git ls-files -u >out &&
401 test_line_count = 0 out &&
402 git ls-files -o >out &&
403 test_line_count = 1 out &&
ac6e8392 404
2a4c19ef
EN
405 echo 0 >expect &&
406 git cat-file -p base:sub/file >>expect &&
407 echo 7 >>expect &&
408 test_cmp expect sub &&
ac6e8392 409
5b0b9712 410 test_path_is_file sub
2a4c19ef 411 )
ac6e8392
EN
412'
413
f0b75fcc
EN
414# Test for all kinds of things that can go wrong with rename/rename (2to1):
415# Commit A: new files: a & b
416# Commit B: rename a->c, modify b
417# Commit C: rename b->c, modify a
418#
419# Merging of B & C should NOT be clean. Questions:
420# * Both a & b should be removed by the merge; are they?
421# * The two c's should contain modifications to a & b; do they?
422# * The index should contain two files, both for c; does it?
423# * The working copy should have two files, both of form c~<unique>; does it?
424# * Nothing else should be present. Is anything?
425
426test_expect_success 'setup rename/rename (2to1) + modify/modify' '
2a4c19ef
EN
427 test_create_repo rename-rename-2to1 &&
428 (
429 cd rename-rename-2to1 &&
430
431 printf "1\n2\n3\n4\n5\n" >a &&
432 printf "5\n4\n3\n2\n1\n" >b &&
433 git add a b &&
434 git commit -m A &&
435 git tag A &&
436
437 git checkout -b B A &&
438 git mv a c &&
439 echo 0 >>b &&
440 git add b &&
441 git commit -m B &&
442
443 git checkout -b C A &&
444 git mv b c &&
445 echo 6 >>a &&
446 git add a &&
447 git commit -m C
448 )
f0b75fcc
EN
449'
450
434b8525 451test_expect_success 'handle rename/rename (2to1) conflict correctly' '
2a4c19ef
EN
452 (
453 cd rename-rename-2to1 &&
454
455 git checkout B^0 &&
f0b75fcc 456
2a4c19ef
EN
457 test_must_fail git merge -s recursive C^0 >out &&
458 test_i18ngrep "CONFLICT (rename/rename)" out &&
f0b75fcc 459
0cdabc10
EN
460 git ls-files -s >out &&
461 test_line_count = 2 out &&
462 git ls-files -u >out &&
463 test_line_count = 2 out &&
464 git ls-files -u c >out &&
465 test_line_count = 2 out &&
466 git ls-files -o >out &&
bbafc9c4 467 test_line_count = 1 out &&
f0b75fcc 468
5b0b9712
EN
469 test_path_is_missing a &&
470 test_path_is_missing b &&
f0b75fcc 471
bbafc9c4
EN
472 git rev-parse >expect \
473 C:a B:b &&
474 git rev-parse >actual \
475 :2:c :3:c &&
476 test_cmp expect actual &&
477
478 # Test that the two-way merge in new_a is as expected
479 git cat-file -p :2:c >>ours &&
480 git cat-file -p :3:c >>theirs &&
481 >empty &&
482 test_must_fail git merge-file \
483 -L "HEAD" \
484 -L "" \
485 -L "C^0" \
486 ours empty theirs &&
487 git hash-object c >actual &&
488 git hash-object ours >expect &&
6ac767e5 489 test_cmp expect actual
2a4c19ef 490 )
f0b75fcc
EN
491'
492
493# Testcase setup for simple rename/rename (1to2) conflict:
494# Commit A: new file: a
495# Commit B: rename a->b
496# Commit C: rename a->c
497test_expect_success 'setup simple rename/rename (1to2) conflict' '
2a4c19ef
EN
498 test_create_repo rename-rename-1to2 &&
499 (
500 cd rename-rename-1to2 &&
501
502 echo stuff >a &&
503 git add a &&
504 test_tick &&
505 git commit -m A &&
506 git tag A &&
507
508 git checkout -b B A &&
509 git mv a b &&
510 test_tick &&
511 git commit -m B &&
512
513 git checkout -b C A &&
514 git mv a c &&
515 test_tick &&
516 git commit -m C
517 )
f0b75fcc
EN
518'
519
520test_expect_success 'merge has correct working tree contents' '
2a4c19ef
EN
521 (
522 cd rename-rename-1to2 &&
523
524 git checkout C^0 &&
f0b75fcc 525
2a4c19ef 526 test_must_fail git merge -s recursive B^0 &&
f0b75fcc 527
0cdabc10
EN
528 git ls-files -s >out &&
529 test_line_count = 3 out &&
530 git ls-files -u >out &&
531 test_line_count = 3 out &&
532 git ls-files -o >out &&
533 test_line_count = 1 out &&
f0b75fcc 534
5b0b9712 535 test_path_is_missing a &&
6ac767e5
EN
536 git rev-parse >expect \
537 A:a A:a A:a \
538 A:a A:a &&
539 git rev-parse >actual \
540 :1:a :3:b :2:c &&
541 git hash-object >>actual \
542 b c &&
543 test_cmp expect actual
2a4c19ef 544 )
f0b75fcc
EN
545'
546
c6966068
EN
547# Testcase setup for rename/rename(1to2)/add-source conflict:
548# Commit A: new file: a
549# Commit B: rename a->b
550# Commit C: rename a->c, add completely different a
551#
552# Merging of B & C should NOT be clean; there's a rename/rename conflict
553
554test_expect_success 'setup rename/rename(1to2)/add-source conflict' '
2a4c19ef
EN
555 test_create_repo rename-rename-1to2-add-source-1 &&
556 (
557 cd rename-rename-1to2-add-source-1 &&
558
559 printf "1\n2\n3\n4\n5\n6\n7\n" >a &&
560 git add a &&
561 git commit -m A &&
562 git tag A &&
563
564 git checkout -b B A &&
565 git mv a b &&
566 git commit -m B &&
567
568 git checkout -b C A &&
569 git mv a c &&
570 echo something completely different >a &&
571 git add a &&
572 git commit -m C
573 )
c6966068
EN
574'
575
576test_expect_failure 'detect conflict with rename/rename(1to2)/add-source merge' '
2a4c19ef
EN
577 (
578 cd rename-rename-1to2-add-source-1 &&
c6966068 579
2a4c19ef 580 git checkout B^0 &&
c6966068 581
2a4c19ef 582 test_must_fail git merge -s recursive C^0 &&
c6966068 583
0cdabc10
EN
584 git ls-files -s >out &&
585 test_line_count = 4 out &&
586 git ls-files -o >out &&
587 test_line_count = 1 out &&
c6966068 588
6ac767e5
EN
589 git rev-parse >expect \
590 C:a A:a B:b C:C &&
591 git rev-parse >actual \
592 :3:a :1:a :2:b :3:c &&
c8ce3763 593 test_cmp expect actual &&
2a4c19ef 594
5b0b9712
EN
595 test_path_is_file a &&
596 test_path_is_file b &&
597 test_path_is_file c
2a4c19ef 598 )
c6966068
EN
599'
600
601test_expect_success 'setup rename/rename(1to2)/add-source resolvable conflict' '
2a4c19ef
EN
602 test_create_repo rename-rename-1to2-add-source-2 &&
603 (
604 cd rename-rename-1to2-add-source-2 &&
605
606 >a &&
607 git add a &&
608 test_tick &&
609 git commit -m base &&
610 git tag A &&
611
612 git checkout -b B A &&
613 git mv a b &&
614 test_tick &&
615 git commit -m one &&
616
617 git checkout -b C A &&
618 git mv a b &&
619 echo important-info >a &&
620 git add a &&
621 test_tick &&
622 git commit -m two
623 )
c6966068
EN
624'
625
626test_expect_failure 'rename/rename/add-source still tracks new a file' '
2a4c19ef
EN
627 (
628 cd rename-rename-1to2-add-source-2 &&
629
630 git checkout C^0 &&
631 git merge -s recursive B^0 &&
c6966068 632
0cdabc10
EN
633 git ls-files -s >out &&
634 test_line_count = 2 out &&
635 git ls-files -o >out &&
636 test_line_count = 1 out &&
c6966068 637
6ac767e5
EN
638 git rev-parse >expect \
639 C:a A:a &&
640 git rev-parse >actual \
641 :0:a :0:b &&
642 test_cmp expect actual
2a4c19ef 643 )
c6966068
EN
644'
645
646test_expect_success 'setup rename/rename(1to2)/add-dest conflict' '
2a4c19ef
EN
647 test_create_repo rename-rename-1to2-add-dest &&
648 (
649 cd rename-rename-1to2-add-dest &&
650
651 echo stuff >a &&
652 git add a &&
653 test_tick &&
654 git commit -m base &&
655 git tag A &&
656
657 git checkout -b B A &&
658 git mv a b &&
659 echo precious-data >c &&
660 git add c &&
661 test_tick &&
662 git commit -m one &&
663
664 git checkout -b C A &&
665 git mv a c &&
666 echo important-info >b &&
667 git add b &&
668 test_tick &&
669 git commit -m two
670 )
c6966068
EN
671'
672
1ac91b32 673test_expect_success 'rename/rename/add-dest merge still knows about conflicting file versions' '
2a4c19ef
EN
674 (
675 cd rename-rename-1to2-add-dest &&
676
677 git checkout C^0 &&
678 test_must_fail git merge -s recursive B^0 &&
679
0cdabc10
EN
680 git ls-files -s >out &&
681 test_line_count = 5 out &&
682 git ls-files -u b >out &&
683 test_line_count = 2 out &&
684 git ls-files -u c >out &&
685 test_line_count = 2 out &&
686 git ls-files -o >out &&
687 test_line_count = 5 out &&
2a4c19ef 688
6ac767e5
EN
689 git rev-parse >expect \
690 A:a C:b B:b C:c B:c &&
691 git rev-parse >actual \
692 :1:a :2:b :3:b :2:c :3:c &&
c8ce3763 693 test_cmp expect actual &&
6ac767e5
EN
694
695 git rev-parse >expect \
696 C:c B:c C:b B:b &&
697 git hash-object >actual \
698 c~HEAD c~B\^0 b~HEAD b~B\^0 &&
c8ce3763 699 test_cmp expect actual &&
2a4c19ef 700
5b0b9712
EN
701 test_path_is_missing b &&
702 test_path_is_missing c
2a4c19ef 703 )
c6966068
EN
704'
705
11d9ade1
EN
706# Testcase rad, rename/add/delete
707# Commit O: foo
708# Commit A: rm foo, add different bar
709# Commit B: rename foo->bar
710# Expected: CONFLICT (rename/add/delete), two-way merged bar
711
712test_expect_success 'rad-setup: rename/add/delete conflict' '
713 test_create_repo rad &&
714 (
715 cd rad &&
716 echo "original file" >foo &&
717 git add foo &&
718 git commit -m "original" &&
719
720 git branch O &&
721 git branch A &&
722 git branch B &&
723
724 git checkout A &&
725 git rm foo &&
726 echo "different file" >bar &&
727 git add bar &&
728 git commit -m "Remove foo, add bar" &&
729
730 git checkout B &&
731 git mv foo bar &&
732 git commit -m "rename foo to bar"
733 )
734'
735
736test_expect_failure 'rad-check: rename/add/delete conflict' '
737 (
738 cd rad &&
739
740 git checkout B^0 &&
741 test_must_fail git merge -s recursive A^0 >out 2>err &&
742
743 # Not sure whether the output should contain just one
744 # "CONFLICT (rename/add/delete)" line, or if it should break
745 # it into a pair of "CONFLICT (rename/delete)" and
746 # "CONFLICT (rename/add)"; allow for either.
747 test_i18ngrep "CONFLICT (rename.*add)" out &&
748 test_i18ngrep "CONFLICT (rename.*delete)" out &&
749 test_must_be_empty err &&
750
751 git ls-files -s >file_count &&
752 test_line_count = 2 file_count &&
753 git ls-files -u >file_count &&
754 test_line_count = 2 file_count &&
755 git ls-files -o >file_count &&
756 test_line_count = 2 file_count &&
757
758 git rev-parse >actual \
759 :2:bar :3:bar &&
760 git rev-parse >expect \
761 B:bar A:bar &&
762
763 test_cmp file_is_missing foo &&
764 # bar should have two-way merged contents of the different
765 # versions of bar; check that content from both sides is
766 # present.
767 grep original bar &&
768 grep different bar
769 )
770'
771
eee73388
EN
772# Testcase rrdd, rename/rename(2to1)/delete/delete
773# Commit O: foo, bar
774# Commit A: rename foo->baz, rm bar
775# Commit B: rename bar->baz, rm foo
776# Expected: CONFLICT (rename/rename/delete/delete), two-way merged baz
777
778test_expect_success 'rrdd-setup: rename/rename(2to1)/delete/delete conflict' '
779 test_create_repo rrdd &&
780 (
781 cd rrdd &&
782 echo foo >foo &&
783 echo bar >bar &&
784 git add foo bar &&
785 git commit -m O &&
786
787 git branch O &&
788 git branch A &&
789 git branch B &&
790
791 git checkout A &&
792 git mv foo baz &&
793 git rm bar &&
794 git commit -m "Rename foo, remove bar" &&
795
796 git checkout B &&
797 git mv bar baz &&
798 git rm foo &&
799 git commit -m "Rename bar, remove foo"
800 )
801'
802
803test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '
804 (
805 cd rrdd &&
806
807 git checkout A^0 &&
808 test_must_fail git merge -s recursive B^0 >out 2>err &&
809
810 # Not sure whether the output should contain just one
811 # "CONFLICT (rename/rename/delete/delete)" line, or if it
812 # should break it into three: "CONFLICT (rename/rename)" and
813 # two "CONFLICT (rename/delete)" lines; allow for either.
814 test_i18ngrep "CONFLICT (rename/rename)" out &&
815 test_i18ngrep "CONFLICT (rename.*delete)" out &&
816 test_must_be_empty err &&
817
818 git ls-files -s >file_count &&
819 test_line_count = 2 file_count &&
820 git ls-files -u >file_count &&
821 test_line_count = 2 file_count &&
822 git ls-files -o >file_count &&
823 test_line_count = 2 file_count &&
824
825 git rev-parse >actual \
826 :2:baz :3:baz &&
827 git rev-parse >expect \
828 O:foo O:bar &&
829
830 test_cmp file_is_missing foo &&
831 test_cmp file_is_missing bar &&
832 # baz should have two-way merged contents of the original
833 # contents of foo and bar; check that content from both sides
834 # is present.
835 grep foo baz &&
836 grep bar baz
837 )
838'
839
651f7f3a
EN
840# Testcase mod6, chains of rename/rename(1to2) and rename/rename(2to1)
841# Commit O: one, three, five
842# Commit A: one->two, three->four, five->six
843# Commit B: one->six, three->two, five->four
844# Expected: six CONFLICT(rename/rename) messages, each path in two of the
845# multi-way merged contents found in two, four, six
846
847test_expect_success 'mod6-setup: chains of rename/rename(1to2) and rename/rename(2to1)' '
848 test_create_repo mod6 &&
849 (
850 cd mod6 &&
851 test_seq 11 19 >one &&
852 test_seq 31 39 >three &&
853 test_seq 51 59 >five &&
854 git add . &&
855 test_tick &&
856 git commit -m "O" &&
857
858 git branch O &&
859 git branch A &&
860 git branch B &&
861
862 git checkout A &&
863 test_seq 10 19 >one &&
864 echo 40 >>three &&
865 git add one three &&
866 git mv one two &&
867 git mv three four &&
868 git mv five six &&
869 test_tick &&
870 git commit -m "A" &&
871
872 git checkout B &&
873 echo 20 >>one &&
874 echo forty >>three &&
875 echo 60 >>five &&
876 git add one three five &&
877 git mv one six &&
878 git mv three two &&
879 git mv five four &&
880 test_tick &&
881 git commit -m "B"
882 )
883'
884
885test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '
886 (
887 cd mod6 &&
888
889 git checkout A^0 &&
890
891 test_must_fail git merge -s recursive B^0 >out 2>err &&
892
893 test_i18ngrep "CONFLICT (rename/rename)" out &&
894 test_must_be_empty err &&
895
896 git ls-files -s >file_count &&
897 test_line_count = 6 file_count &&
898 git ls-files -u >file_count &&
899 test_line_count = 6 file_count &&
900 git ls-files -o >file_count &&
901 test_line_count = 3 file_count &&
902
903 test_seq 10 20 >merged-one &&
904 test_seq 51 60 >merged-five &&
905 # Determine what the merge of three would give us.
906 test_seq 30 40 >three-side-A &&
907 test_seq 31 39 >three-side-B &&
908 echo forty >three-side-B &&
909 >empty &&
910 test_must_fail git merge-file \
911 -L "HEAD" \
912 -L "" \
913 -L "B^0" \
914 three-side-A empty three-side-B &&
915 sed -e "s/^\([<=>]\)/\1\1\1/" three-side-A >merged-three &&
916
917 # Verify the index is as expected
918 git rev-parse >actual \
919 :2:two :3:two \
920 :2:four :3:four \
921 :2:six :3:six &&
922 git hash-object >expect \
923 merged-one merged-three \
924 merged-three merged-five \
925 merged-five merged-one &&
926 test_cmp expect actual &&
927
928 git cat-file -p :2:two >expect &&
929 git cat-file -p :3:two >other &&
930 test_must_fail git merge-file \
931 -L "HEAD" -L "" -L "B^0" \
932 expect empty other &&
933 test_cmp expect two &&
934
935 git cat-file -p :2:four >expect &&
936 git cat-file -p :3:four >other &&
937 test_must_fail git merge-file \
938 -L "HEAD" -L "" -L "B^0" \
939 expect empty other &&
940 test_cmp expect four &&
941
942 git cat-file -p :2:six >expect &&
943 git cat-file -p :3:six >other &&
944 test_must_fail git merge-file \
945 -L "HEAD" -L "" -L "B^0" \
946 expect empty other &&
947 test_cmp expect six
948 )
949'
950
bb05c9f7
EN
951test_conflicts_with_adds_and_renames() {
952 sideL=$1
953 sideR=$2
bb05c9f7
EN
954
955 # Setup:
956 # L
957 # / \
958 # master ?
959 # \ /
960 # R
961 #
962 # Where:
963 # Both L and R have files named 'three' which collide. Each of
964 # the colliding files could have been involved in a rename, in
965 # which case there was a file named 'one' or 'two' that was
966 # modified on the opposite side of history and renamed into the
967 # collision on this side of history.
968 #
969 # Questions:
970 # 1) The index should contain both a stage 2 and stage 3 entry
971 # for the colliding file. Does it?
972 # 2) When renames are involved, the content merges are clean, so
973 # the index should reflect the content merges, not merely the
974 # version of the colliding file from the prior commit. Does
975 # it?
976 # 3) There should be a file in the worktree named 'three'
977 # containing the two-way merged contents of the content-merged
978 # versions of 'three' from each of the two colliding
979 # files. Is it present?
980 # 4) There should not be any three~* files in the working
981 # tree
982 test_expect_success "setup simple $sideL/$sideR conflict" '
983 test_create_repo simple_${sideL}_${sideR} &&
984 (
985 cd simple_${sideL}_${sideR} &&
986
987 # Create some related files now
988 for i in $(test_seq 1 10)
989 do
990 echo Random base content line $i
991 done >file_v1 &&
992 cp file_v1 file_v2 &&
993 echo modification >>file_v2 &&
994
995 cp file_v1 file_v3 &&
996 echo more stuff >>file_v3 &&
997 cp file_v3 file_v4 &&
998 echo yet more stuff >>file_v4 &&
999
1000 # Use a tag to record both these files for simple
1001 # access, and clean out these untracked files
1002 git tag file_v1 $(git hash-object -w file_v1) &&
1003 git tag file_v2 $(git hash-object -w file_v2) &&
1004 git tag file_v3 $(git hash-object -w file_v3) &&
1005 git tag file_v4 $(git hash-object -w file_v4) &&
1006 git clean -f &&
1007
1008 # Setup original commit (or merge-base), consisting of
1009 # files named "one" and "two" if renames were involved.
1010 touch irrelevant_file &&
1011 git add irrelevant_file &&
1012 if [ $sideL = "rename" ]
1013 then
1014 git show file_v1 >one &&
1015 git add one
1016 fi &&
1017 if [ $sideR = "rename" ]
1018 then
1019 git show file_v3 >two &&
1020 git add two
1021 fi &&
1022 test_tick && git commit -m initial &&
1023
1024 git branch L &&
1025 git branch R &&
1026
1027 # Handle the left side
1028 git checkout L &&
1029 if [ $sideL = "rename" ]
1030 then
1031 git mv one three
1032 else
1033 git show file_v2 >three &&
1034 git add three
1035 fi &&
1036 if [ $sideR = "rename" ]
1037 then
1038 git show file_v4 >two &&
1039 git add two
1040 fi &&
1041 test_tick && git commit -m L &&
1042
1043 # Handle the right side
1044 git checkout R &&
1045 if [ $sideL = "rename" ]
1046 then
1047 git show file_v2 >one &&
1048 git add one
1049 fi &&
1050 if [ $sideR = "rename" ]
1051 then
1052 git mv two three
1053 else
1054 git show file_v4 >three &&
1055 git add three
1056 fi &&
1057 test_tick && git commit -m R
1058 )
1059 '
1060
bbafc9c4 1061 test_expect_success "check simple $sideL/$sideR conflict" '
bb05c9f7
EN
1062 (
1063 cd simple_${sideL}_${sideR} &&
1064
1065 git checkout L^0 &&
1066
1067 # Merge must fail; there is a conflict
1068 test_must_fail git merge -s recursive R^0 &&
1069
1070 # Make sure the index has the right number of entries
1071 git ls-files -s >out &&
1072 test_line_count = 3 out &&
1073 git ls-files -u >out &&
1074 test_line_count = 2 out &&
1075 # Ensure we have the correct number of untracked files
1076 git ls-files -o >out &&
1077 test_line_count = 1 out &&
1078
1079 # Nothing should have touched irrelevant_file
1080 git rev-parse >actual \
1081 :0:irrelevant_file \
1082 :2:three \
1083 :3:three &&
1084 git rev-parse >expected \
1085 master:irrelevant_file \
1086 file_v2 \
1087 file_v4 &&
1088 test_cmp expected actual &&
1089
1090 # Make sure we have the correct merged contents for
1091 # three
1092 git show file_v1 >expected &&
1093 cat <<-\EOF >>expected &&
1094 <<<<<<< HEAD
1095 modification
1096 =======
1097 more stuff
1098 yet more stuff
1099 >>>>>>> R^0
1100 EOF
1101
1102 test_cmp expected three
1103 )
1104 '
1105}
1106
bbafc9c4
EN
1107test_conflicts_with_adds_and_renames rename rename
1108test_conflicts_with_adds_and_renames rename add
1109test_conflicts_with_adds_and_renames add rename
1110test_conflicts_with_adds_and_renames add add
bb05c9f7 1111
b28eeb30
EN
1112# Setup:
1113# L
1114# / \
1115# master ?
1116# \ /
1117# R
1118#
1119# Where:
1120# master has two files, named 'one' and 'two'.
1121# branches L and R both modify 'one', in conflicting ways.
1122# branches L and R both modify 'two', in conflicting ways.
1123# branch L also renames 'one' to 'three'.
1124# branch R also renames 'two' to 'three'.
1125#
1126# So, we have four different conflicting files that all end up at path
1127# 'three'.
1128test_expect_success 'setup nested conflicts from rename/rename(2to1)' '
1129 test_create_repo nested_conflicts_from_rename_rename &&
1130 (
1131 cd nested_conflicts_from_rename_rename &&
1132
1133 # Create some related files now
1134 for i in $(test_seq 1 10)
1135 do
1136 echo Random base content line $i
1137 done >file_v1 &&
1138
1139 cp file_v1 file_v2 &&
1140 cp file_v1 file_v3 &&
1141 cp file_v1 file_v4 &&
1142 cp file_v1 file_v5 &&
1143 cp file_v1 file_v6 &&
1144
1145 echo one >>file_v1 &&
1146 echo uno >>file_v2 &&
1147 echo eins >>file_v3 &&
1148
1149 echo two >>file_v4 &&
1150 echo dos >>file_v5 &&
1151 echo zwei >>file_v6 &&
1152
1153 # Setup original commit (or merge-base), consisting of
1154 # files named "one" and "two".
1155 mv file_v1 one &&
1156 mv file_v4 two &&
1157 git add one two &&
1158 test_tick && git commit -m english &&
1159
1160 git branch L &&
1161 git branch R &&
1162
1163 # Handle the left side
1164 git checkout L &&
1165 git mv one three &&
1166 mv -f file_v2 three &&
1167 mv -f file_v5 two &&
1168 git add two three &&
1169 test_tick && git commit -m spanish &&
1170
1171 # Handle the right side
1172 git checkout R &&
1173 git mv two three &&
1174 mv -f file_v3 one &&
1175 mv -f file_v6 three &&
1176 git add one three &&
1177 test_tick && git commit -m german
1178 )
1179'
1180
bbafc9c4 1181test_expect_success 'check nested conflicts from rename/rename(2to1)' '
b28eeb30
EN
1182 (
1183 cd nested_conflicts_from_rename_rename &&
1184
1185 git checkout L^0 &&
1186
1187 # Merge must fail; there is a conflict
1188 test_must_fail git merge -s recursive R^0 &&
1189
1190 # Make sure the index has the right number of entries
1191 git ls-files -s >out &&
1192 test_line_count = 2 out &&
1193 git ls-files -u >out &&
1194 test_line_count = 2 out &&
1195 # Ensure we have the correct number of untracked files
1196 git ls-files -o >out &&
1197 test_line_count = 1 out &&
1198
1199 # Compare :2:three to expected values
1200 git cat-file -p master:one >base &&
1201 git cat-file -p L:three >ours &&
1202 git cat-file -p R:one >theirs &&
1203 test_must_fail git merge-file \
1204 -L "HEAD:three" -L "" -L "R^0:one" \
1205 ours base theirs &&
1206 sed -e "s/^\([<=>]\)/\1\1/" ours >L-three &&
1207 git cat-file -p :2:three >expect &&
1208 test_cmp expect L-three &&
1209
1210 # Compare :2:three to expected values
1211 git cat-file -p master:two >base &&
1212 git cat-file -p L:two >ours &&
1213 git cat-file -p R:three >theirs &&
1214 test_must_fail git merge-file \
1215 -L "HEAD:two" -L "" -L "R^0:three" \
1216 ours base theirs &&
1217 sed -e "s/^\([<=>]\)/\1\1/" ours >R-three &&
1218 git cat-file -p :3:three >expect &&
1219 test_cmp expect R-three &&
1220
1221 # Compare three to expected contents
1222 >empty &&
1223 test_must_fail git merge-file \
1224 -L "HEAD" -L "" -L "R^0" \
1225 L-three empty R-three &&
1226 test_cmp three L-three
1227 )
1228'
1229
695576fd 1230test_done