···785785 die "fatal: '$1' does not look like a ref"
786786}
787787788788-# Usage: check if a commit from another subtree should be
788788+# Usage: should_ignore_subtree_split_commit REV
789789+#
790790+# Check if REV is a commit from another subtree and should be
789791# ignored from processing for splits
790792should_ignore_subtree_split_commit () {
791793 assert test $# = 1
792792- local rev="$1"
793793- if test -n "$(git log -1 --grep="git-subtree-dir:" $rev)"
794794+795795+ git show \
796796+ --no-patch \
797797+ --no-show-signature \
798798+ --format='%(trailers:key=git-subtree-dir,key=git-subtree-mainline)' \
799799+ "$1" |
800800+ (
801801+ have_mainline=
802802+ subtree_dir=
803803+804804+ while read -r trailer val
805805+ do
806806+ case "$trailer" in
807807+ git-subtree-dir:)
808808+ subtree_dir="${val%/}" ;;
809809+ git-subtree-mainline:)
810810+ have_mainline=y ;;
811811+ esac
812812+ done
813813+814814+ if test -n "${subtree_dir}" &&
815815+ test -z "${have_mainline}" &&
816816+ test "${subtree_dir}" != "$arg_prefix"
794817 then
795795- if test -z "$(git log -1 --grep="git-subtree-mainline:" $rev)" &&
796796- test -z "$(git log -1 --grep="git-subtree-dir: $arg_prefix$" $rev)"
797797- then
798798- return 0
799799- fi
818818+ return 0
800819 fi
801820 return 1
821821+ )
802822}
803823804824# Usage: process_split_commit REV PARENTS
+71
contrib/subtree/t/t7900-subtree.sh
···99and push subcommands of git subtree.
1010'
11111212+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
1313+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
1414+1215TEST_DIRECTORY=$(pwd)/../../../t
1316. "$TEST_DIRECTORY"/test-lib.sh
1417. "$TEST_DIRECTORY"/lib-gpg.sh
···6669 git clone --no-local "$1" "$1-clone" &&
6770 new_commit=$(sed -e "s/$commit/$tag/" msg | git -C "$1-clone" commit-tree HEAD^2^{tree}) &&
6871 git -C "$1-clone" replace HEAD^2 $new_commit
7272+}
7373+7474+# test_create_subtree_add REPO ORPHAN PREFIX FILENAME ...
7575+#
7676+# Create a simple subtree on a new branch named ORPHAN in REPO.
7777+# The subtree is then merged into the current branch of REPO,
7878+# under PREFIX. The generated subtree has has one commit
7979+# with subject and tag FILENAME with a single file "FILENAME.t"
8080+#
8181+# When this method returns:
8282+# - the current branch of REPO will have file PREFIX/FILENAME.t
8383+# - REPO will have a branch named ORPHAN with subtree history
8484+#
8585+# additional arguments are forwarded to "subtree add"
8686+test_create_subtree_add () {
8787+ (
8888+ cd "$1" &&
8989+ orphan="$2" &&
9090+ prefix="$3" &&
9191+ filename="$4" &&
9292+ shift 4 &&
9393+ last="$(git branch --show-current)" &&
9494+ git switch --orphan "$orphan" &&
9595+ test_commit "$filename" &&
9696+ git checkout "$last" &&
9797+ git subtree add --prefix="$prefix" "$@" "$orphan"
9898+ )
6999}
7010071101test_expect_success 'shows short help text for -h' '
···425455 test "$(git -C "$test_count" subtree split --prefix=subBDir \
426456 --squash --rejoin -d -m "Sub B Split 1" 2>&1 | grep -w "\[1\]")" = ""
427457'
458458+459459+# When subtree split-ing a directory that has other subtree
460460+# *merges* underneath it, the split must include those subtrees.
461461+# This test creates a nested subtree, `subA/subB`, and tests
462462+# that the tree is correct after a subtree split of `subA/`.
463463+# The test covers:
464464+# - An initial `subtree add`; and
465465+# - A follow-up `subtree merge`
466466+# both with and without `--squashed`.
467467+for is_squashed in '' 'y'
468468+do
469469+ test_expect_success "split keeps nested ${is_squashed:+--squash }subtrees that are part of the split" '
470470+ subtree_test_create_repo "$test_count" &&
471471+ (
472472+ cd "$test_count" &&
473473+ mkdir subA &&
474474+ test_commit subA/file1 &&
475475+ test_create_subtree_add \
476476+ . mksubtree subA/subB file2 ${is_squashed:+--squash} &&
477477+ test_path_is_file subA/file1.t &&
478478+ test_path_is_file subA/subB/file2.t &&
479479+ git subtree split --prefix=subA --branch=bsplit &&
480480+ git checkout bsplit &&
481481+ test_path_is_file file1.t &&
482482+ test_path_is_file subB/file2.t &&
483483+ git checkout mksubtree &&
484484+ git branch -D bsplit &&
485485+ test_commit file3 &&
486486+ git checkout main &&
487487+ git subtree merge \
488488+ ${is_squashed:+--squash} \
489489+ --prefix=subA/subB mksubtree &&
490490+ test_path_is_file subA/subB/file3.t &&
491491+ git subtree split --prefix=subA --branch=bsplit &&
492492+ git checkout bsplit &&
493493+ test_path_is_file file1.t &&
494494+ test_path_is_file subB/file2.t &&
495495+ test_path_is_file subB/file3.t
496496+ )
497497+ '
498498+done
428499429500test_expect_success 'split sub dir/ with --rejoin from scratch' '
430501 subtree_test_create_repo "$test_count" &&