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.)
This commit is contained in:
Wayne Walter 2010-02-13 14:32:21 -05:00 committed by Avery Pennarun
parent ae3301876c
commit c00d1d1168
4 changed files with 77 additions and 18 deletions

11
INSTALL
View File

@ -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 That will make a 'git subtree' (note: space instead of dash) command
available. See the file git-subtree.txt for more. available. See the file git-subtree.txt for more.

View File

@ -11,6 +11,7 @@ OPTS_SPEC="\
git subtree add --prefix=<prefix> <commit> git subtree add --prefix=<prefix> <commit>
git subtree merge --prefix=<prefix> <commit> git subtree merge --prefix=<prefix> <commit>
git subtree pull --prefix=<prefix> <repository> <refspec...> git subtree pull --prefix=<prefix> <repository> <refspec...>
git subtree push --prefix=<prefix> <repository> <refspec...>
git subtree split --prefix=<prefix> <commit...> git subtree split --prefix=<prefix> <commit...>
-- --
h,help show the help 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 ignore-joins ignore prior --rejoin commits
onto= try connecting new tree to an existing one onto= try connecting new tree to an existing one
rejoin merge the new branch back into HEAD 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 squash merge subtree changes as a single commit
" "
eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?) eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)
@ -98,7 +99,7 @@ command="$1"
shift shift
case "$command" in case "$command" in
add|merge|pull) default= ;; add|merge|pull) default= ;;
split) default="--default HEAD" ;; split|push) default="--default HEAD" ;;
*) die "Unknown command '$command'" ;; *) die "Unknown command '$command'" ;;
esac 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 $? revs=$(git rev-parse $default --revs-only "$@") || exit $?
dirs="$(git rev-parse --no-revs --no-flags "$@")" || exit $? dirs="$(git rev-parse --no-revs --no-flags "$@")" || exit $?
if [ -n "$dirs" ]; then 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." die "Working tree has modifications. Cannot add."
fi 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." die "Index has modifications. Cannot add."
fi fi
} }
@ -463,12 +464,34 @@ cmd_add()
if [ -e "$dir" ]; then if [ -e "$dir" ]; then
die "'$dir' already exists. Cannot add." die "'$dir' already exists. Cannot add."
fi fi
ensure_clean ensure_clean
set -- $revs if [ $# -eq 1 ]; then
if [ $# -ne 1 ]; then "cmd_add_commit" "$@"
die "You must provide exactly one revision. Got: '$revs'" 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" rev="$1"
debug "Adding $dir as '$rev'..." 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 ensure_clean
set -- $revs set -- $revs
@ -623,7 +647,23 @@ cmd_pull()
ensure_clean ensure_clean
git fetch "$@" || exit $? git fetch "$@" || exit $?
revs=FETCH_HEAD 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" "$@"

View File

@ -9,10 +9,12 @@ git-subtree - add, merge, and split subprojects stored in subtrees
SYNOPSIS SYNOPSIS
-------- --------
[verse] [verse]
'git subtree' add --prefix=<prefix> <commit> 'git subtree' add --prefix=<prefix> <repository> <refspec...>
'git subtree' merge --prefix=<prefix> <commit>
'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:: add::
Create the <prefix> subtree by importing its contents Create the <prefix> subtree by importing its contents
from the given commit. A new commit is created from the given <refspec> or <repository> and remote <refspec>.
automatically, joining the imported project's history A new commit is created automatically, joining the imported
with your own. With '--squash', imports only a single project's history with your own. With '--squash', imports
commit from the subproject, rather than its entire only a single commit from the subproject, rather than its
history. entire history.
merge:: merge::
Merge recent changes up to <commit> into the <prefix> Merge recent changes up to <commit> into the <prefix>
@ -85,6 +87,12 @@ pull::
it fetches the given commit from the specified remote it fetches the given commit from the specified remote
repository. 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:: split::
Extract a new, synthetic project history from the Extract a new, synthetic project history from the
history of the <prefix> subtree. The new history history of the <prefix> subtree. The new history

2
install.sh Normal file
View File

@ -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