subtree: push: allow specifying a local rev other than HEAD

'git subtree split' lets you specify a rev other than HEAD.  'git push'
lets you specify a mapping between a local thing and a remot ref.  So
smash those together, and have 'git subtree push' let you specify which
local thing to run split on and push the result of that split to the
remote ref.

Signed-off-by: Luke Shumaker <lukeshu@datawire.io>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Luke Shumaker 2021-04-27 15:17:47 -06:00 коммит произвёл Junio C Hamano
Родитель 94389e7c81
Коммит 49470cd445
3 изменённых файлов: 47 добавлений и 13 удалений

Просмотреть файл

@ -27,7 +27,7 @@ git subtree add --prefix=<prefix> <repository> <ref>
git subtree merge --prefix=<prefix> <commit> git subtree merge --prefix=<prefix> <commit>
git subtree split --prefix=<prefix> [<commit>] git subtree split --prefix=<prefix> [<commit>]
git subtree pull --prefix=<prefix> <repository> <ref> git subtree pull --prefix=<prefix> <repository> <ref>
git subtree push --prefix=<prefix> <repository> <ref> git subtree push --prefix=<prefix> <repository> <refspec>
-- --
h,help show the help h,help show the help
q quiet q quiet
@ -952,20 +952,30 @@ cmd_pull () {
cmd_merge FETCH_HEAD cmd_merge FETCH_HEAD
} }
# Usage: cmd_push REPOSITORY REMOTEREF # Usage: cmd_push REPOSITORY [+][LOCALREV:]REMOTEREF
cmd_push () { cmd_push () {
if test $# -ne 2 if test $# -ne 2
then then
die "You must provide <repository> <ref>" die "You must provide <repository> <refspec>"
fi fi
ensure_valid_ref_format "$2"
if test -e "$dir" if test -e "$dir"
then then
repository=$1 repository=$1
refspec=$2 refspec=${2#+}
remoteref=${refspec#*:}
if test "$remoteref" = "$refspec"
then
localrevname_presplit=HEAD
else
localrevname_presplit=${refspec%%:*}
fi
ensure_valid_ref_format "$remoteref"
localrev_presplit=$(git rev-parse -q --verify "$localrevname_presplit^{commit}") ||
die "'$localrevname_presplit' does not refer to a commit"
echo "git push using: " "$repository" "$refspec" echo "git push using: " "$repository" "$refspec"
localrev=$(cmd_split) || die localrev=$(cmd_split "$localrev_presplit") || die
git push "$repository" "$localrev":"refs/heads/$refspec" git push "$repository" "$localrev":"refs/heads/$remoteref"
else else
die "'$dir' must already exist. Try 'git subtree add'." die "'$dir' must already exist. Try 'git subtree add'."
fi fi

Просмотреть файл

@ -16,7 +16,7 @@ SYNOPSIS
[verse] [verse]
'git subtree' [<options>] -P <prefix> pull <repository> <remote-ref> 'git subtree' [<options>] -P <prefix> pull <repository> <remote-ref>
'git subtree' [<options>] -P <prefix> push <repository> <remote-ref> 'git subtree' [<options>] -P <prefix> push <repository> <refspec>
DESCRIPTION DESCRIPTION
----------- -----------
@ -115,11 +115,13 @@ pull <repository> <remote-ref>::
it fetches the given ref from the specified remote it fetches the given ref from the specified remote
repository. repository.
push <repository> <remote-ref>:: push <repository> [+][<local-commit>:]<remote-ref>::
Does a 'split' using the <prefix> subtree of HEAD and then Does a 'split' using the <prefix> subtree of <local-commit>
does a 'git push' to push the result to the <repository> and and then does a 'git push' to push the result to the
<remote-ref>. This can be used to push your subtree to <repository> and <remote-ref>. This can be used to push your
different branches of the remote repository. subtree to different branches of the remote repository. Just
as with 'split', if no <local-commit> is given, then HEAD is
used. The optional leading '+' is ignored.
OPTIONS FOR ALL COMMANDS OPTIONS FOR ALL COMMANDS
------------------------ ------------------------

Просмотреть файл

@ -820,6 +820,28 @@ test_expect_success 'push "sub dir"/ with --branch for an incompatible branch' '
) )
' '
test_expect_success 'push "sub dir"/ with a local rev' '
subtree_test_create_repo "$test_count" &&
subtree_test_create_repo "$test_count/sub proj" &&
test_create_commit "$test_count" main1 &&
test_create_commit "$test_count/sub proj" sub1 &&
(
cd "$test_count" &&
git fetch ./"sub proj" HEAD &&
git subtree add --prefix="sub dir" FETCH_HEAD
) &&
test_create_commit "$test_count" "sub dir"/main-sub1 &&
test_create_commit "$test_count" "sub dir"/main-sub2 &&
(
cd "$test_count" &&
bad_tree=$(git rev-parse --verify HEAD:"sub dir") &&
good_tree=$(git rev-parse --verify HEAD^:"sub dir") &&
git subtree push --prefix="sub dir" --annotate="*" ./"sub proj" HEAD^:from-mainline &&
split_tree=$(git -C "sub proj" rev-parse --verify refs/heads/from-mainline:) &&
test "$split_tree" = "$good_tree"
)
'
# #
# Validity checking # Validity checking
# #