52
test_merge P O --no-ff &&
53
git switch main &&
54
55
+ git switch --orphan unrelated &&
56
+ test_commit unrelated-root &&
57
+
58
git switch -c conflict B &&
56
- test_commit C.conflict C.t conflict
59
+ test_commit C.conflict C.t conflict &&
60
+ git branch -D unrelated &&
61
+
62
+ git switch -c divergent-x main &&
63
+ test_commit X &&
64
+ git switch -c divergent-y main &&
65
+ test_commit Y &&
66
+ git switch divergent-x &&
67
+ test_merge Z divergent-y --no-ff
68
'
69
70
test_expect_success 'setup bare' '
576
test_grep "cannot be used with multiple revision ranges" err
577
'
578
579
+test_expect_success 'replay to rebase merge commit with --linearize' '
580
+ git replay --ref-action=print --linearize \
581
+ --onto main I..topic-with-merge >result &&
582
+
583
+ test_line_count = 1 result &&
584
+
585
+ git log --format=%s $(cut -f 3 -d " " result) >actual &&
586
+ test_write_lines O N J M L B A >expect &&
587
+ test_cmp expect actual
588
+'
589
+
590
+test_expect_success 'replay to rebase merge commit with --linearize down to the root commit' '
591
+ git replay --ref-action=print --linearize \
592
+ --onto unrelated-root topic-with-merge >result &&
593
+
594
+ test_line_count = 1 result &&
595
+
596
+ git log --format=%s $(cut -f 3 -d " " result) >actual &&
597
+ test_write_lines O N J I B A unrelated-root >expect &&
598
+ test_cmp expect actual
599
+'
600
+
601
+test_expect_success 'replay to cherry-pick merge commit with --linearize' '
602
+ git replay --ref-action=print --linearize \
603
+ --advance main I..topic-with-merge >result &&
604
+
605
+ test_line_count = 1 result &&
606
+
607
+ git log --format=%s $(cut -f 3 -d " " result) >actual &&
608
+ test_write_lines O N J M L B A >expect &&
609
+ test_cmp expect actual &&
610
+
611
+ printf "update refs/heads/main " >expect &&
612
+ printf "%s " $(cut -f 3 -d " " result) >>expect &&
613
+ git rev-parse main >>expect &&
614
+ test_cmp expect result
615
+'
616
+
617
+test_expect_success 'replay --linearize produces the same patches' '
618
+ git replay --ref-action=print --linearize \
619
+ --onto main I..topic-with-merge >result &&
620
+
621
+ test_line_count = 1 result &&
622
+ tip=$(cut -f 3 -d " " result) &&
623
+
624
+ # range-diff does not care about the dropped merge,
625
+ # so the original commits (I..topic-with-merge)
626
+ # and the replayed chain (main..tip) must produce identical patches.
627
+ git range-diff I..topic-with-merge main..$tip >out &&
628
+ test_file_not_empty out &&
629
+ test_grep ! -v "=" out &&
630
+
631
+ git log --oneline main..$tip >out &&
632
+ test_line_count = 3 out
633
+'
634
+
635
+test_expect_success 'replay with --linearize rebase multiple divergent branches into a single line' '
636
+ git replay --ref-action=print --linearize \
637
+ --onto main ^B topic2 topic3 topic4 >result &&
638
+
639
+ test_line_count = 3 result &&
640
+ cut -f 3 -d " " result >new-branch-tips &&
641
+
642
+ >expect &&
643
+ for i in 2 3 4
644
+ do
645
+ printf "update refs/heads/topic$i " >>expect &&
646
+ printf "%s " $(grep topic$i result | cut -f 3 -d " ") >>expect &&
647
+ git rev-parse topic$i >>expect || return 1
648
+ done &&
649
+
650
+ test_cmp expect result &&
651
+
652
+ test_write_lines E D C M L B A >expect2 &&
653
+ test_write_lines H G F E D C M L B A >expect3 &&
654
+ test_write_lines J I H G F E D C M L B A >expect4 &&
655
+
656
+ for i in 2 3 4
657
+ do
658
+ git log --format=%s $(grep topic$i result | cut -f 3 -d " ") >actual &&
659
+ test_cmp expect$i actual || return 1
660
+ done
661
+'
662
+
663
+test_expect_success 'replay with --linearize of a divergent merge keeps both sides' '
664
+ git replay --ref-action=print --linearize \
665
+ --onto main main..divergent-x >result &&
666
+ test_line_count = 1 result &&
667
+ tip=$(cut -f 3 -d " " result) &&
668
+
669
+ # The merge Z is dropped, but both X and Y are linearized onto main;
670
+ # neither side is lost.
671
+ git log --format=%s main..$tip >actual &&
672
+ test_write_lines Y X >expect &&
673
+ test_cmp expect actual
674
+'
675
+
676
+test_expect_success '--linearize with --contained updates contained refs' '
677
+ git replay --ref-action=print --linearize --contained \
678
+ --onto main ^B topic-with-merge >result &&
679
+
680
+ test_line_count = 2 result &&
681
+
682
+ git log --format=%s $(head -n 1 result | cut -f 3 -d " ") >actual &&
683
+ test_write_lines J I M L B A >expect &&
684
+ test_cmp expect actual &&
685
+
686
+ git log --format=%s $(tail -n 1 result | cut -f 3 -d " ") >actual &&
687
+ test_write_lines O N J I M L B A >expect &&
688
+ test_cmp expect actual
689
+'
690
+
691
+test_expect_success 'replay --revert with --linearize reverts a range containing a merge' '
692
+ git replay --ref-action=print --revert=divergent-x --linearize \
693
+ main..divergent-x >result &&
694
+ test_line_count = 1 result &&
695
+ tip=$(cut -f 3 -d " " result) &&
696
+
697
+ git log --format=%s $tip >actual &&
698
+ test_write_lines \
699
+ "Revert \"X\"" "Revert \"Y\"" Z Y X M L B A >expect &&
700
+ test_cmp expect actual &&
701
+
702
+ test_must_fail git cat-file -e $tip:X.t &&
703
+ test_must_fail git cat-file -e $tip:Y.t
704
+'
705
+
706
test_done