From c00d1d11688dc02f066196ed18783effdb7767ab Mon Sep 17 00:00:00 2001 From: Wayne Walter Date: Sat, 13 Feb 2010 14:32:21 -0500 Subject: [PATCH] Added new 'push' command and 2-parameter form of 'add'. 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 | 11 +++++++++- git-subtree.sh | 58 +++++++++++++++++++++++++++++++++++++++++-------- git-subtree.txt | 24 +++++++++++++------- install.sh | 2 ++ 4 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 install.sh diff --git a/INSTALL b/INSTALL index 5966dde46..81ac702ad 100644 --- 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. diff --git a/git-subtree.sh b/git-subtree.sh index e76b45c2d..501c6dc2f 100755 --- a/git-subtree.sh +++ b/git-subtree.sh @@ -11,6 +11,7 @@ OPTS_SPEC="\ git subtree add --prefix= git subtree merge --prefix= git subtree pull --prefix= +git subtree push --prefix= git subtree split --prefix= -- 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 " + 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" "$@" diff --git a/git-subtree.txt b/git-subtree.txt index c455f6912..4f715c640 100644 --- a/git-subtree.txt +++ b/git-subtree.txt @@ -9,10 +9,12 @@ git-subtree - add, merge, and split subprojects stored in subtrees SYNOPSIS -------- [verse] -'git subtree' add --prefix= -'git subtree' merge --prefix= +'git subtree' add --prefix= 'git subtree' pull --prefix= -'git subtree' split --prefix= +'git subtree' push --prefix= +'git subtree' add --prefix= +'git subtree' merge --prefix= +'git subtree' split --prefix= DESCRIPTION @@ -60,11 +62,11 @@ COMMANDS -------- add:: Create the 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 or and remote . + 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 into the @@ -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 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 index 000000000..1f87a6243 --- /dev/null +++ b/install.sh @@ -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 -- 2.26.2