Imported Upstream version 2.0.1
[platform/upstream/git.git] / contrib / subtree / git-subtree.sh
index 920c664..db925ca 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 #
 # git-subtree.sh: split/join git repositories in subdirectories of this one
 #
@@ -9,9 +9,10 @@ if [ $# -eq 0 ]; then
 fi
 OPTS_SPEC="\
 git subtree add   --prefix=<prefix> <commit>
+git subtree add   --prefix=<prefix> <repository> <ref>
 git subtree merge --prefix=<prefix> <commit>
-git subtree pull  --prefix=<prefix> <repository> <refspec...>
-git subtree push  --prefix=<prefix> <repository> <refspec...>
+git subtree pull  --prefix=<prefix> <repository> <ref>
+git subtree push  --prefix=<prefix> <repository> <ref>
 git subtree split --prefix=<prefix> <commit...>
 --
 h,help        show the help
@@ -45,6 +46,7 @@ ignore_joins=
 annotate=
 squash=
 message=
+prefix=
 
 debug()
 {
@@ -296,7 +298,7 @@ copy_commit()
        # We're going to set some environment vars here, so
        # do it in a subshell to get rid of them safely later
        debug copy_commit "{$1}" "{$2}" "{$3}"
-       git log -1 --pretty=format:'%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%s%n%n%b' "$1" |
+       git log -1 --pretty=format:'%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%B' "$1" |
        (
                read GIT_AUTHOR_NAME
                read GIT_AUTHOR_EMAIL
@@ -310,7 +312,7 @@ copy_commit()
                        GIT_COMMITTER_NAME \
                        GIT_COMMITTER_EMAIL \
                        GIT_COMMITTER_DATE
-               (echo -n "$annotate"; cat ) |
+               (printf "%s" "$annotate"; cat ) |
                git commit-tree "$2" $3  # reads the rest of stdin
        ) || die "Can't copy commit $1"
 }
@@ -488,6 +490,12 @@ ensure_clean()
        fi
 }
 
+ensure_valid_ref_format()
+{
+       git check-ref-format "refs/heads/$1" ||
+           die "'$1' does not look like a ref"
+}
+
 cmd_add()
 {
        if [ -e "$dir" ]; then
@@ -497,12 +505,22 @@ cmd_add()
        ensure_clean
        
        if [ $# -eq 1 ]; then
-               "cmd_add_commit" "$@"
+           git rev-parse -q --verify "$1^{commit}" >/dev/null ||
+           die "'$1' does not refer to a commit"
+
+           "cmd_add_commit" "$@"
        elif [ $# -eq 2 ]; then
-               "cmd_add_repository" "$@"
+           # Technically we could accept a refspec here but we're
+           # just going to turn around and add FETCH_HEAD under the
+           # specified directory.  Allowing a refspec might be
+           # misleading because we won't do anything with any other
+           # branches fetched via the refspec.
+           ensure_valid_ref_format "$2"
+
+           "cmd_add_repository" "$@"
        else
            say "error: parameters were '$@'"
-           die "Provide either a refspec or a repository and refspec."
+           die "Provide either a commit or a repository and commit."
        fi
 }
 
@@ -687,7 +705,11 @@ cmd_merge()
 
 cmd_pull()
 {
+       if [ $# -ne 2 ]; then
+           die "You must provide <repository> <ref>"
+       fi
        ensure_clean
+       ensure_valid_ref_format "$2"
        git fetch "$@" || exit $?
        revs=FETCH_HEAD
        set -- $revs
@@ -697,13 +719,15 @@ cmd_pull()
 cmd_push()
 {
        if [ $# -ne 2 ]; then
-           die "You must provide <repository> <refspec>"
+           die "You must provide <repository> <ref>"
        fi
+       ensure_valid_ref_format "$2"
        if [ -e "$dir" ]; then
            repository=$1
            refspec=$2
            echo "git push using: " $repository $refspec
-           git push $repository $(git subtree split --prefix=$prefix):refs/heads/$refspec
+           localrev=$(git subtree split --prefix="$prefix") || die
+           git push $repository $localrev:refs/heads/$refspec
        else
            die "'$dir' must already exist. Try 'git subtree add'."
        fi