Added new 'push' command and 2-parameter form of 'add'.
authorWayne Walter <wayne@tickzoom.com>
Sat, 13 Feb 2010 19:32:21 +0000 (14:32 -0500)
committerAvery Pennarun <apenwarr@gmail.com>
Sat, 13 Feb 2010 19:45:04 +0000 (14:45 -0500)
Now you can do:

git subtree add --prefix=whatever git://wherever branchname

to add a new branch, instead of rather weirdly having to do 'git fetch'
first. You can also split and push in one step:

git subtree push --prefix=whatever git://wherever newbranch

(Somewhat cleaned up by apenwarr.)

INSTALL
git-subtree.sh
git-subtree.txt
install.sh [new file with mode: 0644]
diff --git a/INSTALL b/INSTALL
index 5966dde46c214726fc422c2e55cbe0e981db2bd0..81ac702ad22f4e7116459fde665e2159842aa85a 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -2,7 +2,16 @@
 HOW TO INSTALL git-subtree
 ==========================
 
 HOW TO INSTALL git-subtree
 ==========================
 
-Copy the file 'git-subtree.sh' to /usr/local/bin/git-subtree.
+You simply need to copy the file 'git-subtree.sh' to where
+the rest of the git scripts are stored. 
+
+From the Git bash window just run:
+
+install.sh 
+
+Or if you have the full Cygwin installed, you can use make:
+
+make install
 
 That will make a 'git subtree' (note: space instead of dash) command
 available.  See the file git-subtree.txt for more.
 
 That will make a 'git subtree' (note: space instead of dash) command
 available.  See the file git-subtree.txt for more.
index e76b45c2ddcdbd54b944aa72a774b45fa40cbfc3..501c6dc2f1a8e8a646f535074c8e95f7bc445439 100755 (executable)
@@ -11,6 +11,7 @@ OPTS_SPEC="\
 git subtree add   --prefix=<prefix> <commit>
 git subtree merge --prefix=<prefix> <commit>
 git subtree pull  --prefix=<prefix> <repository> <refspec...>
 git subtree add   --prefix=<prefix> <commit>
 git subtree merge --prefix=<prefix> <commit>
 git subtree pull  --prefix=<prefix> <repository> <refspec...>
+git subtree push  --prefix=<prefix> <repository> <refspec...>
 git subtree split --prefix=<prefix> <commit...>
 --
 h,help        show the help
 git subtree split --prefix=<prefix> <commit...>
 --
 h,help        show the help
@@ -24,7 +25,7 @@ b,branch=     create a new branch from the split subtree
 ignore-joins  ignore prior --rejoin commits
 onto=         try connecting new tree to an existing one
 rejoin        merge the new branch back into HEAD
 ignore-joins  ignore prior --rejoin commits
 onto=         try connecting new tree to an existing one
 rejoin        merge the new branch back into HEAD
- options for 'add', 'merge', and 'pull'
+ options for 'add', 'merge', 'pull' and 'push'
 squash        merge subtree changes as a single commit
 "
 eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)
 squash        merge subtree changes as a single commit
 "
 eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)
@@ -98,7 +99,7 @@ command="$1"
 shift
 case "$command" in
        add|merge|pull) default= ;;
 shift
 case "$command" in
        add|merge|pull) default= ;;
-       split) default="--default HEAD" ;;
+       split|push) default="--default HEAD" ;;
        *) die "Unknown command '$command'" ;;
 esac
 
        *) die "Unknown command '$command'" ;;
 esac
 
@@ -115,7 +116,7 @@ esac
 
 dir="$(dirname "$prefix/.")"
 
 
 dir="$(dirname "$prefix/.")"
 
-if [ "$command" != "pull" ]; then
+if [ "$command" != "pull" -a "$command" != "add" -a "$command" != "push" ]; then
        revs=$(git rev-parse $default --revs-only "$@") || exit $?
        dirs="$(git rev-parse --no-revs --no-flags "$@")" || exit $?
        if [ -n "$dirs" ]; then
        revs=$(git rev-parse $default --revs-only "$@") || exit $?
        dirs="$(git rev-parse --no-revs --no-flags "$@")" || exit $?
        if [ -n "$dirs" ]; then
@@ -450,10 +451,10 @@ copy_or_skip()
 
 ensure_clean()
 {
 
 ensure_clean()
 {
-       if ! git diff-index HEAD --exit-code --quiet; then
+       if ! git diff-index HEAD --exit-code --quiet 2>&1; then
                die "Working tree has modifications.  Cannot add."
        fi
                die "Working tree has modifications.  Cannot add."
        fi
-       if ! git diff-index --cached HEAD --exit-code --quiet; then
+       if ! git diff-index --cached HEAD --exit-code --quiet 2>&1; then
                die "Index has modifications.  Cannot add."
        fi
 }
                die "Index has modifications.  Cannot add."
        fi
 }
@@ -463,12 +464,34 @@ cmd_add()
        if [ -e "$dir" ]; then
                die "'$dir' already exists.  Cannot add."
        fi
        if [ -e "$dir" ]; then
                die "'$dir' already exists.  Cannot add."
        fi
+
        ensure_clean
        
        ensure_clean
        
-       set -- $revs
-       if [ $# -ne 1 ]; then
-               die "You must provide exactly one revision.  Got: '$revs'"
+       if [ $# -eq 1 ]; then
+               "cmd_add_commit" "$@"
+       elif [ $# -eq 2 ]; then
+               "cmd_add_repository" "$@"
+       else
+           say "error: parameters were '$@'"
+           die "Provide either a refspec or a repository and refspec."
        fi
        fi
+}
+
+cmd_add_repository()
+{
+       echo "git fetch" "$@"
+       repository=$1
+       refspec=$2
+       git fetch "$@" || exit $?
+       revs=FETCH_HEAD
+       set -- $revs
+       cmd_add_commit "$@"
+}
+
+cmd_add_commit()
+{
+       revs=$(git rev-parse $default --revs-only "$@") || exit $?
+       set -- $revs
        rev="$1"
        
        debug "Adding $dir as '$rev'..."
        rev="$1"
        
        debug "Adding $dir as '$rev'..."
@@ -586,6 +609,7 @@ cmd_split()
 
 cmd_merge()
 {
 
 cmd_merge()
 {
+       revs=$(git rev-parse $default --revs-only "$@") || exit $?
        ensure_clean
        
        set -- $revs
        ensure_clean
        
        set -- $revs
@@ -623,7 +647,23 @@ cmd_pull()
        ensure_clean
        git fetch "$@" || exit $?
        revs=FETCH_HEAD
        ensure_clean
        git fetch "$@" || exit $?
        revs=FETCH_HEAD
-       cmd_merge
+       set -- $revs
+       cmd_merge "$@"
+}
+
+cmd_push()
+{
+       if [ $# -ne 2 ]; then
+           die "You must provide <repository> <refspec>"
+       fi
+       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
+       else
+           die "'$dir' must already exist. Try 'git subtree add'."
+       fi
 }
 
 "cmd_$command" "$@"
 }
 
 "cmd_$command" "$@"
index c455f6912b7ea2ca50358ae6f1c078c4d25c24ef..4f715c640bc6b8f25df9c8306292eb354d16c481 100644 (file)
@@ -9,10 +9,12 @@ git-subtree - add, merge, and split subprojects stored in subtrees
 SYNOPSIS
 --------
 [verse]
 SYNOPSIS
 --------
 [verse]
-'git subtree' add   --prefix=<prefix> <commit>
-'git subtree' merge --prefix=<prefix> <commit>
+'git subtree' add   --prefix=<prefix> <repository> <refspec...>
 'git subtree' pull  --prefix=<prefix> <repository> <refspec...>
 'git subtree' pull  --prefix=<prefix> <repository> <refspec...>
-'git subtree' split --prefix=<prefix> <commit...>
+'git subtree' push  --prefix=<prefix> <repository> <refspec...>
+'git subtree' add   --prefix=<prefix> <refspec>
+'git subtree' merge --prefix=<prefix> <refspec>
+'git subtree' split --prefix=<prefix> <refspec...>
          
 
 DESCRIPTION
          
 
 DESCRIPTION
@@ -60,11 +62,11 @@ COMMANDS
 --------
 add::
        Create the <prefix> subtree by importing its contents
 --------
 add::
        Create the <prefix> subtree by importing its contents
-       from the given commit.  A new commit is created
-       automatically, joining the imported project's history
-       with your own.  With '--squash', imports only a single
-       commit from the subproject, rather than its entire
-       history.
+       from the given <refspec> or <repository> and remote <refspec>.
+       A new commit is created automatically, joining the imported
+       project's history with your own.  With '--squash', imports
+       only a single commit from the subproject, rather than its
+       entire history.
 
 merge::
        Merge recent changes up to <commit> into the <prefix>
 
 merge::
        Merge recent changes up to <commit> into the <prefix>
@@ -84,6 +86,12 @@ pull::
        Exactly like 'merge', but parallels 'git pull' in that
        it fetches the given commit from the specified remote
        repository.
        Exactly like 'merge', but parallels 'git pull' in that
        it fetches the given commit from the specified remote
        repository.
+       
+push::
+       Does a 'split' (see above) using the <prefix> supplied
+       and then does a 'git push' to push the result to the 
+       repository and refspec. This can be used to push your
+       subtree to different branches of the remote repository.
 
 split::
        Extract a new, synthetic project history from the
 
 split::
        Extract a new, synthetic project history from the
diff --git a/install.sh b/install.sh
new file mode 100644 (file)
index 0000000..1f87a62
--- /dev/null
@@ -0,0 +1,2 @@
+# copy Git to where the rest of the Git scripts are found.
+cp git-subtree.sh "$(git --exec-path)"/git-subtree
\ No newline at end of file