Okay, that was a little too aggressive.
Now we only prune out a commit if it has exactly one remaining parent and that parent's tree is identical to ours. But I also changed the test to create the initial "-s ours" merge in one step instead of two, and that merge can be eliminated since one of its parents doesn't affect the subdir at all, and is thus deleted.
Avery Pennarun committed
Apr 24, 2009 at 22:36 UTC
96db2c0448c2f6040c098d73570a96413338c662
2 files changed
+36
-15
git-subtree.sh
+32
-14
@@ -4,17 +4,21 @@
4
#
5
# Copyright (C) 2009 Avery Pennarun <apenwarr@gmail.com>
6
#
7
+if [ $# -eq 0 ]; then
8
+ set -- -h
9
+fi
10
OPTS_SPEC="\
8
-git subtree split [--rejoin] [--onto rev] <commit...> -- <path>
11
+git subtree split [options...] <commit...> -- <path>
12
git subtree merge
13
14
git subtree does foo and bar!
15
--
13
-h,help show the help
14
-q quiet
15
-v verbose
16
-onto= existing subtree revision to search for parent
17
-rejoin merge the new branch back into HEAD
16
+h,help show the help
17
+q quiet
18
+v verbose
19
+onto= try connecting new tree to an existing one
20
+rejoin merge the new branch back into HEAD
21
+ignore-joins ignore prior --rejoin commits
22
"
23
eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)
24
. git-sh-setup
@@ -24,6 +28,7 @@ quiet=
28
command=
29
onto=
30
rejoin=
31
+ignore_joins=
32
33
debug()
34
{
@@ -50,7 +55,11 @@ while [ $# -gt 0 ]; do
55
case "$opt" in
56
-q) quiet=1 ;;
57
--onto) onto="$1"; shift ;;
58
+ --no-onto) onto= ;;
59
--rejoin) rejoin=1 ;;
60
+ --no-rejoin) rejoin= ;;
61
+ --ignore-joins) ignore_joins=1 ;;
62
+ --no-ignore-joins) ignore_joins= ;;
63
--) break ;;
64
esac
65
done
@@ -209,20 +218,25 @@ copy_or_skip()
218
newparents="$3"
219
assert [ -n "$tree" ]
220
212
- p=""
221
+ identical=
222
+ p=
223
for parent in $newparents; do
224
ptree=$(toptree_for_commit $parent) || exit $?
225
if [ "$ptree" = "$tree" ]; then
216
- # any identical parent means this commit is unnecessary
217
- echo $parent
218
- return 0
219
- elif [ -n "$ptree" ]; then
220
- # an existing, non-identical parent is important
226
+ # an identical parent could be used in place of this rev.
227
+ identical="$parent"
228
+ fi
229
+ if [ -n "$ptree" ]; then
230
+ parentmatch="$parentmatch$parent"
231
p="$p -p $parent"
232
fi
233
done
234
225
- copy_commit $rev $tree "$p" || exit $?
235
+ if [ -n "$identical" -a "$parentmatch" = "$identical" ]; then
236
+ echo $identical
237
+ else
238
+ copy_commit $rev $tree "$p" || exit $?
239
+ fi
240
}
241
242
cmd_split()
@@ -241,7 +255,11 @@ cmd_split()
255
done
256
fi
257
244
- unrevs="$(find_existing_splits "$dir" "$revs")"
258
+ if [ -n "$ignore_joins" ]; then
259
+ unrevs=
260
+ else
261
+ unrevs="$(find_existing_splits "$dir" "$revs")"
262
+ fi
263
264
debug "git rev-list --reverse $revs $unrevs"
265
git rev-list --reverse --parents $revs $unrevsx |
test.sh
+4
-1
@@ -35,7 +35,10 @@ git fetch ../subproj sub1
35
git branch sub1 FETCH_HEAD
36
git read-tree --prefix=subdir FETCH_HEAD
37
git checkout subdir
38
-git commit -m 'initial-subdir-merge'
38
+tree=$(git write-tree)
39
+com=$(echo initial-subdir-merge | git commit-tree $tree -p HEAD -p FETCH_HEAD)
40
+git reset $com
41
+#git commit -m 'initial-subdir-merge'
42
43
git merge -m 'merge -s -ours' -s ours FETCH_HEAD
44