>From 2763be1fe68d07af60945762178b8494228eb45f Mon Sep 17 00:00:00 2001 From: Pierre Penninckx <ibizapeanut@xxxxxxxxx> Date: Sat, 23 Nov 2013 20:03:20 +0100 Subject: [PATCH] subtree: add squash handling for split and push The documentation of subtree says that the --squash option can be used for add, merge, split and push subtree commands but only add and merge is implemented. cmd_push() simply forwards the --squash argument to subtree split. All the job is done by cmd_split(). cmd_split() first lets split do it's job: finding which commits need to be extracted. Now we remember which commit is the parent of the first extracted commit. When this step is done, cmd_split() generates a squash of the new commits, starting from the aforementioned parent to the last extracted commit. This new commit's sha1 is then used for the rest of the script. Tests verify that `git subtree split/push --squash` makes only one commit where `git subtree split/push` without squash makes two. --- contrib/subtree/git-subtree.sh | 20 ++++++++++++++++++- contrib/subtree/t/t7900-subtree.sh | 40 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index 7d7af03..76eb136 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -183,6 +183,7 @@ cache_set() newrev="$2" if [ "$oldrev" != "latest_old" \ -a "$oldrev" != "latest_new" \ + -a "$oldrev" != "firstnewparents" \ -a -e "$cachedir/$oldrev" ]; then die "cache for $oldrev already exists!" fi @@ -603,6 +604,10 @@ cmd_split() debug " parents: $parents" newparents=$(cache_get $parents) debug " newparents: $newparents" + if [ -z "$(cache_get firstnewparents)" ]; then + cache_set firstnewparents $newparents + debug " firstnewparents: $(cache_get firstnewparents)" + fi tree=$(subtree_for_commit $rev "$dir") debug " tree is: $tree" @@ -625,11 +630,18 @@ cmd_split() cache_set latest_new $newrev cache_set latest_old $rev done || exit $? + latest_new=$(cache_get latest_new) if [ -z "$latest_new" ]; then die "No new revisions were found" fi + if [ -n "$squash" ]; then + from=$(cache_get firstnewparents) + latest_new=$(new_squash_commit "$from" "$from" "$latest_new") || exit $? + debug "New squash commit: $latest_new" + fi + if [ -n "$rejoin" ]; then debug "Merging split branch into HEAD..." latest_old=$(cache_get latest_old) @@ -711,11 +723,17 @@ cmd_push() if [ $# -ne 2 ]; then die "You must provide <repository> <refspec>" fi + + squash_cmd= + if [ -n "$squash" ]; then + squash_cmd="--squash" + fi + if [ -e "$dir" ]; then repository=$1 refspec=$2 echo "git push using: " $repository $refspec - localrev=$(git subtree split --prefix="$prefix") || die + localrev=$(git subtree split --prefix="$prefix" $squash_cmd) || die git push $repository $localrev:refs/heads/$refspec else die "'$dir' must already exist. Try 'git subtree add'." diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 66ce4b0..04eea94 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -31,6 +31,16 @@ check_equal() fi } +check_not_equal() +{ + check_equal "$1" "$2" + if [ $? -eq 0 ]; then + return 1 + else + return 0 + fi +} + fixnl() { t="" @@ -161,6 +171,36 @@ test_expect_success 'fetch new subproj history' ' git branch sub2 FETCH_HEAD ' +test_expect_success 'check that split and split --squash produce different commits' ' + split=$(git subtree split --prefix=subdir) && + split_squash=$(git subtree split --prefix=subdir --squash) && + check_not_equal "$split" "$split_squash" +' + +test_expect_success 'check that split and split --squash produce same diff' ' + split=$(git subtree split --prefix=subdir) && + split_squash=$(git subtree split --prefix=subdir --squash) && + split_diff=$(git diff sub1 $split) && + split_squash_diff=$(git diff sub1 $split_squash) && + check_equal "$split_diff" "$split_squash_diff" +' + +test_expect_success 'check that push introduces two commits in subproj' ' + git subtree push --prefix=subdir subproj mainline && + cd subproj && + check_equal "$(git rev-parse mainline~2)" "$(git rev-parse sub1)" && + git branch -D mainline && + cd .. +' + +test_expect_success 'check that push --squash introduces only one commit in subproj' ' + git subtree push --prefix=subdir subproj mainline --squash && + cd subproj && + check_equal "$(git rev-parse mainline^)" "$(git rev-parse sub1)" && + git branch -D mainline && + cd .. +' + test_expect_success 'check if --message works for merge' ' git subtree merge --prefix=subdir -m "Merged changes from subproject" sub2 && check_equal ''"$(last_commit_message)"'' "Merged changes from subproject" && -- 1.8.3.4 (Apple Git-47) Signed-off-by: Pierre Penninckx <ibizapeanut@xxxxxxxxx>-- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html