{"thread":{"id":"40737","subject":"[PATCH 7/7] contrib/subtree: Handle '--prefix' argument with a slash appended","startedAt":"2015-11-06T03:34:56Z","lastAt":"2015-11-11T02:52:39Z","messageCount":9,"participants":["David Greene","David A. Greene"],"isPatch":true,"patchVersion":1,"patchTotal":7},"messages":[{"id":"272991","messageId":"1446780903-22156-1-git-send-email-greened@obbligato.org","threadId":"40737","inReplyTo":null,"subject":"(unknown)","fromName":"David Greene","fromEmail":"greened@obbligato.org","sentAt":"2015-11-06T03:34:56Z","receivedAt":"2015-11-06T03:34:56Z","isPatch":false,"sender":{"key":"greened@obbligato.org","avatar":"https://avatars.githubusercontent.com/u/5291869?v=4"},"body":"I'm processing some old patches I have lying around.  These clean up\ngit-subtree's test base and refactor the test code so that each test\nis independent of the others.  This greatly aids debugging and\npost-mortem analysis.\n\nI have rebased these old patches on master, ensuring that new tests\nthat have been added in the interim are incorporated into the new test\ncode.\n\nAfter using git-subtree in real projects for a couple of years and\nexploring similar tools that have been developed, I'm fairly convinced\nwe should change some current behavor of git-subtree.  I have also run\ninto the need for some additional features.  I'm now in a position\nwhere I can work on those.\n\nThis patch set is a prerequisite for that work.\n"},{"id":"272989","messageId":"1446780903-22156-2-git-send-email-greened@obbligato.org","threadId":"40737","inReplyTo":"1446780903-22156-1-git-send-email-greened@obbligato.org","subject":"[PATCH 1/7] contrib/subtree: Clean and refactor test code","fromName":"David Greene","fromEmail":"greened@obbligato.org","sentAt":"2015-11-06T03:34:57Z","receivedAt":"2015-11-06T03:34:57Z","isPatch":true,"sender":{"key":"greened@obbligato.org","avatar":"https://avatars.githubusercontent.com/u/5291869?v=4"},"body":"From: Techlive Zheng <techlivezheng@gmail.com>\n\nMostly prepare for the later tests refactoring.  This moves some\ncommon code to helper functions and generally cleans things up to be\nmore presentable.\n\nSigned-off-by: Techlive Zheng <techlivezheng@gmail.com>\nSigned-off-by: David A. Greene <greened@obbligato.org>\n---\n contrib/subtree/t/Makefile         |  31 ++++++++---\n contrib/subtree/t/t7900-subtree.sh | 103 ++++++++++++++++++++-----------------\n 2 files changed, 79 insertions(+), 55 deletions(-)\n\ndiff --git a/contrib/subtree/t/Makefile b/contrib/subtree/t/Makefile\nindex c864810..276898e 100644\n--- a/contrib/subtree/t/Makefile\n+++ b/contrib/subtree/t/Makefile\n@@ -13,11 +13,23 @@ TAR ?= $(TAR)\n RM ?= rm -f\n PROVE ?= prove\n DEFAULT_TEST_TARGET ?= test\n+TEST_LINT ?= test-lint\n+\n+ifdef TEST_OUTPUT_DIRECTORY\n+TEST_RESULTS_DIRECTORY = $(TEST_OUTPUT_DIRECTORY)/test-results\n+else\n+TEST_RESULTS_DIRECTORY = ../../../t/test-results\n+endif\n \n # Shell quote;\n SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n+PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n+TEST_RESULTS_DIRECTORY_SQ = $(subst ','\\'',$(TEST_RESULTS_DIRECTORY))\n \n-T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)\n+T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))\n+TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh))\n+TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh))\n+THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh)))\n \n all: $(DEFAULT_TEST_TARGET)\n \n@@ -26,20 +38,22 @@ test: pre-clean $(TEST_LINT)\n \n prove: pre-clean $(TEST_LINT)\n \t@echo \"*** prove ***\"; GIT_CONFIG=.git/config $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)\n-\t$(MAKE) clean\n+\t$(MAKE) clean-except-prove-cache\n \n $(T):\n \t@echo \"*** $@ ***\"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)\n \n pre-clean:\n-\t$(RM) -r test-results\n+\t$(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'\n \n-clean:\n-\t$(RM) -r 'trash directory'.* test-results\n+clean-except-prove-cache:\n+\t$(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)'\n \t$(RM) -r valgrind/bin\n+\n+clean: clean-except-prove-cache\n \t$(RM) .prove\n \n-test-lint: test-lint-duplicates test-lint-executable\n+test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax\n \n test-lint-duplicates:\n \t@dups=`echo $(T) | tr ' ' '\\n' | sed 's/-.*//' | sort | uniq -d` && \\\n@@ -51,12 +65,15 @@ test-lint-executable:\n \t\ttest -z \"$$bad\" || { \\\n \t\techo >&2 \"non-executable tests:\" $$bad; exit 1; }\n \n+test-lint-shell-syntax:\n+\t@'$(PERL_PATH_SQ)' ../../../t/check-non-portable-shell.pl $(T) $(THELPERS)\n+\n aggregate-results-and-cleanup: $(T)\n \t$(MAKE) aggregate-results\n \t$(MAKE) clean\n \n aggregate-results:\n-\tfor f in ../../../t/test-results/t*-*.counts; do \\\n+\tfor f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \\\n \t\techo \"$$f\"; \\\n \tdone | '$(SHELL_PATH_SQ)' ../../../t/aggregate-results.sh\n \ndiff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh\nindex dfbe443..f9dda3d 100755\n--- a/contrib/subtree/t/t7900-subtree.sh\n+++ b/contrib/subtree/t/t7900-subtree.sh\n@@ -5,7 +5,7 @@\n #\n test_description='Basic porcelain support for subtrees\n \n-This test verifies the basic operation of the merge, pull, add\n+This test verifies the basic operation of the add, pull, merge\n and split subcommands of git subtree.\n '\n \n@@ -20,7 +20,6 @@ create()\n \tgit add \"$1\"\n }\n \n-\n check_equal()\n {\n \ttest_debug 'echo'\n@@ -38,6 +37,30 @@ undo()\n \tgit reset --hard HEAD~\n }\n \n+# Make sure no patch changes more than one file.\n+# The original set of commits changed only one file each.\n+# A multi-file change would imply that we pruned commits\n+# too aggressively.\n+join_commits()\n+{\n+\tcommit=\n+\tall=\n+\twhile read x y; do\n+\t\tif [ -z \"$x\" ]; then\n+\t\t\tcontinue\n+\t\telif [ \"$x\" = \"commit:\" ]; then\n+\t\t\tif [ -n \"$commit\" ]; then\n+\t\t\t\techo \"$commit $all\"\n+\t\t\t\tall=\n+\t\t\tfi\n+\t\t\tcommit=\"$y\"\n+\t\telse\n+\t\t\tall=\"$all $y\"\n+\t\tfi\n+\tdone\n+\techo \"$commit $all\"\n+}\n+\n last_commit_message()\n {\n \tgit log --pretty=format:%s -1\n@@ -123,9 +146,11 @@ test_expect_success 'add subproj to mainline' '\n \tcheck_equal ''\"$(last_commit_message)\"'' \"Add '\"'sub dir/'\"' from commit '\"'\"'''\"$(git rev-parse sub1)\"'''\"'\"'\"\n '\n \n-# this shouldn't actually do anything, since FETCH_HEAD is already a parent\n-test_expect_success 'merge fetched subproj' '\n-\tgit merge -m \"merge -s -ours\" -s ours FETCH_HEAD\n+test_expect_success 'merge the added subproj again, should do nothing' '\n+\t# this shouldn not actually do anything, since FETCH_HEAD\n+\t# is already a parent\n+\tresult=$(git merge -s ours -m \"merge -s -ours\" FETCH_HEAD) &&\n+\tcheck_equal \"${result}\" \"Already up-to-date.\"\n '\n \n test_expect_success 'add main-sub5' '\n@@ -167,7 +192,7 @@ test_expect_success 'merge new subproj history into subdir' '\n \tundo\n '\n \n-test_expect_success 'Check that prefix argument is required for split' '\n+test_expect_success 'split requires option --prefix' '\n \techo \"You must provide the --prefix option.\" > expected &&\n \ttest_must_fail git subtree split > actual 2>&1 &&\n \ttest_debug \"printf '\"'\"'expected: '\"'\"'\" &&\n@@ -178,15 +203,15 @@ test_expect_success 'Check that prefix argument is required for split' '\n \trm -f expected actual\n '\n \n-test_expect_success 'Check that the <prefix> exists for a split' '\n-\techo \"'\"'\"'non-existent-directory'\"'\"'\" does not exist\\; use \"'\"'\"'git subtree add'\"'\"'\" > expected &&\n+test_expect_success 'split requires path given by option --prefix must exist' '\n+\techo \"'\\''non-existent-directory'\\'' does not exist; use '\\''git subtree add'\\''\" > expected &&\n \ttest_must_fail git subtree split --prefix=non-existent-directory > actual 2>&1 &&\n \ttest_debug \"printf '\"'\"'expected: '\"'\"'\" &&\n \ttest_debug \"cat expected\" &&\n \ttest_debug \"printf '\"'\"'actual: '\"'\"'\" &&\n \ttest_debug \"cat actual\" &&\n-\ttest_cmp expected actual\n-#\trm -f expected actual\n+\ttest_cmp expected actual &&\n+\trm -f expected actual\n '\n \n test_expect_success 'check if --message works for split+rejoin' '\n@@ -279,18 +304,22 @@ test_expect_success 'merge split into subproj' '\n \n chkm=\"main4\n main6\"\n+\n chkms=\"main-sub10\n main-sub5\n main-sub7\n main-sub8\"\n+\n chkms_sub=$(cat <<TXT | sed 's,^,sub dir/,'\n $chkms\n TXT\n )\n+\n chks=\"sub1\n sub2\n sub3\n sub9\"\n+\n chks_sub=$(cat <<TXT | sed 's,^,sub dir/,'\n $chks\n TXT\n@@ -301,6 +330,7 @@ test_expect_success 'make sure exactly the right set of files ends up in the sub\n \tcheck_equal \"$subfiles\" \"$chkms\n $chks\"\n '\n+\n test_expect_success 'make sure the subproj history *only* contains commits that affect the subdir' '\n \tallchanges=''\"$(git log --name-only --pretty=format:'\"''\"' | sort | sed \"/^$/d\")\"'' &&\n \tcheck_equal \"$allchanges\" \"$chkms\n@@ -324,26 +354,27 @@ $chks_sub\"\n '\n \n test_expect_success 'make sure each filename changed exactly once in the entire history' '\n-\t# main-sub?? and /subdir/main-sub?? both change, because those are the\n-\t# changes that were split into their own history.  And subdir/sub?? never\n+\t# main-sub?? and sub dir/main-sub?? both change, because those are the\n+\t# changes that were split into their own history.  And sub dir/sub?? never\n \t# change, since they were *only* changed in the subtree branch.\n \tallchanges=''\"$(git log --name-only --pretty=format:'\"''\"' | sort | sed \"/^$/d\")\"'' &&\n-\tcheck_equal \"$allchanges\" ''\"$(cat <<TXT | sort\n+\texpected=''\"$(cat <<TXT | sort\n $chkms\n $chkm\n $chks\n $chkms_sub\n TXT\n-)\"''\n+)\"'' &&\n+\tcheck_equal \"$allchanges\" \"$expected\"\n '\n \n test_expect_success 'make sure the --rejoin commits never make it into subproj' '\n-\tcheck_equal ''\"$(git log --pretty=format:'\"'%s'\"' HEAD^2 | grep -i split)\"'' \"\"\n+\tcheck_equal \"$(git log --pretty=format:\"%s\" HEAD^2 | grep -i split)\" \"\"\n '\n \n test_expect_success 'make sure no \"git subtree\" tagged commits make it into subproj' '\n \t# They are meaningless to subproj since one side of the merge refers to the mainline\n-\tcheck_equal ''\"$(git log --pretty=format:'\"'%s%n%b'\"' HEAD^2 | grep \"git-subtree.*:\")\"'' \"\"\n+\tcheck_equal \"$(git log --pretty=format:\"%s%n%b\" HEAD^2 | grep \"git-subtree.*:\")\" \"\"\n '\n \n # prepare second pair of repositories\n@@ -408,13 +439,13 @@ test_expect_success 'split for main-sub4 without --onto' '\n \tgit subtree split --prefix \"sub dir\" --branch mainsub4\n '\n \n-# at this point, the new commit parent should be sub3 if it is not,\n+# At this point, the new commit parent should be sub3.  If it is not,\n # something went wrong (the \"newparent\" of \"master~\" commit should\n # have been sub3, but it was not, because its cache was not set to\n-# itself)\n+# itself).\n \n test_expect_success 'check that the commit parent is sub3' '\n-\tcheck_equal ''\"$(git log --pretty=format:%P -1 mainsub4)\"'' ''\"$(git rev-parse sub3)\"''\n+\tcheck_equal \"$(git log --pretty=format:%P -1 mainsub4)\" \"$(git rev-parse sub3)\"\n '\n \n test_expect_success 'add main-sub5' '\n@@ -431,36 +462,12 @@ test_expect_success 'split for main-sub5 without --onto' '\n \tcheck_equal ''\"$(git log --pretty=format:%P -1 mainsub5)\"'' \"\"\n '\n \n-# make sure no patch changes more than one file.  The original set of commits\n-# changed only one file each.  A multi-file change would imply that we pruned\n-# commits too aggressively.\n-joincommits()\n-{\n-\tcommit=\n-\tall=\n-\twhile read x y; do\n-\t\t#echo \"{$x}\" >&2\n-\t\tif [ -z \"$x\" ]; then\n-\t\t\tcontinue\n-\t\telif [ \"$x\" = \"commit:\" ]; then\n-\t\t\tif [ -n \"$commit\" ]; then\n-\t\t\t\techo \"$commit $all\"\n-\t\t\t\tall=\n-\t\t\tfi\n-\t\t\tcommit=\"$y\"\n-\t\telse\n-\t\t\tall=\"$all $y\"\n-\t\tfi\n-\tdone\n-\techo \"$commit $all\"\n-}\n-\n test_expect_success 'verify one file change per commit' '\n \tx= &&\n-\tlist=''\"$(git log --pretty=format:'\"'commit: %H'\"' | joincommits)\"'' &&\n+\tlist=''\"$(git log --pretty=format:'\"'commit: %H'\"' | join_commits)\"'' &&\n #\ttest_debug \"echo HERE\" &&\n #\ttest_debug \"echo ''\"$list\"''\" &&\n-\t(git log --pretty=format:'\"'commit: %H'\"' | joincommits |\n+\tgit log --pretty=format:'\"'commit: %H'\"' | join_commits |\n \t(\twhile read commit a b; do\n \t\t\ttest_debug \"echo Verifying commit \"''\"$commit\"''\n \t\t\ttest_debug \"echo a: \"''\"$a\"''\n@@ -468,15 +475,15 @@ test_expect_success 'verify one file change per commit' '\n \t\t\tcheck_equal \"$b\" \"\"\n \t\t\tx=1\n \t\tdone\n-\t\tcheck_equal \"$x\" 1\n-\t))\n+\t\tcheck_equal \"$x\" \"1\"\n+\t)\n '\n \n # test push\n \n cd ../..\n \n-mkdir test-push\n+mkdir -p test-push\n \n cd test-push\n \n-- \n2.6.1\n"},{"id":"272988","messageId":"1446780903-22156-3-git-send-email-greened@obbligato.org","threadId":"40737","inReplyTo":"1446780903-22156-1-git-send-email-greened@obbligato.org","subject":"[PATCH 2/7] contrib/subtree: Add test for missing subtree","fromName":"David Greene","fromEmail":"greened@obbligato.org","sentAt":"2015-11-06T03:34:58Z","receivedAt":"2015-11-06T03:34:58Z","isPatch":true,"sender":{"key":"greened@obbligato.org","avatar":"https://avatars.githubusercontent.com/u/5291869?v=4"},"body":"From: Techlive Zheng <techlivezheng@gmail.com>\n\nTest that a merge from a non-existant subtree fails.\n\nSigned-off-by: Techlive Zheng <techlivezheng@gmail.com>\nSigned-off-by: David A. Greene <greened@obbligato.org>\n---\n contrib/subtree/t/t7900-subtree.sh | 4 ++++\n 1 file changed, 4 insertions(+)\n\ndiff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh\nindex f9dda3d..4471786 100755\n--- a/contrib/subtree/t/t7900-subtree.sh\n+++ b/contrib/subtree/t/t7900-subtree.sh\n@@ -123,6 +123,10 @@ test_expect_success 'no pull from non-existant subtree' '\n \ttest_must_fail git subtree pull --prefix=\"sub dir\" ./\"sub proj\" sub1\n '\n \n+test_expect_success 'no merge from non-existent subtree' '\n+\ttest_must_fail git subtree merge --prefix=\"sub dir\" FETCH_HEAD\n+'\n+\n test_expect_success 'check if --message works for add' '\n \tgit subtree add --prefix=\"sub dir\" --message=\"Added subproject\" sub1 &&\n \tcheck_equal ''\"$(last_commit_message)\"'' \"Added subproject\" &&\n-- \n2.6.1\n"},{"id":"272987","messageId":"1446780903-22156-4-git-send-email-greened@obbligato.org","threadId":"40737","inReplyTo":"1446780903-22156-1-git-send-email-greened@obbligato.org","subject":"[PATCH 3/7] contrib/subtree: Add tests for subtree add","fromName":"David Greene","fromEmail":"greened@obbligato.org","sentAt":"2015-11-06T03:34:59Z","receivedAt":"2015-11-06T03:34:59Z","isPatch":true,"sender":{"key":"greened@obbligato.org","avatar":"https://avatars.githubusercontent.com/u/5291869?v=4"},"body":"From: Techlive Zheng <techlivezheng@gmail.com>\n\nAdd some tests to check various options to subtree add.  These test\nvarious combinations of --message, --prefix and --squash.\n\nSigned-off-by: Techlive Zheng <techlivezheng@gmail.com>\nSigned-off-by: David A. Greene <greened@obbligato.org>\n---\n contrib/subtree/t/t7900-subtree.sh | 19 +++++++++++++++++++\n 1 file changed, 19 insertions(+)\n\ndiff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh\nindex 4471786..1fa5991 100755\n--- a/contrib/subtree/t/t7900-subtree.sh\n+++ b/contrib/subtree/t/t7900-subtree.sh\n@@ -127,12 +127,24 @@ test_expect_success 'no merge from non-existent subtree' '\n \ttest_must_fail git subtree merge --prefix=\"sub dir\" FETCH_HEAD\n '\n \n+test_expect_success 'add subproj as subtree into sub dir/ with --prefix' '\n+\tgit subtree add --prefix=\"sub dir\" sub1 &&\n+\tcheck_equal \"$(last_commit_message)\" \"Add '\\''sub dir/'\\'' from commit '\\''$(git rev-parse sub1)'\\''\" &&\n+\tundo\n+'\n+\n test_expect_success 'check if --message works for add' '\n \tgit subtree add --prefix=\"sub dir\" --message=\"Added subproject\" sub1 &&\n \tcheck_equal ''\"$(last_commit_message)\"'' \"Added subproject\" &&\n \tundo\n '\n \n+test_expect_success 'add subproj as subtree into sub dir/ with --prefix and --message' '\n+\tgit subtree add --prefix=\"sub dir\" --message=\"Added subproject\" sub1 &&\n+\tcheck_equal \"$(last_commit_message)\" \"Added subproject\" &&\n+\tundo\n+'\n+\n test_expect_success 'check if --message works as -m and --prefix as -P' '\n \tgit subtree add -P \"sub dir\" -m \"Added subproject using git subtree\" sub1 &&\n \tcheck_equal ''\"$(last_commit_message)\"'' \"Added subproject using git subtree\" &&\n@@ -145,6 +157,13 @@ test_expect_success 'check if --message works with squash too' '\n \tundo\n '\n \n+test_expect_success 'add subproj as subtree into sub dir/ with --squash and --prefix and --message' '\n+\tgit subtree add --prefix=\"sub dir\" --message=\"Added subproject with squash\" --squash sub1 &&\n+\tcheck_equal \"$(last_commit_message)\" \"Added subproject with squash\" &&\n+\tundo\n+'\n+\n+# Maybe delete\n test_expect_success 'add subproj to mainline' '\n \tgit subtree add --prefix=\"sub dir\"/ FETCH_HEAD &&\n \tcheck_equal ''\"$(last_commit_message)\"'' \"Add '\"'sub dir/'\"' from commit '\"'\"'''\"$(git rev-parse sub1)\"'''\"'\"'\"\n-- \n2.6.1\n"},{"id":"272986","messageId":"1446780903-22156-5-git-send-email-greened@obbligato.org","threadId":"40737","inReplyTo":"1446780903-22156-1-git-send-email-greened@obbligato.org","subject":"[PATCH 4/7] contrib/subtree: Add merge tests","fromName":"David Greene","fromEmail":"greened@obbligato.org","sentAt":"2015-11-06T03:35:00Z","receivedAt":"2015-11-06T03:35:00Z","isPatch":true,"sender":{"key":"greened@obbligato.org","avatar":"https://avatars.githubusercontent.com/u/5291869?v=4"},"body":"From: Techlive Zheng <techlivezheng@gmail.com>\n\nAdd some tests for various merge operations.  Test combinations of merge\nwith --message, --prefix and --squash.\n\nSigned-off-by: Techlive Zheng <techlivezheng@gmail.com>\nSigned-off-by: David A. Greene <greened@obbligato.org>\n---\n contrib/subtree/t/t7900-subtree.sh | 13 ++++++++++++-\n 1 file changed, 12 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh\nindex 1fa5991..7d59a1a 100755\n--- a/contrib/subtree/t/t7900-subtree.sh\n+++ b/contrib/subtree/t/t7900-subtree.sh\n@@ -210,11 +210,22 @@ test_expect_success 'check if --message for merge works with squash too' '\n \n test_expect_success 'merge new subproj history into subdir' '\n \tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n-\tgit branch pre-split &&\n \tcheck_equal ''\"$(last_commit_message)\"'' \"Merge commit '\"'\"'\"$(git rev-parse sub2)\"'\"'\"' into mainline\" &&\n \tundo\n '\n \n+test_expect_success 'merge new subproj history into subdir/ with --prefix and --message' '\n+\tgit subtree merge --prefix=\"sub dir\" --message=\"Merged changes from subproject\" FETCH_HEAD &&\n+\tcheck_equal \"$(last_commit_message)\" \"Merged changes from subproject\" &&\n+\tundo\n+'\n+\n+test_expect_success 'merge new subproj history into subdir/ with --squash and --prefix and --message' '\n+\tgit subtree merge --prefix=\"sub dir\" --message=\"Merged changes from subproject using squash\" --squash FETCH_HEAD &&\n+\tcheck_equal \"$(last_commit_message)\" \"Merged changes from subproject using squash\" &&\n+\tundo\n+'\n+\n test_expect_success 'split requires option --prefix' '\n \techo \"You must provide the --prefix option.\" > expected &&\n \ttest_must_fail git subtree split > actual 2>&1 &&\n-- \n2.6.1\n"},{"id":"272990","messageId":"1446780903-22156-6-git-send-email-greened@obbligato.org","threadId":"40737","inReplyTo":"1446780903-22156-1-git-send-email-greened@obbligato.org","subject":"[PATCH 5/7] contrib/subtree: Add split tests","fromName":"David Greene","fromEmail":"greened@obbligato.org","sentAt":"2015-11-06T03:35:01Z","receivedAt":"2015-11-06T03:35:01Z","isPatch":true,"sender":{"key":"greened@obbligato.org","avatar":"https://avatars.githubusercontent.com/u/5291869?v=4"},"body":"From: Techlive Zheng <techlivezheng@gmail.com>\n\nAdd tests to check various options to split.  Check combinations of\n--prefix, --message, --annotate, --branch and --rejoin.\n\nSigned-off-by: Techlive Zheng <techlivezheng@gmail.com>\nSigned-off-by: David A. Greene <greened@obbligato.org>\n---\n contrib/subtree/t/t7900-subtree.sh | 17 +++++++++++++++--\n 1 file changed, 15 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh\nindex 7d59a1a..6250194 100755\n--- a/contrib/subtree/t/t7900-subtree.sh\n+++ b/contrib/subtree/t/t7900-subtree.sh\n@@ -250,7 +250,6 @@ test_expect_success 'split requires path given by option --prefix must exist' '\n \n test_expect_success 'check if --message works for split+rejoin' '\n \tspl1=''\"$(git subtree split --annotate='\"'*'\"' --prefix \"sub dir\" --onto FETCH_HEAD --message \"Split & rejoin\" --rejoin)\"'' &&\n-\tgit branch spl1 \"$spl1\" &&\n \tcheck_equal ''\"$(last_commit_message)\"'' \"Split & rejoin\" &&\n \tundo\n '\n@@ -282,7 +281,21 @@ test_expect_success 'check split with --branch for an incompatible branch' '\n \ttest_must_fail git subtree split --prefix \"sub dir\" --onto FETCH_HEAD --branch subdir\n '\n \n-test_expect_success 'check split+rejoin' '\n+test_expect_success 'split sub dir/ with --rejoin' '\n+\tspl1=$(git subtree split --prefix=\"sub dir\" --annotate=\"*\") &&\n+\tgit branch spl1 \"$spl1\" &&\n+\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --rejoin &&\n+\tcheck_equal \"$(last_commit_message)\" \"Split '\\''sub dir/'\\'' into commit '\\''$spl1'\\''\" &&\n+\tundo\n+'\n+\n+test_expect_success 'split sub dir/ with --rejoin and --message' '\n+\tgit subtree split --prefix=\"sub dir\" --message=\"Split & rejoin\" --annotate=\"*\" --rejoin &&\n+\tcheck_equal \"$(last_commit_message)\" \"Split & rejoin\" &&\n+\tundo\n+'\n+\n+test_expect_success 'check split+rejoin+onto' '\n \tspl1=''\"$(git subtree split --annotate='\"'*'\"' --prefix \"sub dir\" --onto FETCH_HEAD --message \"Split & rejoin\" --rejoin)\"'' &&\n \tundo &&\n \tgit subtree split --annotate='\"'*'\"' --prefix \"sub dir\" --onto FETCH_HEAD --rejoin &&\n-- \n2.6.1\n"},{"id":"272992","messageId":"1446780903-22156-7-git-send-email-greened@obbligato.org","threadId":"40737","inReplyTo":"1446780903-22156-1-git-send-email-greened@obbligato.org","subject":"[PATCH 6/7] contrib/subtree: Make each test self-contained","fromName":"David Greene","fromEmail":"greened@obbligato.org","sentAt":"2015-11-06T03:35:02Z","receivedAt":"2015-11-06T03:35:02Z","isPatch":true,"sender":{"key":"greened@obbligato.org","avatar":"https://avatars.githubusercontent.com/u/5291869?v=4"},"body":"From: Techlive Zheng <techlivezheng@gmail.com>\n\nEach test runs a full repository creation and any subtree actions\nneeded to perform the test.  Each test starts with a clean slate,\nmaking debugging and post-mortem analysis much easier.\n\nSigned-off-by: Techlive Zheng <techlivezheng@gmail.com>\nSigned-off-by: David A. Greene <greened@obbligato.org>\n---\n contrib/subtree/t/t7900-subtree.sh | 1258 ++++++++++++++++++++++++------------\n 1 file changed, 840 insertions(+), 418 deletions(-)\n\ndiff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh\nindex 6250194..2683d7d 100755\n--- a/contrib/subtree/t/t7900-subtree.sh\n+++ b/contrib/subtree/t/t7900-subtree.sh\n@@ -14,6 +14,15 @@ export TEST_DIRECTORY\n \n . ../../../t/test-lib.sh\n \n+subtree_test_create_repo()\n+{\n+\ttest_create_repo \"$1\"\n+\t(\n+\t\tcd $1\n+\t\tgit config log.date relative\n+\t)\n+}\n+\n create()\n {\n \techo \"$1\" >\"$1\"\n@@ -61,515 +70,928 @@ join_commits()\n \techo \"$commit $all\"\n }\n \n+test_create_commit() (\n+\trepo=$1\n+\tcommit=$2\n+\tcd \"$repo\"\n+\tmkdir -p $(dirname \"$commit\") \\\n+\t|| error \"Could not create directory for commit\"\n+\techo \"$commit\" >\"$commit\"\n+\tgit add \"$commit\" || error \"Could not add commit\"\n+\tgit commit -m \"$commit\" || error \"Could not commit\"\n+)\n+\n last_commit_message()\n {\n \tgit log --pretty=format:%s -1\n }\n \n-test_expect_success 'init subproj' '\n-\ttest_create_repo \"sub proj\"\n-'\n-\n-# To the subproject!\n-cd ./\"sub proj\"\n-\n-test_expect_success 'add sub1' '\n-\tcreate sub1 &&\n-\tgit commit -m \"sub1\" &&\n-\tgit branch sub1 &&\n-\tgit branch -m master subproj\n-'\n-\n-# Save this hash for testing later.\n-\n-subdir_hash=$(git rev-parse HEAD)\n-\n-test_expect_success 'add sub2' '\n-\tcreate sub2 &&\n-\tgit commit -m \"sub2\" &&\n-\tgit branch sub2\n-'\n-\n-test_expect_success 'add sub3' '\n-\tcreate sub3 &&\n-\tgit commit -m \"sub3\" &&\n-\tgit branch sub3\n-'\n-\n-# Back to mainline\n-cd ..\n-\n-test_expect_success 'enable log.date=relative to catch errors' '\n-\tgit config log.date relative\n-'\n-\n-test_expect_success 'add main4' '\n-\tcreate main4 &&\n-\tgit commit -m \"main4\" &&\n-\tgit branch -m master mainline &&\n-\tgit branch subdir\n-'\n-\n-test_expect_success 'fetch subproj history' '\n-\tgit fetch ./\"sub proj\" sub1 &&\n-\tgit branch sub1 FETCH_HEAD\n-'\n-\n-test_expect_success 'no subtree exists in main tree' '\n-\ttest_must_fail git subtree merge --prefix=\"sub dir\" sub1\n-'\n+subtree_test_count=0\n+next_test() {\n+\tsubtree_test_count=$(($subtree_test_count+1))\n+}\n \n-test_expect_success 'no pull from non-existant subtree' '\n-\ttest_must_fail git subtree pull --prefix=\"sub dir\" ./\"sub proj\" sub1\n-'\n+#\n+# Tests for 'git subtree add'\n+#\n \n+next_test\n test_expect_success 'no merge from non-existent subtree' '\n-\ttest_must_fail git subtree merge --prefix=\"sub dir\" FETCH_HEAD\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\ttest_must_fail git subtree merge --prefix=\"sub dir\" FETCH_HEAD\n+\t)\n '\n \n-test_expect_success 'add subproj as subtree into sub dir/ with --prefix' '\n-\tgit subtree add --prefix=\"sub dir\" sub1 &&\n-\tcheck_equal \"$(last_commit_message)\" \"Add '\\''sub dir/'\\'' from commit '\\''$(git rev-parse sub1)'\\''\" &&\n-\tundo\n-'\n+next_test\n+test_expect_success 'no pull from non-existent subtree' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\ttest_must_fail git subtree pull --prefix=\"sub dir\" ./\"sub proj\" master\n+\t)'\n \n-test_expect_success 'check if --message works for add' '\n-\tgit subtree add --prefix=\"sub dir\" --message=\"Added subproject\" sub1 &&\n-\tcheck_equal ''\"$(last_commit_message)\"'' \"Added subproject\" &&\n-\tundo\n+next_test\n+test_expect_success 'add subproj as subtree into sub dir/ with --prefix' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tcheck_equal \"$(last_commit_message)\" \"Add '\\''sub dir/'\\'' from commit '\\''$(git rev-parse FETCH_HEAD)'\\''\"\n+\t)\n '\n \n+next_test\n test_expect_success 'add subproj as subtree into sub dir/ with --prefix and --message' '\n-\tgit subtree add --prefix=\"sub dir\" --message=\"Added subproject\" sub1 &&\n-\tcheck_equal \"$(last_commit_message)\" \"Added subproject\" &&\n-\tundo\n-'\n-\n-test_expect_success 'check if --message works as -m and --prefix as -P' '\n-\tgit subtree add -P \"sub dir\" -m \"Added subproject using git subtree\" sub1 &&\n-\tcheck_equal ''\"$(last_commit_message)\"'' \"Added subproject using git subtree\" &&\n-\tundo\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" --message=\"Added subproject\" FETCH_HEAD &&\n+\t\tcheck_equal \"$(last_commit_message)\" \"Added subproject\"\n+\t)\n '\n \n-test_expect_success 'check if --message works with squash too' '\n-\tgit subtree add -P \"sub dir\" -m \"Added subproject with squash\" --squash sub1 &&\n-\tcheck_equal ''\"$(last_commit_message)\"'' \"Added subproject with squash\" &&\n-\tundo\n+next_test\n+test_expect_success 'add subproj as subtree into sub dir/ with --prefix as -P and --message as -m' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add -P \"sub dir\" -m \"Added subproject\" FETCH_HEAD &&\n+\t\tcheck_equal \"$(last_commit_message)\" \"Added subproject\"\n+\t)\n '\n \n+next_test\n test_expect_success 'add subproj as subtree into sub dir/ with --squash and --prefix and --message' '\n-\tgit subtree add --prefix=\"sub dir\" --message=\"Added subproject with squash\" --squash sub1 &&\n-\tcheck_equal \"$(last_commit_message)\" \"Added subproject with squash\" &&\n-\tundo\n-'\n-\n-# Maybe delete\n-test_expect_success 'add subproj to mainline' '\n-\tgit subtree add --prefix=\"sub dir\"/ FETCH_HEAD &&\n-\tcheck_equal ''\"$(last_commit_message)\"'' \"Add '\"'sub dir/'\"' from commit '\"'\"'''\"$(git rev-parse sub1)\"'''\"'\"'\"\n-'\n-\n-test_expect_success 'merge the added subproj again, should do nothing' '\n-\t# this shouldn not actually do anything, since FETCH_HEAD\n-\t# is already a parent\n-\tresult=$(git merge -s ours -m \"merge -s -ours\" FETCH_HEAD) &&\n-\tcheck_equal \"${result}\" \"Already up-to-date.\"\n-'\n-\n-test_expect_success 'add main-sub5' '\n-\tcreate \"sub dir/main-sub5\" &&\n-\tgit commit -m \"main-sub5\"\n-'\n-\n-test_expect_success 'add main6' '\n-\tcreate main6 &&\n-\tgit commit -m \"main6 boring\"\n-'\n-\n-test_expect_success 'add main-sub7' '\n-\tcreate \"sub dir/main-sub7\" &&\n-\tgit commit -m \"main-sub7\"\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" --message=\"Added subproject with squash\" --squash FETCH_HEAD &&\n+\t\tcheck_equal \"$(last_commit_message)\" \"Added subproject with squash\"\n+\t)\n '\n \n-test_expect_success 'fetch new subproj history' '\n-\tgit fetch ./\"sub proj\" sub2 &&\n-\tgit branch sub2 FETCH_HEAD\n-'\n+#\n+# Tests for 'git subtree merge'\n+#\n \n-test_expect_success 'check if --message works for merge' '\n-\tgit subtree merge --prefix=\"sub dir\" -m \"Merged changes from subproject\" sub2 &&\n-\tcheck_equal ''\"$(last_commit_message)\"'' \"Merged changes from subproject\" &&\n-\tundo\n+next_test\n+test_expect_success 'merge new subproj history into sub dir/ with --prefix' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tcheck_equal \"$(last_commit_message)\" \"Merge commit '\\''$(git rev-parse FETCH_HEAD)'\\''\"\n+\t)\n '\n \n-test_expect_success 'check if --message for merge works with squash too' '\n-\tgit subtree merge --prefix \"sub dir\" -m \"Merged changes from subproject using squash\" --squash sub2 &&\n-\tcheck_equal ''\"$(last_commit_message)\"'' \"Merged changes from subproject using squash\" &&\n-\tundo\n+next_test\n+test_expect_success 'merge new subproj history into sub dir/ with --prefix and --message' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" --message=\"Merged changes from subproject\" FETCH_HEAD &&\n+\t\tcheck_equal \"$(last_commit_message)\" \"Merged changes from subproject\"\n+\t)\n '\n \n-test_expect_success 'merge new subproj history into subdir' '\n-\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n-\tcheck_equal ''\"$(last_commit_message)\"'' \"Merge commit '\"'\"'\"$(git rev-parse sub2)\"'\"'\"' into mainline\" &&\n-\tundo\n+next_test\n+test_expect_success 'merge new subproj history into sub dir/ with --squash and --prefix and --message' '\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" --message=\"Merged changes from subproject using squash\" --squash FETCH_HEAD &&\n+\t\tcheck_equal \"$(last_commit_message)\" \"Merged changes from subproject using squash\"\n+\t)\n '\n \n-test_expect_success 'merge new subproj history into subdir/ with --prefix and --message' '\n-\tgit subtree merge --prefix=\"sub dir\" --message=\"Merged changes from subproject\" FETCH_HEAD &&\n-\tcheck_equal \"$(last_commit_message)\" \"Merged changes from subproject\" &&\n-\tundo\n+next_test\n+test_expect_success 'merge the added subproj again, should do nothing' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\t# this shouldn not actually do anything, since FETCH_HEAD\n+\t\t# is already a parent\n+\t\tresult=$(git merge -s ours -m \"merge -s -ours\" FETCH_HEAD) &&\n+\t\tcheck_equal \"${result}\" \"Already up-to-date.\"\n+\t)\n '\n \n-test_expect_success 'merge new subproj history into subdir/ with --squash and --prefix and --message' '\n-\tgit subtree merge --prefix=\"sub dir\" --message=\"Merged changes from subproject using squash\" --squash FETCH_HEAD &&\n-\tcheck_equal \"$(last_commit_message)\" \"Merged changes from subproject using squash\" &&\n-\tundo\n-'\n+#\n+# Tests for 'git subtree split'\n+#\n \n+next_test\n test_expect_success 'split requires option --prefix' '\n-\techo \"You must provide the --prefix option.\" > expected &&\n-\ttest_must_fail git subtree split > actual 2>&1 &&\n-\ttest_debug \"printf '\"'\"'expected: '\"'\"'\" &&\n-\ttest_debug \"cat expected\" &&\n-\ttest_debug \"printf '\"'\"'actual: '\"'\"'\" &&\n-\ttest_debug \"cat actual\" &&\n-\ttest_cmp expected actual &&\n-\trm -f expected actual\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\techo \"You must provide the --prefix option.\" > expected &&\n+\t\ttest_must_fail git subtree split > actual 2>&1 &&\n+\t\ttest_debug \"printf '\"expected: \"'\" &&\n+\t\ttest_debug \"cat expected\" &&\n+\t\ttest_debug \"printf '\"actual: \"'\" &&\n+\t\ttest_debug \"cat actual\" &&\n+\t\ttest_cmp expected actual\n+\t)\n '\n \n+next_test\n test_expect_success 'split requires path given by option --prefix must exist' '\n-\techo \"'\\''non-existent-directory'\\'' does not exist; use '\\''git subtree add'\\''\" > expected &&\n-\ttest_must_fail git subtree split --prefix=non-existent-directory > actual 2>&1 &&\n-\ttest_debug \"printf '\"'\"'expected: '\"'\"'\" &&\n-\ttest_debug \"cat expected\" &&\n-\ttest_debug \"printf '\"'\"'actual: '\"'\"'\" &&\n-\ttest_debug \"cat actual\" &&\n-\ttest_cmp expected actual &&\n-\trm -f expected actual\n-'\n-\n-test_expect_success 'check if --message works for split+rejoin' '\n-\tspl1=''\"$(git subtree split --annotate='\"'*'\"' --prefix \"sub dir\" --onto FETCH_HEAD --message \"Split & rejoin\" --rejoin)\"'' &&\n-\tcheck_equal ''\"$(last_commit_message)\"'' \"Split & rejoin\" &&\n-\tundo\n-'\n-\n-test_expect_success 'check split with --branch' '\n-\tspl1=$(git subtree split --annotate='\"'*'\"' --prefix \"sub dir\" --onto FETCH_HEAD --message \"Split & rejoin\" --rejoin) &&\n-\tundo &&\n-\tgit subtree split --annotate='\"'*'\"' --prefix \"sub dir\" --onto FETCH_HEAD --branch splitbr1 &&\n-\tcheck_equal ''\"$(git rev-parse splitbr1)\"'' \"$spl1\"\n-'\n-\n-test_expect_success 'check hash of split' '\n-\tspl1=$(git subtree split --prefix \"sub dir\") &&\n-\tgit subtree split --prefix \"sub dir\" --branch splitbr1test &&\n-\tcheck_equal ''\"$(git rev-parse splitbr1test)\"'' \"$spl1\" &&\n-\tnew_hash=$(git rev-parse splitbr1test~2) &&\n-\tcheck_equal ''\"$new_hash\"'' \"$subdir_hash\"\n-'\n-\n-test_expect_success 'check split with --branch for an existing branch' '\n-\tspl1=''\"$(git subtree split --annotate='\"'*'\"' --prefix \"sub dir\" --onto FETCH_HEAD --message \"Split & rejoin\" --rejoin)\"'' &&\n-\tundo &&\n-\tgit branch splitbr2 sub1 &&\n-\tgit subtree split --annotate='\"'*'\"' --prefix \"sub dir\" --onto FETCH_HEAD --branch splitbr2 &&\n-\tcheck_equal ''\"$(git rev-parse splitbr2)\"'' \"$spl1\"\n-'\n-\n-test_expect_success 'check split with --branch for an incompatible branch' '\n-\ttest_must_fail git subtree split --prefix \"sub dir\" --onto FETCH_HEAD --branch subdir\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\techo \"'\\''non-existent-directory'\\'' does not exist; use '\\''git subtree add'\\''\" > expected &&\n+\t\ttest_must_fail git subtree split --prefix=non-existent-directory > actual 2>&1 &&\n+\t\ttest_debug \"printf '\"expected: \"'\" &&\n+\t\ttest_debug \"cat expected\" &&\n+\t\ttest_debug \"printf '\"actual: \"'\" &&\n+\t\ttest_debug \"cat actual\" &&\n+\t\ttest_cmp expected actual\n+\t)\n '\n \n+next_test\n test_expect_success 'split sub dir/ with --rejoin' '\n-\tspl1=$(git subtree split --prefix=\"sub dir\" --annotate=\"*\") &&\n-\tgit branch spl1 \"$spl1\" &&\n-\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --rejoin &&\n-\tcheck_equal \"$(last_commit_message)\" \"Split '\\''sub dir/'\\'' into commit '\\''$spl1'\\''\" &&\n-\tundo\n-'\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tsplit_hash=$(git subtree split --prefix=\"sub dir\" --annotate=\"*\") &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --rejoin &&\n+\t\tcheck_equal \"$(last_commit_message)\" \"Split '\\''sub dir/'\\'' into commit '\\''$split_hash'\\''\"\n+\t)\n+ '\n \n+next_test\n test_expect_success 'split sub dir/ with --rejoin and --message' '\n-\tgit subtree split --prefix=\"sub dir\" --message=\"Split & rejoin\" --annotate=\"*\" --rejoin &&\n-\tcheck_equal \"$(last_commit_message)\" \"Split & rejoin\" &&\n-\tundo\n-'\n-\n-test_expect_success 'check split+rejoin+onto' '\n-\tspl1=''\"$(git subtree split --annotate='\"'*'\"' --prefix \"sub dir\" --onto FETCH_HEAD --message \"Split & rejoin\" --rejoin)\"'' &&\n-\tundo &&\n-\tgit subtree split --annotate='\"'*'\"' --prefix \"sub dir\" --onto FETCH_HEAD --rejoin &&\n-\tcheck_equal ''\"$(last_commit_message)\"'' \"Split '\"'\"'sub dir/'\"'\"' into commit '\"'\"'\"$spl1\"'\"'\"'\"\n-'\n-\n-test_expect_success 'add main-sub8' '\n-\tcreate \"sub dir/main-sub8\" &&\n-\tgit commit -m \"main-sub8\"\n-'\n-\n-# To the subproject!\n-cd ./\"sub proj\"\n-\n-test_expect_success 'merge split into subproj' '\n-\tgit fetch .. spl1 &&\n-\tgit branch spl1 FETCH_HEAD &&\n-\tgit merge FETCH_HEAD\n-'\n-\n-test_expect_success 'add sub9' '\n-\tcreate sub9 &&\n-\tgit commit -m \"sub9\"\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tgit subtree split --prefix=\"sub dir\" --message=\"Split & rejoin\" --annotate=\"*\" --rejoin &&\n+\t\tcheck_equal \"$(last_commit_message)\" \"Split & rejoin\"\n+\t)\n '\n \n-# Back to mainline\n-cd ..\n-\n-test_expect_success 'split for sub8' '\n-\tsplit2=''\"$(git subtree split --annotate='\"'*'\"' --prefix \"sub dir/\" --rejoin)\"'' &&\n-\tgit branch split2 \"$split2\"\n+next_test\n+test_expect_success 'split \"sub dir\"/ with --branch' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tsplit_hash=$(git subtree split --prefix=\"sub dir\" --annotate=\"*\") &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br &&\n+\t\tcheck_equal \"$(git rev-parse subproj-br)\" \"$split_hash\"\n+\t)\n '\n \n-test_expect_success 'add main-sub10' '\n-\tcreate \"sub dir/main-sub10\" &&\n-\tgit commit -m \"main-sub10\"\n+next_test\n+test_expect_success 'check hash of split' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tsplit_hash=$(git subtree split --prefix=\"sub dir\" --annotate=\"*\") &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br &&\n+\t\tcheck_equal \"$(git rev-parse subproj-br)\" \"$split_hash\" &&\n+\t\t# Check hash of split\n+\t\tnew_hash=$(git rev-parse subproj-br^2) &&\n+\t\t(\n+\t\t\tcd ./\"sub proj\" &&\n+\t\t\tsubdir_hash=$(git rev-parse HEAD) &&\n+\t\t\tcheck_equal ''\"$new_hash\"'' \"$subdir_hash\"\n+\t\t)\n+\t)\n '\n \n-test_expect_success 'split for sub10' '\n-\tspl3=''\"$(git subtree split --annotate='\"'*'\"' --prefix \"sub dir\" --rejoin)\"'' &&\n-\tgit branch spl3 \"$spl3\"\n+next_test\n+test_expect_success 'split \"sub dir\"/ with --branch for an existing branch' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit branch subproj-br FETCH_HEAD &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tsplit_hash=$(git subtree split --prefix=\"sub dir\" --annotate=\"*\") &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br &&\n+\t\tcheck_equal \"$(git rev-parse subproj-br)\" \"$split_hash\"\n+\t)\n '\n \n-# To the subproject!\n-cd ./\"sub proj\"\n-\n-test_expect_success 'merge split into subproj' '\n-\tgit fetch .. spl3 &&\n-\tgit branch spl3 FETCH_HEAD &&\n-\tgit merge FETCH_HEAD &&\n-\tgit branch subproj-merge-spl3\n+next_test\n+test_expect_success 'split \"sub dir\"/ with --branch for an incompatible branch' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit branch init HEAD &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\ttest_must_fail git subtree split --prefix=\"sub dir\" --branch init\n+\t)\n '\n \n-chkm=\"main4\n-main6\"\n-\n-chkms=\"main-sub10\n-main-sub5\n-main-sub7\n-main-sub8\"\n-\n-chkms_sub=$(cat <<TXT | sed 's,^,sub dir/,'\n-$chkms\n-TXT\n-)\n+#\n+# Validity checking\n+#\n \n-chks=\"sub1\n+next_test\n+test_expect_success 'make sure exactly the right set of files ends up in the subproj' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\tgit merge FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\tgit merge FETCH_HEAD &&\n+\n+\t\tchks=\"sub1\n sub2\n sub3\n-sub9\"\n-\n-chks_sub=$(cat <<TXT | sed 's,^,sub dir/,'\n+sub4\" &&\n+\t\tchks_sub=$(cat <<TXT | sed '\\''s,^,sub dir/,'\\''\n $chks\n TXT\n-)\n+) &&\n+\t\tchkms=\"main-sub1\n+main-sub2\n+main-sub3\n+main-sub4\" &&\n+\t\tchkms_sub=$(cat <<TXT | sed '\\''s,^,sub dir/,'\\''\n+$chkms\n+TXT\n+) &&\n \n-test_expect_success 'make sure exactly the right set of files ends up in the subproj' '\n-\tsubfiles=\"$(git ls-files)\" &&\n-\tcheck_equal \"$subfiles\" \"$chkms\n+\t\tsubfiles=$(git ls-files) &&\n+\t\tcheck_equal \"$subfiles\" \"$chkms\n $chks\"\n+\t)\n '\n \n-test_expect_success 'make sure the subproj history *only* contains commits that affect the subdir' '\n-\tallchanges=''\"$(git log --name-only --pretty=format:'\"''\"' | sort | sed \"/^$/d\")\"'' &&\n-\tcheck_equal \"$allchanges\" \"$chkms\n+next_test\n+test_expect_success 'make sure the subproj *only* contains commits that affect the \"sub dir\"' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\tgit merge FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\tgit merge FETCH_HEAD &&\n+\n+\t\tchks=\"sub1\n+sub2\n+sub3\n+sub4\" &&\n+\t\tchks_sub=$(cat <<TXT | sed '\\''s,^,sub dir/,'\\''\n+$chks\n+TXT\n+) &&\n+\t\tchkms=\"main-sub1\n+main-sub2\n+main-sub3\n+main-sub4\" &&\n+\t\tchkms_sub=$(cat <<TXT | sed '\\''s,^,sub dir/,'\\''\n+$chkms\n+TXT\n+) &&\n+\t\tallchanges=$(git log --name-only --pretty=format:\"\" | sort | sed \"/^$/d\") &&\n+\t\tcheck_equal \"$allchanges\" \"$chkms\n $chks\"\n+\t)\n '\n \n-# Back to mainline\n-cd ..\n-\n-test_expect_success 'pull from subproj' '\n-\tgit fetch ./\"sub proj\" subproj-merge-spl3 &&\n-\tgit branch subproj-merge-spl3 FETCH_HEAD &&\n-\tgit subtree pull --prefix=\"sub dir\" ./\"sub proj\" subproj-merge-spl3\n-'\n-\n+next_test\n test_expect_success 'make sure exactly the right set of files ends up in the mainline' '\n-\tmainfiles=$(git ls-files) &&\n-\tcheck_equal \"$mainfiles\" \"$chkm\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\tgit merge FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\tgit merge FETCH_HEAD\n+\t) &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree pull --prefix=\"sub dir\" ./\"sub proj\" master &&\n+\n+\t\tchkm=\"main1\n+main2\" &&\n+\t\tchks=\"sub1\n+sub2\n+sub3\n+sub4\" &&\n+\t\tchks_sub=$(cat <<TXT | sed '\\''s,^,sub dir/,'\\''\n+$chks\n+TXT\n+) &&\n+\t\tchkms=\"main-sub1\n+main-sub2\n+main-sub3\n+main-sub4\" &&\n+\t\tchkms_sub=$(cat <<TXT | sed '\\''s,^,sub dir/,'\\''\n+$chkms\n+TXT\n+) &&\n+\t\tmainfiles=$(git ls-files) &&\n+\t\tcheck_equal \"$mainfiles\" \"$chkm\n $chkms_sub\n $chks_sub\"\n+)\n '\n \n+next_test\n test_expect_success 'make sure each filename changed exactly once in the entire history' '\n-\t# main-sub?? and sub dir/main-sub?? both change, because those are the\n-\t# changes that were split into their own history.  And sub dir/sub?? never\n-\t# change, since they were *only* changed in the subtree branch.\n-\tallchanges=''\"$(git log --name-only --pretty=format:'\"''\"' | sort | sed \"/^$/d\")\"'' &&\n-\texpected=''\"$(cat <<TXT | sort\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit config log.date relative\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\tgit merge FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\tgit merge FETCH_HEAD\n+\t) &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree pull --prefix=\"sub dir\" ./\"sub proj\" master &&\n+\n+\t\tchkm=\"main1\n+main2\" &&\n+\t\tchks=\"sub1\n+sub2\n+sub3\n+sub4\" &&\n+\t\tchks_sub=$(cat <<TXT | sed '\\''s,^,sub dir/,'\\''\n+$chks\n+TXT\n+) &&\n+\t\tchkms=\"main-sub1\n+main-sub2\n+main-sub3\n+main-sub4\" &&\n+\t\tchkms_sub=$(cat <<TXT | sed '\\''s,^,sub dir/,'\\''\n+$chkms\n+TXT\n+) &&\n+\n+\t\t# main-sub?? and /\"sub dir\"/main-sub?? both change, because those are the\n+\t\t# changes that were split into their own history.  And \"sub dir\"/sub?? never\n+\t\t# change, since they were *only* changed in the subtree branch.\n+\t\tallchanges=$(git log --name-only --pretty=format:\"\" | sort | sed \"/^$/d\") &&\n+\t\texpected=''\"$(cat <<TXT | sort\n $chkms\n $chkm\n $chks\n $chkms_sub\n TXT\n )\"'' &&\n-\tcheck_equal \"$allchanges\" \"$expected\"\n+\t\tcheck_equal \"$allchanges\" \"$expected\"\n+\t)\n '\n \n+next_test\n test_expect_success 'make sure the --rejoin commits never make it into subproj' '\n-\tcheck_equal \"$(git log --pretty=format:\"%s\" HEAD^2 | grep -i split)\" \"\"\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\tgit merge FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\tgit merge FETCH_HEAD\n+\t) &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree pull --prefix=\"sub dir\" ./\"sub proj\" master &&\n+\t\tcheck_equal \"$(git log --pretty=format:\"%s\" HEAD^2 | grep -i split)\" \"\"\n+\t)\n '\n \n+next_test\n test_expect_success 'make sure no \"git subtree\" tagged commits make it into subproj' '\n-\t# They are meaningless to subproj since one side of the merge refers to the mainline\n-\tcheck_equal \"$(git log --pretty=format:\"%s%n%b\" HEAD^2 | grep \"git-subtree.*:\")\" \"\"\n-'\n-\n-# prepare second pair of repositories\n-mkdir test2\n-cd test2\n-\n-test_expect_success 'init main' '\n-\ttest_create_repo main\n-'\n-\n-cd main\n-\n-test_expect_success 'add main1' '\n-\tcreate main1 &&\n-\tgit commit -m \"main1\"\n-'\n-\n-cd ..\n-\n-test_expect_success 'init sub' '\n-\ttest_create_repo sub\n-'\n-\n-cd sub\n-\n-test_expect_success 'add sub2' '\n-\tcreate sub2 &&\n-\tgit commit -m \"sub2\"\n-'\n-\n-cd ../main\n-\n-# check if split can find proper base without --onto\n-\n-test_expect_success 'add sub as subdir in main' '\n-\tgit fetch ../sub master &&\n-\tgit branch sub2 FETCH_HEAD &&\n-\tgit subtree add --prefix \"sub dir\" sub2\n-'\n-\n-cd ../sub\n-\n-test_expect_success 'add sub3' '\n-\tcreate sub3 &&\n-\tgit commit -m \"sub3\"\n-'\n-\n-cd ../main\n-\n-test_expect_success 'merge from sub' '\n-\tgit fetch ../sub master &&\n-\tgit branch sub3 FETCH_HEAD &&\n-\tgit subtree merge --prefix \"sub dir\" sub3\n-'\n-\n-test_expect_success 'add main-sub4' '\n-\tcreate \"sub dir/main-sub4\" &&\n-\tgit commit -m \"main-sub4\"\n-'\n-\n-test_expect_success 'split for main-sub4 without --onto' '\n-\tgit subtree split --prefix \"sub dir\" --branch mainsub4\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\t git merge FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n+\t) &&\n+\t(\n+\t\tcd \"$subtree_test_count/sub proj\" &&\n+\t\tgit fetch .. subproj-br &&\n+\t\tgit merge FETCH_HEAD\n+\t) &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree pull --prefix=\"sub dir\" ./\"sub proj\" master &&\n+\n+\t\t# They are meaningless to subproj since one side of the merge refers to the mainline\n+\t\tcheck_equal \"$(git log --pretty=format:\"%s%n%b\" HEAD^2 | grep \"git-subtree.*:\")\" \"\"\n+\t)\n '\n \n-# At this point, the new commit parent should be sub3.  If it is not,\n-# something went wrong (the \"newparent\" of \"master~\" commit should\n-# have been sub3, but it was not, because its cache was not set to\n-# itself).\n-\n-test_expect_success 'check that the commit parent is sub3' '\n-\tcheck_equal \"$(git log --pretty=format:%P -1 mainsub4)\" \"$(git rev-parse sub3)\"\n-'\n+#\n+# A new set of tests\n+#\n \n-test_expect_success 'add main-sub5' '\n-\tmkdir subdir2 &&\n-\tcreate subdir2/main-sub5 &&\n-\tgit commit -m \"main-sub5\"\n+next_test\n+test_expect_success 'make sure \"git subtree split\" find the correct parent' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit branch subproj-ref FETCH_HEAD &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --branch subproj-br &&\n+\n+\t\t# at this point, the new commit parent should be subproj-ref, if it is\n+\t\t# not, something went wrong (the \"newparent\" of \"master~\" commit should\n+\t\t# have been sub2, but it was not, because its cache was not set to\n+\t\t# itself)\n+\t\tcheck_equal \"$(git log --pretty=format:%P -1 subproj-br)\" \"$(git rev-parse subproj-ref)\"\n+\t)\n '\n \n-test_expect_success 'split for main-sub5 without --onto' '\n-\t# also test that we still can split out an entirely new subtree\n-\t# if the parent of the first commit in the tree is not empty,\n-\t# then the new subtree has accidentally been attached to something\n-\tgit subtree split --prefix subdir2 --branch mainsub5 &&\n-\tcheck_equal ''\"$(git log --pretty=format:%P -1 mainsub5)\"'' \"\"\n+next_test\n+test_expect_success 'split a new subtree without --onto option' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --branch subproj-br\n+\t) &&\n+\tmkdir \"$subtree_test_count\"/\"sub dir2\" &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir2\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\n+\t\t# also test that we still can split out an entirely new subtree\n+\t\t# if the parent of the first commit in the tree is not empty,\n+\t\t# then the new subtree has accidently been attached to something\n+\t\tgit subtree split --prefix=\"sub dir2\" --branch subproj2-br &&\n+\t\tcheck_equal \"$(git log --pretty=format:%P -1 subproj2-br)\" \"\"\n+\t)\n '\n \n+next_test\n test_expect_success 'verify one file change per commit' '\n-\tx= &&\n-\tlist=''\"$(git log --pretty=format:'\"'commit: %H'\"' | join_commits)\"'' &&\n-#\ttest_debug \"echo HERE\" &&\n-#\ttest_debug \"echo ''\"$list\"''\" &&\n-\tgit log --pretty=format:'\"'commit: %H'\"' | join_commits |\n-\t(\twhile read commit a b; do\n-\t\t\ttest_debug \"echo Verifying commit \"''\"$commit\"''\n-\t\t\ttest_debug \"echo a: \"''\"$a\"''\n-\t\t\ttest_debug \"echo b: \"''\"$b\"''\n-\t\t\tcheck_equal \"$b\" \"\"\n-\t\t\tx=1\n-\t\tdone\n-\t\tcheck_equal \"$x\" \"1\"\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit branch sub1 FETCH_HEAD &&\n+\t\tgit subtree add --prefix=\"sub dir\" sub1\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir\" --branch subproj-br\n+\t) &&\n+\tmkdir \"$subtree_test_count\"/\"sub dir2\" &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir2\"/main-sub2 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit subtree split --prefix=\"sub dir2\" --branch subproj2-br &&\n+\n+\t\tx= &&\n+\t\tgit log --pretty=format:\"commit: %H\" | join_commits |\n+\t\t(\n+\t\t\twhile read commit a b; do\n+\t\t\t\ttest_debug \"echo Verifying commit $commit\"\n+\t\t\t\ttest_debug \"echo a: $a\"\n+\t\t\t\ttest_debug \"echo b: $b\"\n+\t\t\t\tcheck_equal \"$b\" \"\"\n+\t\t\t\tx=1\n+\t\t\tdone\n+\t\t\tcheck_equal \"$x\" 1\n+\t\t)\n \t)\n '\n \n-# test push\n-\n-cd ../..\n-\n-mkdir -p test-push\n-\n-cd test-push\n-\n-test_expect_success 'init main' '\n-\ttest_create_repo main\n-'\n-\n-test_expect_success 'init sub' '\n-\ttest_create_repo \"sub project\"\n-'\n-\n-cd ./\"sub project\"\n-\n-test_expect_success 'add subproject' '\n-\tcreate \"sub project\" &&\n-\tgit commit -m \"Sub project: 1\" &&\n-\tgit branch sub-branch-1\n-'\n-\n-cd ../main\n-\n-test_expect_success 'make first commit and add subproject' '\n-\tcreate \"main-1\" &&\n-\tgit commit -m \"main: 1\" &&\n-\tgit subtree add \"../sub project\" --prefix \"sub dir\" --message \"Added subproject\" sub-branch-1 &&\n-\tcheck_equal \"$(last_commit_message)\" \"Added subproject\"\n-'\n-\n-test_expect_success 'make second commit to a subproject file and push it into a sub project' '\n-\tcreate \"sub dir/sub1\" &&\n-\tgit commit -m \"Sub project: 2\" &&\n-\tgit subtree push \"../sub project\" --prefix \"sub dir\" sub-branch-1\n-'\n-\n-cd ../\"sub project\"\n-\n-test_expect_success 'Test second commit is pushed' '\n-\tgit checkout sub-branch-1 &&\n-\tcheck_equal \"$(last_commit_message)\" \"Sub project: 2\"\n+next_test\n+test_expect_success 'push split to subproj' '\n+\tsubtree_test_create_repo \"$subtree_test_count\" &&\n+\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n+\ttest_create_commit \"$subtree_test_count\" main1 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n+\t(\n+\t\tcd \"$subtree_test_count\" &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n+\ttest_create_commit \"$subtree_test_count\" main2 &&\n+\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n+\t(\n+\t\tcd $subtree_test_count/\"sub proj\" &&\n+                git branch sub-branch-1 &&\n+                cd .. &&\n+\t\tgit fetch ./\"sub proj\" master &&\n+\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n+        (\n+\t\tcd \"$subtree_test_count\" &&\n+\t        git subtree push ./\"sub proj\" --prefix \"sub dir\" sub-branch-1 &&\n+                cd ./\"sub proj\" &&\n+                git checkout sub-branch-1 &&\n+         \tcheck_equal \"$(last_commit_message)\" \"sub dir/main-sub3\"\n+\t)\n '\n \n test_done\n-- \n2.6.1\n"},{"id":"272985","messageId":"1446780903-22156-8-git-send-email-greened@obbligato.org","threadId":"40737","inReplyTo":"1446780903-22156-1-git-send-email-greened@obbligato.org","subject":"[PATCH 7/7] contrib/subtree: Handle '--prefix' argument with a slash appended","fromName":"David Greene","fromEmail":"greened@obbligato.org","sentAt":"2015-11-06T03:35:03Z","receivedAt":"2015-11-06T03:35:03Z","isPatch":true,"sender":{"key":"greened@obbligato.org","avatar":"https://avatars.githubusercontent.com/u/5291869?v=4"},"body":"From: Techlive Zheng <techlivezheng@gmail.com>\n\n'git subtree merge' will fail if the argument of '--prefix' has a slash\nappended.\n\nSigned-off-by: Techlive Zheng <techlivezheng@gmail.com>\nSigned-off-by: David A. Greene <greened@obbligato.org>\n---\n contrib/subtree/git-subtree.sh     |  2 +-\n contrib/subtree/t/t7900-subtree.sh | 20 ++++++++++++++++++++\n 2 files changed, 21 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh\nindex 308b777..edf36f8 100755\n--- a/contrib/subtree/git-subtree.sh\n+++ b/contrib/subtree/git-subtree.sh\n@@ -90,7 +90,7 @@ while [ $# -gt 0 ]; do\n \t\t--annotate) annotate=\"$1\"; shift ;;\n \t\t--no-annotate) annotate= ;;\n \t\t-b) branch=\"$1\"; shift ;;\n-\t\t-P) prefix=\"$1\"; shift ;;\n+\t\t-P) prefix=\"${1%/}\"; shift ;;\n \t\t-m) message=\"$1\"; shift ;;\n \t\t--no-prefix) prefix= ;;\n \t\t--onto) onto=\"$1\"; shift ;;\ndiff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh\nindex 2683d7d..751aee3 100755\n--- a/contrib/subtree/t/t7900-subtree.sh\n+++ b/contrib/subtree/t/t7900-subtree.sh\n@@ -257,6 +257,26 @@ test_expect_success 'merge the added subproj again, should do nothing' '\n \t)\n '\n \n+next_test\n+test_expect_success 'merge new subproj history into subdir/ with a slash appended to the argument of --prefix' '\n+\ttest_create_repo \"$test_count\" &&\n+\ttest_create_repo \"$test_count/subproj\" &&\n+\ttest_create_commit \"$test_count\" main1 &&\n+\ttest_create_commit \"$test_count/subproj\" sub1 &&\n+\t(\n+\t\tcd \"$test_count\" &&\n+\t\tgit fetch ./subproj master &&\n+\t\tgit subtree add --prefix=subdir/ FETCH_HEAD\n+\t) &&\n+\ttest_create_commit \"$test_count/subproj\" sub2 &&\n+\t(\n+\t\tcd \"$test_count\" &&\n+\t\tgit fetch ./subproj master &&\n+\t\tgit subtree merge --prefix=subdir/ FETCH_HEAD &&\n+\t\tcheck_equal \"$(last_commit_message)\" \"Merge commit '\\''$(git rev-parse FETCH_HEAD)'\\''\"\n+\t)\n+'\n+\n #\n # Tests for 'git subtree split'\n #\n-- \n2.6.1\n"},{"id":"273176","messageId":"87egfx1c3s.fsf@waller.obbligato.org","threadId":"40737","inReplyTo":"1446780903-22156-2-git-send-email-greened@obbligato.org","subject":"Re: [PATCH 1/7] contrib/subtree: Clean and refactor test code","fromName":"David A. Greene","fromEmail":"greened@obbligato.org","sentAt":"2015-11-11T02:52:39Z","receivedAt":"2015-11-11T02:52:39Z","isPatch":true,"sender":{"key":"greened@obbligato.org","avatar":"https://avatars.githubusercontent.com/u/5291869?v=4"},"body":"David Greene <greened@obbligato.org> writes:\n\nJust a ping to ask if anyone has looked at this.  Apparently send-email\nuses the commit author as the From address.  These messages are actually\nfrom me, sent on behalf of the commit authors.\n\nI've got more coming, but want to get these in first as they clean up\nthe testsuite and will make adding future changes easier.\n\n                      -David\n\n> From: Techlive Zheng <techlivezheng@gmail.com>\n>\n> Mostly prepare for the later tests refactoring.  This moves some\n> common code to helper functions and generally cleans things up to be\n> more presentable.\n>\n> Signed-off-by: Techlive Zheng <techlivezheng@gmail.com>\n> Signed-off-by: David A. Greene <greened@obbligato.org>\n> ---\n>  contrib/subtree/t/Makefile         |  31 ++++++++---\n>  contrib/subtree/t/t7900-subtree.sh | 103 ++++++++++++++++++++-----------------\n>  2 files changed, 79 insertions(+), 55 deletions(-)\n>\n> diff --git a/contrib/subtree/t/Makefile b/contrib/subtree/t/Makefile\n> index c864810..276898e 100644\n> --- a/contrib/subtree/t/Makefile\n> +++ b/contrib/subtree/t/Makefile\n> @@ -13,11 +13,23 @@ TAR ?= $(TAR)\n>  RM ?= rm -f\n>  PROVE ?= prove\n>  DEFAULT_TEST_TARGET ?= test\n> +TEST_LINT ?= test-lint\n> +\n> +ifdef TEST_OUTPUT_DIRECTORY\n> +TEST_RESULTS_DIRECTORY = $(TEST_OUTPUT_DIRECTORY)/test-results\n> +else\n> +TEST_RESULTS_DIRECTORY = ../../../t/test-results\n> +endif\n>  \n>  # Shell quote;\n>  SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n> +PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n> +TEST_RESULTS_DIRECTORY_SQ = $(subst ','\\'',$(TEST_RESULTS_DIRECTORY))\n>  \n> -T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)\n> +T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))\n> +TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh))\n> +TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh))\n> +THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh)))\n>  \n>  all: $(DEFAULT_TEST_TARGET)\n>  \n> @@ -26,20 +38,22 @@ test: pre-clean $(TEST_LINT)\n>  \n>  prove: pre-clean $(TEST_LINT)\n>  \t@echo \"*** prove ***\"; GIT_CONFIG=.git/config $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)\n> -\t$(MAKE) clean\n> +\t$(MAKE) clean-except-prove-cache\n>  \n>  $(T):\n>  \t@echo \"*** $@ ***\"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)\n>  \n>  pre-clean:\n> -\t$(RM) -r test-results\n> +\t$(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'\n>  \n> -clean:\n> -\t$(RM) -r 'trash directory'.* test-results\n> +clean-except-prove-cache:\n> +\t$(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)'\n>  \t$(RM) -r valgrind/bin\n> +\n> +clean: clean-except-prove-cache\n>  \t$(RM) .prove\n>  \n> -test-lint: test-lint-duplicates test-lint-executable\n> +test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax\n>  \n>  test-lint-duplicates:\n>  \t@dups=`echo $(T) | tr ' ' '\\n' | sed 's/-.*//' | sort | uniq -d` && \\\n> @@ -51,12 +65,15 @@ test-lint-executable:\n>  \t\ttest -z \"$$bad\" || { \\\n>  \t\techo >&2 \"non-executable tests:\" $$bad; exit 1; }\n>  \n> +test-lint-shell-syntax:\n> +\t@'$(PERL_PATH_SQ)' ../../../t/check-non-portable-shell.pl $(T) $(THELPERS)\n> +\n>  aggregate-results-and-cleanup: $(T)\n>  \t$(MAKE) aggregate-results\n>  \t$(MAKE) clean\n>  \n>  aggregate-results:\n> -\tfor f in ../../../t/test-results/t*-*.counts; do \\\n> +\tfor f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \\\n>  \t\techo \"$$f\"; \\\n>  \tdone | '$(SHELL_PATH_SQ)' ../../../t/aggregate-results.sh\n>  \n> diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh\n> index dfbe443..f9dda3d 100755\n> --- a/contrib/subtree/t/t7900-subtree.sh\n> +++ b/contrib/subtree/t/t7900-subtree.sh\n> @@ -5,7 +5,7 @@\n>  #\n>  test_description='Basic porcelain support for subtrees\n>  \n> -This test verifies the basic operation of the merge, pull, add\n> +This test verifies the basic operation of the add, pull, merge\n>  and split subcommands of git subtree.\n>  '\n>  \n> @@ -20,7 +20,6 @@ create()\n>  \tgit add \"$1\"\n>  }\n>  \n> -\n>  check_equal()\n>  {\n>  \ttest_debug 'echo'\n> @@ -38,6 +37,30 @@ undo()\n>  \tgit reset --hard HEAD~\n>  }\n>  \n> +# Make sure no patch changes more than one file.\n> +# The original set of commits changed only one file each.\n> +# A multi-file change would imply that we pruned commits\n> +# too aggressively.\n> +join_commits()\n> +{\n> +\tcommit=\n> +\tall=\n> +\twhile read x y; do\n> +\t\tif [ -z \"$x\" ]; then\n> +\t\t\tcontinue\n> +\t\telif [ \"$x\" = \"commit:\" ]; then\n> +\t\t\tif [ -n \"$commit\" ]; then\n> +\t\t\t\techo \"$commit $all\"\n> +\t\t\t\tall=\n> +\t\t\tfi\n> +\t\t\tcommit=\"$y\"\n> +\t\telse\n> +\t\t\tall=\"$all $y\"\n> +\t\tfi\n> +\tdone\n> +\techo \"$commit $all\"\n> +}\n> +\n>  last_commit_message()\n>  {\n>  \tgit log --pretty=format:%s -1\n> @@ -123,9 +146,11 @@ test_expect_success 'add subproj to mainline' '\n>  \tcheck_equal ''\"$(last_commit_message)\"'' \"Add '\"'sub dir/'\"' from commit '\"'\"'''\"$(git rev-parse sub1)\"'''\"'\"'\"\n>  '\n>  \n> -# this shouldn't actually do anything, since FETCH_HEAD is already a parent\n> -test_expect_success 'merge fetched subproj' '\n> -\tgit merge -m \"merge -s -ours\" -s ours FETCH_HEAD\n> +test_expect_success 'merge the added subproj again, should do nothing' '\n> +\t# this shouldn not actually do anything, since FETCH_HEAD\n> +\t# is already a parent\n> +\tresult=$(git merge -s ours -m \"merge -s -ours\" FETCH_HEAD) &&\n> +\tcheck_equal \"${result}\" \"Already up-to-date.\"\n>  '\n>  \n>  test_expect_success 'add main-sub5' '\n> @@ -167,7 +192,7 @@ test_expect_success 'merge new subproj history into subdir' '\n>  \tundo\n>  '\n>  \n> -test_expect_success 'Check that prefix argument is required for split' '\n> +test_expect_success 'split requires option --prefix' '\n>  \techo \"You must provide the --prefix option.\" > expected &&\n>  \ttest_must_fail git subtree split > actual 2>&1 &&\n>  \ttest_debug \"printf '\"'\"'expected: '\"'\"'\" &&\n> @@ -178,15 +203,15 @@ test_expect_success 'Check that prefix argument is required for split' '\n>  \trm -f expected actual\n>  '\n>  \n> -test_expect_success 'Check that the <prefix> exists for a split' '\n> -\techo \"'\"'\"'non-existent-directory'\"'\"'\" does not exist\\; use \"'\"'\"'git subtree add'\"'\"'\" > expected &&\n> +test_expect_success 'split requires path given by option --prefix must exist' '\n> +\techo \"'\\''non-existent-directory'\\'' does not exist; use '\\''git subtree add'\\''\" > expected &&\n>  \ttest_must_fail git subtree split --prefix=non-existent-directory > actual 2>&1 &&\n>  \ttest_debug \"printf '\"'\"'expected: '\"'\"'\" &&\n>  \ttest_debug \"cat expected\" &&\n>  \ttest_debug \"printf '\"'\"'actual: '\"'\"'\" &&\n>  \ttest_debug \"cat actual\" &&\n> -\ttest_cmp expected actual\n> -#\trm -f expected actual\n> +\ttest_cmp expected actual &&\n> +\trm -f expected actual\n>  '\n>  \n>  test_expect_success 'check if --message works for split+rejoin' '\n> @@ -279,18 +304,22 @@ test_expect_success 'merge split into subproj' '\n>  \n>  chkm=\"main4\n>  main6\"\n> +\n>  chkms=\"main-sub10\n>  main-sub5\n>  main-sub7\n>  main-sub8\"\n> +\n>  chkms_sub=$(cat <<TXT | sed 's,^,sub dir/,'\n>  $chkms\n>  TXT\n>  )\n> +\n>  chks=\"sub1\n>  sub2\n>  sub3\n>  sub9\"\n> +\n>  chks_sub=$(cat <<TXT | sed 's,^,sub dir/,'\n>  $chks\n>  TXT\n> @@ -301,6 +330,7 @@ test_expect_success 'make sure exactly the right set of files ends up in the sub\n>  \tcheck_equal \"$subfiles\" \"$chkms\n>  $chks\"\n>  '\n> +\n>  test_expect_success 'make sure the subproj history *only* contains commits that affect the subdir' '\n>  \tallchanges=''\"$(git log --name-only --pretty=format:'\"''\"' | sort | sed \"/^$/d\")\"'' &&\n>  \tcheck_equal \"$allchanges\" \"$chkms\n> @@ -324,26 +354,27 @@ $chks_sub\"\n>  '\n>  \n>  test_expect_success 'make sure each filename changed exactly once in the entire history' '\n> -\t# main-sub?? and /subdir/main-sub?? both change, because those are the\n> -\t# changes that were split into their own history.  And subdir/sub?? never\n> +\t# main-sub?? and sub dir/main-sub?? both change, because those are the\n> +\t# changes that were split into their own history.  And sub dir/sub?? never\n>  \t# change, since they were *only* changed in the subtree branch.\n>  \tallchanges=''\"$(git log --name-only --pretty=format:'\"''\"' | sort | sed \"/^$/d\")\"'' &&\n> -\tcheck_equal \"$allchanges\" ''\"$(cat <<TXT | sort\n> +\texpected=''\"$(cat <<TXT | sort\n>  $chkms\n>  $chkm\n>  $chks\n>  $chkms_sub\n>  TXT\n> -)\"''\n> +)\"'' &&\n> +\tcheck_equal \"$allchanges\" \"$expected\"\n>  '\n>  \n>  test_expect_success 'make sure the --rejoin commits never make it into subproj' '\n> -\tcheck_equal ''\"$(git log --pretty=format:'\"'%s'\"' HEAD^2 | grep -i split)\"'' \"\"\n> +\tcheck_equal \"$(git log --pretty=format:\"%s\" HEAD^2 | grep -i split)\" \"\"\n>  '\n>  \n>  test_expect_success 'make sure no \"git subtree\" tagged commits make it into subproj' '\n>  \t# They are meaningless to subproj since one side of the merge refers to the mainline\n> -\tcheck_equal ''\"$(git log --pretty=format:'\"'%s%n%b'\"' HEAD^2 | grep \"git-subtree.*:\")\"'' \"\"\n> +\tcheck_equal \"$(git log --pretty=format:\"%s%n%b\" HEAD^2 | grep \"git-subtree.*:\")\" \"\"\n>  '\n>  \n>  # prepare second pair of repositories\n> @@ -408,13 +439,13 @@ test_expect_success 'split for main-sub4 without --onto' '\n>  \tgit subtree split --prefix \"sub dir\" --branch mainsub4\n>  '\n>  \n> -# at this point, the new commit parent should be sub3 if it is not,\n> +# At this point, the new commit parent should be sub3.  If it is not,\n>  # something went wrong (the \"newparent\" of \"master~\" commit should\n>  # have been sub3, but it was not, because its cache was not set to\n> -# itself)\n> +# itself).\n>  \n>  test_expect_success 'check that the commit parent is sub3' '\n> -\tcheck_equal ''\"$(git log --pretty=format:%P -1 mainsub4)\"'' ''\"$(git rev-parse sub3)\"''\n> +\tcheck_equal \"$(git log --pretty=format:%P -1 mainsub4)\" \"$(git rev-parse sub3)\"\n>  '\n>  \n>  test_expect_success 'add main-sub5' '\n> @@ -431,36 +462,12 @@ test_expect_success 'split for main-sub5 without --onto' '\n>  \tcheck_equal ''\"$(git log --pretty=format:%P -1 mainsub5)\"'' \"\"\n>  '\n>  \n> -# make sure no patch changes more than one file.  The original set of commits\n> -# changed only one file each.  A multi-file change would imply that we pruned\n> -# commits too aggressively.\n> -joincommits()\n> -{\n> -\tcommit=\n> -\tall=\n> -\twhile read x y; do\n> -\t\t#echo \"{$x}\" >&2\n> -\t\tif [ -z \"$x\" ]; then\n> -\t\t\tcontinue\n> -\t\telif [ \"$x\" = \"commit:\" ]; then\n> -\t\t\tif [ -n \"$commit\" ]; then\n> -\t\t\t\techo \"$commit $all\"\n> -\t\t\t\tall=\n> -\t\t\tfi\n> -\t\t\tcommit=\"$y\"\n> -\t\telse\n> -\t\t\tall=\"$all $y\"\n> -\t\tfi\n> -\tdone\n> -\techo \"$commit $all\"\n> -}\n> -\n>  test_expect_success 'verify one file change per commit' '\n>  \tx= &&\n> -\tlist=''\"$(git log --pretty=format:'\"'commit: %H'\"' | joincommits)\"'' &&\n> +\tlist=''\"$(git log --pretty=format:'\"'commit: %H'\"' | join_commits)\"'' &&\n>  #\ttest_debug \"echo HERE\" &&\n>  #\ttest_debug \"echo ''\"$list\"''\" &&\n> -\t(git log --pretty=format:'\"'commit: %H'\"' | joincommits |\n> +\tgit log --pretty=format:'\"'commit: %H'\"' | join_commits |\n>  \t(\twhile read commit a b; do\n>  \t\t\ttest_debug \"echo Verifying commit \"''\"$commit\"''\n>  \t\t\ttest_debug \"echo a: \"''\"$a\"''\n> @@ -468,15 +475,15 @@ test_expect_success 'verify one file change per commit' '\n>  \t\t\tcheck_equal \"$b\" \"\"\n>  \t\t\tx=1\n>  \t\tdone\n> -\t\tcheck_equal \"$x\" 1\n> -\t))\n> +\t\tcheck_equal \"$x\" \"1\"\n> +\t)\n>  '\n>  \n>  # test push\n>  \n>  cd ../..\n>  \n> -mkdir test-push\n> +mkdir -p test-push\n>  \n>  cd test-push\n"}]}