]> git.ipfire.org Git - thirdparty/git.git/commitdiff
subtree: push: allow specifying a local rev other than HEAD
authorLuke Shumaker <lukeshu@datawire.io>
Tue, 27 Apr 2021 21:17:47 +0000 (15:17 -0600)
committerJunio C Hamano <gitster@pobox.com>
Wed, 28 Apr 2021 07:47:19 +0000 (16:47 +0900)
'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>
contrib/subtree/git-subtree.sh
contrib/subtree/git-subtree.txt
contrib/subtree/t/t7900-subtree.sh

index 431214a1d336ac9de5af010d0150fecbd1392b4e..9e4d9a0619c0652b95b59356dc0a48155e0b5e43 100755 (executable)
@@ -27,7 +27,7 @@ git subtree add   --prefix=<prefix> <repository> <ref>
 git subtree merge --prefix=<prefix> <commit>
 git subtree split --prefix=<prefix> [<commit>]
 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
 q             quiet
@@ -952,20 +952,30 @@ cmd_pull () {
        cmd_merge FETCH_HEAD
 }
 
-# Usage: cmd_push REPOSITORY REMOTEREF
+# Usage: cmd_push REPOSITORY [+][LOCALREV:]REMOTEREF
 cmd_push () {
        if test $# -ne 2
        then
-               die "You must provide <repository> <ref>"
+               die "You must provide <repository> <refspec>"
        fi
-       ensure_valid_ref_format "$2"
        if test -e "$dir"
        then
                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"
-               localrev=$(cmd_split) || die
-               git push "$repository" "$localrev":"refs/heads/$refspec"
+               localrev=$(cmd_split "$localrev_presplit") || die
+               git push "$repository" "$localrev":"refs/heads/$remoteref"
        else
                die "'$dir' must already exist. Try 'git subtree add'."
        fi
index fbb52f127badc6ca866f407699b4fcc6beb4f3c1..9cddfa26540a241d88c8ab049632797b6038e377 100644 (file)
@@ -16,7 +16,7 @@ SYNOPSIS
 
 [verse]
 '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
 -----------
@@ -115,11 +115,13 @@ pull <repository> <remote-ref>::
        it fetches the given ref from the specified remote
        repository.
 
-push <repository> <remote-ref>::
-       Does a 'split' using the <prefix> subtree of HEAD and then
-       does a 'git push' to push the result to the <repository> and
-       <remote-ref>.  This can be used to push your subtree to
-       different branches of the remote repository.
+push <repository> [+][<local-commit>:]<remote-ref>::
+       Does a 'split' using the <prefix> subtree of <local-commit>
+       and then does a 'git push' to push the result to the
+       <repository> and <remote-ref>.  This can be used to push your
+       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
 ------------------------
index 5a6541437b7c222cbcfc1dfc20467152ebe99ef0..d7ad6ffff0e7dd66d0a5c06d64b6c9ed38b6f409 100755 (executable)
@@ -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
 #