From 96db2c0448c2f6040c098d73570a96413338c662 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Fri, 24 Apr 2009 22:36:06 -0400 Subject: [PATCH] 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. --- git-subtree.sh | 46 ++++++++++++++++++++++++++++++++-------------- test.sh | 5 ++++- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/git-subtree.sh b/git-subtree.sh index 03107e2251..d42cc1a164 100755 --- a/git-subtree.sh +++ b/git-subtree.sh @@ -4,17 +4,21 @@ # # Copyright (C) 2009 Avery Pennarun # +if [ $# -eq 0 ]; then + set -- -h +fi OPTS_SPEC="\ -git subtree split [--rejoin] [--onto rev] -- +git subtree split [options...] -- git subtree merge git subtree does foo and bar! -- -h,help show the help -q quiet -v verbose -onto= existing subtree revision to search for parent -rejoin merge the new branch back into HEAD +h,help show the help +q quiet +v verbose +onto= try connecting new tree to an existing one +rejoin merge the new branch back into HEAD +ignore-joins ignore prior --rejoin commits " eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?) . git-sh-setup @@ -24,6 +28,7 @@ quiet= command= onto= rejoin= +ignore_joins= debug() { @@ -50,7 +55,11 @@ while [ $# -gt 0 ]; do case "$opt" in -q) quiet=1 ;; --onto) onto="$1"; shift ;; + --no-onto) onto= ;; --rejoin) rejoin=1 ;; + --no-rejoin) rejoin= ;; + --ignore-joins) ignore_joins=1 ;; + --no-ignore-joins) ignore_joins= ;; --) break ;; esac done @@ -209,20 +218,25 @@ copy_or_skip() newparents="$3" assert [ -n "$tree" ] - p="" + identical= + p= for parent in $newparents; do ptree=$(toptree_for_commit $parent) || exit $? if [ "$ptree" = "$tree" ]; then - # any identical parent means this commit is unnecessary - echo $parent - return 0 - elif [ -n "$ptree" ]; then - # an existing, non-identical parent is important + # an identical parent could be used in place of this rev. + identical="$parent" + fi + if [ -n "$ptree" ]; then + parentmatch="$parentmatch$parent" p="$p -p $parent" fi done - copy_commit $rev $tree "$p" || exit $? + if [ -n "$identical" -a "$parentmatch" = "$identical" ]; then + echo $identical + else + copy_commit $rev $tree "$p" || exit $? + fi } cmd_split() @@ -241,7 +255,11 @@ cmd_split() done fi - unrevs="$(find_existing_splits "$dir" "$revs")" + if [ -n "$ignore_joins" ]; then + unrevs= + else + unrevs="$(find_existing_splits "$dir" "$revs")" + fi debug "git rev-list --reverse $revs $unrevs" git rev-list --reverse --parents $revs $unrevsx | diff --git a/test.sh b/test.sh index a8ed0dbc7d..39c4382f0d 100755 --- a/test.sh +++ b/test.sh @@ -35,7 +35,10 @@ git fetch ../subproj sub1 git branch sub1 FETCH_HEAD git read-tree --prefix=subdir FETCH_HEAD git checkout subdir -git commit -m 'initial-subdir-merge' +tree=$(git write-tree) +com=$(echo initial-subdir-merge | git commit-tree $tree -p HEAD -p FETCH_HEAD) +git reset $com +#git commit -m 'initial-subdir-merge' git merge -m 'merge -s -ours' -s ours FETCH_HEAD -- 2.43.2