Skip to content

Commit 49470cd

Browse files
LukeShugitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 94389e7 commit 49470cd

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

contrib/subtree/git-subtree.sh

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ git subtree add --prefix=<prefix> <repository> <ref>
2727
git subtree merge --prefix=<prefix> <commit>
2828
git subtree split --prefix=<prefix> [<commit>]
2929
git subtree pull --prefix=<prefix> <repository> <ref>
30-
git subtree push --prefix=<prefix> <repository> <ref>
30+
git subtree push --prefix=<prefix> <repository> <refspec>
3131
--
3232
h,help show the help
3333
q quiet
@@ -952,20 +952,30 @@ cmd_pull () {
952952
cmd_merge FETCH_HEAD
953953
}
954954

955-
# Usage: cmd_push REPOSITORY REMOTEREF
955+
# Usage: cmd_push REPOSITORY [+][LOCALREV:]REMOTEREF
956956
cmd_push () {
957957
if test $# -ne 2
958958
then
959-
die "You must provide <repository> <ref>"
959+
die "You must provide <repository> <refspec>"
960960
fi
961-
ensure_valid_ref_format "$2"
962961
if test -e "$dir"
963962
then
964963
repository=$1
965-
refspec=$2
964+
refspec=${2#+}
965+
remoteref=${refspec#*:}
966+
if test "$remoteref" = "$refspec"
967+
then
968+
localrevname_presplit=HEAD
969+
else
970+
localrevname_presplit=${refspec%%:*}
971+
fi
972+
ensure_valid_ref_format "$remoteref"
973+
localrev_presplit=$(git rev-parse -q --verify "$localrevname_presplit^{commit}") ||
974+
die "'$localrevname_presplit' does not refer to a commit"
975+
966976
echo "git push using: " "$repository" "$refspec"
967-
localrev=$(cmd_split) || die
968-
git push "$repository" "$localrev":"refs/heads/$refspec"
977+
localrev=$(cmd_split "$localrev_presplit") || die
978+
git push "$repository" "$localrev":"refs/heads/$remoteref"
969979
else
970980
die "'$dir' must already exist. Try 'git subtree add'."
971981
fi

contrib/subtree/git-subtree.txt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ SYNOPSIS
1616

1717
[verse]
1818
'git subtree' [<options>] -P <prefix> pull <repository> <remote-ref>
19-
'git subtree' [<options>] -P <prefix> push <repository> <remote-ref>
19+
'git subtree' [<options>] -P <prefix> push <repository> <refspec>
2020

2121
DESCRIPTION
2222
-----------
@@ -115,11 +115,13 @@ pull <repository> <remote-ref>::
115115
it fetches the given ref from the specified remote
116116
repository.
117117

118-
push <repository> <remote-ref>::
119-
Does a 'split' using the <prefix> subtree of HEAD and then
120-
does a 'git push' to push the result to the <repository> and
121-
<remote-ref>. This can be used to push your subtree to
122-
different branches of the remote repository.
118+
push <repository> [+][<local-commit>:]<remote-ref>::
119+
Does a 'split' using the <prefix> subtree of <local-commit>
120+
and then does a 'git push' to push the result to the
121+
<repository> and <remote-ref>. This can be used to push your
122+
subtree to different branches of the remote repository. Just
123+
as with 'split', if no <local-commit> is given, then HEAD is
124+
used. The optional leading '+' is ignored.
123125

124126
OPTIONS FOR ALL COMMANDS
125127
------------------------

contrib/subtree/t/t7900-subtree.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,28 @@ test_expect_success 'push "sub dir"/ with --branch for an incompatible branch' '
820820
)
821821
'
822822

823+
test_expect_success 'push "sub dir"/ with a local rev' '
824+
subtree_test_create_repo "$test_count" &&
825+
subtree_test_create_repo "$test_count/sub proj" &&
826+
test_create_commit "$test_count" main1 &&
827+
test_create_commit "$test_count/sub proj" sub1 &&
828+
(
829+
cd "$test_count" &&
830+
git fetch ./"sub proj" HEAD &&
831+
git subtree add --prefix="sub dir" FETCH_HEAD
832+
) &&
833+
test_create_commit "$test_count" "sub dir"/main-sub1 &&
834+
test_create_commit "$test_count" "sub dir"/main-sub2 &&
835+
(
836+
cd "$test_count" &&
837+
bad_tree=$(git rev-parse --verify HEAD:"sub dir") &&
838+
good_tree=$(git rev-parse --verify HEAD^:"sub dir") &&
839+
git subtree push --prefix="sub dir" --annotate="*" ./"sub proj" HEAD^:from-mainline &&
840+
split_tree=$(git -C "sub proj" rev-parse --verify refs/heads/from-mainline:) &&
841+
test "$split_tree" = "$good_tree"
842+
)
843+
'
844+
823845
#
824846
# Validity checking
825847
#

0 commit comments

Comments
 (0)