contrib/subtree: capture additional test-cases

Patch series e7b07376e5 (Merge branch 'rs/subtree-fixes', 2018-10-26) corrects several defects in `git subtree split`. The defects affect `split --rejoin` and merge commit processing. There is no test coverage for this, and e7b07376e5 did not introduce any. Convert the minimum working example [1] from the original patch submission [2] into test cases. [1]: https://gist.github.com/FoxFireX/1b794384612b7fd5e7cd157cff96269e [2]: <20180928183540.48968-1-roger.strain@swri.org> Signed-off-by: Colin Stagner <ask+git@howdoi.land> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Colin Stagner committed Feb 17, 2026 at 20:31 UTC 767ee993b7ea3175691444af67550817de7f6c73
1 file changed +110
contrib/subtree/t/t7900-subtree.sh
+110
@@ -1575,6 +1575,116 @@ test_expect_success 'push split to subproj' '
1575 )
1576 '
1577
1578 +# --ignore-joins must ignore mainline content outside of the
1579 +# subtree. This test verifies that the logic in
1580 +# `find_existing_splits()` correctly handles a `git subtree add`
1581 +# In this test, the split history must not contain a commit titled
1582 +#
1583 +# Add 'sub/' from commit ...
1584 +#
1585 +# see: dd21d43b58 (subtree: make --ignore-joins pay
1586 +# attention to adds, 2018-09-28)
1587 +test_expect_success 'split --ignore-joins respects subtree add' '
1588 + subtree_test_create_repo "$test_count" &&
1589 + (
1590 + cd "$test_count" &&
1591 + test_commit main_must_not_be_in_subtree &&
1592 + test_create_subtree_add . mksubtree sub sub1 &&
1593 + test_commit sub/sub2 &&
1594 + test_commit main_must_not_be_in_subtree2 &&
1595 + git subtree split --prefix sub -b first_split --rejoin &&
1596 + test_commit sub/sub3 &&
1597 + no_ignore_joins="$(git subtree split --prefix sub -b no_ignore_joins)" &&
1598 + ignore_joins="$(git subtree split --prefix sub --ignore-joins -b ignore_joins)" &&
1599 + git checkout ignore_joins &&
1600 + test_path_is_file sub1.t &&
1601 + test_path_is_file sub2.t &&
1602 + test_path_is_file sub3.t &&
1603 + ! test_path_is_file main_must_not_be_in_subtree.t &&
1604 + ! test_path_is_file main_must_not_be_in_subtree2.t &&
1605 + test -z "$(git log -1 --grep "Add '''sub/''' from commit" ignore_joins)" &&
1606 + test "$no_ignore_joins" = "$ignore_joins" &&
1607 + test "$(git rev-list --count ignore_joins)" -eq 3;
1608 + )
1609 +'
1610 +
1611 +# split excludes commits reachable from any previous --rejoin.
1612 +# These ignored commits can still be the basis for new work
1613 +# after the --rejoin. These commits must be processed, even
1614 +# if they are excluded. Otherwise, the split history will be
1615 +# incorrect.
1616 +#
1617 +# here, the merge
1618 +#
1619 +# git merge --no-ff new_work_based_on_prejoin
1620 +#
1621 +# doesn't contain any subtree changes and so should not end
1622 +# up in the split history. this subtree should be flat,
1623 +# with no merges.
1624 +#
1625 +# see: 315a84f9aa (subtree: use commits before rejoins for
1626 +# splits, 2018-09-28)
1627 +test_expect_success 'split links out-of-tree pre --rejoin commits with post --rejoin commits' '
1628 + subtree_test_create_repo "$test_count" &&
1629 + (
1630 + cd "$test_count" &&
1631 + test_commit main_must_not_be_in_subtree &&
1632 + mkdir sub &&
1633 + test_commit sub/sub1 &&
1634 + test_commit sub/sub2 &&
1635 + git subtree split --prefix sub --rejoin &&
1636 + test "$(git rev-list --count HEAD)" -eq 6 &&
1637 + git checkout sub/sub1 &&
1638 + git checkout -b new_work_based_on_prejoin &&
1639 + test_commit main_must_not_be_in_subtree2 &&
1640 + git checkout main &&
1641 + git merge --no-ff new_work_based_on_prejoin &&
1642 + test_commit sub/sub3 &&
1643 + git subtree split -d --prefix sub -b second_split &&
1644 + git checkout second_split &&
1645 + test_path_is_file sub1.t &&
1646 + test_path_is_file sub2.t &&
1647 + test_path_is_file sub3.t &&
1648 + ! test_path_is_file main_must_not_be_in_subtree.t &&
1649 + ! test_path_is_file main_must_not_be_in_subtree2.t &&
1650 + test "$(git rev-list --count --merges second_split)" -eq 0 &&
1651 + test "$(git rev-list --count second_split)" -eq 3;
1652 + )
1653 +'
1654 +
1655 +# split must keep merge commits with unrelated histories, even
1656 +# if both parents are treesame. When deciding whether or not
1657 +# to eliminate a parent, copy_or_skip compares the merge-base
1658 +# of each parent.
1659 +#
1660 +# in the split_of_merges branch:
1661 +#
1662 +# * expect 4 commits
1663 +# * HEAD~ must be a merge
1664 +#
1665 +# see: 68f8ff8151 (subtree: improve decision on merges kept
1666 +# in split, 2018-09-28)
1667 +test_expect_success 'split preserves merges with unrelated history' '
1668 + subtree_test_create_repo "$test_count" &&
1669 + (
1670 + cd "$test_count" &&
1671 + test_commit main_must_not_be_in_subtree &&
1672 + mkdir sub &&
1673 + test_commit sub/sub1 &&
1674 + git checkout --orphan new_history &&
1675 + git checkout sub/sub1 -- . &&
1676 + git add . &&
1677 + git commit -m "treesame history but not a merge-base" &&
1678 + git checkout main &&
1679 + git merge --allow-unrelated-histories --no-ff new_history &&
1680 + test "$(git rev-parse "HEAD^1^{tree}")" = "$(git rev-parse "HEAD^2^{tree}")" &&
1681 + test_commit sub/sub2 &&
1682 + git subtree split -d --prefix sub -b split_of_merges &&
1683 + test "$(git rev-list --count split_of_merges)" -eq 4 &&
1684 + test -n "$(git rev-list --merges HEAD~)";
1685 + )
1686 +'
1687 +
1688 #
1689 # This test covers 2 cases in subtree split copy_or_skip code
1690 # 1) Merges where one parent is a superset of the changes of the other