Code

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
 ==========================
 
-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.
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 push  --prefix=<prefix> <repository> <refspec...>
 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
- 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 $?)
@@ -98,7 +99,7 @@ command="$1"
 shift
 case "$command" in
        add|merge|pull) default= ;;
-       split) default="--default HEAD" ;;
+       split|push) default="--default HEAD" ;;
        *) die "Unknown command '$command'" ;;
 esac
 
@@ -115,7 +116,7 @@ esac
 
 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
@@ -450,10 +451,10 @@ copy_or_skip()
 
 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
-       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
 }
@@ -463,12 +464,34 @@ cmd_add()
        if [ -e "$dir" ]; then
                die "'$dir' already exists.  Cannot add."
        fi
+
        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
+}
+
+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'..."
@@ -586,6 +609,7 @@ cmd_split()
 
 cmd_merge()
 {
+       revs=$(git rev-parse $default --revs-only "$@") || exit $?
        ensure_clean
        
        set -- $revs
@@ -623,7 +647,23 @@ cmd_pull()
        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" "$@"
index c455f6912b7ea2ca50358ae6f1c078c4d25c24ef..4f715c640bc6b8f25df9c8306292eb354d16c481 100644 (file)
@@ -9,10 +9,12 @@ git-subtree - add, merge, and split subprojects stored in subtrees
 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' 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
@@ -60,11 +62,11 @@ COMMANDS
 --------
 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>
@@ -84,6 +86,12 @@ pull::
        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
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