@matheusbsbs / matheus-bagliano / commits / c00d1d1168
Fork 0

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.)

Wayne Walter committed Feb 13, 2010 at 14:32 UTC c00d1d11688dc02f066196ed18783effdb7767ab
4 files changed +77 -18
INSTALL
+10 -1
@@ -2,7 +2,16 @@
2 HOW TO INSTALL git-subtree
3 ==========================
4
5 -Copy the file 'git-subtree.sh' to /usr/local/bin/git-subtree.
5 +You simply need to copy the file 'git-subtree.sh' to where
6 +the rest of the git scripts are stored.
7 +
8 +From the Git bash window just run:
9 +
10 +install.sh
11 +
12 +Or if you have the full Cygwin installed, you can use make:
13 +
14 +make install
15
16 That will make a 'git subtree' (note: space instead of dash) command
17 available. See the file git-subtree.txt for more.
git-subtree.sh
+49 -9
@@ -11,6 +11,7 @@ OPTS_SPEC="\
11 git subtree add --prefix=<prefix> <commit>
12 git subtree merge --prefix=<prefix> <commit>
13 git subtree pull --prefix=<prefix> <repository> <refspec...>
14 +git subtree push --prefix=<prefix> <repository> <refspec...>
15 git subtree split --prefix=<prefix> <commit...>
16 --
17 h,help show the help
@@ -24,7 +25,7 @@ b,branch= create a new branch from the split subtree
25 ignore-joins ignore prior --rejoin commits
26 onto= try connecting new tree to an existing one
27 rejoin merge the new branch back into HEAD
27 - options for 'add', 'merge', and 'pull'
28 + options for 'add', 'merge', 'pull' and 'push'
29 squash merge subtree changes as a single commit
30 "
31 eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)
@@ -98,7 +99,7 @@ command="$1"
99 shift
100 case "$command" in
101 add|merge|pull) default= ;;
101 - split) default="--default HEAD" ;;
102 + split|push) default="--default HEAD" ;;
103 *) die "Unknown command '$command'" ;;
104 esac
105
@@ -115,7 +116,7 @@ esac
116
117 dir="$(dirname "$prefix/.")"
118
118 -if [ "$command" != "pull" ]; then
119 +if [ "$command" != "pull" -a "$command" != "add" -a "$command" != "push" ]; then
120 revs=$(git rev-parse $default --revs-only "$@") || exit $?
121 dirs="$(git rev-parse --no-revs --no-flags "$@")" || exit $?
122 if [ -n "$dirs" ]; then
@@ -450,10 +451,10 @@ copy_or_skip()
451
452 ensure_clean()
453 {
453 - if ! git diff-index HEAD --exit-code --quiet; then
454 + if ! git diff-index HEAD --exit-code --quiet 2>&1; then
455 die "Working tree has modifications. Cannot add."
456 fi
456 - if ! git diff-index --cached HEAD --exit-code --quiet; then
457 + if ! git diff-index --cached HEAD --exit-code --quiet 2>&1; then
458 die "Index has modifications. Cannot add."
459 fi
460 }
@@ -463,12 +464,34 @@ cmd_add()
464 if [ -e "$dir" ]; then
465 die "'$dir' already exists. Cannot add."
466 fi
467 +
468 ensure_clean
469
468 - set -- $revs
469 - if [ $# -ne 1 ]; then
470 - die "You must provide exactly one revision. Got: '$revs'"
470 + if [ $# -eq 1 ]; then
471 + "cmd_add_commit" "$@"
472 + elif [ $# -eq 2 ]; then
473 + "cmd_add_repository" "$@"
474 + else
475 + say "error: parameters were '$@'"
476 + die "Provide either a refspec or a repository and refspec."
477 fi
478 +}
479 +
480 +cmd_add_repository()
481 +{
482 + echo "git fetch" "$@"
483 + repository=$1
484 + refspec=$2
485 + git fetch "$@" || exit $?
486 + revs=FETCH_HEAD
487 + set -- $revs
488 + cmd_add_commit "$@"
489 +}
490 +
491 +cmd_add_commit()
492 +{
493 + revs=$(git rev-parse $default --revs-only "$@") || exit $?
494 + set -- $revs
495 rev="$1"
496
497 debug "Adding $dir as '$rev'..."
@@ -586,6 +609,7 @@ cmd_split()
609
610 cmd_merge()
611 {
612 + revs=$(git rev-parse $default --revs-only "$@") || exit $?
613 ensure_clean
614
615 set -- $revs
@@ -623,7 +647,23 @@ cmd_pull()
647 ensure_clean
648 git fetch "$@" || exit $?
649 revs=FETCH_HEAD
626 - cmd_merge
650 + set -- $revs
651 + cmd_merge "$@"
652 +}
653 +
654 +cmd_push()
655 +{
656 + if [ $# -ne 2 ]; then
657 + die "You must provide <repository> <refspec>"
658 + fi
659 + if [ -e "$dir" ]; then
660 + repository=$1
661 + refspec=$2
662 + echo "git push using: " $repository $refspec
663 + git push $repository $(git subtree split --prefix=$prefix):refs/heads/$refspec
664 + else
665 + die "'$dir' must already exist. Try 'git subtree add'."
666 + fi
667 }
668
669 "cmd_$command" "$@"
git-subtree.txt
+16 -8
@@ -9,10 +9,12 @@ git-subtree - add, merge, and split subprojects stored in subtrees
9 SYNOPSIS
10 --------
11 [verse]
12 -'git subtree' add --prefix=<prefix> <commit>
13 -'git subtree' merge --prefix=<prefix> <commit>
12 +'git subtree' add --prefix=<prefix> <repository> <refspec...>
13 'git subtree' pull --prefix=<prefix> <repository> <refspec...>
15 -'git subtree' split --prefix=<prefix> <commit...>
14 +'git subtree' push --prefix=<prefix> <repository> <refspec...>
15 +'git subtree' add --prefix=<prefix> <refspec>
16 +'git subtree' merge --prefix=<prefix> <refspec>
17 +'git subtree' split --prefix=<prefix> <refspec...>
18
19
20 DESCRIPTION
@@ -60,11 +62,11 @@ COMMANDS
62 --------
63 add::
64 Create the <prefix> subtree by importing its contents
63 - from the given commit. A new commit is created
64 - automatically, joining the imported project's history
65 - with your own. With '--squash', imports only a single
66 - commit from the subproject, rather than its entire
67 - history.
65 + from the given <refspec> or <repository> and remote <refspec>.
66 + A new commit is created automatically, joining the imported
67 + project's history with your own. With '--squash', imports
68 + only a single commit from the subproject, rather than its
69 + entire history.
70
71 merge::
72 Merge recent changes up to <commit> into the <prefix>
@@ -84,6 +86,12 @@ pull::
86 Exactly like 'merge', but parallels 'git pull' in that
87 it fetches the given commit from the specified remote
88 repository.
89 +
90 +push::
91 + Does a 'split' (see above) using the <prefix> supplied
92 + and then does a 'git push' to push the result to the
93 + repository and refspec. This can be used to push your
94 + subtree to different branches of the remote repository.
95
96 split::
97 Extract a new, synthetic project history from the
install.sh new
+2
@@ -0,0 +1,2 @@
1 +# copy Git to where the rest of the Git scripts are found.
2 +cp git-subtree.sh "$(git --exec-path)"/git-subtree
\ No newline at end of file