]> git.ipfire.org Git - thirdparty/git.git/blob - t/t4301-merge-tree-write-tree.sh
Merge branch 'jk/clone-allow-bare-and-o-together'
[thirdparty/git.git] / t / t4301-merge-tree-write-tree.sh
1 #!/bin/sh
2
3 test_description='git merge-tree --write-tree'
4
5 . ./test-lib.sh
6
7 # This test is ort-specific
8 if test "$GIT_TEST_MERGE_ALGORITHM" != "ort"
9 then
10 skip_all="GIT_TEST_MERGE_ALGORITHM != ort"
11 test_done
12 fi
13
14 test_expect_success setup '
15 test_write_lines 1 2 3 4 5 >numbers &&
16 echo hello >greeting &&
17 echo foo >whatever &&
18 git add numbers greeting whatever &&
19 test_tick &&
20 git commit -m initial &&
21
22 git branch side1 &&
23 git branch side2 &&
24 git branch side3 &&
25
26 git checkout side1 &&
27 test_write_lines 1 2 3 4 5 6 >numbers &&
28 echo hi >greeting &&
29 echo bar >whatever &&
30 git add numbers greeting whatever &&
31 test_tick &&
32 git commit -m modify-stuff &&
33
34 git checkout side2 &&
35 test_write_lines 0 1 2 3 4 5 >numbers &&
36 echo yo >greeting &&
37 git rm whatever &&
38 mkdir whatever &&
39 >whatever/empty &&
40 git add numbers greeting whatever/empty &&
41 test_tick &&
42 git commit -m other-modifications &&
43
44 git checkout side3 &&
45 git mv numbers sequence &&
46 test_tick &&
47 git commit -m rename-numbers &&
48
49 git switch --orphan unrelated &&
50 >something-else &&
51 git add something-else &&
52 test_tick &&
53 git commit -m first-commit
54 '
55
56 test_expect_success 'Clean merge' '
57 TREE_OID=$(git merge-tree --write-tree side1 side3) &&
58 q_to_tab <<-EOF >expect &&
59 100644 blob $(git rev-parse side1:greeting)Qgreeting
60 100644 blob $(git rev-parse side1:numbers)Qsequence
61 100644 blob $(git rev-parse side1:whatever)Qwhatever
62 EOF
63
64 git ls-tree $TREE_OID >actual &&
65 test_cmp expect actual
66 '
67
68 test_expect_success 'Content merge and a few conflicts' '
69 git checkout side1^0 &&
70 test_must_fail git merge side2 &&
71 expected_tree=$(git rev-parse AUTO_MERGE) &&
72
73 # We will redo the merge, while we are still in a conflicted state!
74 git ls-files -u >conflicted-file-info &&
75 test_when_finished "git reset --hard" &&
76
77 test_expect_code 1 git merge-tree --write-tree side1 side2 >RESULT &&
78 actual_tree=$(head -n 1 RESULT) &&
79
80 # Due to differences of e.g. "HEAD" vs "side1", the results will not
81 # exactly match. Dig into individual files.
82
83 # Numbers should have three-way merged cleanly
84 test_write_lines 0 1 2 3 4 5 6 >expect &&
85 git show ${actual_tree}:numbers >actual &&
86 test_cmp expect actual &&
87
88 # whatever and whatever~<branch> should have same HASHES
89 git rev-parse ${expected_tree}:whatever ${expected_tree}:whatever~HEAD >expect &&
90 git rev-parse ${actual_tree}:whatever ${actual_tree}:whatever~side1 >actual &&
91 test_cmp expect actual &&
92
93 # greeting should have a merge conflict
94 git show ${expected_tree}:greeting >tmp &&
95 sed -e s/HEAD/side1/ tmp >expect &&
96 git show ${actual_tree}:greeting >actual &&
97 test_cmp expect actual
98 '
99
100 test_expect_success 'Barf on misspelled option, with exit code other than 0 or 1' '
101 # Mis-spell with single "s" instead of double "s"
102 test_expect_code 129 git merge-tree --write-tree --mesages FOOBAR side1 side2 2>expect &&
103
104 grep "error: unknown option.*mesages" expect
105 '
106
107 test_expect_success 'Barf on too many arguments' '
108 test_expect_code 129 git merge-tree --write-tree side1 side2 invalid 2>expect &&
109
110 grep "^usage: git merge-tree" expect
111 '
112
113 anonymize_hash() {
114 sed -e "s/[0-9a-f]\{40,\}/HASH/g" "$@"
115 }
116
117 test_expect_success 'test conflict notices and such' '
118 test_expect_code 1 git merge-tree --write-tree --name-only side1 side2 >out &&
119 anonymize_hash out >actual &&
120
121 # Expected results:
122 # "greeting" should merge with conflicts
123 # "numbers" should merge cleanly
124 # "whatever" has *both* a modify/delete and a file/directory conflict
125 cat <<-EOF >expect &&
126 HASH
127 greeting
128 whatever~side1
129
130 Auto-merging greeting
131 CONFLICT (content): Merge conflict in greeting
132 Auto-merging numbers
133 CONFLICT (file/directory): directory in the way of whatever from side1; moving it to whatever~side1 instead.
134 CONFLICT (modify/delete): whatever~side1 deleted in side2 and modified in side1. Version side1 of whatever~side1 left in tree.
135 EOF
136
137 test_cmp expect actual
138 '
139
140 # directory rename + content conflict
141 # Commit O: foo, olddir/{a,b,c}
142 # Commit A: modify foo, newdir/{a,b,c}
143 # Commit B: modify foo differently & rename foo -> olddir/bar
144 # Expected: CONFLICT(content) for for newdir/bar (not olddir/bar or foo)
145
146 test_expect_success 'directory rename + content conflict' '
147 # Setup
148 git init dir-rename-and-content &&
149 (
150 cd dir-rename-and-content &&
151 test_write_lines 1 2 3 4 5 >foo &&
152 mkdir olddir &&
153 for i in a b c; do echo $i >olddir/$i || exit 1; done &&
154 git add foo olddir &&
155 git commit -m "original" &&
156
157 git branch O &&
158 git branch A &&
159 git branch B &&
160
161 git checkout A &&
162 test_write_lines 1 2 3 4 5 6 >foo &&
163 git add foo &&
164 git mv olddir newdir &&
165 git commit -m "Modify foo, rename olddir to newdir" &&
166
167 git checkout B &&
168 test_write_lines 1 2 3 4 5 six >foo &&
169 git add foo &&
170 git mv foo olddir/bar &&
171 git commit -m "Modify foo & rename foo -> olddir/bar"
172 ) &&
173 # Testing
174 (
175 cd dir-rename-and-content &&
176
177 test_expect_code 1 \
178 git merge-tree -z A^0 B^0 >out &&
179 echo >>out &&
180 anonymize_hash out >actual &&
181 q_to_tab <<-\EOF | lf_to_nul >expect &&
182 HASH
183 100644 HASH 1Qnewdir/bar
184 100644 HASH 2Qnewdir/bar
185 100644 HASH 3Qnewdir/bar
186 EOF
187
188 q_to_nul <<-EOF >>expect &&
189 Q2Qnewdir/barQolddir/barQCONFLICT (directory rename suggested)QCONFLICT (file location): foo renamed to olddir/bar in B^0, inside a directory that was renamed in A^0, suggesting it should perhaps be moved to newdir/bar.
190 Q1Qnewdir/barQAuto-mergingQAuto-merging newdir/bar
191 Q1Qnewdir/barQCONFLICT (contents)QCONFLICT (content): Merge conflict in newdir/bar
192 Q
193 EOF
194 test_cmp expect actual
195 )
196 '
197
198 # rename/delete + modify/delete handling
199 # Commit O: foo
200 # Commit A: modify foo + rename to bar
201 # Commit B: delete foo
202 # Expected: CONFLICT(rename/delete) + CONFLICT(modify/delete)
203
204 test_expect_success 'rename/delete handling' '
205 # Setup
206 git init rename-delete &&
207 (
208 cd rename-delete &&
209 test_write_lines 1 2 3 4 5 >foo &&
210 git add foo &&
211 git commit -m "original" &&
212
213 git branch O &&
214 git branch A &&
215 git branch B &&
216
217 git checkout A &&
218 test_write_lines 1 2 3 4 5 6 >foo &&
219 git add foo &&
220 git mv foo bar &&
221 git commit -m "Modify foo, rename to bar" &&
222
223 git checkout B &&
224 git rm foo &&
225 git commit -m "remove foo"
226 ) &&
227 # Testing
228 (
229 cd rename-delete &&
230
231 test_expect_code 1 \
232 git merge-tree -z A^0 B^0 >out &&
233 echo >>out &&
234 anonymize_hash out >actual &&
235 q_to_tab <<-\EOF | lf_to_nul >expect &&
236 HASH
237 100644 HASH 1Qbar
238 100644 HASH 2Qbar
239 EOF
240
241 q_to_nul <<-EOF >>expect &&
242 Q2QbarQfooQCONFLICT (rename/delete)QCONFLICT (rename/delete): foo renamed to bar in A^0, but deleted in B^0.
243 Q1QbarQCONFLICT (modify/delete)QCONFLICT (modify/delete): bar deleted in B^0 and modified in A^0. Version A^0 of bar left in tree.
244 Q
245 EOF
246 test_cmp expect actual
247 )
248 '
249
250 # rename/add handling
251 # Commit O: foo
252 # Commit A: modify foo, add different bar
253 # Commit B: modify & rename foo->bar
254 # Expected: CONFLICT(add/add) [via rename collide] for bar
255
256 test_expect_success 'rename/add handling' '
257 # Setup
258 git init rename-add &&
259 (
260 cd rename-add &&
261 test_write_lines original 1 2 3 4 5 >foo &&
262 git add foo &&
263 git commit -m "original" &&
264
265 git branch O &&
266 git branch A &&
267 git branch B &&
268
269 git checkout A &&
270 test_write_lines 1 2 3 4 5 >foo &&
271 echo "different file" >bar &&
272 git add foo bar &&
273 git commit -m "Modify foo, add bar" &&
274
275 git checkout B &&
276 test_write_lines original 1 2 3 4 5 6 >foo &&
277 git add foo &&
278 git mv foo bar &&
279 git commit -m "rename foo to bar"
280 ) &&
281 # Testing
282 (
283 cd rename-add &&
284
285 test_expect_code 1 \
286 git merge-tree -z A^0 B^0 >out &&
287 echo >>out &&
288
289 #
290 # First, check that the bar that appears at stage 3 does not
291 # correspond to an individual blob anywhere in history
292 #
293 hash=$(cat out | tr "\0" "\n" | head -n 3 | grep 3.bar | cut -f 2 -d " ") &&
294 git rev-list --objects --all >all_blobs &&
295 ! grep $hash all_blobs &&
296
297 #
298 # Second, check anonymized hash output against expectation
299 #
300 anonymize_hash out >actual &&
301 q_to_tab <<-\EOF | lf_to_nul >expect &&
302 HASH
303 100644 HASH 2Qbar
304 100644 HASH 3Qbar
305 EOF
306
307 q_to_nul <<-EOF >>expect &&
308 Q1QbarQAuto-mergingQAuto-merging bar
309 Q1QbarQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in bar
310 Q1QfooQAuto-mergingQAuto-merging foo
311 Q
312 EOF
313 test_cmp expect actual
314 )
315 '
316
317 # rename/add, where add is a mode conflict
318 # Commit O: foo
319 # Commit A: modify foo, add symlink bar
320 # Commit B: modify & rename foo->bar
321 # Expected: CONFLICT(distinct modes) for bar
322
323 test_expect_success SYMLINKS 'rename/add, where add is a mode conflict' '
324 # Setup
325 git init rename-add-symlink &&
326 (
327 cd rename-add-symlink &&
328 test_write_lines original 1 2 3 4 5 >foo &&
329 git add foo &&
330 git commit -m "original" &&
331
332 git branch O &&
333 git branch A &&
334 git branch B &&
335
336 git checkout A &&
337 test_write_lines 1 2 3 4 5 >foo &&
338 ln -s foo bar &&
339 git add foo bar &&
340 git commit -m "Modify foo, add symlink bar" &&
341
342 git checkout B &&
343 test_write_lines original 1 2 3 4 5 6 >foo &&
344 git add foo &&
345 git mv foo bar &&
346 git commit -m "rename foo to bar"
347 ) &&
348 # Testing
349 (
350 cd rename-add-symlink &&
351
352 test_expect_code 1 \
353 git merge-tree -z A^0 B^0 >out &&
354 echo >>out &&
355
356 #
357 # First, check that the bar that appears at stage 3 does not
358 # correspond to an individual blob anywhere in history
359 #
360 hash=$(cat out | tr "\0" "\n" | head -n 3 | grep 3.bar | cut -f 2 -d " ") &&
361 git rev-list --objects --all >all_blobs &&
362 ! grep $hash all_blobs &&
363
364 #
365 # Second, check anonymized hash output against expectation
366 #
367 anonymize_hash out >actual &&
368 q_to_tab <<-\EOF | lf_to_nul >expect &&
369 HASH
370 120000 HASH 2Qbar
371 100644 HASH 3Qbar~B^0
372 EOF
373
374 q_to_nul <<-EOF >>expect &&
375 Q2QbarQbar~B^0QCONFLICT (distinct modes)QCONFLICT (distinct types): bar had different types on each side; renamed one of them so each can be recorded somewhere.
376 Q1QfooQAuto-mergingQAuto-merging foo
377 Q
378 EOF
379 test_cmp expect actual
380 )
381 '
382
383 # rename/rename(1to2) + content conflict handling
384 # Commit O: foo
385 # Commit A: modify foo & rename to bar
386 # Commit B: modify foo & rename to baz
387 # Expected: CONFLICT(rename/rename)
388
389 test_expect_success 'rename/rename + content conflict' '
390 # Setup
391 git init rr-plus-content &&
392 (
393 cd rr-plus-content &&
394 test_write_lines 1 2 3 4 5 >foo &&
395 git add foo &&
396 git commit -m "original" &&
397
398 git branch O &&
399 git branch A &&
400 git branch B &&
401
402 git checkout A &&
403 test_write_lines 1 2 3 4 5 six >foo &&
404 git add foo &&
405 git mv foo bar &&
406 git commit -m "Modify foo + rename to bar" &&
407
408 git checkout B &&
409 test_write_lines 1 2 3 4 5 6 >foo &&
410 git add foo &&
411 git mv foo baz &&
412 git commit -m "Modify foo + rename to baz"
413 ) &&
414 # Testing
415 (
416 cd rr-plus-content &&
417
418 test_expect_code 1 \
419 git merge-tree -z A^0 B^0 >out &&
420 echo >>out &&
421 anonymize_hash out >actual &&
422 q_to_tab <<-\EOF | lf_to_nul >expect &&
423 HASH
424 100644 HASH 2Qbar
425 100644 HASH 3Qbaz
426 100644 HASH 1Qfoo
427 EOF
428
429 q_to_nul <<-EOF >>expect &&
430 Q1QfooQAuto-mergingQAuto-merging foo
431 Q3QfooQbarQbazQCONFLICT (rename/rename)QCONFLICT (rename/rename): foo renamed to bar in A^0 and to baz in B^0.
432 Q
433 EOF
434 test_cmp expect actual
435 )
436 '
437
438 # rename/add/delete
439 # Commit O: foo
440 # Commit A: rm foo, add different bar
441 # Commit B: rename foo->bar
442 # Expected: CONFLICT (rename/delete), CONFLICT(add/add) [via rename collide]
443 # for bar
444
445 test_expect_success 'rename/add/delete conflict' '
446 # Setup
447 git init rad &&
448 (
449 cd rad &&
450 echo "original file" >foo &&
451 git add foo &&
452 git commit -m "original" &&
453
454 git branch O &&
455 git branch A &&
456 git branch B &&
457
458 git checkout A &&
459 git rm foo &&
460 echo "different file" >bar &&
461 git add bar &&
462 git commit -m "Remove foo, add bar" &&
463
464 git checkout B &&
465 git mv foo bar &&
466 git commit -m "rename foo to bar"
467 ) &&
468 # Testing
469 (
470 cd rad &&
471
472 test_expect_code 1 \
473 git merge-tree -z B^0 A^0 >out &&
474 echo >>out &&
475 anonymize_hash out >actual &&
476
477 q_to_tab <<-\EOF | lf_to_nul >expect &&
478 HASH
479 100644 HASH 2Qbar
480 100644 HASH 3Qbar
481
482 EOF
483
484 q_to_nul <<-EOF >>expect &&
485 2QbarQfooQCONFLICT (rename/delete)QCONFLICT (rename/delete): foo renamed to bar in B^0, but deleted in A^0.
486 Q1QbarQAuto-mergingQAuto-merging bar
487 Q1QbarQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in bar
488 Q
489 EOF
490 test_cmp expect actual
491 )
492 '
493
494 # rename/rename(2to1)/delete/delete
495 # Commit O: foo, bar
496 # Commit A: rename foo->baz, rm bar
497 # Commit B: rename bar->baz, rm foo
498 # Expected: 2x CONFLICT (rename/delete), CONFLICT (add/add) via colliding
499 # renames for baz
500
501 test_expect_success 'rename/rename(2to1)/delete/delete conflict' '
502 # Setup
503 git init rrdd &&
504 (
505 cd rrdd &&
506 echo foo >foo &&
507 echo bar >bar &&
508 git add foo bar &&
509 git commit -m O &&
510
511 git branch O &&
512 git branch A &&
513 git branch B &&
514
515 git checkout A &&
516 git mv foo baz &&
517 git rm bar &&
518 git commit -m "Rename foo, remove bar" &&
519
520 git checkout B &&
521 git mv bar baz &&
522 git rm foo &&
523 git commit -m "Rename bar, remove foo"
524 ) &&
525 # Testing
526 (
527 cd rrdd &&
528
529 test_expect_code 1 \
530 git merge-tree -z A^0 B^0 >out &&
531 echo >>out &&
532 anonymize_hash out >actual &&
533
534 q_to_tab <<-\EOF | lf_to_nul >expect &&
535 HASH
536 100644 HASH 2Qbaz
537 100644 HASH 3Qbaz
538
539 EOF
540
541 q_to_nul <<-EOF >>expect &&
542 2QbazQbarQCONFLICT (rename/delete)QCONFLICT (rename/delete): bar renamed to baz in B^0, but deleted in A^0.
543 Q2QbazQfooQCONFLICT (rename/delete)QCONFLICT (rename/delete): foo renamed to baz in A^0, but deleted in B^0.
544 Q1QbazQAuto-mergingQAuto-merging baz
545 Q1QbazQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in baz
546 Q
547 EOF
548 test_cmp expect actual
549 )
550 '
551
552 # mod6: chains of rename/rename(1to2) + add/add via colliding renames
553 # Commit O: one, three, five
554 # Commit A: one->two, three->four, five->six
555 # Commit B: one->six, three->two, five->four
556 # Expected: three CONFLICT(rename/rename) messages + three CONFLICT(add/add)
557 # messages; each path in two of the multi-way merged contents
558 # found in two, four, six
559
560 test_expect_success 'mod6: chains of rename/rename(1to2) and add/add via colliding renames' '
561 # Setup
562 git init mod6 &&
563 (
564 cd mod6 &&
565 test_seq 11 19 >one &&
566 test_seq 31 39 >three &&
567 test_seq 51 59 >five &&
568 git add . &&
569 test_tick &&
570 git commit -m "O" &&
571
572 git branch O &&
573 git branch A &&
574 git branch B &&
575
576 git checkout A &&
577 test_seq 10 19 >one &&
578 echo 40 >>three &&
579 git add one three &&
580 git mv one two &&
581 git mv three four &&
582 git mv five six &&
583 test_tick &&
584 git commit -m "A" &&
585
586 git checkout B &&
587 echo 20 >>one &&
588 echo forty >>three &&
589 echo 60 >>five &&
590 git add one three five &&
591 git mv one six &&
592 git mv three two &&
593 git mv five four &&
594 test_tick &&
595 git commit -m "B"
596 ) &&
597 # Testing
598 (
599 cd mod6 &&
600
601 test_expect_code 1 \
602 git merge-tree -z A^0 B^0 >out &&
603 echo >>out &&
604
605 #
606 # First, check that some of the hashes that appear as stage
607 # conflict entries do not appear as individual blobs anywhere
608 # in history.
609 #
610 hash1=$(cat out | tr "\0" "\n" | head | grep 2.four | cut -f 2 -d " ") &&
611 hash2=$(cat out | tr "\0" "\n" | head | grep 3.two | cut -f 2 -d " ") &&
612 git rev-list --objects --all >all_blobs &&
613 ! grep $hash1 all_blobs &&
614 ! grep $hash2 all_blobs &&
615
616 #
617 # Now compare anonymized hash output with expectation
618 #
619 anonymize_hash out >actual &&
620 q_to_tab <<-\EOF | lf_to_nul >expect &&
621 HASH
622 100644 HASH 1Qfive
623 100644 HASH 2Qfour
624 100644 HASH 3Qfour
625 100644 HASH 1Qone
626 100644 HASH 2Qsix
627 100644 HASH 3Qsix
628 100644 HASH 1Qthree
629 100644 HASH 2Qtwo
630 100644 HASH 3Qtwo
631
632 EOF
633
634 q_to_nul <<-EOF >>expect &&
635 3QfiveQsixQfourQCONFLICT (rename/rename)QCONFLICT (rename/rename): five renamed to six in A^0 and to four in B^0.
636 Q1QfourQAuto-mergingQAuto-merging four
637 Q1QfourQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in four
638 Q1QoneQAuto-mergingQAuto-merging one
639 Q3QoneQtwoQsixQCONFLICT (rename/rename)QCONFLICT (rename/rename): one renamed to two in A^0 and to six in B^0.
640 Q1QsixQAuto-mergingQAuto-merging six
641 Q1QsixQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in six
642 Q1QthreeQAuto-mergingQAuto-merging three
643 Q3QthreeQfourQtwoQCONFLICT (rename/rename)QCONFLICT (rename/rename): three renamed to four in A^0 and to two in B^0.
644 Q1QtwoQAuto-mergingQAuto-merging two
645 Q1QtwoQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in two
646 Q
647 EOF
648 test_cmp expect actual
649 )
650 '
651
652 # directory rename + rename/delete + modify/delete + directory/file conflict
653 # Commit O: foo, olddir/{a,b,c}
654 # Commit A: delete foo, rename olddir/ -> newdir/, add newdir/bar/file
655 # Commit B: modify foo & rename foo -> olddir/bar
656 # Expected: CONFLICT(content) for for newdir/bar (not olddir/bar or foo)
657
658 test_expect_success 'directory rename + rename/delete + modify/delete + directory/file conflict' '
659 # Setup
660 git init 4-stacked-conflict &&
661 (
662 cd 4-stacked-conflict &&
663 test_write_lines 1 2 3 4 5 >foo &&
664 mkdir olddir &&
665 for i in a b c; do echo $i >olddir/$i || exit 1; done &&
666 git add foo olddir &&
667 git commit -m "original" &&
668
669 git branch O &&
670 git branch A &&
671 git branch B &&
672
673 git checkout A &&
674 git rm foo &&
675 git mv olddir newdir &&
676 mkdir newdir/bar &&
677 >newdir/bar/file &&
678 git add newdir/bar/file &&
679 git commit -m "rm foo, olddir/ -> newdir/, + newdir/bar/file" &&
680
681 git checkout B &&
682 test_write_lines 1 2 3 4 5 6 >foo &&
683 git add foo &&
684 git mv foo olddir/bar &&
685 git commit -m "Modify foo & rename foo -> olddir/bar"
686 ) &&
687 # Testing
688 (
689 cd 4-stacked-conflict &&
690
691 test_expect_code 1 \
692 git merge-tree -z A^0 B^0 >out &&
693 echo >>out &&
694 anonymize_hash out >actual &&
695
696 q_to_tab <<-\EOF | lf_to_nul >expect &&
697 HASH
698 100644 HASH 1Qnewdir/bar~B^0
699 100644 HASH 3Qnewdir/bar~B^0
700 EOF
701
702 q_to_nul <<-EOF >>expect &&
703 Q2Qnewdir/barQolddir/barQCONFLICT (directory rename suggested)QCONFLICT (file location): foo renamed to olddir/bar in B^0, inside a directory that was renamed in A^0, suggesting it should perhaps be moved to newdir/bar.
704 Q2Qnewdir/barQfooQCONFLICT (rename/delete)QCONFLICT (rename/delete): foo renamed to newdir/bar in B^0, but deleted in A^0.
705 Q2Qnewdir/bar~B^0Qnewdir/barQCONFLICT (file/directory)QCONFLICT (file/directory): directory in the way of newdir/bar from B^0; moving it to newdir/bar~B^0 instead.
706 Q1Qnewdir/bar~B^0QCONFLICT (modify/delete)QCONFLICT (modify/delete): newdir/bar~B^0 deleted in A^0 and modified in B^0. Version B^0 of newdir/bar~B^0 left in tree.
707 Q
708 EOF
709 test_cmp expect actual
710 )
711 '
712
713 for opt in $(git merge-tree --git-completion-helper-all)
714 do
715 if test $opt = "--trivial-merge" || test $opt = "--write-tree"
716 then
717 continue
718 fi
719
720 test_expect_success "usage: --trivial-merge is incompatible with $opt" '
721 test_expect_code 128 git merge-tree --trivial-merge $opt side1 side2 side3
722 '
723 done
724
725 test_expect_success 'Just the conflicted files without the messages' '
726 test_expect_code 1 git merge-tree --write-tree --no-messages --name-only side1 side2 >out &&
727 anonymize_hash out >actual &&
728
729 test_write_lines HASH greeting whatever~side1 >expect &&
730
731 test_cmp expect actual
732 '
733
734 test_expect_success 'Check conflicted oids and modes without messages' '
735 test_expect_code 1 git merge-tree --write-tree --no-messages side1 side2 >out &&
736 anonymize_hash out >actual &&
737
738 # Compare the basic output format
739 q_to_tab >expect <<-\EOF &&
740 HASH
741 100644 HASH 1Qgreeting
742 100644 HASH 2Qgreeting
743 100644 HASH 3Qgreeting
744 100644 HASH 1Qwhatever~side1
745 100644 HASH 2Qwhatever~side1
746 EOF
747
748 test_cmp expect actual &&
749
750 # Check the actual hashes against the `ls-files -u` output too
751 tail -n +2 out | sed -e s/side1/HEAD/ >actual &&
752 test_cmp conflicted-file-info actual
753 '
754
755 test_expect_success 'NUL terminated conflicted file "lines"' '
756 git checkout -b tweak1 side1 &&
757 test_write_lines zero 1 2 3 4 5 6 >numbers &&
758 git add numbers &&
759 git mv numbers "Αυτά μου φαίνονται κινέζικα" &&
760 git commit -m "Renamed numbers" &&
761
762 test_expect_code 1 git merge-tree --write-tree -z tweak1 side2 >out &&
763 echo >>out &&
764 anonymize_hash out >actual &&
765
766 # Expected results:
767 # "greeting" should merge with conflicts
768 # "whatever" has *both* a modify/delete and a file/directory conflict
769 # "Αυτά μου φαίνονται κινέζικα" should have a conflict
770 echo HASH | lf_to_nul >expect &&
771
772 q_to_tab <<-EOF | lf_to_nul >>expect &&
773 100644 HASH 1Qgreeting
774 100644 HASH 2Qgreeting
775 100644 HASH 3Qgreeting
776 100644 HASH 1Qwhatever~tweak1
777 100644 HASH 2Qwhatever~tweak1
778 100644 HASH 1QΑυτά μου φαίνονται κινέζικα
779 100644 HASH 2QΑυτά μου φαίνονται κινέζικα
780 100644 HASH 3QΑυτά μου φαίνονται κινέζικα
781
782 EOF
783
784 q_to_nul <<-EOF >>expect &&
785 1QgreetingQAuto-mergingQAuto-merging greeting
786 Q1QgreetingQCONFLICT (contents)QCONFLICT (content): Merge conflict in greeting
787 Q2Qwhatever~tweak1QwhateverQCONFLICT (file/directory)QCONFLICT (file/directory): directory in the way of whatever from tweak1; moving it to whatever~tweak1 instead.
788 Q1Qwhatever~tweak1QCONFLICT (modify/delete)QCONFLICT (modify/delete): whatever~tweak1 deleted in side2 and modified in tweak1. Version tweak1 of whatever~tweak1 left in tree.
789 Q1QΑυτά μου φαίνονται κινέζικαQAuto-mergingQAuto-merging Αυτά μου φαίνονται κινέζικα
790 Q1QΑυτά μου φαίνονται κινέζικαQCONFLICT (contents)QCONFLICT (content): Merge conflict in Αυτά μου φαίνονται κινέζικα
791 Q
792 EOF
793
794 test_cmp expect actual
795 '
796
797 test_expect_success 'error out by default for unrelated histories' '
798 test_expect_code 128 git merge-tree --write-tree side1 unrelated 2>error &&
799
800 grep "refusing to merge unrelated histories" error
801 '
802
803 test_expect_success 'can override merge of unrelated histories' '
804 git merge-tree --write-tree --allow-unrelated-histories side1 unrelated >tree &&
805 TREE=$(cat tree) &&
806
807 git rev-parse side1:numbers side1:greeting side1:whatever unrelated:something-else >expect &&
808 git rev-parse $TREE:numbers $TREE:greeting $TREE:whatever $TREE:something-else >actual &&
809
810 test_cmp expect actual
811 '
812
813 test_done