Skip to content

Commit

Permalink
Added new 'push' command and 2-parameter form of 'add'.
Browse files Browse the repository at this point in the history
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.)
  • Loading branch information
Wayne Walter authored and apenwarr committed Feb 13, 2010
1 parent ae33018 commit c00d1d1
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 18 deletions.
11 changes: 10 additions & 1 deletion INSTALL
Expand Up @@ -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.
Expand Down
58 changes: 49 additions & 9 deletions git-subtree.sh
Expand Up @@ -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
Expand All @@ -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 $?)
Expand Down Expand Up @@ -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


Expand All @@ -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
Expand Down Expand Up @@ -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
} }
Expand All @@ -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'..."
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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" "$@"
Expand Down
24 changes: 16 additions & 8 deletions git-subtree.txt
Expand Up @@ -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
Expand Down Expand Up @@ -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>

This comment has been minimized.

Copy link
@Vanuan

Vanuan Aug 12, 2010

Contributor

Not all of "<commit>" replaced with "<refspec>" in documentation

Expand All @@ -84,6 +86,12 @@ pull::
Exactly like 'merge', but parallels 'git pull' in that Exactly like 'merge', but parallels 'git pull' in that
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
Expand Down
2 changes: 2 additions & 0 deletions 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

0 comments on commit c00d1d1

Please sign in to comment.