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