Skip to content

Commit 1762382

Browse files
phil-blaingitster
authored andcommitted
subtree: fix split after annotated tag was squashed merged
The previous commit fixed a failure in 'git subtree merge --squash' when the previous squash-merge merged an annotated tag of the subtree repository which is missing locally. The same failure happens in 'git subtree split', either directly or when called by 'git subtree push', under the same circumstances: 'cmd_split' invokes 'find_existing_splits', which loops through previous commits and invokes 'git rev-parse' (via 'process_subtree_split_trailer') on the value of any 'git subtree-split' trailer it finds. This fails if this value is the hash of an annotated tag which is missing locally. Add a new optional argument 'repository' to 'cmd_split' and 'find_existing_splits', and invoke 'cmd_split' with that argument from 'cmd_push'. This allows 'process_subtree_split_trailer' to try to fetch the missing tag from the 'repository' if it's not available locally, mirroring the new behaviour of 'git subtree pull' and 'git subtree merge'. Signed-off-by: Philippe Blain <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0d33067 commit 1762382

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

contrib/subtree/git-subtree.sh

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -453,14 +453,19 @@ find_latest_squash () {
453453
done || exit $?
454454
}
455455

456-
# Usage: find_existing_splits DIR REV
456+
# Usage: find_existing_splits DIR REV [REPOSITORY]
457457
find_existing_splits () {
458-
assert test $# = 2
458+
assert test $# = 2 -o $# = 3
459459
debug "Looking for prior splits..."
460460
local indent=$(($indent + 1))
461461

462462
dir="$1"
463463
rev="$2"
464+
repository=""
465+
if test "$#" = 3
466+
then
467+
repository="$3"
468+
fi
464469
main=
465470
sub=
466471
local grep_format="^git-subtree-dir: $dir/*\$"
@@ -480,7 +485,7 @@ find_existing_splits () {
480485
main="$b"
481486
;;
482487
git-subtree-split:)
483-
process_subtree_split_trailer "$b" "$sq"
488+
process_subtree_split_trailer "$b" "$sq" "$repository"
484489
;;
485490
END)
486491
debug "Main is: '$main'"
@@ -906,17 +911,22 @@ cmd_add_commit () {
906911
say >&2 "Added dir '$dir'"
907912
}
908913

909-
# Usage: cmd_split [REV]
914+
# Usage: cmd_split [REV] [REPOSITORY]
910915
cmd_split () {
911916
if test $# -eq 0
912917
then
913918
rev=$(git rev-parse HEAD)
914-
elif test $# -eq 1
919+
elif test $# -eq 1 -o $# -eq 2
915920
then
916921
rev=$(git rev-parse -q --verify "$1^{commit}") ||
917922
die "fatal: '$1' does not refer to a commit"
918923
else
919-
die "fatal: you must provide exactly one revision. Got: '$*'"
924+
die "fatal: you must provide exactly one revision, and optionnally a repository. Got: '$*'"
925+
fi
926+
repository=""
927+
if test "$#" = 2
928+
then
929+
repository="$2"
920930
fi
921931

922932
if test -n "$arg_split_rejoin"
@@ -940,7 +950,7 @@ cmd_split () {
940950
done || exit $?
941951
fi
942952

943-
unrevs="$(find_existing_splits "$dir" "$rev")" || exit $?
953+
unrevs="$(find_existing_splits "$dir" "$rev" "$repository")" || exit $?
944954

945955
# We can't restrict rev-list to only $dir here, because some of our
946956
# parents have the $dir contents the root, and those won't match.
@@ -1072,7 +1082,7 @@ cmd_push () {
10721082
die "fatal: '$localrevname_presplit' does not refer to a commit"
10731083

10741084
echo "git push using: " "$repository" "$refspec"
1075-
localrev=$(cmd_split "$localrev_presplit") || die
1085+
localrev=$(cmd_split "$localrev_presplit" "$repository") || die
10761086
git push "$repository" "$localrev":"refs/heads/$remoteref"
10771087
else
10781088
die "fatal: '$dir' must already exist. Try 'git subtree add'."

contrib/subtree/git-subtree.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ annotated tag of the subtree repository, that tag needs to be available locally.
9494
If <repository> is given, a missing tag will automatically be fetched from that
9595
repository.
9696

97-
split [<local-commit>]::
97+
split [<local-commit>] [<repository>]::
9898
Extract a new, synthetic project history from the
9999
history of the <prefix> subtree of <local-commit>, or of
100100
HEAD if no <local-commit> is given. The new history
@@ -114,6 +114,11 @@ settings passed to 'split' (such as '--annotate') are the same.
114114
Because of this, if you add new commits and then re-split, the new
115115
commits will be attached as commits on top of the history you
116116
generated last time, so 'git merge' and friends will work as expected.
117+
+
118+
When a previous merge with '--squash' merged an annotated tag of the
119+
subtree repository, that tag needs to be available locally.
120+
If <repository> is given, a missing tag will automatically be fetched from that
121+
repository.
117122

118123
pull <repository> <remote-ref>::
119124
Exactly like 'merge', but parallels 'git pull' in that

contrib/subtree/t/t7900-subtree.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,12 @@ test_expect_success 'split "sub dir"/ with --branch for an incompatible branch'
582582
)
583583
'
584584

585+
test_expect_success 'split after annotated tag was added/merged with --squash pre-v2.32.0' '
586+
test_create_pre2_32_repo "$test_count" &&
587+
test_must_fail git -C "$test_count-clone" subtree split --prefix="sub" HEAD &&
588+
git -C "$test_count-clone" subtree split --prefix="sub" HEAD "../$test_count-sub"
589+
'
590+
585591
#
586592
# Tests for 'git subtree pull'
587593
#
@@ -989,6 +995,12 @@ test_expect_success 'push "sub dir"/ with a local rev' '
989995
)
990996
'
991997

998+
test_expect_success 'push after annotated tag was added/merged with --squash pre-v2.32.0' '
999+
test_create_pre2_32_repo "$test_count" &&
1000+
test_create_commit "$test_count-clone" sub/main-sub1 &&
1001+
git -C "$test_count-clone" subtree push --prefix="sub" "../$test_count-sub" from-mainline
1002+
'
1003+
9921004
#
9931005
# Validity checking
9941006
#

0 commit comments

Comments
 (0)