[PATCH v6 1/1] contrib/subtree: Add a test for subtree rebase that loses commits
From: David A. Greene This test merges an external tree in as a subtree, makes some commits on top of it and splits it back out. In the process the added commits are lost or the rebase aborts with an internal error. The tests are marked to expect failure so that we don't forget to fix it. Signed-off-by: David A. Greene --- Notes: Change History: v1 - Initial version v2 - Additional tests and code cleanup v3 - Remove check_equal, mark comments on failure and remove test_debug statements v4 - Send correct v3 test (botched v3) v5 - Fix use of verbose v6 - Add individual tests for each potentially dropped commit t/t3427-rebase-subtree.sh | 119 ++ 1 file changed, 119 insertions(+) diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh new file mode 100755 index 000..3780877 --- /dev/null +++ b/t/t3427-rebase-subtree.sh @@ -0,0 +1,119 @@ +#!/bin/sh + +test_description='git rebase tests for -Xsubtree + +This test runs git rebase and tests the subtree strategy. +' +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-rebase.sh + +commit_message() { + git log --pretty=format:%s -1 "$1" +} + +test_expect_success 'setup' ' + test_commit README && + mkdir files && + ( + cd files && + git init && + test_commit master1 && + test_commit master2 && + test_commit master3 + ) && + git fetch files master && + git branch files-master FETCH_HEAD && + git read-tree --prefix=files_subtree files-master && + git checkout -- files_subtree && + tree=$(git write-tree) && + head=$(git rev-parse HEAD) && + rev=$(git rev-parse --verify files-master^0) && + commit=$(git commit-tree -p $head -p $rev -m "Add subproject master" $tree) && + git update-ref HEAD $commit && + ( + cd files_subtree && + test_commit master4 + ) && + test_commit files_subtree/master5 +' + +# FAILURE: Does not preserve master4. +test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 4' ' + reset_rebase && + git checkout -b rebase-preserve-merges-4 master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master && + verbose test "$(commit_message HEAD~)" = "files_subtree/master4" +' + +# FAILURE: Does not preserve master5. +test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 5' ' + reset_rebase && + git checkout -b rebase-preserve-merges-5 master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master && + verbose test "$(commit_message HEAD)" = "files_subtree/master5" +' + +# FAILURE: Does not preserve master4. +test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' ' + reset_rebase && + git checkout -b rebase-keep-empty-4 master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master && + verbose test "$(commit_message HEAD~2)" = "files_subtree/master4" +' + +# FAILURE: Does not preserve master5. +test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' ' + reset_rebase && + git checkout -b rebase-keep-empty-5 master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master && + verbose test "$(commit_message HEAD~)" = "files_subtree/master5" +' + +# FAILURE: Does not preserve Empty. +test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' ' + reset_rebase && + git checkout -b rebase-keep-empty-empty master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master && + verbose test "$(commit_message HEAD)" = "Empty commit" +' + +# FAILURE: fatal: Could not parse object +test_expect_failure 'Rebase -Xsubtree --onto commit 4' ' + reset_rebase && + git checkout -b rebase-onto-4 master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtre
Re: Detecting redundant commits
On January 4, 2016 10:00:26 PM CST, Jeff King wrote: >Or do you mean commits that, when applied, we find turn out to have >empty changes (e.g., because we have a set of commits that have >different patch-ids, but do roughly the same thing)? I don't think you >can find that with a straight end-to-end diff. You have try to apply >and >then look at the result. I think we already catch that case (see >--allow-empty), though I think the only options are "preserve" or >"abort", not "silently skip" (and it sounds like the latter is what you >would want). This. I see where --allow-empty is handled in prepare_to_commit but it is not so easy to skip the commit at that point due to state changes. I was trying to avoid going into commit at all by determining ahead of time whether the commit would become empty. Any ideas? David -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Test rebase -Xsubtree
Here is a test that finds a bug in rebase -Xsubtree. With --preserve-merges, commits are lost. -David -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Add a test for subtree rebase that loses commits
From: "David A. Greene" This test merges an external tree in as a subtree, makes some commits on top of it and splits it back out. In the process the added commits are lost. This is marked to expect failure so that we don't forget to fix it. Signed-off-by: David A. Greene --- t/t3427-rebase-subtree.sh | 68 +++ 1 file changed, 68 insertions(+) create mode 100755 t/t3427-rebase-subtree.sh diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh new file mode 100755 index 000..7eb28ab --- /dev/null +++ b/t/t3427-rebase-subtree.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +test_description='git rebase tests for -Xsubtree + +This test runs git rebase and tests the subtree strategy. +' +. ./test-lib.sh + +addfile() { +name=$1 +echo $(basename ${name}) > ${name} +${git} add ${name} +${git} commit -m "Add $(basename ${name})" +} + +check_equal() +{ + test_debug 'echo' + test_debug "echo \"check a:\" \"{$1}\"" + test_debug "echo \" b:\" \"{$2}\"" + if [ "$1" = "$2" ]; then + return 0 + else + return 1 + fi +} + +last_commit_message() +{ + git log --pretty=format:%s -1 +} + +test_expect_success 'setup' ' + test_commit README && + mkdir files && + cd files && + git init && + test_commit master1 && + test_commit master2 && + test_commit master3 && + cd .. && + test_debug "echo Add project master to master" && + git fetch files master && + git branch files-master FETCH_HEAD && + test_debug "echo Add subtree master to master via subtree" && + git read-tree --prefix=files_subtree files-master && + git checkout -- files_subtree && + tree=$(git write-tree) && + head=$(git rev-parse HEAD) && + rev=$(git rev-parse --verify files-master^0) && + commit=$(git commit-tree -p ${head} -p ${rev} -m "Add subproject master" ${tree}) && + git reset ${commit} && + cd files_subtree && + test_commit master4 && + cd .. && + test_commit files_subtree/master5 +' + +# Does not preserve master4 and master5. +test_expect_failure 'Rebase default' ' + git checkout -b rebase-default master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master && + check_equal "$(last_commit_message)" "files_subtree/master5" +' + +test_done -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] Remote subtree split --annotate
Here's a re-roll with the commit message change suggested by Sebastian. Please apply. Thanks! -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] contrib/subtree: Remove --annotate
From: "David A. Greene" Remove --annotate. This obviates the need for an --unannotate command, which is both an obvious addition and difficult to define due to the numerous ways one might want to specify how to edit commit messages. git has other tools more suited to rewriting commit messages and it's easy enough to use them after a subtree split. Such tools include filter-branch, rebase -i and commit --amend. Signed-off-by: David A. Greene --- contrib/subtree/git-subtree.sh | 6 + contrib/subtree/t/t7900-subtree.sh | 50 +++--- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index edf36f8..699c954 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -21,7 +21,6 @@ d show debug messages P,prefix= the name of the subdir to split out m,message=use the given message as the commit message for the merge commit options for 'split' -annotate= add a prefix to commit message of new commits b,branch= create a new branch from the split subtree ignore-joins ignore prior --rejoin commits onto= try connecting new tree to an existing one @@ -43,7 +42,6 @@ command= onto= rejoin= ignore_joins= -annotate= squash= message= prefix= @@ -87,8 +85,6 @@ while [ $# -gt 0 ]; do case "$opt" in -q) quiet=1 ;; -d) debug=1 ;; - --annotate) annotate="$1"; shift ;; - --no-annotate) annotate= ;; -b) branch="$1"; shift ;; -P) prefix="${1%/}"; shift ;; -m) message="$1"; shift ;; @@ -319,7 +315,7 @@ copy_commit() GIT_COMMITTER_NAME \ GIT_COMMITTER_EMAIL \ GIT_COMMITTER_DATE - (printf "%s" "$annotate"; cat ) | + (echo -n ""; cat ) | git commit-tree "$2" $3 # reads the rest of stdin ) || die "Can't copy commit $1" } diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 751aee3..521c401 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -340,8 +340,8 @@ test_expect_success 'split sub dir/ with --rejoin' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - split_hash=$(git subtree split --prefix="sub dir" --annotate="*") && - git subtree split --prefix="sub dir" --annotate="*" --rejoin && + split_hash=$(git subtree split --prefix="sub dir") && + git subtree split --prefix="sub dir" --rejoin && check_equal "$(last_commit_message)" "Split '\''sub dir/'\'' into commit '\''$split_hash'\''" ) ' @@ -365,7 +365,7 @@ test_expect_success 'split sub dir/ with --rejoin and --message' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - git subtree split --prefix="sub dir" --message="Split & rejoin" --annotate="*" --rejoin && + git subtree split --prefix="sub dir" --message="Split & rejoin" --rejoin && check_equal "$(last_commit_message)" "Split & rejoin" ) ' @@ -389,8 +389,8 @@ test_expect_success 'split "sub dir"/ with --branch' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - split_hash=$(git subtree split --prefix="sub dir" --annotate="*") && - git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br && + split_hash=$(git subtree split --prefix="sub dir") && + git subtree split --prefix="sub dir" --branch subproj-br && check_equal "$(git rev-parse subproj-br)" "$split_hash" ) ' @@ -414,8 +414,8 @@ test_expect_success 'check hash of split' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - split_hash=$(git subtree split --prefix="sub dir" --annotate="*") && - git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br && + split_hash=$(git subtree split --prefix="sub dir") && + git subtree split --prefix="sub dir" --branch subproj-br && check_equal "$(git rev-parse subproj-br)" "$split_hash" && # Check hash of split new_hash=$(git rev-parse subproj-br^2) && @@ -500,7 +500,7 @@ test_expect_success 'make sure exactly the right set of files ends up in the sub cd "$subtree_test_count" && git fetch ./"sub proj" mas
[PATCH] contrib/subtree: Remove --annotate
From: "David A. Greene" Remove --annotate. This obviates the need for an --unannotate command, which is both an obvious addition and difficult to define due to the numerous ways one might want to specify how to edit commit messages. git has other tools more suited to rewriting commit messages and it's easy enough to use them after a subtree split. Signed-off-by: David A. Greene --- contrib/subtree/git-subtree.sh | 6 + contrib/subtree/t/t7900-subtree.sh | 50 +++--- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index edf36f8..699c954 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -21,7 +21,6 @@ d show debug messages P,prefix= the name of the subdir to split out m,message=use the given message as the commit message for the merge commit options for 'split' -annotate= add a prefix to commit message of new commits b,branch= create a new branch from the split subtree ignore-joins ignore prior --rejoin commits onto= try connecting new tree to an existing one @@ -43,7 +42,6 @@ command= onto= rejoin= ignore_joins= -annotate= squash= message= prefix= @@ -87,8 +85,6 @@ while [ $# -gt 0 ]; do case "$opt" in -q) quiet=1 ;; -d) debug=1 ;; - --annotate) annotate="$1"; shift ;; - --no-annotate) annotate= ;; -b) branch="$1"; shift ;; -P) prefix="${1%/}"; shift ;; -m) message="$1"; shift ;; @@ -319,7 +315,7 @@ copy_commit() GIT_COMMITTER_NAME \ GIT_COMMITTER_EMAIL \ GIT_COMMITTER_DATE - (printf "%s" "$annotate"; cat ) | + (echo -n ""; cat ) | git commit-tree "$2" $3 # reads the rest of stdin ) || die "Can't copy commit $1" } diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 751aee3..521c401 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -340,8 +340,8 @@ test_expect_success 'split sub dir/ with --rejoin' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - split_hash=$(git subtree split --prefix="sub dir" --annotate="*") && - git subtree split --prefix="sub dir" --annotate="*" --rejoin && + split_hash=$(git subtree split --prefix="sub dir") && + git subtree split --prefix="sub dir" --rejoin && check_equal "$(last_commit_message)" "Split '\''sub dir/'\'' into commit '\''$split_hash'\''" ) ' @@ -365,7 +365,7 @@ test_expect_success 'split sub dir/ with --rejoin and --message' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - git subtree split --prefix="sub dir" --message="Split & rejoin" --annotate="*" --rejoin && + git subtree split --prefix="sub dir" --message="Split & rejoin" --rejoin && check_equal "$(last_commit_message)" "Split & rejoin" ) ' @@ -389,8 +389,8 @@ test_expect_success 'split "sub dir"/ with --branch' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - split_hash=$(git subtree split --prefix="sub dir" --annotate="*") && - git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br && + split_hash=$(git subtree split --prefix="sub dir") && + git subtree split --prefix="sub dir" --branch subproj-br && check_equal "$(git rev-parse subproj-br)" "$split_hash" ) ' @@ -414,8 +414,8 @@ test_expect_success 'check hash of split' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - split_hash=$(git subtree split --prefix="sub dir" --annotate="*") && - git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br && + split_hash=$(git subtree split --prefix="sub dir") && + git subtree split --prefix="sub dir" --branch subproj-br && check_equal "$(git rev-parse subproj-br)" "$split_hash" && # Check hash of split new_hash=$(git rev-parse subproj-br^2) && @@ -500,7 +500,7 @@ test_expect_success 'make sure exactly the right set of files ends up in the sub cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH
Remote subtree split --annotate
This is a fairly simple patch to remove subtree's split --annotate option. The intent of the option is to mark commits split from a subdirectory but git has other tools more suitable for editing commit messages. Given --annotate an --unannotate feature seems obvious and in fact was requested at one point. Discussion ensued and it became clear that the definition of --unannotate is not obvious given the multitude of ways one might want to rewrite a commit message. Since it is simple to run other git commit message rewriting tools on commits split from a subdirectory, it seems best to just get git-subtree out of the commit rewriting business altogether. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: (unknown)
Patrick Steinhardt writes: > On Tue, Dec 15, 2015 at 09:57:50PM -0800, Junio C Hamano wrote: >> David Greene writes: >> >> > - If new option --keep-redundant is specified, invoke cherry-pick with >> > --keep-redundant-commits. >> >> This came up in the past several weeks, I think; you would need to >> disable patch-equivalence based commit filtering if you really want >> to do a --keep-redundant that is reproducible and/or reliable. > > Here are the links to the previous proposal [1] and following > discussion [2] (see 'ps/rebase-keep-empty') if you are > interested. > > Patrick > > [1]: http://thread.gmane.org/gmane.comp.version-control.git/281515[2]: > http://thread.gmane.org/gmane.comp.version-control.git/281917 Thanks. That makes total sense. I actually would prefer a behavior where cherry-pick would just drop redundant commits rather than stopping and asking the user to reset. The problem is that rebase --preserve-merges seems to force the drop to use cherry-pick and cherry-pick doesn't behave well (from a scripting perspective) in the presence of redundant commits. As it is, it's difficult to rebase as part of a scripted operation due to this issue. Any ideas on how to teach cherry-pick to automatically drop such commits? -David -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Support rebase --keep-empty and --keep-redundant
From: "David A. Greene" Teach rebase how to invoke cherry-pick to keep empty commits. Add a new option --keep-redundant equivalent to cherry-pick's --keep-redundant-commits. With this option, rebase will preserve empty commits generated as a result of the merging process. Signed-off-by: David A. Greene --- git-rebase--interactive.sh | 11 +++- git-rebase.sh | 5 ++ t/t3427-rebase-empty.sh| 127 + 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100755 t/t3427-rebase-empty.sh diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index b938a6d..8466cb9 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -393,7 +393,16 @@ pick_one_preserving_merges () { echo "$sha1 $(git rev-parse HEAD^0)" >> "$rewritten_list" ;; *) - output eval git cherry-pick \ + cherry_keep_empty= + if test -n "$keep_empty"; then + cherry_keep_empty="--allow-empty" + fi + cherry_keep_redundant= + if test -n "$keep_redundant"; then + cherry_keep_redundant="--keep-redundant-commits" + fi + output eval git cherry-pick "$cherry_keep_empty" \ + "$cherry_keep_redundant" \ ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \ "$strategy_args" "$@" || die_with_patch $sha1 "Could not pick $sha1" diff --git a/git-rebase.sh b/git-rebase.sh index af7ba5f..1eae688 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -24,6 +24,7 @@ m,merge! use merging strategies to rebase i,interactive! let the user edit the list of commits to rebase x,exec=! add exec lines after each commit of the editable list k,keep-empty preserve empty commits during rebase +keep-redundant preserve redundant commits during rebase f,force-rebase!force rebase even if branch is up to date X,strategy-option=! pass the argument through to the merge strategy stat! display a diffstat of what changed upstream @@ -86,6 +87,7 @@ action= preserve_merges= autosquash= keep_empty= +keep_redundant= test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t gpg_sign_opt= @@ -255,6 +257,9 @@ do --keep-empty) keep_empty=yes ;; + --keep-redundant) + keep_redundant=yes + ;; --preserve-merges) preserve_merges=t test -z "$interactive_rebase" && interactive_rebase=implied diff --git a/t/t3427-rebase-empty.sh b/t/t3427-rebase-empty.sh new file mode 100755 index 000..9e67e00 --- /dev/null +++ b/t/t3427-rebase-empty.sh @@ -0,0 +1,127 @@ +#!/bin/sh + +test_description='git rebase tests for empty commits + +This test runs git rebase and tests handling of empty commits. +' +. ./test-lib.sh + +addfile() { +name=$1 +echo $(basename ${name}) > ${name} +${git} add ${name} +${git} commit -m "Add $(basename ${name})" +} + +check_equal() +{ + test_debug 'echo' + test_debug "echo \"check a:\" \"{$1}\"" + test_debug "echo \" b:\" \"{$2}\"" + if [ "$1" = "$2" ]; then + return 0 + else + return 1 + fi +} + +last_commit_message() +{ + git log --pretty=format:%s -1 +} + +test_expect_success 'setup' ' + test_commit README && + mkdir files && + cd files && + git init && + test_commit master1 && + test_commit master2 && + test_commit master3 && + cd .. && + test_debug "echo Add project master to master" && + git fetch files master && + git branch files-master FETCH_HEAD && + test_debug "echo Add subtree master to master via subtree" && + git read-tree --prefix=files_subtree files-master && + git checkout -- files_subtree && + tree=$(git write-tree) && + head=$(git rev-parse HEAD) && + rev=$(git rev-parse --verify files-master^0) && + commit=$(git commit-tree -p ${head} -p ${rev} -m "Add subproject master" ${tree}) && + git reset ${commit} && + cd files_subtree && + test_commit master4 && + cd .. && + test_commit files_subtree/master5 +' + +# Does not preserve master4 and master5. +#test_expect_success 'Rebase default' ' +# git checkout -b rebase-default master && +# git filter-branch --prune-empty -f --subdirectory-filter files_subtree && +# git commit -m "Empty commit" --allow-empty && +# git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master && +# check_equal "$(last_commit_message)" "files_subtree/master5"
[no subject]
This patch isn't ready for prime-time yet but I wanted to get it out for some discussion. While cleaning up and enhancing git-subtree, I've come across the need to have rebase behave nicely in the case of empty and redundant commits. There's a case in pick_one_preserving_merges where git-cherry pick is used to process the rebase and if cherry-pick fails, the rebase aborts. This change does two things: - If --keep-empty is specified, invoke cherry-pick with --allow-empty. - If new option --keep-redundant is specified, invoke cherry-pick with --keep-redundant-commits. This allows the rebase to go forward without intrruption in the included tests. I will also need a third option that has cherry-pick ignore redundant commits and remove them from the history. Unfortunately, I can't make out exactly how to do that in commit.c, which is where I gather the cherry-pick stuff happens. I'll need some help with that if there's general agreement that this is a useful enhancement. During the course of developing this, I've encountered some strange rebase behavior. I'll send another message about that. I'd appreciate feedback on this direction and any help with the cherry-pick stuff. Thanks! -David -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/7] contrib/subtree: Make each test self-contained
From: Techlive Zheng Each test runs a full repository creation and any subtree actions needed to perform the test. Each test starts with a clean slate, making debugging and post-mortem analysis much easier. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/t7900-subtree.sh | 1258 1 file changed, 840 insertions(+), 418 deletions(-) diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 6250194..2683d7d 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -14,6 +14,15 @@ export TEST_DIRECTORY . ../../../t/test-lib.sh +subtree_test_create_repo() +{ + test_create_repo "$1" + ( + cd $1 + git config log.date relative + ) +} + create() { echo "$1" >"$1" @@ -61,515 +70,928 @@ join_commits() echo "$commit $all" } +test_create_commit() ( + repo=$1 + commit=$2 + cd "$repo" + mkdir -p $(dirname "$commit") \ + || error "Could not create directory for commit" + echo "$commit" >"$commit" + git add "$commit" || error "Could not add commit" + git commit -m "$commit" || error "Could not commit" +) + last_commit_message() { git log --pretty=format:%s -1 } -test_expect_success 'init subproj' ' - test_create_repo "sub proj" -' - -# To the subproject! -cd ./"sub proj" - -test_expect_success 'add sub1' ' - create sub1 && - git commit -m "sub1" && - git branch sub1 && - git branch -m master subproj -' - -# Save this hash for testing later. - -subdir_hash=$(git rev-parse HEAD) - -test_expect_success 'add sub2' ' - create sub2 && - git commit -m "sub2" && - git branch sub2 -' - -test_expect_success 'add sub3' ' - create sub3 && - git commit -m "sub3" && - git branch sub3 -' - -# Back to mainline -cd .. - -test_expect_success 'enable log.date=relative to catch errors' ' - git config log.date relative -' - -test_expect_success 'add main4' ' - create main4 && - git commit -m "main4" && - git branch -m master mainline && - git branch subdir -' - -test_expect_success 'fetch subproj history' ' - git fetch ./"sub proj" sub1 && - git branch sub1 FETCH_HEAD -' - -test_expect_success 'no subtree exists in main tree' ' - test_must_fail git subtree merge --prefix="sub dir" sub1 -' +subtree_test_count=0 +next_test() { + subtree_test_count=$(($subtree_test_count+1)) +} -test_expect_success 'no pull from non-existant subtree' ' - test_must_fail git subtree pull --prefix="sub dir" ./"sub proj" sub1 -' +# +# Tests for 'git subtree add' +# +next_test test_expect_success 'no merge from non-existent subtree' ' - test_must_fail git subtree merge --prefix="sub dir" FETCH_HEAD + subtree_test_create_repo "$subtree_test_count" && + subtree_test_create_repo "$subtree_test_count/sub proj" && + test_create_commit "$subtree_test_count" main1 && + test_create_commit "$subtree_test_count/sub proj" sub1 && + ( + cd "$subtree_test_count" && + git fetch ./"sub proj" master && + test_must_fail git subtree merge --prefix="sub dir" FETCH_HEAD + ) ' -test_expect_success 'add subproj as subtree into sub dir/ with --prefix' ' - git subtree add --prefix="sub dir" sub1 && - check_equal "$(last_commit_message)" "Add '\''sub dir/'\'' from commit '\''$(git rev-parse sub1)'\''" && - undo -' +next_test +test_expect_success 'no pull from non-existent subtree' ' + subtree_test_create_repo "$subtree_test_count" && + subtree_test_create_repo "$subtree_test_count/sub proj" && + test_create_commit "$subtree_test_count" main1 && + test_create_commit "$subtree_test_count/sub proj" sub1 && + ( + cd "$subtree_test_count" && + git fetch ./"sub proj" master && + test_must_fail git subtree pull --prefix="sub dir" ./"sub proj" master + )' -test_expect_success 'check if --message works for add' ' - git subtree add --prefix="sub dir" --message="Added subproject" sub1 && - check_equal ''"$(last_commit_message)"'' "Added subproject" && - undo +next_test +test_expect_success 'add subproj as subtree into sub dir/ with --prefix' ' + subtree_test_create_repo "$subtree_test_count" && + subtree_test_create_repo "$subtree_test_count/sub proj" && + test_create_commit "$subtree_test_count" main1 && + test_create_commit "$subtree_test_count/sub proj" sub1 && + ( + cd "$subtree_test_count" && + git fetch ./"sub proj" master && + git subtree add --prefix="sub dir" FETCH_HEAD && + check_equal "$(last_commit_message)" "Add '\''sub dir/'\'' from commit '\''$(git rev-parse FETCH_HEAD)'\''" + ) ' +next_tes
[PATCH 7/7] contrib/subtree: Handle '--prefix' argument with a slash appended
From: Techlive Zheng 'git subtree merge' will fail if the argument of '--prefix' has a slash appended. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/git-subtree.sh | 2 +- contrib/subtree/t/t7900-subtree.sh | 20 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index 308b777..edf36f8 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -90,7 +90,7 @@ while [ $# -gt 0 ]; do --annotate) annotate="$1"; shift ;; --no-annotate) annotate= ;; -b) branch="$1"; shift ;; - -P) prefix="$1"; shift ;; + -P) prefix="${1%/}"; shift ;; -m) message="$1"; shift ;; --no-prefix) prefix= ;; --onto) onto="$1"; shift ;; diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 2683d7d..751aee3 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -257,6 +257,26 @@ test_expect_success 'merge the added subproj again, should do nothing' ' ) ' +next_test +test_expect_success 'merge new subproj history into subdir/ with a slash appended to the argument of --prefix' ' + test_create_repo "$test_count" && + test_create_repo "$test_count/subproj" && + test_create_commit "$test_count" main1 && + test_create_commit "$test_count/subproj" sub1 && + ( + cd "$test_count" && + git fetch ./subproj master && + git subtree add --prefix=subdir/ FETCH_HEAD + ) && + test_create_commit "$test_count/subproj" sub2 && + ( + cd "$test_count" && + git fetch ./subproj master && + git subtree merge --prefix=subdir/ FETCH_HEAD && + check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''" + ) +' + # # Tests for 'git subtree split' # -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/7] contrib/subtree: Testsuite cleanup
Sending again with a proper From: address after rebasing on latest master. Copying the maintainers because the origin patchset didn't get any comments and I'm unsure of how to proceed. These are some old changes I have lying around that should get applied to clean up git-subtree's testbase. With these changes post-mortem analysis is much easier and adding new tests can be done in an orderly fashion. I have a number of future patches and further development ideas for git-subtree that require these changes as a prerequisite. -David contrib/subtree/git-subtree.sh |2 +- contrib/subtree/t/Makefile | 31 +- contrib/subtree/t/t7900-subtree.sh | 1366 +-- 3 files changed, 956 insertions(+), 443 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/7] contrib/subtree: Add split tests
From: Techlive Zheng Add tests to check various options to split. Check combinations of --prefix, --message, --annotate, --branch and --rejoin. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/t7900-subtree.sh | 17 +++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 7d59a1a..6250194 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -250,7 +250,6 @@ test_expect_success 'split requires path given by option --prefix must exist' ' test_expect_success 'check if --message works for split+rejoin' ' spl1=''"$(git subtree split --annotate='"'*'"' --prefix "sub dir" --onto FETCH_HEAD --message "Split & rejoin" --rejoin)"'' && - git branch spl1 "$spl1" && check_equal ''"$(last_commit_message)"'' "Split & rejoin" && undo ' @@ -282,7 +281,21 @@ test_expect_success 'check split with --branch for an incompatible branch' ' test_must_fail git subtree split --prefix "sub dir" --onto FETCH_HEAD --branch subdir ' -test_expect_success 'check split+rejoin' ' +test_expect_success 'split sub dir/ with --rejoin' ' + spl1=$(git subtree split --prefix="sub dir" --annotate="*") && + git branch spl1 "$spl1" && + git subtree split --prefix="sub dir" --annotate="*" --rejoin && + check_equal "$(last_commit_message)" "Split '\''sub dir/'\'' into commit '\''$spl1'\''" && + undo +' + +test_expect_success 'split sub dir/ with --rejoin and --message' ' + git subtree split --prefix="sub dir" --message="Split & rejoin" --annotate="*" --rejoin && + check_equal "$(last_commit_message)" "Split & rejoin" && + undo +' + +test_expect_success 'check split+rejoin+onto' ' spl1=''"$(git subtree split --annotate='"'*'"' --prefix "sub dir" --onto FETCH_HEAD --message "Split & rejoin" --rejoin)"'' && undo && git subtree split --annotate='"'*'"' --prefix "sub dir" --onto FETCH_HEAD --rejoin && -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/7] contrib/subtree: Add merge tests
From: Techlive Zheng Add some tests for various merge operations. Test combinations of merge with --message, --prefix and --squash. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/t7900-subtree.sh | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 1fa5991..7d59a1a 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -210,11 +210,22 @@ test_expect_success 'check if --message for merge works with squash too' ' test_expect_success 'merge new subproj history into subdir' ' git subtree merge --prefix="sub dir" FETCH_HEAD && - git branch pre-split && check_equal ''"$(last_commit_message)"'' "Merge commit '"'"'"$(git rev-parse sub2)"'"'"' into mainline" && undo ' +test_expect_success 'merge new subproj history into subdir/ with --prefix and --message' ' + git subtree merge --prefix="sub dir" --message="Merged changes from subproject" FETCH_HEAD && + check_equal "$(last_commit_message)" "Merged changes from subproject" && + undo +' + +test_expect_success 'merge new subproj history into subdir/ with --squash and --prefix and --message' ' + git subtree merge --prefix="sub dir" --message="Merged changes from subproject using squash" --squash FETCH_HEAD && + check_equal "$(last_commit_message)" "Merged changes from subproject using squash" && + undo +' + test_expect_success 'split requires option --prefix' ' echo "You must provide the --prefix option." > expected && test_must_fail git subtree split > actual 2>&1 && -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/7] contrib/subtree: Add tests for subtree add
From: Techlive Zheng Add some tests to check various options to subtree add. These test various combinations of --message, --prefix and --squash. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/t7900-subtree.sh | 19 +++ 1 file changed, 19 insertions(+) diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 4471786..1fa5991 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -127,12 +127,24 @@ test_expect_success 'no merge from non-existent subtree' ' test_must_fail git subtree merge --prefix="sub dir" FETCH_HEAD ' +test_expect_success 'add subproj as subtree into sub dir/ with --prefix' ' + git subtree add --prefix="sub dir" sub1 && + check_equal "$(last_commit_message)" "Add '\''sub dir/'\'' from commit '\''$(git rev-parse sub1)'\''" && + undo +' + test_expect_success 'check if --message works for add' ' git subtree add --prefix="sub dir" --message="Added subproject" sub1 && check_equal ''"$(last_commit_message)"'' "Added subproject" && undo ' +test_expect_success 'add subproj as subtree into sub dir/ with --prefix and --message' ' + git subtree add --prefix="sub dir" --message="Added subproject" sub1 && + check_equal "$(last_commit_message)" "Added subproject" && + undo +' + test_expect_success 'check if --message works as -m and --prefix as -P' ' git subtree add -P "sub dir" -m "Added subproject using git subtree" sub1 && check_equal ''"$(last_commit_message)"'' "Added subproject using git subtree" && @@ -145,6 +157,13 @@ test_expect_success 'check if --message works with squash too' ' undo ' +test_expect_success 'add subproj as subtree into sub dir/ with --squash and --prefix and --message' ' + git subtree add --prefix="sub dir" --message="Added subproject with squash" --squash sub1 && + check_equal "$(last_commit_message)" "Added subproject with squash" && + undo +' + +# Maybe delete test_expect_success 'add subproj to mainline' ' git subtree add --prefix="sub dir"/ FETCH_HEAD && check_equal ''"$(last_commit_message)"'' "Add '"'sub dir/'"' from commit '"'"'''"$(git rev-parse sub1)"'''"'"'" -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/7] contrib/subtree: Clean and refactor test code
From: Techlive Zheng Mostly prepare for the later tests refactoring. This moves some common code to helper functions and generally cleans things up to be more presentable. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/Makefile | 31 --- contrib/subtree/t/t7900-subtree.sh | 103 - 2 files changed, 79 insertions(+), 55 deletions(-) diff --git a/contrib/subtree/t/Makefile b/contrib/subtree/t/Makefile index c864810..276898e 100644 --- a/contrib/subtree/t/Makefile +++ b/contrib/subtree/t/Makefile @@ -13,11 +13,23 @@ TAR ?= $(TAR) RM ?= rm -f PROVE ?= prove DEFAULT_TEST_TARGET ?= test +TEST_LINT ?= test-lint + +ifdef TEST_OUTPUT_DIRECTORY +TEST_RESULTS_DIRECTORY = $(TEST_OUTPUT_DIRECTORY)/test-results +else +TEST_RESULTS_DIRECTORY = ../../../t/test-results +endif # Shell quote; SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) +PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) +TEST_RESULTS_DIRECTORY_SQ = $(subst ','\'',$(TEST_RESULTS_DIRECTORY)) -T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh) +T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)) +TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh)) +TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh)) +THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh))) all: $(DEFAULT_TEST_TARGET) @@ -26,20 +38,22 @@ test: pre-clean $(TEST_LINT) prove: pre-clean $(TEST_LINT) @echo "*** prove ***"; GIT_CONFIG=.git/config $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS) - $(MAKE) clean + $(MAKE) clean-except-prove-cache $(T): @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS) pre-clean: - $(RM) -r test-results + $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)' -clean: - $(RM) -r 'trash directory'.* test-results +clean-except-prove-cache: + $(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)' $(RM) -r valgrind/bin + +clean: clean-except-prove-cache $(RM) .prove -test-lint: test-lint-duplicates test-lint-executable +test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax test-lint-duplicates: @dups=`echo $(T) | tr ' ' '\n' | sed 's/-.*//' | sort | uniq -d` && \ @@ -51,12 +65,15 @@ test-lint-executable: test -z "$$bad" || { \ echo >&2 "non-executable tests:" $$bad; exit 1; } +test-lint-shell-syntax: + @'$(PERL_PATH_SQ)' ../../../t/check-non-portable-shell.pl $(T) $(THELPERS) + aggregate-results-and-cleanup: $(T) $(MAKE) aggregate-results $(MAKE) clean aggregate-results: - for f in ../../../t/test-results/t*-*.counts; do \ + for f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \ echo "$$f"; \ done | '$(SHELL_PATH_SQ)' ../../../t/aggregate-results.sh diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index dfbe443..f9dda3d 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -5,7 +5,7 @@ # test_description='Basic porcelain support for subtrees -This test verifies the basic operation of the merge, pull, add +This test verifies the basic operation of the add, pull, merge and split subcommands of git subtree. ' @@ -20,7 +20,6 @@ create() git add "$1" } - check_equal() { test_debug 'echo' @@ -38,6 +37,30 @@ undo() git reset --hard HEAD~ } +# Make sure no patch changes more than one file. +# The original set of commits changed only one file each. +# A multi-file change would imply that we pruned commits +# too aggressively. +join_commits() +{ + commit= + all= + while read x y; do + if [ -z "$x" ]; then + continue + elif [ "$x" = "commit:" ]; then + if [ -n "$commit" ]; then + echo "$commit $all" + all= + fi + commit="$y" + else + all="$all $y" + fi + done + echo "$commit $all" +} + last_commit_message() { git log --pretty=format:%s -1 @@ -123,9 +146,11 @@ test_expect_success 'add subproj to mainline' ' check_equal ''"$(last_commit_message)"'' "Add '"'sub dir/'"' from commit '"'"'''"$(git rev-parse sub1)"'''"'"'" ' -# this shouldn't actually do anything, since FETCH_HEAD is already a parent -test_expect_success 'merge fetched subproj' ' - git merge -m "merge -s -ours" -s ours FETCH_HEAD +test_expect_success 'merge the added subproj again, should do nothing' ' + # this shouldn not actually do anything, since FETCH_HEAD + # is already a parent + result=$(git merge -s ours -m "merge -s -ours" FETCH_HEAD) && + check_equal "${result}" "Already up-to-date." ' test_expect_success 'add main-sub5' ' @@ -167,7 +192,7 @@ test_ex
[PATCH 2/7] contrib/subtree: Add test for missing subtree
From: Techlive Zheng Test that a merge from a non-existant subtree fails. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/t7900-subtree.sh | 4 1 file changed, 4 insertions(+) diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index f9dda3d..4471786 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -123,6 +123,10 @@ test_expect_success 'no pull from non-existant subtree' ' test_must_fail git subtree pull --prefix="sub dir" ./"sub proj" sub1 ' +test_expect_success 'no merge from non-existent subtree' ' + test_must_fail git subtree merge --prefix="sub dir" FETCH_HEAD +' + test_expect_success 'check if --message works for add' ' git subtree add --prefix="sub dir" --message="Added subproject" sub1 && check_equal ''"$(last_commit_message)"'' "Added subproject" && -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/7] contrib/subtree: Clean and refactor test code
From: Techlive Zheng Mostly prepare for the later tests refactoring. This moves some common code to helper functions and generally cleans things up to be more presentable. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/Makefile | 31 --- contrib/subtree/t/t7900-subtree.sh | 103 - 2 files changed, 79 insertions(+), 55 deletions(-) diff --git a/contrib/subtree/t/Makefile b/contrib/subtree/t/Makefile index c864810..276898e 100644 --- a/contrib/subtree/t/Makefile +++ b/contrib/subtree/t/Makefile @@ -13,11 +13,23 @@ TAR ?= $(TAR) RM ?= rm -f PROVE ?= prove DEFAULT_TEST_TARGET ?= test +TEST_LINT ?= test-lint + +ifdef TEST_OUTPUT_DIRECTORY +TEST_RESULTS_DIRECTORY = $(TEST_OUTPUT_DIRECTORY)/test-results +else +TEST_RESULTS_DIRECTORY = ../../../t/test-results +endif # Shell quote; SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) +PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) +TEST_RESULTS_DIRECTORY_SQ = $(subst ','\'',$(TEST_RESULTS_DIRECTORY)) -T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh) +T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)) +TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh)) +TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh)) +THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh))) all: $(DEFAULT_TEST_TARGET) @@ -26,20 +38,22 @@ test: pre-clean $(TEST_LINT) prove: pre-clean $(TEST_LINT) @echo "*** prove ***"; GIT_CONFIG=.git/config $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS) - $(MAKE) clean + $(MAKE) clean-except-prove-cache $(T): @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS) pre-clean: - $(RM) -r test-results + $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)' -clean: - $(RM) -r 'trash directory'.* test-results +clean-except-prove-cache: + $(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)' $(RM) -r valgrind/bin + +clean: clean-except-prove-cache $(RM) .prove -test-lint: test-lint-duplicates test-lint-executable +test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax test-lint-duplicates: @dups=`echo $(T) | tr ' ' '\n' | sed 's/-.*//' | sort | uniq -d` && \ @@ -51,12 +65,15 @@ test-lint-executable: test -z "$$bad" || { \ echo >&2 "non-executable tests:" $$bad; exit 1; } +test-lint-shell-syntax: + @'$(PERL_PATH_SQ)' ../../../t/check-non-portable-shell.pl $(T) $(THELPERS) + aggregate-results-and-cleanup: $(T) $(MAKE) aggregate-results $(MAKE) clean aggregate-results: - for f in ../../../t/test-results/t*-*.counts; do \ + for f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \ echo "$$f"; \ done | '$(SHELL_PATH_SQ)' ../../../t/aggregate-results.sh diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index dfbe443..f9dda3d 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -5,7 +5,7 @@ # test_description='Basic porcelain support for subtrees -This test verifies the basic operation of the merge, pull, add +This test verifies the basic operation of the add, pull, merge and split subcommands of git subtree. ' @@ -20,7 +20,6 @@ create() git add "$1" } - check_equal() { test_debug 'echo' @@ -38,6 +37,30 @@ undo() git reset --hard HEAD~ } +# Make sure no patch changes more than one file. +# The original set of commits changed only one file each. +# A multi-file change would imply that we pruned commits +# too aggressively. +join_commits() +{ + commit= + all= + while read x y; do + if [ -z "$x" ]; then + continue + elif [ "$x" = "commit:" ]; then + if [ -n "$commit" ]; then + echo "$commit $all" + all= + fi + commit="$y" + else + all="$all $y" + fi + done + echo "$commit $all" +} + last_commit_message() { git log --pretty=format:%s -1 @@ -123,9 +146,11 @@ test_expect_success 'add subproj to mainline' ' check_equal ''"$(last_commit_message)"'' "Add '"'sub dir/'"' from commit '"'"'''"$(git rev-parse sub1)"'''"'"'" ' -# this shouldn't actually do anything, since FETCH_HEAD is already a parent -test_expect_success 'merge fetched subproj' ' - git merge -m "merge -s -ours" -s ours FETCH_HEAD +test_expect_success 'merge the added subproj again, should do nothing' ' + # this shouldn not actually do anything, since FETCH_HEAD + # is already a parent + result=$(git merge -s ours -m "merge -s -ours" FETCH_HEAD) && + check_equal "${result}" "Already up-to-date." ' test_expect_success 'add main-sub5' ' @@ -167,7 +192,7 @@ test_ex
[PATCH 2/7] contrib/subtree: Add test for missing subtree
From: Techlive Zheng Test that a merge from a non-existant subtree fails. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/t7900-subtree.sh | 4 1 file changed, 4 insertions(+) diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index f9dda3d..4471786 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -123,6 +123,10 @@ test_expect_success 'no pull from non-existant subtree' ' test_must_fail git subtree pull --prefix="sub dir" ./"sub proj" sub1 ' +test_expect_success 'no merge from non-existent subtree' ' + test_must_fail git subtree merge --prefix="sub dir" FETCH_HEAD +' + test_expect_success 'check if --message works for add' ' git subtree add --prefix="sub dir" --message="Added subproject" sub1 && check_equal ''"$(last_commit_message)"'' "Added subproject" && -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/7] contrib/subtree: Add split tests
From: Techlive Zheng Add tests to check various options to split. Check combinations of --prefix, --message, --annotate, --branch and --rejoin. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/t7900-subtree.sh | 17 +++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 7d59a1a..6250194 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -250,7 +250,6 @@ test_expect_success 'split requires path given by option --prefix must exist' ' test_expect_success 'check if --message works for split+rejoin' ' spl1=''"$(git subtree split --annotate='"'*'"' --prefix "sub dir" --onto FETCH_HEAD --message "Split & rejoin" --rejoin)"'' && - git branch spl1 "$spl1" && check_equal ''"$(last_commit_message)"'' "Split & rejoin" && undo ' @@ -282,7 +281,21 @@ test_expect_success 'check split with --branch for an incompatible branch' ' test_must_fail git subtree split --prefix "sub dir" --onto FETCH_HEAD --branch subdir ' -test_expect_success 'check split+rejoin' ' +test_expect_success 'split sub dir/ with --rejoin' ' + spl1=$(git subtree split --prefix="sub dir" --annotate="*") && + git branch spl1 "$spl1" && + git subtree split --prefix="sub dir" --annotate="*" --rejoin && + check_equal "$(last_commit_message)" "Split '\''sub dir/'\'' into commit '\''$spl1'\''" && + undo +' + +test_expect_success 'split sub dir/ with --rejoin and --message' ' + git subtree split --prefix="sub dir" --message="Split & rejoin" --annotate="*" --rejoin && + check_equal "$(last_commit_message)" "Split & rejoin" && + undo +' + +test_expect_success 'check split+rejoin+onto' ' spl1=''"$(git subtree split --annotate='"'*'"' --prefix "sub dir" --onto FETCH_HEAD --message "Split & rejoin" --rejoin)"'' && undo && git subtree split --annotate='"'*'"' --prefix "sub dir" --onto FETCH_HEAD --rejoin && -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/7] contrib/subtree: Add merge tests
From: Techlive Zheng Add some tests for various merge operations. Test combinations of merge with --message, --prefix and --squash. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/t7900-subtree.sh | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 1fa5991..7d59a1a 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -210,11 +210,22 @@ test_expect_success 'check if --message for merge works with squash too' ' test_expect_success 'merge new subproj history into subdir' ' git subtree merge --prefix="sub dir" FETCH_HEAD && - git branch pre-split && check_equal ''"$(last_commit_message)"'' "Merge commit '"'"'"$(git rev-parse sub2)"'"'"' into mainline" && undo ' +test_expect_success 'merge new subproj history into subdir/ with --prefix and --message' ' + git subtree merge --prefix="sub dir" --message="Merged changes from subproject" FETCH_HEAD && + check_equal "$(last_commit_message)" "Merged changes from subproject" && + undo +' + +test_expect_success 'merge new subproj history into subdir/ with --squash and --prefix and --message' ' + git subtree merge --prefix="sub dir" --message="Merged changes from subproject using squash" --squash FETCH_HEAD && + check_equal "$(last_commit_message)" "Merged changes from subproject using squash" && + undo +' + test_expect_success 'split requires option --prefix' ' echo "You must provide the --prefix option." > expected && test_must_fail git subtree split > actual 2>&1 && -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/7] contrib/subtree: Add tests for subtree add
From: Techlive Zheng Add some tests to check various options to subtree add. These test various combinations of --message, --prefix and --squash. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/t7900-subtree.sh | 19 +++ 1 file changed, 19 insertions(+) diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 4471786..1fa5991 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -127,12 +127,24 @@ test_expect_success 'no merge from non-existent subtree' ' test_must_fail git subtree merge --prefix="sub dir" FETCH_HEAD ' +test_expect_success 'add subproj as subtree into sub dir/ with --prefix' ' + git subtree add --prefix="sub dir" sub1 && + check_equal "$(last_commit_message)" "Add '\''sub dir/'\'' from commit '\''$(git rev-parse sub1)'\''" && + undo +' + test_expect_success 'check if --message works for add' ' git subtree add --prefix="sub dir" --message="Added subproject" sub1 && check_equal ''"$(last_commit_message)"'' "Added subproject" && undo ' +test_expect_success 'add subproj as subtree into sub dir/ with --prefix and --message' ' + git subtree add --prefix="sub dir" --message="Added subproject" sub1 && + check_equal "$(last_commit_message)" "Added subproject" && + undo +' + test_expect_success 'check if --message works as -m and --prefix as -P' ' git subtree add -P "sub dir" -m "Added subproject using git subtree" sub1 && check_equal ''"$(last_commit_message)"'' "Added subproject using git subtree" && @@ -145,6 +157,13 @@ test_expect_success 'check if --message works with squash too' ' undo ' +test_expect_success 'add subproj as subtree into sub dir/ with --squash and --prefix and --message' ' + git subtree add --prefix="sub dir" --message="Added subproject with squash" --squash sub1 && + check_equal "$(last_commit_message)" "Added subproject with squash" && + undo +' + +# Maybe delete test_expect_success 'add subproj to mainline' ' git subtree add --prefix="sub dir"/ FETCH_HEAD && check_equal ''"$(last_commit_message)"'' "Add '"'sub dir/'"' from commit '"'"'''"$(git rev-parse sub1)"'''"'"'" -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/7] contrib/subtree: Make each test self-contained
From: Techlive Zheng Each test runs a full repository creation and any subtree actions needed to perform the test. Each test starts with a clean slate, making debugging and post-mortem analysis much easier. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/t/t7900-subtree.sh | 1258 1 file changed, 840 insertions(+), 418 deletions(-) diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 6250194..2683d7d 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -14,6 +14,15 @@ export TEST_DIRECTORY . ../../../t/test-lib.sh +subtree_test_create_repo() +{ + test_create_repo "$1" + ( + cd $1 + git config log.date relative + ) +} + create() { echo "$1" >"$1" @@ -61,515 +70,928 @@ join_commits() echo "$commit $all" } +test_create_commit() ( + repo=$1 + commit=$2 + cd "$repo" + mkdir -p $(dirname "$commit") \ + || error "Could not create directory for commit" + echo "$commit" >"$commit" + git add "$commit" || error "Could not add commit" + git commit -m "$commit" || error "Could not commit" +) + last_commit_message() { git log --pretty=format:%s -1 } -test_expect_success 'init subproj' ' - test_create_repo "sub proj" -' - -# To the subproject! -cd ./"sub proj" - -test_expect_success 'add sub1' ' - create sub1 && - git commit -m "sub1" && - git branch sub1 && - git branch -m master subproj -' - -# Save this hash for testing later. - -subdir_hash=$(git rev-parse HEAD) - -test_expect_success 'add sub2' ' - create sub2 && - git commit -m "sub2" && - git branch sub2 -' - -test_expect_success 'add sub3' ' - create sub3 && - git commit -m "sub3" && - git branch sub3 -' - -# Back to mainline -cd .. - -test_expect_success 'enable log.date=relative to catch errors' ' - git config log.date relative -' - -test_expect_success 'add main4' ' - create main4 && - git commit -m "main4" && - git branch -m master mainline && - git branch subdir -' - -test_expect_success 'fetch subproj history' ' - git fetch ./"sub proj" sub1 && - git branch sub1 FETCH_HEAD -' - -test_expect_success 'no subtree exists in main tree' ' - test_must_fail git subtree merge --prefix="sub dir" sub1 -' +subtree_test_count=0 +next_test() { + subtree_test_count=$(($subtree_test_count+1)) +} -test_expect_success 'no pull from non-existant subtree' ' - test_must_fail git subtree pull --prefix="sub dir" ./"sub proj" sub1 -' +# +# Tests for 'git subtree add' +# +next_test test_expect_success 'no merge from non-existent subtree' ' - test_must_fail git subtree merge --prefix="sub dir" FETCH_HEAD + subtree_test_create_repo "$subtree_test_count" && + subtree_test_create_repo "$subtree_test_count/sub proj" && + test_create_commit "$subtree_test_count" main1 && + test_create_commit "$subtree_test_count/sub proj" sub1 && + ( + cd "$subtree_test_count" && + git fetch ./"sub proj" master && + test_must_fail git subtree merge --prefix="sub dir" FETCH_HEAD + ) ' -test_expect_success 'add subproj as subtree into sub dir/ with --prefix' ' - git subtree add --prefix="sub dir" sub1 && - check_equal "$(last_commit_message)" "Add '\''sub dir/'\'' from commit '\''$(git rev-parse sub1)'\''" && - undo -' +next_test +test_expect_success 'no pull from non-existent subtree' ' + subtree_test_create_repo "$subtree_test_count" && + subtree_test_create_repo "$subtree_test_count/sub proj" && + test_create_commit "$subtree_test_count" main1 && + test_create_commit "$subtree_test_count/sub proj" sub1 && + ( + cd "$subtree_test_count" && + git fetch ./"sub proj" master && + test_must_fail git subtree pull --prefix="sub dir" ./"sub proj" master + )' -test_expect_success 'check if --message works for add' ' - git subtree add --prefix="sub dir" --message="Added subproject" sub1 && - check_equal ''"$(last_commit_message)"'' "Added subproject" && - undo +next_test +test_expect_success 'add subproj as subtree into sub dir/ with --prefix' ' + subtree_test_create_repo "$subtree_test_count" && + subtree_test_create_repo "$subtree_test_count/sub proj" && + test_create_commit "$subtree_test_count" main1 && + test_create_commit "$subtree_test_count/sub proj" sub1 && + ( + cd "$subtree_test_count" && + git fetch ./"sub proj" master && + git subtree add --prefix="sub dir" FETCH_HEAD && + check_equal "$(last_commit_message)" "Add '\''sub dir/'\'' from commit '\''$(git rev-parse FETCH_HEAD)'\''" + ) ' +next_tes
[no subject]
I'm processing some old patches I have lying around. These clean up git-subtree's test base and refactor the test code so that each test is independent of the others. This greatly aids debugging and post-mortem analysis. I have rebased these old patches on master, ensuring that new tests that have been added in the interim are incorporated into the new test code. After using git-subtree in real projects for a couple of years and exploring similar tools that have been developed, I'm fairly convinced we should change some current behavor of git-subtree. I have also run into the need for some additional features. I'm now in a position where I can work on those. This patch set is a prerequisite for that work. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/7] contrib/subtree: Handle '--prefix' argument with a slash appended
From: Techlive Zheng 'git subtree merge' will fail if the argument of '--prefix' has a slash appended. Signed-off-by: Techlive Zheng Signed-off-by: David A. Greene --- contrib/subtree/git-subtree.sh | 2 +- contrib/subtree/t/t7900-subtree.sh | 20 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index 308b777..edf36f8 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -90,7 +90,7 @@ while [ $# -gt 0 ]; do --annotate) annotate="$1"; shift ;; --no-annotate) annotate= ;; -b) branch="$1"; shift ;; - -P) prefix="$1"; shift ;; + -P) prefix="${1%/}"; shift ;; -m) message="$1"; shift ;; --no-prefix) prefix= ;; --onto) onto="$1"; shift ;; diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 2683d7d..751aee3 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -257,6 +257,26 @@ test_expect_success 'merge the added subproj again, should do nothing' ' ) ' +next_test +test_expect_success 'merge new subproj history into subdir/ with a slash appended to the argument of --prefix' ' + test_create_repo "$test_count" && + test_create_repo "$test_count/subproj" && + test_create_commit "$test_count" main1 && + test_create_commit "$test_count/subproj" sub1 && + ( + cd "$test_count" && + git fetch ./subproj master && + git subtree add --prefix=subdir/ FETCH_HEAD + ) && + test_create_commit "$test_count/subproj" sub2 && + ( + cd "$test_count" && + git fetch ./subproj master && + git subtree merge --prefix=subdir/ FETCH_HEAD && + check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''" + ) +' + # # Tests for 'git subtree split' # -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html