{"thread":{"id":"51746","subject":"[PATCH 5/5] Signing API: Duplicated signing tests using new config aliases","startedAt":"2019-08-26T19:58:52Z","lastAt":"2019-08-27T18:54:31Z","messageCount":3,"participants":["Ibrahim El","brian m. carlson"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"381250","messageId":"xidzc1zBudSNNUInNKpDPgAw3AlwtABPT9VpKuPpAfVodvQejHn5WHIYTrqlMlJEYB11iMVhxNCQKBnx7phcHaiPQhHLaqKgeVZwPTCx4n4=@pm.me","threadId":"51746","inReplyTo":null,"subject":"[PATCH 5/5] Signing API: Duplicated signing tests using new config aliases","fromName":"Ibrahim El","fromEmail":"ibrahim.el@pm.me","sentAt":"2019-08-26T19:58:10Z","receivedAt":"2019-08-26T19:58:52Z","isPatch":true,"sender":{"key":"ibrahim.el@pm.me","avatar":null},"body":"From: Ibrahim El Rhezzali <ibrahim.el@pm.me>\n\nc6a1d1c21 Duplicated signing tests using new config aliases\n\nDuplicating existing tests that are signature related and updating them to use the new config aliases\n\nSigned-off-by: Ibrahim El <ibrahim.el@pm.me>\n---\n t/t3431-rebase-interactive-signconfig.sh | 1480 +++++++++++++++++++++\n t/t4215-log-signconfig.sh                | 1710 ++++++++++++++++++++++++\n t/t5548-push-signed-signconfig.sh        |  276 ++++\n t/t7013-tag-signconfig.sh                | 2074 ++++++++++++++++++++++++++++++\n t/t7031-verify-tag-signconfig.sh         |  175 +++\n t/t7522-signed-commit-signconfig.sh      |  288 +++++\n 6 files changed, 6003 insertions(+)\n create mode 100755 t/t3431-rebase-interactive-signconfig.sh\n create mode 100755 t/t4215-log-signconfig.sh\n create mode 100755 t/t5548-push-signed-signconfig.sh\n create mode 100755 t/t7013-tag-signconfig.sh\n create mode 100755 t/t7031-verify-tag-signconfig.sh\n create mode 100755 t/t7522-signed-commit-signconfig.sh\n\ndiff --git a/t/t3431-rebase-interactive-signconfig.sh b/t/t3431-rebase-interactive-signconfig.sh\nnew file mode 100755\nindex 000000000..ffa409292\n--- /dev/null\n+++ b/t/t3431-rebase-interactive-signconfig.sh\n@@ -0,0 +1,1480 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2007 Johannes E. Schindelin\n+#\n+\n+test_description='git rebase interactive\n+\n+This test runs git rebase \"interactively\", by faking an edit, and verifies\n+that the result still makes sense.\n+\n+Initial setup:\n+\n+     one - two - three - four (conflict-branch)\n+   /\n+ A - B - C - D - E            (master)\n+ | \\\n+ |   F - G - H                (branch1)\n+ |     \\\n+ |\\      I                    (branch2)\n+ | \\\n+ |   J - K - L - M            (no-conflict-branch)\n+  \\\n+    N - O - P                 (no-ff-branch)\n+\n+ where A, B, D and G all touch file1, and one, two, three, four all\n+ touch file \"conflict\".\n+'\n+. ./test-lib.sh\n+\n+. \"$TEST_DIRECTORY\"/lib-rebase.sh\n+\n+# WARNING: Modifications to the initial repository can change the SHA ID used\n+# in the expect2 file for the 'stop on conflicting pick' test.\n+\n+test_expect_success 'setup' '\n+\ttest_commit A file1 &&\n+\ttest_commit B file1 &&\n+\ttest_commit C file2 &&\n+\ttest_commit D file1 &&\n+\ttest_commit E file3 &&\n+\tgit checkout -b branch1 A &&\n+\ttest_commit F file4 &&\n+\ttest_commit G file1 &&\n+\ttest_commit H file5 &&\n+\tgit checkout -b branch2 F &&\n+\ttest_commit I file6 &&\n+\tgit checkout -b conflict-branch A &&\n+\ttest_commit one conflict &&\n+\ttest_commit two conflict &&\n+\ttest_commit three conflict &&\n+\ttest_commit four conflict &&\n+\tgit checkout -b no-conflict-branch A &&\n+\ttest_commit J fileJ &&\n+\ttest_commit K fileK &&\n+\ttest_commit L fileL &&\n+\ttest_commit M fileM &&\n+\tgit checkout -b no-ff-branch A &&\n+\ttest_commit N fileN &&\n+\ttest_commit O fileO &&\n+\ttest_commit P fileP\n+'\n+\n+# \"exec\" commands are run with the user shell by default, but this may\n+# be non-POSIX. For example, if SHELL=zsh then \">file\" doesn't work\n+# to create a file. Unsetting SHELL avoids such non-portable behavior\n+# in tests. It must be exported for it to take effect where needed.\n+SHELL=\n+export SHELL\n+\n+test_expect_success 'rebase --keep-empty' '\n+\tgit checkout -b emptybranch master &&\n+\tgit commit --allow-empty -m \"empty\" &&\n+\tgit rebase --keep-empty -i HEAD~2 &&\n+\tgit log --oneline >actual &&\n+\ttest_line_count = 6 actual\n+'\n+\n+cat > expect <<EOF\n+error: nothing to do\n+EOF\n+\n+test_expect_success 'rebase -i with empty HEAD' '\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"1 exec_true\" git rebase -i HEAD^ >actual 2>&1 &&\n+\ttest_i18ncmp expect actual\n+'\n+\n+test_expect_success 'rebase -i with the exec command' '\n+\tgit checkout master &&\n+\t(\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 exec_>touch-one\n+\t\t2 exec_>touch-two exec_false exec_>touch-three\n+\t\t3 4 exec_>\\\"touch-file__name_with_spaces\\\";_>touch-after-semicolon 5\" &&\n+\texport FAKE_LINES &&\n+\ttest_must_fail git rebase -i A\n+\t) &&\n+\ttest_path_is_file touch-one &&\n+\ttest_path_is_file touch-two &&\n+\ttest_path_is_missing touch-three \" (should have stopped before)\" &&\n+\ttest_cmp_rev C HEAD &&\n+\tgit rebase --continue &&\n+\ttest_path_is_file touch-three &&\n+\ttest_path_is_file \"touch-file  name with spaces\" &&\n+\ttest_path_is_file touch-after-semicolon &&\n+\ttest_cmp_rev master HEAD &&\n+\trm -f touch-*\n+'\n+\n+test_expect_success 'rebase -i with the exec command runs from tree root' '\n+\tgit checkout master &&\n+\tmkdir subdir && (cd subdir &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 exec_>touch-subdir\" \\\n+\t\tgit rebase -i HEAD^\n+\t) &&\n+\ttest_path_is_file touch-subdir &&\n+\trm -fr subdir\n+'\n+\n+test_expect_success 'rebase -i with exec allows git commands in subdirs' '\n+\ttest_when_finished \"rm -rf subdir\" &&\n+\ttest_when_finished \"git rebase --abort ||:\" &&\n+\tgit checkout master &&\n+\tmkdir subdir && (cd subdir &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 x_cd_subdir_&&_git_rev-parse_--is-inside-work-tree\" \\\n+\t\tgit rebase -i HEAD^\n+\t)\n+'\n+\n+test_expect_success 'rebase -i sets work tree properly' '\n+\ttest_when_finished \"rm -rf subdir\" &&\n+\ttest_when_finished \"test_might_fail git rebase --abort\" &&\n+\tmkdir subdir &&\n+\tgit rebase -x \"(cd subdir && git rev-parse --show-toplevel)\" HEAD^ \\\n+\t\t>actual &&\n+\t! grep \"/subdir$\" actual\n+'\n+\n+test_expect_success 'rebase -i with the exec command checks tree cleanness' '\n+\tgit checkout master &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"exec_echo_foo_>file1 1\" git rebase -i HEAD^ &&\n+\ttest_cmp_rev master^ HEAD &&\n+\tgit reset --hard &&\n+\tgit rebase --continue\n+'\n+\n+test_expect_success 'rebase -x with empty command fails' '\n+\ttest_when_finished \"git rebase --abort ||:\" &&\n+\ttest_must_fail env git rebase -x \"\" @ 2>actual &&\n+\ttest_write_lines \"error: empty exec command\" >expected &&\n+\ttest_i18ncmp expected actual &&\n+\ttest_must_fail env git rebase -x \" \" @ 2>actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+LF='\n+'\n+test_expect_success 'rebase -x with newline in command fails' '\n+\ttest_when_finished \"git rebase --abort ||:\" &&\n+\ttest_must_fail env git rebase -x \"a${LF}b\" @ 2>actual &&\n+\ttest_write_lines \"error: exec commands cannot contain newlines\" \\\n+\t\t\t >expected &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+test_expect_success 'rebase -i with exec of inexistent command' '\n+\tgit checkout master &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"exec_this-command-does-not-exist 1\" \\\n+\tgit rebase -i HEAD^ >actual 2>&1 &&\n+\t! grep \"Maybe git-rebase is broken\" actual\n+'\n+\n+test_expect_success 'implicit interactive rebase does not invoke sequence editor' '\n+\ttest_when_finished \"git rebase --abort ||:\" &&\n+\tGIT_SEQUENCE_EDITOR=\"echo bad >\" git rebase -x\"echo one\" @^\n+'\n+\n+test_expect_success 'no changes are a nop' '\n+\tgit checkout branch2 &&\n+\tset_fake_editor &&\n+\tgit rebase -i F &&\n+\ttest \"$(git symbolic-ref -q HEAD)\" = \"refs/heads/branch2\" &&\n+\ttest $(git rev-parse I) = $(git rev-parse HEAD)\n+'\n+\n+test_expect_success 'test the [branch] option' '\n+\tgit checkout -b dead-end &&\n+\tgit rm file6 &&\n+\tgit commit -m \"stop here\" &&\n+\tset_fake_editor &&\n+\tgit rebase -i F branch2 &&\n+\ttest \"$(git symbolic-ref -q HEAD)\" = \"refs/heads/branch2\" &&\n+\ttest $(git rev-parse I) = $(git rev-parse branch2) &&\n+\ttest $(git rev-parse I) = $(git rev-parse HEAD)\n+'\n+\n+test_expect_success 'test --onto <branch>' '\n+\tgit checkout -b test-onto branch2 &&\n+\tset_fake_editor &&\n+\tgit rebase -i --onto branch1 F &&\n+\ttest \"$(git symbolic-ref -q HEAD)\" = \"refs/heads/test-onto\" &&\n+\ttest $(git rev-parse HEAD^) = $(git rev-parse branch1) &&\n+\ttest $(git rev-parse I) = $(git rev-parse branch2)\n+'\n+\n+test_expect_success 'rebase on top of a non-conflicting commit' '\n+\tgit checkout branch1 &&\n+\tgit tag original-branch1 &&\n+\tset_fake_editor &&\n+\tgit rebase -i branch2 &&\n+\ttest file6 = $(git diff --name-only original-branch1) &&\n+\ttest \"$(git symbolic-ref -q HEAD)\" = \"refs/heads/branch1\" &&\n+\ttest $(git rev-parse I) = $(git rev-parse branch2) &&\n+\ttest $(git rev-parse I) = $(git rev-parse HEAD~2)\n+'\n+\n+test_expect_success 'reflog for the branch shows state before rebase' '\n+\ttest $(git rev-parse branch1@{1}) = $(git rev-parse original-branch1)\n+'\n+\n+test_expect_success 'reflog for the branch shows correct finish message' '\n+\tprintf \"rebase -i (finish): refs/heads/branch1 onto %s\\n\" \\\n+\t\t\"$(git rev-parse branch2)\" >expected &&\n+\tgit log -g --pretty=%gs -1 refs/heads/branch1 >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'exchange two commits' '\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"2 1\" git rebase -i HEAD~2 &&\n+\ttest H = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n+\ttest G = $(git cat-file commit HEAD | sed -ne \\$p)\n+'\n+\n+cat > expect << EOF\n+diff --git a/file1 b/file1\n+index f70f10e..fd79235 100644\n+--- a/file1\n++++ b/file1\n+@@ -1 +1 @@\n+-A\n++G\n+EOF\n+\n+cat > expect2 << EOF\n+<<<<<<< HEAD\n+D\n+=======\n+G\n+>>>>>>> 5d18e54... G\n+EOF\n+\n+test_expect_success 'stop on conflicting pick' '\n+\tgit tag new-branch1 &&\n+\tset_fake_editor &&\n+\ttest_must_fail git rebase -i master &&\n+\ttest \"$(git rev-parse HEAD~3)\" = \"$(git rev-parse master)\" &&\n+\ttest_cmp expect .git/rebase-merge/patch &&\n+\ttest_cmp expect2 file1 &&\n+\ttest \"$(git diff --name-status |\n+\t\tsed -n -e \"/^U/s/^U[^a-z]*//p\")\" = file1 &&\n+\ttest 4 = $(grep -v \"^#\" < .git/rebase-merge/done | wc -l) &&\n+\ttest 0 = $(grep -c \"^[^#]\" < .git/rebase-merge/git-rebase-todo)\n+'\n+\n+test_expect_success 'show conflicted patch' '\n+\tGIT_TRACE=1 git rebase --show-current-patch >/dev/null 2>stderr &&\n+\tgrep \"show.*REBASE_HEAD\" stderr &&\n+\t# the original stopped-sha1 is abbreviated\n+\tstopped_sha1=\"$(git rev-parse $(cat \".git/rebase-merge/stopped-sha\"))\" &&\n+\ttest \"$(git rev-parse REBASE_HEAD)\" = \"$stopped_sha1\"\n+'\n+\n+test_expect_success 'abort' '\n+\tgit rebase --abort &&\n+\ttest $(git rev-parse new-branch1) = $(git rev-parse HEAD) &&\n+\ttest \"$(git symbolic-ref -q HEAD)\" = \"refs/heads/branch1\" &&\n+\ttest_path_is_missing .git/rebase-merge\n+'\n+\n+test_expect_success 'abort with error when new base cannot be checked out' '\n+\tgit rm --cached file1 &&\n+\tgit commit -m \"remove file in base\" &&\n+\tset_fake_editor &&\n+\ttest_must_fail git rebase -i master > output 2>&1 &&\n+\ttest_i18ngrep \"The following untracked working tree files would be overwritten by checkout:\" \\\n+\t\toutput &&\n+\ttest_i18ngrep \"file1\" output &&\n+\ttest_path_is_missing .git/rebase-merge &&\n+\tgit reset --hard HEAD^\n+'\n+\n+test_expect_success 'retain authorship' '\n+\techo A > file7 &&\n+\tgit add file7 &&\n+\ttest_tick &&\n+\tGIT_AUTHOR_NAME=\"Twerp Snog\" git commit -m \"different author\" &&\n+\tgit tag twerp &&\n+\tset_fake_editor &&\n+\tgit rebase -i --onto master HEAD^ &&\n+\tgit show HEAD | grep \"^Author: Twerp Snog\"\n+'\n+\n+test_expect_success 'retain authorship w/ conflicts' '\n+\toGIT_AUTHOR_NAME=$GIT_AUTHOR_NAME &&\n+\ttest_when_finished \"GIT_AUTHOR_NAME=\\$oGIT_AUTHOR_NAME\" &&\n+\n+\tgit reset --hard twerp &&\n+\ttest_commit a conflict a conflict-a &&\n+\tgit reset --hard twerp &&\n+\n+\tGIT_AUTHOR_NAME=AttributeMe &&\n+\texport GIT_AUTHOR_NAME &&\n+\ttest_commit b conflict b conflict-b &&\n+\tGIT_AUTHOR_NAME=$oGIT_AUTHOR_NAME &&\n+\n+\tset_fake_editor &&\n+\ttest_must_fail git rebase -i conflict-a &&\n+\techo resolved >conflict &&\n+\tgit add conflict &&\n+\tgit rebase --continue &&\n+\ttest $(git rev-parse conflict-a^0) = $(git rev-parse HEAD^) &&\n+\tgit show >out &&\n+\tgrep AttributeMe out\n+'\n+\n+test_expect_success 'squash' '\n+\tgit reset --hard twerp &&\n+\techo B > file7 &&\n+\ttest_tick &&\n+\tGIT_AUTHOR_NAME=\"Nitfol\" git commit -m \"nitfol\" file7 &&\n+\techo \"******************************\" &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 squash 2\" EXPECT_HEADER_COUNT=2 \\\n+\t\tgit rebase -i --onto master HEAD~2 &&\n+\ttest B = $(cat file7) &&\n+\ttest $(git rev-parse HEAD^) = $(git rev-parse master)\n+'\n+\n+test_expect_success 'retain authorship when squashing' '\n+\tgit show HEAD | grep \"^Author: Twerp Snog\"\n+'\n+\n+test_expect_success REBASE_P '-p handles \"no changes\" gracefully' '\n+\tHEAD=$(git rev-parse HEAD) &&\n+\tset_fake_editor &&\n+\tgit rebase -i -p HEAD^ &&\n+\tgit update-index --refresh &&\n+\tgit diff-files --quiet &&\n+\tgit diff-index --quiet --cached HEAD -- &&\n+\ttest $HEAD = $(git rev-parse HEAD)\n+'\n+\n+test_expect_failure REBASE_P 'exchange two commits with -p' '\n+\tgit checkout H &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"2 1\" git rebase -i -p HEAD~2 &&\n+\ttest H = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n+\ttest G = $(git cat-file commit HEAD | sed -ne \\$p)\n+'\n+\n+test_expect_success REBASE_P 'preserve merges with -p' '\n+\tgit checkout -b to-be-preserved master^ &&\n+\t: > unrelated-file &&\n+\tgit add unrelated-file &&\n+\ttest_tick &&\n+\tgit commit -m \"unrelated\" &&\n+\tgit checkout -b another-branch master &&\n+\techo B > file1 &&\n+\ttest_tick &&\n+\tgit commit -m J file1 &&\n+\ttest_tick &&\n+\tgit merge to-be-preserved &&\n+\techo C > file1 &&\n+\ttest_tick &&\n+\tgit commit -m K file1 &&\n+\techo D > file1 &&\n+\ttest_tick &&\n+\tgit commit -m L1 file1 &&\n+\tgit checkout HEAD^ &&\n+\techo 1 > unrelated-file &&\n+\ttest_tick &&\n+\tgit commit -m L2 unrelated-file &&\n+\ttest_tick &&\n+\tgit merge another-branch &&\n+\techo E > file1 &&\n+\ttest_tick &&\n+\tgit commit -m M file1 &&\n+\tgit checkout -b to-be-rebased &&\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\tgit rebase -i -p --onto branch1 master &&\n+\tgit update-index --refresh &&\n+\tgit diff-files --quiet &&\n+\tgit diff-index --quiet --cached HEAD -- &&\n+\ttest $(git rev-parse HEAD~6) = $(git rev-parse branch1) &&\n+\ttest $(git rev-parse HEAD~4^2) = $(git rev-parse to-be-preserved) &&\n+\ttest $(git rev-parse HEAD^^2^) = $(git rev-parse HEAD^^^) &&\n+\ttest $(git show HEAD~5:file1) = B &&\n+\ttest $(git show HEAD~3:file1) = C &&\n+\ttest $(git show HEAD:file1) = E &&\n+\ttest $(git show HEAD:unrelated-file) = 1\n+'\n+\n+test_expect_success REBASE_P 'edit ancestor with -p' '\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 2 edit 3 4\" git rebase -i -p HEAD~3 &&\n+\techo 2 > unrelated-file &&\n+\ttest_tick &&\n+\tgit commit -m L2-modified --amend unrelated-file &&\n+\tgit rebase --continue &&\n+\tgit update-index --refresh &&\n+\tgit diff-files --quiet &&\n+\tgit diff-index --quiet --cached HEAD -- &&\n+\ttest $(git show HEAD:unrelated-file) = 2\n+'\n+\n+test_expect_success '--continue tries to commit' '\n+\tgit reset --hard D &&\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\ttest_must_fail git rebase -i --onto new-branch1 HEAD^ &&\n+\techo resolved > file1 &&\n+\tgit add file1 &&\n+\tFAKE_COMMIT_MESSAGE=\"chouette!\" git rebase --continue &&\n+\ttest $(git rev-parse HEAD^) = $(git rev-parse new-branch1) &&\n+\tgit show HEAD | grep chouette\n+'\n+\n+test_expect_success 'verbose flag is heeded, even after --continue' '\n+\tgit reset --hard master@{1} &&\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\ttest_must_fail git rebase -v -i --onto new-branch1 HEAD^ &&\n+\techo resolved > file1 &&\n+\tgit add file1 &&\n+\tgit rebase --continue > output &&\n+\tgrep \"^ file1 | 2 +-$\" output\n+'\n+\n+test_expect_success C_LOCALE_OUTPUT 'multi-squash only fires up editor once' '\n+\tbase=$(git rev-parse HEAD~4) &&\n+\tset_fake_editor &&\n+\tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"1 squash 2 squash 3 squash 4\" \\\n+\t\tEXPECT_HEADER_COUNT=4 \\\n+\t\tgit rebase -i $base &&\n+\ttest $base = $(git rev-parse HEAD^) &&\n+\ttest 1 = $(git show | grep ONCE | wc -l)\n+'\n+\n+test_expect_success C_LOCALE_OUTPUT 'multi-fixup does not fire up editor' '\n+\tgit checkout -b multi-fixup E &&\n+\tbase=$(git rev-parse HEAD~4) &&\n+\tset_fake_editor &&\n+\tFAKE_COMMIT_AMEND=\"NEVER\" FAKE_LINES=\"1 fixup 2 fixup 3 fixup 4\" \\\n+\t\tgit rebase -i $base &&\n+\ttest $base = $(git rev-parse HEAD^) &&\n+\ttest 0 = $(git show | grep NEVER | wc -l) &&\n+\tgit checkout @{-1} &&\n+\tgit branch -D multi-fixup\n+'\n+\n+test_expect_success 'commit message used after conflict' '\n+\tgit checkout -b conflict-fixup conflict-branch &&\n+\tbase=$(git rev-parse HEAD~4) &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"1 fixup 3 fixup 4\" git rebase -i $base &&\n+\techo three > conflict &&\n+\tgit add conflict &&\n+\tFAKE_COMMIT_AMEND=\"ONCE\" EXPECT_HEADER_COUNT=2 \\\n+\t\tgit rebase --continue &&\n+\ttest $base = $(git rev-parse HEAD^) &&\n+\ttest 1 = $(git show | grep ONCE | wc -l) &&\n+\tgit checkout @{-1} &&\n+\tgit branch -D conflict-fixup\n+'\n+\n+test_expect_success 'commit message retained after conflict' '\n+\tgit checkout -b conflict-squash conflict-branch &&\n+\tbase=$(git rev-parse HEAD~4) &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"1 fixup 3 squash 4\" git rebase -i $base &&\n+\techo three > conflict &&\n+\tgit add conflict &&\n+\tFAKE_COMMIT_AMEND=\"TWICE\" EXPECT_HEADER_COUNT=2 \\\n+\t\tgit rebase --continue &&\n+\ttest $base = $(git rev-parse HEAD^) &&\n+\ttest 2 = $(git show | grep TWICE | wc -l) &&\n+\tgit checkout @{-1} &&\n+\tgit branch -D conflict-squash\n+'\n+\n+cat > expect-squash-fixup << EOF\n+B\n+\n+D\n+\n+ONCE\n+EOF\n+\n+test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messages' '\n+\tgit checkout -b squash-fixup E &&\n+\tbase=$(git rev-parse HEAD~4) &&\n+\tset_fake_editor &&\n+\tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"1 fixup 2 squash 3 fixup 4\" \\\n+\t\tEXPECT_HEADER_COUNT=4 \\\n+\t\tgit rebase -i $base &&\n+\tgit cat-file commit HEAD | sed -e 1,/^\\$/d > actual-squash-fixup &&\n+\ttest_cmp expect-squash-fixup actual-squash-fixup &&\n+\tgit cat-file commit HEAD@{2} |\n+\t\tgrep \"^# This is a combination of 3 commits\\.\"  &&\n+\tgit cat-file commit HEAD@{3} |\n+\t\tgrep \"^# This is a combination of 2 commits\\.\"  &&\n+\tgit checkout @{-1} &&\n+\tgit branch -D squash-fixup\n+'\n+\n+test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '\n+\tgit checkout -b skip-comments E &&\n+\tbase=$(git rev-parse HEAD~4) &&\n+\tset_fake_editor &&\n+\tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"# 1 # squash 2 # squash 3 # squash 4 #\" \\\n+\t\tEXPECT_HEADER_COUNT=4 \\\n+\t\tgit rebase -i $base &&\n+\ttest $base = $(git rev-parse HEAD^) &&\n+\ttest 1 = $(git show | grep ONCE | wc -l) &&\n+\tgit checkout @{-1} &&\n+\tgit branch -D skip-comments\n+'\n+\n+test_expect_success C_LOCALE_OUTPUT 'squash ignores blank lines' '\n+\tgit checkout -b skip-blank-lines E &&\n+\tbase=$(git rev-parse HEAD~4) &&\n+\tset_fake_editor &&\n+\tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"> 1 > squash 2 > squash 3 > squash 4 >\" \\\n+\t\tEXPECT_HEADER_COUNT=4 \\\n+\t\tgit rebase -i $base &&\n+\ttest $base = $(git rev-parse HEAD^) &&\n+\ttest 1 = $(git show | grep ONCE | wc -l) &&\n+\tgit checkout @{-1} &&\n+\tgit branch -D skip-blank-lines\n+'\n+\n+test_expect_success 'squash works as expected' '\n+\tgit checkout -b squash-works no-conflict-branch &&\n+\tone=$(git rev-parse HEAD~3) &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 s 3 2\" EXPECT_HEADER_COUNT=2 \\\n+\t\tgit rebase -i HEAD~3 &&\n+\ttest $one = $(git rev-parse HEAD~2)\n+'\n+\n+test_expect_success 'interrupted squash works as expected' '\n+\tgit checkout -b interrupted-squash conflict-branch &&\n+\tone=$(git rev-parse HEAD~3) &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"1 squash 3 2\" git rebase -i HEAD~3 &&\n+\ttest_write_lines one two four > conflict &&\n+\tgit add conflict &&\n+\ttest_must_fail git rebase --continue &&\n+\techo resolved > conflict &&\n+\tgit add conflict &&\n+\tgit rebase --continue &&\n+\ttest $one = $(git rev-parse HEAD~2)\n+'\n+\n+test_expect_success 'interrupted squash works as expected (case 2)' '\n+\tgit checkout -b interrupted-squash2 conflict-branch &&\n+\tone=$(git rev-parse HEAD~3) &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"3 squash 1 2\" git rebase -i HEAD~3 &&\n+\ttest_write_lines one four > conflict &&\n+\tgit add conflict &&\n+\ttest_must_fail git rebase --continue &&\n+\ttest_write_lines one two four > conflict &&\n+\tgit add conflict &&\n+\ttest_must_fail git rebase --continue &&\n+\techo resolved > conflict &&\n+\tgit add conflict &&\n+\tgit rebase --continue &&\n+\ttest $one = $(git rev-parse HEAD~2)\n+'\n+\n+test_expect_success '--continue tries to commit, even for \"edit\"' '\n+\techo unrelated > file7 &&\n+\tgit add file7 &&\n+\ttest_tick &&\n+\tgit commit -m \"unrelated change\" &&\n+\tparent=$(git rev-parse HEAD^) &&\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"edit 1\" git rebase -i HEAD^ &&\n+\techo edited > file7 &&\n+\tgit add file7 &&\n+\tFAKE_COMMIT_MESSAGE=\"chouette!\" git rebase --continue &&\n+\ttest edited = $(git show HEAD:file7) &&\n+\tgit show HEAD | grep chouette &&\n+\ttest $parent = $(git rev-parse HEAD^)\n+'\n+\n+test_expect_success 'aborted --continue does not squash commits after \"edit\"' '\n+\told=$(git rev-parse HEAD) &&\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"edit 1\" git rebase -i HEAD^ &&\n+\techo \"edited again\" > file7 &&\n+\tgit add file7 &&\n+\ttest_must_fail env FAKE_COMMIT_MESSAGE=\" \" git rebase --continue &&\n+\ttest $old = $(git rev-parse HEAD) &&\n+\tgit rebase --abort\n+'\n+\n+test_expect_success 'auto-amend only edited commits after \"edit\"' '\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"edit 1\" git rebase -i HEAD^ &&\n+\techo \"edited again\" > file7 &&\n+\tgit add file7 &&\n+\tFAKE_COMMIT_MESSAGE=\"edited file7 again\" git commit &&\n+\techo \"and again\" > file7 &&\n+\tgit add file7 &&\n+\ttest_tick &&\n+\ttest_must_fail env FAKE_COMMIT_MESSAGE=\"and again\" git rebase --continue &&\n+\tgit rebase --abort\n+'\n+\n+test_expect_success 'clean error after failed \"exec\"' '\n+\ttest_tick &&\n+\ttest_when_finished \"git rebase --abort || :\" &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"1 exec_false\" git rebase -i HEAD^ &&\n+\techo \"edited again\" > file7 &&\n+\tgit add file7 &&\n+\ttest_must_fail git rebase --continue 2>error &&\n+\ttest_i18ngrep \"you have staged changes in your working tree\" error\n+'\n+\n+test_expect_success 'rebase a detached HEAD' '\n+\tgrandparent=$(git rev-parse HEAD~2) &&\n+\tgit checkout $(git rev-parse HEAD) &&\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"2 1\" git rebase -i HEAD~2 &&\n+\ttest $grandparent = $(git rev-parse HEAD~2)\n+'\n+\n+test_expect_success 'rebase a commit violating pre-commit' '\n+\n+\tmkdir -p .git/hooks &&\n+\twrite_script .git/hooks/pre-commit <<-\\EOF &&\n+\ttest -z \"$(git diff --cached --check)\"\n+\tEOF\n+\techo \"monde! \" >> file1 &&\n+\ttest_tick &&\n+\ttest_must_fail git commit -m doesnt-verify file1 &&\n+\tgit commit -m doesnt-verify --no-verify file1 &&\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=2 git rebase -i HEAD~2\n+\n+'\n+\n+test_expect_success 'rebase with a file named HEAD in worktree' '\n+\n+\trm -fr .git/hooks &&\n+\tgit reset --hard &&\n+\tgit checkout -b branch3 A &&\n+\n+\t(\n+\t\tGIT_AUTHOR_NAME=\"Squashed Away\" &&\n+\t\texport GIT_AUTHOR_NAME &&\n+\t\t>HEAD &&\n+\t\tgit add HEAD &&\n+\t\tgit commit -m \"Add head\" &&\n+\t\t>BODY &&\n+\t\tgit add BODY &&\n+\t\tgit commit -m \"Add body\"\n+\t) &&\n+\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 squash 2\" git rebase -i @{-1} &&\n+\ttest \"$(git show -s --pretty=format:%an)\" = \"Squashed Away\"\n+\n+'\n+\n+test_expect_success 'do \"noop\" when there is nothing to cherry-pick' '\n+\n+\tgit checkout -b branch4 HEAD &&\n+\tGIT_EDITOR=: git commit --amend \\\n+\t\t--author=\"Somebody else <somebody@else.com>\" &&\n+\ttest $(git rev-parse branch3) != $(git rev-parse branch4) &&\n+\tset_fake_editor &&\n+\tgit rebase -i branch3 &&\n+\ttest $(git rev-parse branch3) = $(git rev-parse branch4)\n+\n+'\n+\n+test_expect_success 'submodule rebase setup' '\n+\tgit checkout A &&\n+\tmkdir sub &&\n+\t(\n+\t\tcd sub && git init && >elif &&\n+\t\tgit add elif && git commit -m \"submodule initial\"\n+\t) &&\n+\techo 1 >file1 &&\n+\tgit add file1 sub &&\n+\ttest_tick &&\n+\tgit commit -m \"One\" &&\n+\techo 2 >file1 &&\n+\ttest_tick &&\n+\tgit commit -a -m \"Two\" &&\n+\t(\n+\t\tcd sub && echo 3 >elif &&\n+\t\tgit commit -a -m \"submodule second\"\n+\t) &&\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\tgit commit -a -m \"Three changes submodule\"\n+'\n+\n+test_expect_success 'submodule rebase -i' '\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 squash 2 3\" git rebase -i A\n+'\n+\n+test_expect_success 'submodule conflict setup' '\n+\tgit tag submodule-base &&\n+\tgit checkout HEAD^ &&\n+\t(\n+\t\tcd sub && git checkout HEAD^ && echo 4 >elif &&\n+\t\tgit add elif && git commit -m \"submodule conflict\"\n+\t) &&\n+\tgit add sub &&\n+\ttest_tick &&\n+\tgit commit -m \"Conflict in submodule\" &&\n+\tgit tag submodule-topic\n+'\n+\n+test_expect_success 'rebase -i continue with only submodule staged' '\n+\tset_fake_editor &&\n+\ttest_must_fail git rebase -i submodule-base &&\n+\tgit add sub &&\n+\tgit rebase --continue &&\n+\ttest $(git rev-parse submodule-base) != $(git rev-parse HEAD)\n+'\n+\n+test_expect_success 'rebase -i continue with unstaged submodule' '\n+\tgit checkout submodule-topic &&\n+\tgit reset --hard &&\n+\tset_fake_editor &&\n+\ttest_must_fail git rebase -i submodule-base &&\n+\tgit reset &&\n+\tgit rebase --continue &&\n+\ttest $(git rev-parse submodule-base) = $(git rev-parse HEAD)\n+'\n+\n+test_expect_success 'avoid unnecessary reset' '\n+\tgit checkout master &&\n+\tgit reset --hard &&\n+\ttest-tool chmtime =123456789 file3 &&\n+\tgit update-index --refresh &&\n+\tHEAD=$(git rev-parse HEAD) &&\n+\tset_fake_editor &&\n+\tgit rebase -i HEAD~4 &&\n+\ttest $HEAD = $(git rev-parse HEAD) &&\n+\tMTIME=$(test-tool chmtime --get file3) &&\n+\ttest 123456789 = $MTIME\n+'\n+\n+test_expect_success 'reword' '\n+\tgit checkout -b reword-branch master &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 2 3 reword 4\" FAKE_COMMIT_MESSAGE=\"E changed\" git rebase -i A &&\n+\tgit show HEAD | grep \"E changed\" &&\n+\ttest $(git rev-parse master) != $(git rev-parse HEAD) &&\n+\ttest $(git rev-parse master^) = $(git rev-parse HEAD^) &&\n+\tFAKE_LINES=\"1 2 reword 3 4\" FAKE_COMMIT_MESSAGE=\"D changed\" git rebase -i A &&\n+\tgit show HEAD^ | grep \"D changed\" &&\n+\tFAKE_LINES=\"reword 1 2 3 4\" FAKE_COMMIT_MESSAGE=\"B changed\" git rebase -i A &&\n+\tgit show HEAD~3 | grep \"B changed\" &&\n+\tFAKE_LINES=\"1 r 2 pick 3 p 4\" FAKE_COMMIT_MESSAGE=\"C changed\" git rebase -i A &&\n+\tgit show HEAD~2 | grep \"C changed\"\n+'\n+\n+test_expect_success 'rebase -i can copy notes' '\n+\tgit config notes.rewrite.rebase true &&\n+\tgit config notes.rewriteRef \"refs/notes/*\" &&\n+\ttest_commit n1 &&\n+\ttest_commit n2 &&\n+\ttest_commit n3 &&\n+\tgit notes add -m\"a note\" n3 &&\n+\tset_fake_editor &&\n+\tgit rebase -i --onto n1 n2 &&\n+\ttest \"a note\" = \"$(git notes show HEAD)\"\n+'\n+\n+cat >expect <<EOF\n+an earlier note\n+\n+a note\n+EOF\n+\n+test_expect_success 'rebase -i can copy notes over a fixup' '\n+\tgit reset --hard n3 &&\n+\tgit notes add -m\"an earlier note\" n2 &&\n+\tset_fake_editor &&\n+\tGIT_NOTES_REWRITE_MODE=concatenate FAKE_LINES=\"1 f 2\" git rebase -i n1 &&\n+\tgit notes show > output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success 'rebase while detaching HEAD' '\n+\tgit symbolic-ref HEAD &&\n+\tgrandparent=$(git rev-parse HEAD~2) &&\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"2 1\" git rebase -i HEAD~2 HEAD^0 &&\n+\ttest $grandparent = $(git rev-parse HEAD~2) &&\n+\ttest_must_fail git symbolic-ref HEAD\n+'\n+\n+test_tick # Ensure that the rebased commits get a different timestamp.\n+test_expect_success 'always cherry-pick with --no-ff' '\n+\tgit checkout no-ff-branch &&\n+\tgit tag original-no-ff-branch &&\n+\tset_fake_editor &&\n+\tgit rebase -i --no-ff A &&\n+\tfor p in 0 1 2\n+\tdo\n+\t\ttest ! $(git rev-parse HEAD~$p) = $(git rev-parse original-no-ff-branch~$p) &&\n+\t\tgit diff HEAD~$p original-no-ff-branch~$p > out &&\n+\t\ttest_must_be_empty out\n+\tdone &&\n+\ttest $(git rev-parse HEAD~3) = $(git rev-parse original-no-ff-branch~3) &&\n+\tgit diff HEAD~3 original-no-ff-branch~3 > out &&\n+\ttest_must_be_empty out\n+'\n+\n+test_expect_success 'set up commits with funny messages' '\n+\tgit checkout -b funny A &&\n+\techo >>file1 &&\n+\ttest_tick &&\n+\tgit commit -a -m \"end with slash\\\\\" &&\n+\techo >>file1 &&\n+\ttest_tick &&\n+\tgit commit -a -m \"something (\\000) that looks like octal\" &&\n+\techo >>file1 &&\n+\ttest_tick &&\n+\tgit commit -a -m \"something (\\n) that looks like a newline\" &&\n+\techo >>file1 &&\n+\ttest_tick &&\n+\tgit commit -a -m \"another commit\"\n+'\n+\n+test_expect_success 'rebase-i history with funny messages' '\n+\tgit rev-list A..funny >expect &&\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 2 3 4\" git rebase -i A &&\n+\tgit rev-list A.. >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'prepare for rebase -i --exec' '\n+\tgit checkout master &&\n+\tgit checkout -b execute &&\n+\ttest_commit one_exec main.txt one_exec &&\n+\ttest_commit two_exec main.txt two_exec &&\n+\ttest_commit three_exec main.txt three_exec\n+'\n+\n+test_expect_success 'running \"git rebase -i --exec git show HEAD\"' '\n+\tset_fake_editor &&\n+\tgit rebase -i --exec \"git show HEAD\" HEAD~2 >actual &&\n+\t(\n+\t\tFAKE_LINES=\"1 exec_git_show_HEAD 2 exec_git_show_HEAD\" &&\n+\t\texport FAKE_LINES &&\n+\t\tgit rebase -i HEAD~2 >expect\n+\t) &&\n+\tsed -e \"1,9d\" expect >expected &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'running \"git rebase --exec git show HEAD -i\"' '\n+\tgit reset --hard execute &&\n+\tset_fake_editor &&\n+\tgit rebase --exec \"git show HEAD\" -i HEAD~2 >actual &&\n+\t(\n+\t\tFAKE_LINES=\"1 exec_git_show_HEAD 2 exec_git_show_HEAD\" &&\n+\t\texport FAKE_LINES &&\n+\t\tgit rebase -i HEAD~2 >expect\n+\t) &&\n+\tsed -e \"1,9d\" expect >expected &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'running \"git rebase -ix git show HEAD\"' '\n+\tgit reset --hard execute &&\n+\tset_fake_editor &&\n+\tgit rebase -ix \"git show HEAD\" HEAD~2 >actual &&\n+\t(\n+\t\tFAKE_LINES=\"1 exec_git_show_HEAD 2 exec_git_show_HEAD\" &&\n+\t\texport FAKE_LINES &&\n+\t\tgit rebase -i HEAD~2 >expect\n+\t) &&\n+\tsed -e \"1,9d\" expect >expected &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'rebase -ix with several <CMD>' '\n+\tgit reset --hard execute &&\n+\tset_fake_editor &&\n+\tgit rebase -ix \"git show HEAD; pwd\" HEAD~2 >actual &&\n+\t(\n+\t\tFAKE_LINES=\"1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd\" &&\n+\t\texport FAKE_LINES &&\n+\t\tgit rebase -i HEAD~2 >expect\n+\t) &&\n+\tsed -e \"1,9d\" expect >expected &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'rebase -ix with several instances of --exec' '\n+\tgit reset --hard execute &&\n+\tset_fake_editor &&\n+\tgit rebase -i --exec \"git show HEAD\" --exec \"pwd\" HEAD~2 >actual &&\n+\t(\n+\t\tFAKE_LINES=\"1 exec_git_show_HEAD exec_pwd 2\n+\t\t\t\texec_git_show_HEAD exec_pwd\" &&\n+\t\texport FAKE_LINES &&\n+\t\tgit rebase -i HEAD~2 >expect\n+\t) &&\n+\tsed -e \"1,11d\" expect >expected &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success C_LOCALE_OUTPUT 'rebase -ix with --autosquash' '\n+\tgit reset --hard execute &&\n+\tgit checkout -b autosquash &&\n+\techo second >second.txt &&\n+\tgit add second.txt &&\n+\tgit commit -m \"fixup! two_exec\" &&\n+\techo bis >bis.txt &&\n+\tgit add bis.txt &&\n+\tgit commit -m \"fixup! two_exec\" &&\n+\tset_fake_editor &&\n+\t(\n+\t\tgit checkout -b autosquash_actual &&\n+\t\tgit rebase -i --exec \"git show HEAD\" --autosquash HEAD~4 >actual\n+\t) &&\n+\tgit checkout autosquash &&\n+\t(\n+\t\tgit checkout -b autosquash_expected &&\n+\t\tFAKE_LINES=\"1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD\" &&\n+\t\texport FAKE_LINES &&\n+\t\tgit rebase -i HEAD~4 >expect\n+\t) &&\n+\tsed -e \"1,13d\" expect >expected &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'rebase --exec works without -i ' '\n+\tgit reset --hard execute &&\n+\trm -rf exec_output &&\n+\tEDITOR=\"echo >invoked_editor\" git rebase --exec \"echo a line >>exec_output\"  HEAD~2 2>actual &&\n+\ttest_i18ngrep  \"Successfully rebased and updated\" actual &&\n+\ttest_line_count = 2 exec_output &&\n+\ttest_path_is_missing invoked_editor\n+'\n+\n+test_expect_success 'rebase -i --exec without <CMD>' '\n+\tgit reset --hard execute &&\n+\tset_fake_editor &&\n+\ttest_must_fail git rebase -i --exec 2>actual &&\n+\ttest_i18ngrep \"requires a value\" actual &&\n+\tgit checkout master\n+'\n+\n+test_expect_success 'rebase -i --root re-order and drop commits' '\n+\tgit checkout E &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"3 1 2 5\" git rebase -i --root &&\n+\ttest E = $(git cat-file commit HEAD | sed -ne \\$p) &&\n+\ttest B = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n+\ttest A = $(git cat-file commit HEAD^^ | sed -ne \\$p) &&\n+\ttest C = $(git cat-file commit HEAD^^^ | sed -ne \\$p) &&\n+\ttest 0 = $(git cat-file commit HEAD^^^ | grep -c ^parent\\ )\n+'\n+\n+test_expect_success 'rebase -i --root retain root commit author and message' '\n+\tgit checkout A &&\n+\techo B >file7 &&\n+\tgit add file7 &&\n+\tGIT_AUTHOR_NAME=\"Twerp Snog\" git commit -m \"different author\" &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"2\" git rebase -i --root &&\n+\tgit cat-file commit HEAD | grep -q \"^author Twerp Snog\" &&\n+\tgit cat-file commit HEAD | grep -q \"^different author$\"\n+'\n+\n+test_expect_success 'rebase -i --root temporary sentinel commit' '\n+\tgit checkout B &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"2\" git rebase -i --root &&\n+\tgit cat-file commit HEAD | grep \"^tree 4b825dc642cb\" &&\n+\tgit rebase --abort\n+'\n+\n+test_expect_success 'rebase -i --root fixup root commit' '\n+\tgit checkout B &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 fixup 2\" git rebase -i --root &&\n+\ttest A = $(git cat-file commit HEAD | sed -ne \\$p) &&\n+\ttest B = $(git show HEAD:file1) &&\n+\ttest 0 = $(git cat-file commit HEAD | grep -c ^parent\\ )\n+'\n+\n+test_expect_success 'rebase -i --root reword root commit' '\n+\ttest_when_finished \"test_might_fail git rebase --abort\" &&\n+\tgit checkout -b reword-root-branch master &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"reword 1 2\" FAKE_COMMIT_MESSAGE=\"A changed\" \\\n+\tgit rebase -i --root &&\n+\tgit show HEAD^ | grep \"A changed\" &&\n+\ttest -z \"$(git show -s --format=%p HEAD^)\"\n+'\n+\n+test_expect_success 'rebase -i --root when root has untracked file confilct' '\n+\ttest_when_finished \"reset_rebase\" &&\n+\tgit checkout -b failing-root-pick A &&\n+\techo x >file2 &&\n+\tgit rm file1 &&\n+\tgit commit -m \"remove file 1 add file 2\" &&\n+\techo z >file1 &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"1 2\" git rebase -i --root &&\n+\trm file1 &&\n+\tgit rebase --continue &&\n+\ttest \"$(git log -1 --format=%B)\" = \"remove file 1 add file 2\" &&\n+\ttest \"$(git rev-list --count HEAD)\" = 2\n+'\n+\n+test_expect_success 'rebase -i --root reword root when root has untracked file conflict' '\n+\ttest_when_finished \"reset_rebase\" &&\n+\techo z>file1 &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"reword 1 2\" \\\n+\t\tFAKE_COMMIT_MESSAGE=\"Modified A\" git rebase -i --root &&\n+\trm file1 &&\n+\tFAKE_COMMIT_MESSAGE=\"Reworded A\" git rebase --continue &&\n+\ttest \"$(git log -1 --format=%B HEAD^)\" = \"Reworded A\" &&\n+\ttest \"$(git rev-list --count HEAD)\" = 2\n+'\n+\n+test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-interactive rebase' '\n+\tgit checkout reword-root-branch &&\n+\tgit reset --hard &&\n+\tgit checkout conflict-branch &&\n+\tset_fake_editor &&\n+\ttest_must_fail git rebase --onto HEAD~2 HEAD~ &&\n+\ttest_must_fail git rebase --edit-todo &&\n+\tgit rebase --abort\n+'\n+\n+test_expect_success 'rebase --edit-todo can be used to modify todo' '\n+\tgit reset --hard &&\n+\tgit checkout no-conflict-branch^0 &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"edit 1 2 3\" git rebase -i HEAD~3 &&\n+\tFAKE_LINES=\"2 1\" git rebase --edit-todo &&\n+\tgit rebase --continue &&\n+\ttest M = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n+\ttest L = $(git cat-file commit HEAD | sed -ne \\$p)\n+'\n+\n+test_expect_success 'rebase -i produces readable reflog' '\n+\tgit reset --hard &&\n+\tgit branch -f branch-reflog-test H &&\n+\tset_fake_editor &&\n+\tgit rebase -i --onto I F branch-reflog-test &&\n+\tcat >expect <<-\\EOF &&\n+\trebase -i (finish): returning to refs/heads/branch-reflog-test\n+\trebase -i (pick): H\n+\trebase -i (pick): G\n+\trebase -i (start): checkout I\n+\tEOF\n+\tgit reflog -n4 HEAD |\n+\tsed \"s/[^:]*: //\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'rebase -i respects core.commentchar' '\n+\tgit reset --hard &&\n+\tgit checkout E^0 &&\n+\ttest_config core.commentchar \"\\\\\" &&\n+\twrite_script remove-all-but-first.sh <<-\\EOF &&\n+\tsed -e \"2,\\$s/^/\\\\\\\\/\" \"$1\" >\"$1.tmp\" &&\n+\tmv \"$1.tmp\" \"$1\"\n+\tEOF\n+\ttest_set_editor \"$(pwd)/remove-all-but-first.sh\" &&\n+\tgit rebase -i B &&\n+\ttest B = $(git cat-file commit HEAD^ | sed -ne \\$p)\n+'\n+\n+test_expect_success 'rebase -i respects core.commentchar=auto' '\n+\ttest_config core.commentchar auto &&\n+\twrite_script copy-edit-script.sh <<-\\EOF &&\n+\tcp \"$1\" edit-script\n+\tEOF\n+\ttest_set_editor \"$(pwd)/copy-edit-script.sh\" &&\n+\ttest_when_finished \"git rebase --abort || :\" &&\n+\tgit rebase -i HEAD^ &&\n+\ttest -z \"$(grep -ve \"^#\" -e \"^\\$\" -e \"^pick\" edit-script)\"\n+'\n+\n+test_expect_success 'rebase -i, with <onto> and <upstream> specified as :/quuxery' '\n+\ttest_when_finished \"git branch -D torebase\" &&\n+\tgit checkout -b torebase branch1 &&\n+\tupstream=$(git rev-parse \":/J\") &&\n+\tonto=$(git rev-parse \":/A\") &&\n+\tgit rebase --onto $onto $upstream &&\n+\tgit reset --hard branch1 &&\n+\tgit rebase --onto \":/A\" \":/J\" &&\n+\tgit checkout branch1\n+'\n+\n+test_expect_success 'rebase -i with --strategy and -X' '\n+\tgit checkout -b conflict-merge-use-theirs conflict-branch &&\n+\tgit reset --hard HEAD^ &&\n+\techo five >conflict &&\n+\techo Z >file1 &&\n+\tgit commit -a -m \"one file conflict\" &&\n+\tEDITOR=true git rebase -i --strategy=recursive -Xours conflict-branch &&\n+\ttest $(git show conflict-branch:conflict) = $(cat conflict) &&\n+\ttest $(cat file1) = Z\n+'\n+\n+test_expect_success 'interrupted rebase -i with --strategy and -X' '\n+\tgit checkout -b conflict-merge-use-theirs-interrupted conflict-branch &&\n+\tgit reset --hard HEAD^ &&\n+\t>breakpoint &&\n+\tgit add breakpoint &&\n+\tgit commit -m \"breakpoint for interactive mode\" &&\n+\techo five >conflict &&\n+\techo Z >file1 &&\n+\tgit commit -a -m \"one file conflict\" &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"edit 1 2\" git rebase -i --strategy=recursive -Xours conflict-branch &&\n+\tgit rebase --continue &&\n+\ttest $(git show conflict-branch:conflict) = $(cat conflict) &&\n+\ttest $(cat file1) = Z\n+'\n+\n+test_expect_success 'rebase -i error on commits with \\ in message' '\n+\tcurrent_head=$(git rev-parse HEAD) &&\n+\ttest_when_finished \"git rebase --abort; git reset --hard $current_head; rm -f error\" &&\n+\ttest_commit TO-REMOVE will-conflict old-content &&\n+\ttest_commit \"\\temp\" will-conflict new-content dummy &&\n+\ttest_must_fail env EDITOR=true git rebase -i HEAD^ --onto HEAD^^ 2>error &&\n+\ttest_expect_code 1 grep  \"\temp\" error\n+'\n+\n+test_expect_success 'short SHA-1 setup' '\n+\ttest_when_finished \"git checkout master\" &&\n+\tgit checkout --orphan collide &&\n+\tgit rm -rf . &&\n+\t(\n+\tunset test_tick &&\n+\ttest_commit collide1 collide &&\n+\ttest_commit --notick collide2 collide &&\n+\ttest_commit --notick collide3 collide\n+\t)\n+'\n+\n+test_expect_success 'short SHA-1 collide' '\n+\ttest_when_finished \"reset_rebase && git checkout master\" &&\n+\tgit checkout collide &&\n+\t(\n+\tunset test_tick &&\n+\ttest_tick &&\n+\tset_fake_editor &&\n+\tFAKE_COMMIT_MESSAGE=\"collide2 ac4f2ee\" \\\n+\tFAKE_LINES=\"reword 1 2\" git rebase -i HEAD~2\n+\t)\n+'\n+\n+test_expect_success 'respect core.abbrev' '\n+\tgit config core.abbrev 12 &&\n+\tset_cat_todo_editor &&\n+\ttest_must_fail git rebase -i HEAD~4 >todo-list &&\n+\ttest 4 = $(grep -c \"pick [0-9a-f]\\{12,\\}\" todo-list)\n+'\n+\n+test_expect_success 'todo count' '\n+\twrite_script dump-raw.sh <<-\\EOF &&\n+\t\tcat \"$1\"\n+\tEOF\n+\ttest_set_editor \"$(pwd)/dump-raw.sh\" &&\n+\tgit rebase -i HEAD~4 >actual &&\n+\ttest_i18ngrep \"^# Rebase ..* onto ..* ([0-9]\" actual\n+'\n+\n+test_expect_success 'rebase -i commits that overwrite untracked files (pick)' '\n+\tgit checkout --force branch2 &&\n+\tgit clean -f &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"edit 1 2\" git rebase -i A &&\n+\ttest_cmp_rev HEAD F &&\n+\ttest_path_is_missing file6 &&\n+\t>file6 &&\n+\ttest_must_fail git rebase --continue &&\n+\ttest_cmp_rev HEAD F &&\n+\trm file6 &&\n+\tgit rebase --continue &&\n+\ttest_cmp_rev HEAD I\n+'\n+\n+test_expect_success 'rebase -i commits that overwrite untracked files (squash)' '\n+\tgit checkout --force branch2 &&\n+\tgit clean -f &&\n+\tgit tag original-branch2 &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"edit 1 squash 2\" git rebase -i A &&\n+\ttest_cmp_rev HEAD F &&\n+\ttest_path_is_missing file6 &&\n+\t>file6 &&\n+\ttest_must_fail git rebase --continue &&\n+\ttest_cmp_rev HEAD F &&\n+\trm file6 &&\n+\tgit rebase --continue &&\n+\ttest $(git cat-file commit HEAD | sed -ne \\$p) = I &&\n+\tgit reset --hard original-branch2\n+'\n+\n+test_expect_success 'rebase -i commits that overwrite untracked files (no ff)' '\n+\tgit checkout --force branch2 &&\n+\tgit clean -f &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"edit 1 2\" git rebase -i --no-ff A &&\n+\ttest $(git cat-file commit HEAD | sed -ne \\$p) = F &&\n+\ttest_path_is_missing file6 &&\n+\t>file6 &&\n+\ttest_must_fail git rebase --continue &&\n+\ttest $(git cat-file commit HEAD | sed -ne \\$p) = F &&\n+\trm file6 &&\n+\tgit rebase --continue &&\n+\ttest $(git cat-file commit HEAD | sed -ne \\$p) = I\n+'\n+\n+test_expect_success 'rebase --continue removes CHERRY_PICK_HEAD' '\n+\tgit checkout -b commit-to-skip &&\n+\tfor double in X 3 1\n+\tdo\n+\t\ttest_seq 5 | sed \"s/$double/&&/\" >seq &&\n+\t\tgit add seq &&\n+\t\ttest_tick &&\n+\t\tgit commit -m seq-$double\n+\tdone &&\n+\tgit tag seq-onto &&\n+\tgit reset --hard HEAD~2 &&\n+\tgit cherry-pick seq-onto &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES= git rebase -i seq-onto &&\n+\ttest -d .git/rebase-merge &&\n+\tgit rebase --continue &&\n+\tgit diff --exit-code seq-onto &&\n+\ttest ! -d .git/rebase-merge &&\n+\ttest ! -f .git/CHERRY_PICK_HEAD\n+'\n+\n+rebase_setup_and_clean () {\n+\ttest_when_finished \"\n+\t\tgit checkout master &&\n+\t\ttest_might_fail git branch -D $1 &&\n+\t\ttest_might_fail git rebase --abort\n+\t\" &&\n+\tgit checkout -b $1 ${2:-master}\n+}\n+\n+test_expect_success 'drop' '\n+\trebase_setup_and_clean drop-test &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 drop 2 3 d 4 5\" git rebase -i --root &&\n+\ttest E = $(git cat-file commit HEAD | sed -ne \\$p) &&\n+\ttest C = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n+\ttest A = $(git cat-file commit HEAD^^ | sed -ne \\$p)\n+'\n+\n+test_expect_success 'rebase -i respects rebase.missingCommitsCheck = ignore' '\n+\ttest_config rebase.missingCommitsCheck ignore &&\n+\trebase_setup_and_clean missing-commit &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 2 3 4\" \\\n+\t\tgit rebase -i --root 2>actual &&\n+\ttest D = $(git cat-file commit HEAD | sed -ne \\$p) &&\n+\ttest_i18ngrep \\\n+\t\t\"Successfully rebased and updated refs/heads/missing-commit\" \\\n+\t\tactual\n+'\n+\n+cat >expect <<EOF\n+Warning: some commits may have been dropped accidentally.\n+Dropped commits (newer to older):\n+ - $(git rev-list --pretty=oneline --abbrev-commit -1 master)\n+To avoid this message, use \"drop\" to explicitly remove a commit.\n+\n+Use 'git config rebase.missingCommitsCheck' to change the level of warnings.\n+The possible behaviours are: ignore, warn, error.\n+\n+Rebasing (1/4)\n+Rebasing (2/4)\n+Rebasing (3/4)\n+Rebasing (4/4)\n+Successfully rebased and updated refs/heads/missing-commit.\n+EOF\n+\n+cr_to_nl () {\n+\ttr '\\015' '\\012'\n+}\n+\n+test_expect_success 'rebase -i respects rebase.missingCommitsCheck = warn' '\n+\ttest_config rebase.missingCommitsCheck warn &&\n+\trebase_setup_and_clean missing-commit &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"1 2 3 4\" \\\n+\t\tgit rebase -i --root 2>actual.2 &&\n+\tcr_to_nl <actual.2 >actual &&\n+\ttest_i18ncmp expect actual &&\n+\ttest D = $(git cat-file commit HEAD | sed -ne \\$p)\n+'\n+\n+cat >expect <<EOF\n+Warning: some commits may have been dropped accidentally.\n+Dropped commits (newer to older):\n+ - $(git rev-list --pretty=oneline --abbrev-commit -1 master)\n+ - $(git rev-list --pretty=oneline --abbrev-commit -1 master~2)\n+To avoid this message, use \"drop\" to explicitly remove a commit.\n+\n+Use 'git config rebase.missingCommitsCheck' to change the level of warnings.\n+The possible behaviours are: ignore, warn, error.\n+\n+You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'.\n+Or you can abort the rebase with 'git rebase --abort'.\n+EOF\n+\n+test_expect_success 'rebase -i respects rebase.missingCommitsCheck = error' '\n+\ttest_config rebase.missingCommitsCheck error &&\n+\trebase_setup_and_clean missing-commit &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"1 2 4\" \\\n+\t\tgit rebase -i --root 2>actual &&\n+\ttest_i18ncmp expect actual &&\n+\tcp .git/rebase-merge/git-rebase-todo.backup \\\n+\t\t.git/rebase-merge/git-rebase-todo &&\n+\tFAKE_LINES=\"1 2 drop 3 4 drop 5\" \\\n+\t\tgit rebase --edit-todo &&\n+\tgit rebase --continue &&\n+\ttest D = $(git cat-file commit HEAD | sed -ne \\$p) &&\n+\ttest B = $(git cat-file commit HEAD^ | sed -ne \\$p)\n+'\n+\n+test_expect_success 'respects rebase.abbreviateCommands with fixup, squash and exec' '\n+\trebase_setup_and_clean abbrevcmd &&\n+\ttest_commit \"first\" file1.txt \"first line\" first &&\n+\ttest_commit \"second\" file1.txt \"another line\" second &&\n+\ttest_commit \"fixup! first\" file2.txt \"first line again\" first_fixup &&\n+\ttest_commit \"squash! second\" file1.txt \"another line here\" second_squash &&\n+\tcat >expected <<-EOF &&\n+\tp $(git rev-list --abbrev-commit -1 first) first\n+\tf $(git rev-list --abbrev-commit -1 first_fixup) fixup! first\n+\tx git show HEAD\n+\tp $(git rev-list --abbrev-commit -1 second) second\n+\ts $(git rev-list --abbrev-commit -1 second_squash) squash! second\n+\tx git show HEAD\n+\tEOF\n+\tgit checkout abbrevcmd &&\n+\tset_cat_todo_editor &&\n+\ttest_config rebase.abbreviateCommands true &&\n+\ttest_must_fail git rebase -i --exec \"git show HEAD\" \\\n+\t\t--autosquash master >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'static check of bad command' '\n+\trebase_setup_and_clean bad-cmd &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"1 2 3 bad 4 5\" \\\n+\t\tgit rebase -i --root 2>actual &&\n+\ttest_i18ngrep \"badcmd $(git rev-list --oneline -1 master~1)\" actual &&\n+\ttest_i18ngrep \"You can fix this with .git rebase --edit-todo..\" actual &&\n+\tFAKE_LINES=\"1 2 3 drop 4 5\" git rebase --edit-todo &&\n+\tgit rebase --continue &&\n+\ttest E = $(git cat-file commit HEAD | sed -ne \\$p) &&\n+\ttest C = $(git cat-file commit HEAD^ | sed -ne \\$p)\n+'\n+\n+test_expect_success 'tabs and spaces are accepted in the todolist' '\n+\trebase_setup_and_clean indented-comment &&\n+\twrite_script add-indent.sh <<-\\EOF &&\n+\t(\n+\t\t# Turn single spaces into space/tab mix\n+\t\tsed \"1s/ /\t/g; 2s/ /  /g; 3s/ / \t/g\" \"$1\"\n+\t\tprintf \"\\n\\t# comment\\n #more\\n\\t # comment\\n\"\n+\t) >\"$1.new\"\n+\tmv \"$1.new\" \"$1\"\n+\tEOF\n+\ttest_set_editor \"$(pwd)/add-indent.sh\" &&\n+\tgit rebase -i HEAD^^^ &&\n+\ttest E = $(git cat-file commit HEAD | sed -ne \\$p)\n+'\n+\n+test_expect_success 'static check of bad SHA-1' '\n+\trebase_setup_and_clean bad-sha &&\n+\tset_fake_editor &&\n+\ttest_must_fail env FAKE_LINES=\"1 2 edit fakesha 3 4 5 #\" \\\n+\t\tgit rebase -i --root 2>actual &&\n+\ttest_i18ngrep \"edit XXXXXXX False commit\" actual &&\n+\ttest_i18ngrep \"You can fix this with .git rebase --edit-todo..\" actual &&\n+\tFAKE_LINES=\"1 2 4 5 6\" git rebase --edit-todo &&\n+\tgit rebase --continue &&\n+\ttest E = $(git cat-file commit HEAD | sed -ne \\$p)\n+'\n+\n+test_expect_success 'editor saves as CR/LF' '\n+\tgit checkout -b with-crlf &&\n+\twrite_script add-crs.sh <<-\\EOF &&\n+\tsed -e \"s/\\$/Q/\" <\"$1\" | tr Q \"\\\\015\" >\"$1\".new &&\n+\tmv -f \"$1\".new \"$1\"\n+\tEOF\n+\t(\n+\t\ttest_set_editor \"$(pwd)/add-crs.sh\" &&\n+\t\tgit rebase -i HEAD^\n+\t)\n+'\n+\n+SQ=\"'\"\n+test_expect_success 'rebase -i --gpg-sign=<key-id>' '\n+\ttest_when_finished \"test_might_fail git rebase --abort\" &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"edit 1\" git rebase -i --gpg-sign=\"\\\"S I Gner\\\"\" HEAD^ \\\n+\t\t>out 2>err &&\n+\ttest_i18ngrep \"$SQ-S\\\"S I Gner\\\"$SQ\" err\n+'\n+\n+test_expect_success 'rebase -i --gpg-sign=<key-id> overrides commit.sign' '\n+\ttest_when_finished \"test_might_fail git rebase --abort\" &&\n+\ttest_config commit.sign true &&\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"edit 1\" git rebase -i --gpg-sign=\"\\\"S I Gner\\\"\" HEAD^ \\\n+\t\t>out 2>err &&\n+\ttest_i18ngrep \"$SQ-S\\\"S I Gner\\\"$SQ\" err\n+'\n+\n+test_expect_success 'valid author header after --root swap' '\n+\trebase_setup_and_clean author-header no-conflict-branch &&\n+\tset_fake_editor &&\n+\tgit commit --amend --author=\"Au ${SQ}thor <author@example.com>\" --no-edit &&\n+\tgit cat-file commit HEAD | grep ^author >expected &&\n+\tFAKE_LINES=\"5 1\" git rebase -i --root &&\n+\tgit cat-file commit HEAD^ | grep ^author >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'valid author header when author contains single quote' '\n+\trebase_setup_and_clean author-header no-conflict-branch &&\n+\tset_fake_editor &&\n+\tgit commit --amend --author=\"Au ${SQ}thor <author@example.com>\" --no-edit &&\n+\tgit cat-file commit HEAD | grep ^author >expected &&\n+\tFAKE_LINES=\"2\" git rebase -i HEAD~2 &&\n+\tgit cat-file commit HEAD | grep ^author >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_done\ndiff --git a/t/t4215-log-signconfig.sh b/t/t4215-log-signconfig.sh\nnew file mode 100755\nindex 000000000..a2f2342b0\n--- /dev/null\n+++ b/t/t4215-log-signconfig.sh\n@@ -0,0 +1,1710 @@\n+#!/bin/sh\n+\n+test_description='git log'\n+\n+. ./test-lib.sh\n+. \"$TEST_DIRECTORY/lib-gpg.sh\"\n+. \"$TEST_DIRECTORY/lib-terminal.sh\"\n+\n+test_expect_success setup '\n+\n+\techo one >one &&\n+\tgit add one &&\n+\ttest_tick &&\n+\tgit commit -m initial &&\n+\n+\techo ichi >one &&\n+\tgit add one &&\n+\ttest_tick &&\n+\tgit commit -m second &&\n+\n+\tgit mv one ichi &&\n+\ttest_tick &&\n+\tgit commit -m third &&\n+\n+\tcp ichi ein &&\n+\tgit add ein &&\n+\ttest_tick &&\n+\tgit commit -m fourth &&\n+\n+\tmkdir a &&\n+\techo ni >a/two &&\n+\tgit add a/two &&\n+\ttest_tick &&\n+\tgit commit -m fifth  &&\n+\n+\tgit rm a/two &&\n+\ttest_tick &&\n+\tgit commit -m sixth\n+\n+'\n+\n+printf \"sixth\\nfifth\\nfourth\\nthird\\nsecond\\ninitial\" > expect\n+test_expect_success 'pretty' '\n+\n+\tgit log --pretty=\"format:%s\" > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+printf \"sixth\\nfifth\\nfourth\\nthird\\nsecond\\ninitial\\n\" > expect\n+test_expect_success 'pretty (tformat)' '\n+\n+\tgit log --pretty=\"tformat:%s\" > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'pretty (shortcut)' '\n+\n+\tgit log --pretty=\"%s\" > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'format' '\n+\n+\tgit log --format=\"%s\" > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat > expect << EOF\n+ This is\n+  the sixth\n+  commit.\n+ This is\n+  the fifth\n+  commit.\n+EOF\n+\n+test_expect_success 'format %w(11,1,2)' '\n+\n+\tgit log -2 --format=\"%w(11,1,2)This is the %s commit.\" > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'format %w(,1,2)' '\n+\n+\tgit log -2 --format=\"%w(,1,2)This is%nthe %s%ncommit.\" > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat > expect << EOF\n+804a787 sixth\n+394ef78 fifth\n+5d31159 fourth\n+2fbe8c0 third\n+f7dab8e second\n+3a2fdcb initial\n+EOF\n+test_expect_success 'oneline' '\n+\n+\tgit log --oneline > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'diff-filter=A' '\n+\n+\tgit log --no-renames --pretty=\"format:%s\" --diff-filter=A HEAD > actual &&\n+\tgit log --no-renames --pretty=\"format:%s\" --diff-filter A HEAD > actual-separate &&\n+\tprintf \"fifth\\nfourth\\nthird\\ninitial\" > expect &&\n+\ttest_cmp expect actual &&\n+\ttest_cmp expect actual-separate\n+\n+'\n+\n+test_expect_success 'diff-filter=M' '\n+\n+\tactual=$(git log --pretty=\"format:%s\" --diff-filter=M HEAD) &&\n+\texpect=$(echo second) &&\n+\tverbose test \"$actual\" = \"$expect\"\n+\n+'\n+\n+test_expect_success 'diff-filter=D' '\n+\n+\tactual=$(git log --no-renames --pretty=\"format:%s\" --diff-filter=D HEAD) &&\n+\texpect=$(echo sixth ; echo third) &&\n+\tverbose test \"$actual\" = \"$expect\"\n+\n+'\n+\n+test_expect_success 'diff-filter=R' '\n+\n+\tactual=$(git log -M --pretty=\"format:%s\" --diff-filter=R HEAD) &&\n+\texpect=$(echo third) &&\n+\tverbose test \"$actual\" = \"$expect\"\n+\n+'\n+\n+test_expect_success 'diff-filter=C' '\n+\n+\tactual=$(git log -C -C --pretty=\"format:%s\" --diff-filter=C HEAD) &&\n+\texpect=$(echo fourth) &&\n+\tverbose test \"$actual\" = \"$expect\"\n+\n+'\n+\n+test_expect_success 'git log --follow' '\n+\n+\tactual=$(git log --follow --pretty=\"format:%s\" ichi) &&\n+\texpect=$(echo third ; echo second ; echo initial) &&\n+\tverbose test \"$actual\" = \"$expect\"\n+'\n+\n+test_expect_success 'git config log.follow works like --follow' '\n+\ttest_config log.follow true &&\n+\tactual=$(git log --pretty=\"format:%s\" ichi) &&\n+\texpect=$(echo third ; echo second ; echo initial) &&\n+\tverbose test \"$actual\" = \"$expect\"\n+'\n+\n+test_expect_success 'git config log.follow does not die with multiple paths' '\n+\ttest_config log.follow true &&\n+\tgit log --pretty=\"format:%s\" ichi ein\n+'\n+\n+test_expect_success 'git config log.follow does not die with no paths' '\n+\ttest_config log.follow true &&\n+\tgit log --\n+'\n+\n+test_expect_success 'git config log.follow is overridden by --no-follow' '\n+\ttest_config log.follow true &&\n+\tactual=$(git log --no-follow --pretty=\"format:%s\" ichi) &&\n+\texpect=\"third\" &&\n+\tverbose test \"$actual\" = \"$expect\"\n+'\n+\n+cat > expect << EOF\n+804a787 sixth\n+394ef78 fifth\n+5d31159 fourth\n+EOF\n+test_expect_success 'git log --no-walk <commits> sorts by commit time' '\n+\tgit log --no-walk --oneline 5d31159 804a787 394ef78 > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git log --no-walk=sorted <commits> sorts by commit time' '\n+\tgit log --no-walk=sorted --oneline 5d31159 804a787 394ef78 > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat > expect << EOF\n+=== 804a787 sixth\n+=== 394ef78 fifth\n+=== 5d31159 fourth\n+EOF\n+test_expect_success 'git log --line-prefix=\"=== \" --no-walk <commits> sorts by commit time' '\n+\tgit log --line-prefix=\"=== \" --no-walk --oneline 5d31159 804a787 394ef78 > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat > expect << EOF\n+5d31159 fourth\n+804a787 sixth\n+394ef78 fifth\n+EOF\n+test_expect_success 'git log --no-walk=unsorted <commits> leaves list of commits as given' '\n+\tgit log --no-walk=unsorted --oneline 5d31159 804a787 394ef78 > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git show <commits> leaves list of commits as given' '\n+\tgit show --oneline -s 5d31159 804a787 394ef78 > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'setup case sensitivity tests' '\n+\techo case >one &&\n+\ttest_tick &&\n+\tgit add one &&\n+\tgit commit -a -m Second\n+'\n+\n+test_expect_success 'log --grep' '\n+\techo second >expect &&\n+\tgit log -1 --pretty=\"tformat:%s\" --grep=sec >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat > expect << EOF\n+second\n+initial\n+EOF\n+test_expect_success 'log --invert-grep --grep' '\n+\t# Fixed\n+\tgit -c grep.patternType=fixed log --pretty=\"tformat:%s\" --invert-grep --grep=th --grep=Sec >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t# POSIX basic\n+\tgit -c grep.patternType=basic log --pretty=\"tformat:%s\" --invert-grep --grep=t[h] --grep=S[e]c >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t# POSIX extended\n+\tgit -c grep.patternType=basic log --pretty=\"tformat:%s\" --invert-grep --grep=t[h] --grep=S[e]c >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t# PCRE\n+\tif test_have_prereq PCRE\n+\tthen\n+\t\tgit -c grep.patternType=perl log --pretty=\"tformat:%s\" --invert-grep --grep=t[h] --grep=S[e]c >actual &&\n+\t\ttest_cmp expect actual\n+\tfi\n+'\n+\n+test_expect_success 'log --invert-grep --grep -i' '\n+\techo initial >expect &&\n+\n+\t# Fixed\n+\tgit -c grep.patternType=fixed log --pretty=\"tformat:%s\" --invert-grep -i --grep=th --grep=Sec >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t# POSIX basic\n+\tgit -c grep.patternType=basic log --pretty=\"tformat:%s\" --invert-grep -i --grep=t[h] --grep=S[e]c >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t# POSIX extended\n+\tgit -c grep.patternType=extended log --pretty=\"tformat:%s\" --invert-grep -i --grep=t[h] --grep=S[e]c >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t# PCRE\n+\tif test_have_prereq PCRE\n+\tthen\n+\t\tgit -c grep.patternType=perl log --pretty=\"tformat:%s\" --invert-grep -i --grep=t[h] --grep=S[e]c >actual &&\n+\t\ttest_cmp expect actual\n+\tfi\n+'\n+\n+test_expect_success 'log --grep option parsing' '\n+\techo second >expect &&\n+\tgit log -1 --pretty=\"tformat:%s\" --grep sec >actual &&\n+\ttest_cmp expect actual &&\n+\ttest_must_fail git log -1 --pretty=\"tformat:%s\" --grep\n+'\n+\n+test_expect_success 'log -i --grep' '\n+\techo Second >expect &&\n+\tgit log -1 --pretty=\"tformat:%s\" -i --grep=sec >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'log --grep -i' '\n+\techo Second >expect &&\n+\n+\t# Fixed\n+\tgit log -1 --pretty=\"tformat:%s\" --grep=sec -i >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t# POSIX basic\n+\tgit -c grep.patternType=basic log -1 --pretty=\"tformat:%s\" --grep=s[e]c -i >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t# POSIX extended\n+\tgit -c grep.patternType=extended log -1 --pretty=\"tformat:%s\" --grep=s[e]c -i >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t# PCRE\n+\tif test_have_prereq PCRE\n+\tthen\n+\t\tgit -c grep.patternType=perl log -1 --pretty=\"tformat:%s\" --grep=s[e]c -i >actual &&\n+\t\ttest_cmp expect actual\n+\tfi\n+'\n+\n+test_expect_success 'log -F -E --grep=<ere> uses ere' '\n+\techo second >expect &&\n+\t# basic would need \\(s\\) to do the same\n+\tgit log -1 --pretty=\"tformat:%s\" -F -E --grep=\"(s).c.nd\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success PCRE 'log -F -E --perl-regexp --grep=<pcre> uses PCRE' '\n+\ttest_when_finished \"rm -rf num_commits\" &&\n+\tgit init num_commits &&\n+\t(\n+\t\tcd num_commits &&\n+\t\ttest_commit 1d &&\n+\t\ttest_commit 2e\n+\t) &&\n+\n+\t# In PCRE \\d in [\\d] is like saying \"0-9\", and matches the 2\n+\t# in 2e...\n+\techo 2e >expect &&\n+\tgit -C num_commits log -1 --pretty=\"tformat:%s\" -F -E --perl-regexp --grep=\"[\\d]\" >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t# ...in POSIX basic and extended it is the same as [d],\n+\t# i.e. \"d\", which matches 1d, but does not match 2e.\n+\techo 1d >expect &&\n+\tgit -C num_commits log -1 --pretty=\"tformat:%s\" -F -E --grep=\"[\\d]\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'log with grep.patternType configuration' '\n+\tgit -c grep.patterntype=fixed \\\n+\tlog -1 --pretty=tformat:%s --grep=s.c.nd >actual &&\n+\ttest_must_be_empty actual\n+'\n+\n+test_expect_success 'log with grep.patternType configuration and command line' '\n+\techo second >expect &&\n+\tgit -c grep.patterntype=fixed \\\n+\tlog -1 --pretty=tformat:%s --basic-regexp --grep=s.c.nd >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success !FAIL_PREREQS 'log with various grep.patternType configurations & command-lines' '\n+\tgit init pattern-type &&\n+\t(\n+\t\tcd pattern-type &&\n+\t\ttest_commit 1 file A &&\n+\n+\t\t# The tagname is overridden here because creating a\n+\t\t# tag called \"(1|2)\" as test_commit would otherwise\n+\t\t# implicitly do would fail on e.g. MINGW.\n+\t\ttest_commit \"(1|2)\" file B 2 &&\n+\n+\t\techo \"(1|2)\" >expect.fixed &&\n+\t\tcp expect.fixed expect.basic &&\n+\t\tcp expect.fixed expect.extended &&\n+\t\tcp expect.fixed expect.perl &&\n+\n+\t\t# A strcmp-like match with fixed.\n+\t\tgit -c grep.patternType=fixed log --pretty=tformat:%s \\\n+\t\t\t--grep=\"(1|2)\" >actual.fixed &&\n+\n+\t\t# POSIX basic matches (, | and ) literally.\n+\t\tgit -c grep.patternType=basic log --pretty=tformat:%s \\\n+\t\t\t--grep=\"(.|.)\" >actual.basic &&\n+\n+\t\t# POSIX extended needs to have | escaped to match it\n+\t\t# literally, whereas under basic this is the same as\n+\t\t# (|2), i.e. it would also match \"1\". This test checks\n+\t\t# for extended by asserting that it is not matching\n+\t\t# what basic would match.\n+\t\tgit -c grep.patternType=extended log --pretty=tformat:%s \\\n+\t\t\t--grep=\"\\|2\" >actual.extended &&\n+\t\tif test_have_prereq PCRE\n+\t\tthen\n+\t\t\t# Only PCRE would match [\\d]\\| with only\n+\t\t\t# \"(1|2)\" due to [\\d]. POSIX basic would match\n+\t\t\t# both it and \"1\" since similarly to the\n+\t\t\t# extended match above it is the same as\n+\t\t\t# \\([\\d]\\|\\). POSIX extended would\n+\t\t\t# match neither.\n+\t\t\tgit -c grep.patternType=perl log --pretty=tformat:%s \\\n+\t\t\t\t--grep=\"[\\d]\\|\" >actual.perl &&\n+\t\t\ttest_cmp expect.perl actual.perl\n+\t\tfi &&\n+\t\ttest_cmp expect.fixed actual.fixed &&\n+\t\ttest_cmp expect.basic actual.basic &&\n+\t\ttest_cmp expect.extended actual.extended &&\n+\n+\t\tgit log --pretty=tformat:%s -F \\\n+\t\t\t--grep=\"(1|2)\" >actual.fixed.short-arg &&\n+\t\tgit log --pretty=tformat:%s -E \\\n+\t\t\t--grep=\"\\|2\" >actual.extended.short-arg &&\n+\t\tif test_have_prereq PCRE\n+\t\tthen\n+\t\t\tgit log --pretty=tformat:%s -P \\\n+\t\t\t\t--grep=\"[\\d]\\|\" >actual.perl.short-arg\n+\t\telse\n+\t\t\ttest_must_fail git log -P \\\n+\t\t\t\t--grep=\"[\\d]\\|\"\n+\t\tfi &&\n+\t\ttest_cmp expect.fixed actual.fixed.short-arg &&\n+\t\ttest_cmp expect.extended actual.extended.short-arg &&\n+\t\tif test_have_prereq PCRE\n+\t\tthen\n+\t\t\ttest_cmp expect.perl actual.perl.short-arg\n+\t\tfi &&\n+\n+\t\tgit log --pretty=tformat:%s --fixed-strings \\\n+\t\t\t--grep=\"(1|2)\" >actual.fixed.long-arg &&\n+\t\tgit log --pretty=tformat:%s --basic-regexp \\\n+\t\t\t--grep=\"(.|.)\" >actual.basic.long-arg &&\n+\t\tgit log --pretty=tformat:%s --extended-regexp \\\n+\t\t\t--grep=\"\\|2\" >actual.extended.long-arg &&\n+\t\tif test_have_prereq PCRE\n+\t\tthen\n+\t\t\tgit log --pretty=tformat:%s --perl-regexp \\\n+\t\t\t\t--grep=\"[\\d]\\|\" >actual.perl.long-arg &&\n+\t\t\ttest_cmp expect.perl actual.perl.long-arg\n+\t\telse\n+\t\t\ttest_must_fail git log --perl-regexp \\\n+\t\t\t\t--grep=\"[\\d]\\|\"\n+\t\tfi &&\n+\t\ttest_cmp expect.fixed actual.fixed.long-arg &&\n+\t\ttest_cmp expect.basic actual.basic.long-arg &&\n+\t\ttest_cmp expect.extended actual.extended.long-arg\n+\t)\n+'\n+\n+cat > expect <<EOF\n+* Second\n+* sixth\n+* fifth\n+* fourth\n+* third\n+* second\n+* initial\n+EOF\n+\n+test_expect_success 'simple log --graph' '\n+\tgit log --graph --pretty=tformat:%s >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat > expect <<EOF\n+123 * Second\n+123 * sixth\n+123 * fifth\n+123 * fourth\n+123 * third\n+123 * second\n+123 * initial\n+EOF\n+\n+test_expect_success 'simple log --graph --line-prefix=\"123 \"' '\n+\tgit log --graph --line-prefix=\"123 \" --pretty=tformat:%s >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'set up merge history' '\n+\tgit checkout -b side HEAD~4 &&\n+\ttest_commit side-1 1 1 &&\n+\ttest_commit side-2 2 2 &&\n+\tgit checkout master &&\n+\tgit merge side\n+'\n+\n+cat > expect <<\\EOF\n+*   Merge branch 'side'\n+|\\\n+| * side-2\n+| * side-1\n+* | Second\n+* | sixth\n+* | fifth\n+* | fourth\n+|/\n+* third\n+* second\n+* initial\n+EOF\n+\n+test_expect_success 'log --graph with merge' '\n+\tgit log --graph --date-order --pretty=tformat:%s |\n+\t\tsed \"s/ *\\$//\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat > expect <<\\EOF\n+| | | *   Merge branch 'side'\n+| | | |\\\n+| | | | * side-2\n+| | | | * side-1\n+| | | * | Second\n+| | | * | sixth\n+| | | * | fifth\n+| | | * | fourth\n+| | | |/\n+| | | * third\n+| | | * second\n+| | | * initial\n+EOF\n+\n+test_expect_success 'log --graph --line-prefix=\"| | | \" with merge' '\n+\tgit log --line-prefix=\"| | | \" --graph --date-order --pretty=tformat:%s |\n+\t\tsed \"s/ *\\$//\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat > expect.colors <<\\EOF\n+*   Merge branch 'side'\n+<BLUE>|<RESET><CYAN>\\<RESET>\n+<BLUE>|<RESET> * side-2\n+<BLUE>|<RESET> * side-1\n+* <CYAN>|<RESET> Second\n+* <CYAN>|<RESET> sixth\n+* <CYAN>|<RESET> fifth\n+* <CYAN>|<RESET> fourth\n+<CYAN>|<RESET><CYAN>/<RESET>\n+* third\n+* second\n+* initial\n+EOF\n+\n+test_expect_success 'log --graph with merge with log.graphColors' '\n+\ttest_config log.graphColors \" blue,invalid-color, cyan, red  , \" &&\n+\tgit log --color=always --graph --date-order --pretty=tformat:%s |\n+\t\ttest_decode_color | sed \"s/ *\\$//\" >actual &&\n+\ttest_cmp expect.colors actual\n+'\n+\n+test_expect_success 'log --raw --graph -m with merge' '\n+\tgit log --raw --graph --oneline -m master | head -n 500 >actual &&\n+\tgrep \"initial\" actual\n+'\n+\n+test_expect_success 'diff-tree --graph' '\n+\tgit diff-tree --graph master^ | head -n 500 >actual &&\n+\tgrep \"one\" actual\n+'\n+\n+cat > expect <<\\EOF\n+*   commit master\n+|\\  Merge: A B\n+| | Author: A U Thor <author@example.com>\n+| |\n+| |     Merge branch 'side'\n+| |\n+| * commit tags/side-2\n+| | Author: A U Thor <author@example.com>\n+| |\n+| |     side-2\n+| |\n+| * commit tags/side-1\n+| | Author: A U Thor <author@example.com>\n+| |\n+| |     side-1\n+| |\n+* | commit master~1\n+| | Author: A U Thor <author@example.com>\n+| |\n+| |     Second\n+| |\n+* | commit master~2\n+| | Author: A U Thor <author@example.com>\n+| |\n+| |     sixth\n+| |\n+* | commit master~3\n+| | Author: A U Thor <author@example.com>\n+| |\n+| |     fifth\n+| |\n+* | commit master~4\n+|/  Author: A U Thor <author@example.com>\n+|\n+|       fourth\n+|\n+* commit tags/side-1~1\n+| Author: A U Thor <author@example.com>\n+|\n+|     third\n+|\n+* commit tags/side-1~2\n+| Author: A U Thor <author@example.com>\n+|\n+|     second\n+|\n+* commit tags/side-1~3\n+  Author: A U Thor <author@example.com>\n+\n+      initial\n+EOF\n+\n+test_expect_success 'log --graph with full output' '\n+\tgit log --graph --date-order --pretty=short |\n+\t\tgit name-rev --name-only --stdin |\n+\t\tsed \"s/Merge:.*/Merge: A B/;s/ *\\$//\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'set up more tangled history' '\n+\tgit checkout -b tangle HEAD~6 &&\n+\ttest_commit tangle-a tangle-a a &&\n+\tgit merge master~3 &&\n+\tgit merge side~1 &&\n+\tgit checkout master &&\n+\tgit merge tangle &&\n+\tgit checkout -b reach &&\n+\ttest_commit reach &&\n+\tgit checkout master &&\n+\tgit checkout -b octopus-a &&\n+\ttest_commit octopus-a &&\n+\tgit checkout master &&\n+\tgit checkout -b octopus-b &&\n+\ttest_commit octopus-b &&\n+\tgit checkout master &&\n+\ttest_commit seventh &&\n+\tgit merge octopus-a octopus-b &&\n+\tgit merge reach\n+'\n+\n+cat > expect <<\\EOF\n+*   Merge tag 'reach'\n+|\\\n+| \\\n+|  \\\n+*-. \\   Merge tags 'octopus-a' and 'octopus-b'\n+|\\ \\ \\\n+* | | | seventh\n+| | * | octopus-b\n+| |/ /\n+|/| |\n+| * | octopus-a\n+|/ /\n+| * reach\n+|/\n+*   Merge branch 'tangle'\n+|\\\n+| *   Merge branch 'side' (early part) into tangle\n+| |\\\n+| * \\   Merge branch 'master' (early part) into tangle\n+| |\\ \\\n+| * | | tangle-a\n+* | | |   Merge branch 'side'\n+|\\ \\ \\ \\\n+| * | | | side-2\n+| | |_|/\n+| |/| |\n+| * | | side-1\n+* | | | Second\n+* | | | sixth\n+| |_|/\n+|/| |\n+* | | fifth\n+* | | fourth\n+|/ /\n+* | third\n+|/\n+* second\n+* initial\n+EOF\n+\n+test_expect_success 'log --graph with merge' '\n+\tgit log --graph --date-order --pretty=tformat:%s |\n+\t\tsed \"s/ *\\$//\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'log.decorate configuration' '\n+\tgit log --oneline --no-decorate >expect.none &&\n+\tgit log --oneline --decorate >expect.short &&\n+\tgit log --oneline --decorate=full >expect.full &&\n+\n+\techo \"[log] decorate\" >>.git/config &&\n+\tgit log --oneline >actual &&\n+\ttest_cmp expect.short actual &&\n+\n+\ttest_config log.decorate true &&\n+\tgit log --oneline >actual &&\n+\ttest_cmp expect.short actual &&\n+\tgit log --oneline --decorate=full >actual &&\n+\ttest_cmp expect.full actual &&\n+\tgit log --oneline --decorate=no >actual &&\n+\ttest_cmp expect.none actual &&\n+\n+\ttest_config log.decorate no &&\n+\tgit log --oneline >actual &&\n+\ttest_cmp expect.none actual &&\n+\tgit log --oneline --decorate >actual &&\n+\ttest_cmp expect.short actual &&\n+\tgit log --oneline --decorate=full >actual &&\n+\ttest_cmp expect.full actual &&\n+\n+\ttest_config log.decorate 1 &&\n+\tgit log --oneline >actual &&\n+\ttest_cmp expect.short actual &&\n+\tgit log --oneline --decorate=full >actual &&\n+\ttest_cmp expect.full actual &&\n+\tgit log --oneline --decorate=no >actual &&\n+\ttest_cmp expect.none actual &&\n+\n+\ttest_config log.decorate short &&\n+\tgit log --oneline >actual &&\n+\ttest_cmp expect.short actual &&\n+\tgit log --oneline --no-decorate >actual &&\n+\ttest_cmp expect.none actual &&\n+\tgit log --oneline --decorate=full >actual &&\n+\ttest_cmp expect.full actual &&\n+\n+\ttest_config log.decorate full &&\n+\tgit log --oneline >actual &&\n+\ttest_cmp expect.full actual &&\n+\tgit log --oneline --no-decorate >actual &&\n+\ttest_cmp expect.none actual &&\n+\tgit log --oneline --decorate >actual &&\n+\ttest_cmp expect.short actual &&\n+\n+\ttest_unconfig log.decorate &&\n+\tgit log --pretty=raw >expect.raw &&\n+\ttest_config log.decorate full &&\n+\tgit log --pretty=raw >actual &&\n+\ttest_cmp expect.raw actual\n+\n+'\n+\n+test_expect_success 'decorate-refs with glob' '\n+\tcat >expect.decorate <<-\\EOF &&\n+\tMerge-tag-reach\n+\tMerge-tags-octopus-a-and-octopus-b\n+\tseventh\n+\toctopus-b (octopus-b)\n+\toctopus-a (octopus-a)\n+\treach\n+\tEOF\n+\tgit log -n6 --decorate=short --pretty=\"tformat:%f%d\" \\\n+\t\t--decorate-refs=\"heads/octopus*\" >actual &&\n+\ttest_cmp expect.decorate actual\n+'\n+\n+test_expect_success 'decorate-refs without globs' '\n+\tcat >expect.decorate <<-\\EOF &&\n+\tMerge-tag-reach\n+\tMerge-tags-octopus-a-and-octopus-b\n+\tseventh\n+\toctopus-b\n+\toctopus-a\n+\treach (tag: reach)\n+\tEOF\n+\tgit log -n6 --decorate=short --pretty=\"tformat:%f%d\" \\\n+\t\t--decorate-refs=\"tags/reach\" >actual &&\n+\ttest_cmp expect.decorate actual\n+'\n+\n+test_expect_success 'multiple decorate-refs' '\n+\tcat >expect.decorate <<-\\EOF &&\n+\tMerge-tag-reach\n+\tMerge-tags-octopus-a-and-octopus-b\n+\tseventh\n+\toctopus-b (octopus-b)\n+\toctopus-a (octopus-a)\n+\treach (tag: reach)\n+\tEOF\n+\tgit log -n6 --decorate=short --pretty=\"tformat:%f%d\" \\\n+\t\t--decorate-refs=\"heads/octopus*\" \\\n+\t\t--decorate-refs=\"tags/reach\" >actual &&\n+    test_cmp expect.decorate actual\n+'\n+\n+test_expect_success 'decorate-refs-exclude with glob' '\n+\tcat >expect.decorate <<-\\EOF &&\n+\tMerge-tag-reach (HEAD -> master)\n+\tMerge-tags-octopus-a-and-octopus-b\n+\tseventh (tag: seventh)\n+\toctopus-b (tag: octopus-b)\n+\toctopus-a (tag: octopus-a)\n+\treach (tag: reach, reach)\n+\tEOF\n+\tgit log -n6 --decorate=short --pretty=\"tformat:%f%d\" \\\n+\t\t--decorate-refs-exclude=\"heads/octopus*\" >actual &&\n+\ttest_cmp expect.decorate actual\n+'\n+\n+test_expect_success 'decorate-refs-exclude without globs' '\n+\tcat >expect.decorate <<-\\EOF &&\n+\tMerge-tag-reach (HEAD -> master)\n+\tMerge-tags-octopus-a-and-octopus-b\n+\tseventh (tag: seventh)\n+\toctopus-b (tag: octopus-b, octopus-b)\n+\toctopus-a (tag: octopus-a, octopus-a)\n+\treach (reach)\n+\tEOF\n+\tgit log -n6 --decorate=short --pretty=\"tformat:%f%d\" \\\n+\t\t--decorate-refs-exclude=\"tags/reach\" >actual &&\n+\ttest_cmp expect.decorate actual\n+'\n+\n+test_expect_success 'multiple decorate-refs-exclude' '\n+\tcat >expect.decorate <<-\\EOF &&\n+\tMerge-tag-reach (HEAD -> master)\n+\tMerge-tags-octopus-a-and-octopus-b\n+\tseventh (tag: seventh)\n+\toctopus-b (tag: octopus-b)\n+\toctopus-a (tag: octopus-a)\n+\treach (reach)\n+\tEOF\n+\tgit log -n6 --decorate=short --pretty=\"tformat:%f%d\" \\\n+\t\t--decorate-refs-exclude=\"heads/octopus*\" \\\n+\t\t--decorate-refs-exclude=\"tags/reach\" >actual &&\n+\ttest_cmp expect.decorate actual\n+'\n+\n+test_expect_success 'decorate-refs and decorate-refs-exclude' '\n+\tcat >expect.decorate <<-\\EOF &&\n+\tMerge-tag-reach (master)\n+\tMerge-tags-octopus-a-and-octopus-b\n+\tseventh\n+\toctopus-b\n+\toctopus-a\n+\treach (reach)\n+\tEOF\n+\tgit log -n6 --decorate=short --pretty=\"tformat:%f%d\" \\\n+\t\t--decorate-refs=\"heads/*\" \\\n+\t\t--decorate-refs-exclude=\"heads/oc*\" >actual &&\n+\ttest_cmp expect.decorate actual\n+'\n+\n+test_expect_success 'log.decorate config parsing' '\n+\tgit log --oneline --decorate=full >expect.full &&\n+\tgit log --oneline --decorate=short >expect.short &&\n+\n+\ttest_config log.decorate full &&\n+\ttest_config log.mailmap true &&\n+\tgit log --oneline >actual &&\n+\ttest_cmp expect.full actual &&\n+\tgit log --oneline --decorate=short >actual &&\n+\ttest_cmp expect.short actual\n+'\n+\n+test_expect_success TTY 'log output on a TTY' '\n+\tgit log --color --oneline --decorate >expect.short &&\n+\n+\ttest_terminal git log --oneline >actual &&\n+\ttest_cmp expect.short actual\n+'\n+\n+test_expect_success 'reflog is expected format' '\n+\tgit log -g --abbrev-commit --pretty=oneline >expect &&\n+\tgit reflog >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'whatchanged is expected format' '\n+\tgit log --no-merges --raw >expect &&\n+\tgit whatchanged >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'log.abbrevCommit configuration' '\n+\tgit log --abbrev-commit >expect.log.abbrev &&\n+\tgit log --no-abbrev-commit >expect.log.full &&\n+\tgit log --pretty=raw >expect.log.raw &&\n+\tgit reflog --abbrev-commit >expect.reflog.abbrev &&\n+\tgit reflog --no-abbrev-commit >expect.reflog.full &&\n+\tgit whatchanged --abbrev-commit >expect.whatchanged.abbrev &&\n+\tgit whatchanged --no-abbrev-commit >expect.whatchanged.full &&\n+\n+\ttest_config log.abbrevCommit true &&\n+\n+\tgit log >actual &&\n+\ttest_cmp expect.log.abbrev actual &&\n+\tgit log --no-abbrev-commit >actual &&\n+\ttest_cmp expect.log.full actual &&\n+\n+\tgit log --pretty=raw >actual &&\n+\ttest_cmp expect.log.raw actual &&\n+\n+\tgit reflog >actual &&\n+\ttest_cmp expect.reflog.abbrev actual &&\n+\tgit reflog --no-abbrev-commit >actual &&\n+\ttest_cmp expect.reflog.full actual &&\n+\n+\tgit whatchanged >actual &&\n+\ttest_cmp expect.whatchanged.abbrev actual &&\n+\tgit whatchanged --no-abbrev-commit >actual &&\n+\ttest_cmp expect.whatchanged.full actual\n+'\n+\n+test_expect_success 'show added path under \"--follow -M\"' '\n+\t# This tests for a regression introduced in v1.7.2-rc0~103^2~2\n+\ttest_create_repo regression &&\n+\t(\n+\t\tcd regression &&\n+\t\ttest_commit needs-another-commit &&\n+\t\ttest_commit foo.bar &&\n+\t\tgit log -M --follow -p foo.bar.t &&\n+\t\tgit log -M --follow --stat foo.bar.t &&\n+\t\tgit log -M --follow --name-only foo.bar.t\n+\t)\n+'\n+\n+test_expect_success 'git log -c --follow' '\n+\ttest_create_repo follow-c &&\n+\t(\n+\t\tcd follow-c &&\n+\t\ttest_commit initial file original &&\n+\t\tgit rm file &&\n+\t\ttest_commit rename file2 original &&\n+\t\tgit reset --hard initial &&\n+\t\ttest_commit modify file foo &&\n+\t\tgit merge -m merge rename &&\n+\t\tgit log -c --follow file2\n+\t)\n+'\n+\n+cat >expect <<\\EOF\n+*   commit COMMIT_OBJECT_NAME\n+|\\  Merge: MERGE_PARENTS\n+| | Author: A U Thor <author@example.com>\n+| |\n+| |     Merge HEADS DESCRIPTION\n+| |\n+| * commit COMMIT_OBJECT_NAME\n+| | Author: A U Thor <author@example.com>\n+| |\n+| |     reach\n+| | ---\n+| |  reach.t | 1 +\n+| |  1 file changed, 1 insertion(+)\n+| |\n+| | diff --git a/reach.t b/reach.t\n+| | new file mode 100644\n+| | index 0000000..10c9591\n+| | --- /dev/null\n+| | +++ b/reach.t\n+| | @@ -0,0 +1 @@\n+| | +reach\n+| |\n+|  \\\n+*-. \\   commit COMMIT_OBJECT_NAME\n+|\\ \\ \\  Merge: MERGE_PARENTS\n+| | | | Author: A U Thor <author@example.com>\n+| | | |\n+| | | |     Merge HEADS DESCRIPTION\n+| | | |\n+| | * | commit COMMIT_OBJECT_NAME\n+| | |/  Author: A U Thor <author@example.com>\n+| | |\n+| | |       octopus-b\n+| | |   ---\n+| | |    octopus-b.t | 1 +\n+| | |    1 file changed, 1 insertion(+)\n+| | |\n+| | |   diff --git a/octopus-b.t b/octopus-b.t\n+| | |   new file mode 100644\n+| | |   index 0000000..d5fcad0\n+| | |   --- /dev/null\n+| | |   +++ b/octopus-b.t\n+| | |   @@ -0,0 +1 @@\n+| | |   +octopus-b\n+| | |\n+| * | commit COMMIT_OBJECT_NAME\n+| |/  Author: A U Thor <author@example.com>\n+| |\n+| |       octopus-a\n+| |   ---\n+| |    octopus-a.t | 1 +\n+| |    1 file changed, 1 insertion(+)\n+| |\n+| |   diff --git a/octopus-a.t b/octopus-a.t\n+| |   new file mode 100644\n+| |   index 0000000..11ee015\n+| |   --- /dev/null\n+| |   +++ b/octopus-a.t\n+| |   @@ -0,0 +1 @@\n+| |   +octopus-a\n+| |\n+* | commit COMMIT_OBJECT_NAME\n+|/  Author: A U Thor <author@example.com>\n+|\n+|       seventh\n+|   ---\n+|    seventh.t | 1 +\n+|    1 file changed, 1 insertion(+)\n+|\n+|   diff --git a/seventh.t b/seventh.t\n+|   new file mode 100644\n+|   index 0000000..9744ffc\n+|   --- /dev/null\n+|   +++ b/seventh.t\n+|   @@ -0,0 +1 @@\n+|   +seventh\n+|\n+*   commit COMMIT_OBJECT_NAME\n+|\\  Merge: MERGE_PARENTS\n+| | Author: A U Thor <author@example.com>\n+| |\n+| |     Merge branch 'tangle'\n+| |\n+| *   commit COMMIT_OBJECT_NAME\n+| |\\  Merge: MERGE_PARENTS\n+| | | Author: A U Thor <author@example.com>\n+| | |\n+| | |     Merge branch 'side' (early part) into tangle\n+| | |\n+| * |   commit COMMIT_OBJECT_NAME\n+| |\\ \\  Merge: MERGE_PARENTS\n+| | | | Author: A U Thor <author@example.com>\n+| | | |\n+| | | |     Merge branch 'master' (early part) into tangle\n+| | | |\n+| * | | commit COMMIT_OBJECT_NAME\n+| | | | Author: A U Thor <author@example.com>\n+| | | |\n+| | | |     tangle-a\n+| | | | ---\n+| | | |  tangle-a | 1 +\n+| | | |  1 file changed, 1 insertion(+)\n+| | | |\n+| | | | diff --git a/tangle-a b/tangle-a\n+| | | | new file mode 100644\n+| | | | index 0000000..7898192\n+| | | | --- /dev/null\n+| | | | +++ b/tangle-a\n+| | | | @@ -0,0 +1 @@\n+| | | | +a\n+| | | |\n+* | | |   commit COMMIT_OBJECT_NAME\n+|\\ \\ \\ \\  Merge: MERGE_PARENTS\n+| | | | | Author: A U Thor <author@example.com>\n+| | | | |\n+| | | | |     Merge branch 'side'\n+| | | | |\n+| * | | | commit COMMIT_OBJECT_NAME\n+| | |_|/  Author: A U Thor <author@example.com>\n+| |/| |\n+| | | |       side-2\n+| | | |   ---\n+| | | |    2 | 1 +\n+| | | |    1 file changed, 1 insertion(+)\n+| | | |\n+| | | |   diff --git a/2 b/2\n+| | | |   new file mode 100644\n+| | | |   index 0000000..0cfbf08\n+| | | |   --- /dev/null\n+| | | |   +++ b/2\n+| | | |   @@ -0,0 +1 @@\n+| | | |   +2\n+| | | |\n+| * | | commit COMMIT_OBJECT_NAME\n+| | | | Author: A U Thor <author@example.com>\n+| | | |\n+| | | |     side-1\n+| | | | ---\n+| | | |  1 | 1 +\n+| | | |  1 file changed, 1 insertion(+)\n+| | | |\n+| | | | diff --git a/1 b/1\n+| | | | new file mode 100644\n+| | | | index 0000000..d00491f\n+| | | | --- /dev/null\n+| | | | +++ b/1\n+| | | | @@ -0,0 +1 @@\n+| | | | +1\n+| | | |\n+* | | | commit COMMIT_OBJECT_NAME\n+| | | | Author: A U Thor <author@example.com>\n+| | | |\n+| | | |     Second\n+| | | | ---\n+| | | |  one | 1 +\n+| | | |  1 file changed, 1 insertion(+)\n+| | | |\n+| | | | diff --git a/one b/one\n+| | | | new file mode 100644\n+| | | | index 0000000..9a33383\n+| | | | --- /dev/null\n+| | | | +++ b/one\n+| | | | @@ -0,0 +1 @@\n+| | | | +case\n+| | | |\n+* | | | commit COMMIT_OBJECT_NAME\n+| |_|/  Author: A U Thor <author@example.com>\n+|/| |\n+| | |       sixth\n+| | |   ---\n+| | |    a/two | 1 -\n+| | |    1 file changed, 1 deletion(-)\n+| | |\n+| | |   diff --git a/a/two b/a/two\n+| | |   deleted file mode 100644\n+| | |   index 9245af5..0000000\n+| | |   --- a/a/two\n+| | |   +++ /dev/null\n+| | |   @@ -1 +0,0 @@\n+| | |   -ni\n+| | |\n+* | | commit COMMIT_OBJECT_NAME\n+| | | Author: A U Thor <author@example.com>\n+| | |\n+| | |     fifth\n+| | | ---\n+| | |  a/two | 1 +\n+| | |  1 file changed, 1 insertion(+)\n+| | |\n+| | | diff --git a/a/two b/a/two\n+| | | new file mode 100644\n+| | | index 0000000..9245af5\n+| | | --- /dev/null\n+| | | +++ b/a/two\n+| | | @@ -0,0 +1 @@\n+| | | +ni\n+| | |\n+* | | commit COMMIT_OBJECT_NAME\n+|/ /  Author: A U Thor <author@example.com>\n+| |\n+| |       fourth\n+| |   ---\n+| |    ein | 1 +\n+| |    1 file changed, 1 insertion(+)\n+| |\n+| |   diff --git a/ein b/ein\n+| |   new file mode 100644\n+| |   index 0000000..9d7e69f\n+| |   --- /dev/null\n+| |   +++ b/ein\n+| |   @@ -0,0 +1 @@\n+| |   +ichi\n+| |\n+* | commit COMMIT_OBJECT_NAME\n+|/  Author: A U Thor <author@example.com>\n+|\n+|       third\n+|   ---\n+|    ichi | 1 +\n+|    one  | 1 -\n+|    2 files changed, 1 insertion(+), 1 deletion(-)\n+|\n+|   diff --git a/ichi b/ichi\n+|   new file mode 100644\n+|   index 0000000..9d7e69f\n+|   --- /dev/null\n+|   +++ b/ichi\n+|   @@ -0,0 +1 @@\n+|   +ichi\n+|   diff --git a/one b/one\n+|   deleted file mode 100644\n+|   index 9d7e69f..0000000\n+|   --- a/one\n+|   +++ /dev/null\n+|   @@ -1 +0,0 @@\n+|   -ichi\n+|\n+* commit COMMIT_OBJECT_NAME\n+| Author: A U Thor <author@example.com>\n+|\n+|     second\n+| ---\n+|  one | 2 +-\n+|  1 file changed, 1 insertion(+), 1 deletion(-)\n+|\n+| diff --git a/one b/one\n+| index 5626abf..9d7e69f 100644\n+| --- a/one\n+| +++ b/one\n+| @@ -1 +1 @@\n+| -one\n+| +ichi\n+|\n+* commit COMMIT_OBJECT_NAME\n+  Author: A U Thor <author@example.com>\n+\n+      initial\n+  ---\n+   one | 1 +\n+   1 file changed, 1 insertion(+)\n+\n+  diff --git a/one b/one\n+  new file mode 100644\n+  index 0000000..5626abf\n+  --- /dev/null\n+  +++ b/one\n+  @@ -0,0 +1 @@\n+  +one\n+EOF\n+\n+sanitize_output () {\n+\tsed -e 's/ *$//' \\\n+\t    -e 's/commit [0-9a-f]*$/commit COMMIT_OBJECT_NAME/' \\\n+\t    -e 's/Merge: [ 0-9a-f]*$/Merge: MERGE_PARENTS/' \\\n+\t    -e 's/Merge tag.*/Merge HEADS DESCRIPTION/' \\\n+\t    -e 's/Merge commit.*/Merge HEADS DESCRIPTION/' \\\n+\t    -e 's/, 0 deletions(-)//' \\\n+\t    -e 's/, 0 insertions(+)//' \\\n+\t    -e 's/ 1 files changed, / 1 file changed, /' \\\n+\t    -e 's/, 1 deletions(-)/, 1 deletion(-)/' \\\n+\t    -e 's/, 1 insertions(+)/, 1 insertion(+)/'\n+}\n+\n+test_expect_success 'log --graph with diff and stats' '\n+\tgit log --no-renames --graph --pretty=short --stat -p >actual &&\n+\tsanitize_output >actual.sanitized <actual &&\n+\ttest_i18ncmp expect actual.sanitized\n+'\n+\n+cat >expect <<\\EOF\n+*** *   commit COMMIT_OBJECT_NAME\n+*** |\\  Merge: MERGE_PARENTS\n+*** | | Author: A U Thor <author@example.com>\n+*** | |\n+*** | |     Merge HEADS DESCRIPTION\n+*** | |\n+*** | * commit COMMIT_OBJECT_NAME\n+*** | | Author: A U Thor <author@example.com>\n+*** | |\n+*** | |     reach\n+*** | | ---\n+*** | |  reach.t | 1 +\n+*** | |  1 file changed, 1 insertion(+)\n+*** | |\n+*** | | diff --git a/reach.t b/reach.t\n+*** | | new file mode 100644\n+*** | | index 0000000..10c9591\n+*** | | --- /dev/null\n+*** | | +++ b/reach.t\n+*** | | @@ -0,0 +1 @@\n+*** | | +reach\n+*** | |\n+*** |  \\\n+*** *-. \\   commit COMMIT_OBJECT_NAME\n+*** |\\ \\ \\  Merge: MERGE_PARENTS\n+*** | | | | Author: A U Thor <author@example.com>\n+*** | | | |\n+*** | | | |     Merge HEADS DESCRIPTION\n+*** | | | |\n+*** | | * | commit COMMIT_OBJECT_NAME\n+*** | | |/  Author: A U Thor <author@example.com>\n+*** | | |\n+*** | | |       octopus-b\n+*** | | |   ---\n+*** | | |    octopus-b.t | 1 +\n+*** | | |    1 file changed, 1 insertion(+)\n+*** | | |\n+*** | | |   diff --git a/octopus-b.t b/octopus-b.t\n+*** | | |   new file mode 100644\n+*** | | |   index 0000000..d5fcad0\n+*** | | |   --- /dev/null\n+*** | | |   +++ b/octopus-b.t\n+*** | | |   @@ -0,0 +1 @@\n+*** | | |   +octopus-b\n+*** | | |\n+*** | * | commit COMMIT_OBJECT_NAME\n+*** | |/  Author: A U Thor <author@example.com>\n+*** | |\n+*** | |       octopus-a\n+*** | |   ---\n+*** | |    octopus-a.t | 1 +\n+*** | |    1 file changed, 1 insertion(+)\n+*** | |\n+*** | |   diff --git a/octopus-a.t b/octopus-a.t\n+*** | |   new file mode 100644\n+*** | |   index 0000000..11ee015\n+*** | |   --- /dev/null\n+*** | |   +++ b/octopus-a.t\n+*** | |   @@ -0,0 +1 @@\n+*** | |   +octopus-a\n+*** | |\n+*** * | commit COMMIT_OBJECT_NAME\n+*** |/  Author: A U Thor <author@example.com>\n+*** |\n+*** |       seventh\n+*** |   ---\n+*** |    seventh.t | 1 +\n+*** |    1 file changed, 1 insertion(+)\n+*** |\n+*** |   diff --git a/seventh.t b/seventh.t\n+*** |   new file mode 100644\n+*** |   index 0000000..9744ffc\n+*** |   --- /dev/null\n+*** |   +++ b/seventh.t\n+*** |   @@ -0,0 +1 @@\n+*** |   +seventh\n+*** |\n+*** *   commit COMMIT_OBJECT_NAME\n+*** |\\  Merge: MERGE_PARENTS\n+*** | | Author: A U Thor <author@example.com>\n+*** | |\n+*** | |     Merge branch 'tangle'\n+*** | |\n+*** | *   commit COMMIT_OBJECT_NAME\n+*** | |\\  Merge: MERGE_PARENTS\n+*** | | | Author: A U Thor <author@example.com>\n+*** | | |\n+*** | | |     Merge branch 'side' (early part) into tangle\n+*** | | |\n+*** | * |   commit COMMIT_OBJECT_NAME\n+*** | |\\ \\  Merge: MERGE_PARENTS\n+*** | | | | Author: A U Thor <author@example.com>\n+*** | | | |\n+*** | | | |     Merge branch 'master' (early part) into tangle\n+*** | | | |\n+*** | * | | commit COMMIT_OBJECT_NAME\n+*** | | | | Author: A U Thor <author@example.com>\n+*** | | | |\n+*** | | | |     tangle-a\n+*** | | | | ---\n+*** | | | |  tangle-a | 1 +\n+*** | | | |  1 file changed, 1 insertion(+)\n+*** | | | |\n+*** | | | | diff --git a/tangle-a b/tangle-a\n+*** | | | | new file mode 100644\n+*** | | | | index 0000000..7898192\n+*** | | | | --- /dev/null\n+*** | | | | +++ b/tangle-a\n+*** | | | | @@ -0,0 +1 @@\n+*** | | | | +a\n+*** | | | |\n+*** * | | |   commit COMMIT_OBJECT_NAME\n+*** |\\ \\ \\ \\  Merge: MERGE_PARENTS\n+*** | | | | | Author: A U Thor <author@example.com>\n+*** | | | | |\n+*** | | | | |     Merge branch 'side'\n+*** | | | | |\n+*** | * | | | commit COMMIT_OBJECT_NAME\n+*** | | |_|/  Author: A U Thor <author@example.com>\n+*** | |/| |\n+*** | | | |       side-2\n+*** | | | |   ---\n+*** | | | |    2 | 1 +\n+*** | | | |    1 file changed, 1 insertion(+)\n+*** | | | |\n+*** | | | |   diff --git a/2 b/2\n+*** | | | |   new file mode 100644\n+*** | | | |   index 0000000..0cfbf08\n+*** | | | |   --- /dev/null\n+*** | | | |   +++ b/2\n+*** | | | |   @@ -0,0 +1 @@\n+*** | | | |   +2\n+*** | | | |\n+*** | * | | commit COMMIT_OBJECT_NAME\n+*** | | | | Author: A U Thor <author@example.com>\n+*** | | | |\n+*** | | | |     side-1\n+*** | | | | ---\n+*** | | | |  1 | 1 +\n+*** | | | |  1 file changed, 1 insertion(+)\n+*** | | | |\n+*** | | | | diff --git a/1 b/1\n+*** | | | | new file mode 100644\n+*** | | | | index 0000000..d00491f\n+*** | | | | --- /dev/null\n+*** | | | | +++ b/1\n+*** | | | | @@ -0,0 +1 @@\n+*** | | | | +1\n+*** | | | |\n+*** * | | | commit COMMIT_OBJECT_NAME\n+*** | | | | Author: A U Thor <author@example.com>\n+*** | | | |\n+*** | | | |     Second\n+*** | | | | ---\n+*** | | | |  one | 1 +\n+*** | | | |  1 file changed, 1 insertion(+)\n+*** | | | |\n+*** | | | | diff --git a/one b/one\n+*** | | | | new file mode 100644\n+*** | | | | index 0000000..9a33383\n+*** | | | | --- /dev/null\n+*** | | | | +++ b/one\n+*** | | | | @@ -0,0 +1 @@\n+*** | | | | +case\n+*** | | | |\n+*** * | | | commit COMMIT_OBJECT_NAME\n+*** | |_|/  Author: A U Thor <author@example.com>\n+*** |/| |\n+*** | | |       sixth\n+*** | | |   ---\n+*** | | |    a/two | 1 -\n+*** | | |    1 file changed, 1 deletion(-)\n+*** | | |\n+*** | | |   diff --git a/a/two b/a/two\n+*** | | |   deleted file mode 100644\n+*** | | |   index 9245af5..0000000\n+*** | | |   --- a/a/two\n+*** | | |   +++ /dev/null\n+*** | | |   @@ -1 +0,0 @@\n+*** | | |   -ni\n+*** | | |\n+*** * | | commit COMMIT_OBJECT_NAME\n+*** | | | Author: A U Thor <author@example.com>\n+*** | | |\n+*** | | |     fifth\n+*** | | | ---\n+*** | | |  a/two | 1 +\n+*** | | |  1 file changed, 1 insertion(+)\n+*** | | |\n+*** | | | diff --git a/a/two b/a/two\n+*** | | | new file mode 100644\n+*** | | | index 0000000..9245af5\n+*** | | | --- /dev/null\n+*** | | | +++ b/a/two\n+*** | | | @@ -0,0 +1 @@\n+*** | | | +ni\n+*** | | |\n+*** * | | commit COMMIT_OBJECT_NAME\n+*** |/ /  Author: A U Thor <author@example.com>\n+*** | |\n+*** | |       fourth\n+*** | |   ---\n+*** | |    ein | 1 +\n+*** | |    1 file changed, 1 insertion(+)\n+*** | |\n+*** | |   diff --git a/ein b/ein\n+*** | |   new file mode 100644\n+*** | |   index 0000000..9d7e69f\n+*** | |   --- /dev/null\n+*** | |   +++ b/ein\n+*** | |   @@ -0,0 +1 @@\n+*** | |   +ichi\n+*** | |\n+*** * | commit COMMIT_OBJECT_NAME\n+*** |/  Author: A U Thor <author@example.com>\n+*** |\n+*** |       third\n+*** |   ---\n+*** |    ichi | 1 +\n+*** |    one  | 1 -\n+*** |    2 files changed, 1 insertion(+), 1 deletion(-)\n+*** |\n+*** |   diff --git a/ichi b/ichi\n+*** |   new file mode 100644\n+*** |   index 0000000..9d7e69f\n+*** |   --- /dev/null\n+*** |   +++ b/ichi\n+*** |   @@ -0,0 +1 @@\n+*** |   +ichi\n+*** |   diff --git a/one b/one\n+*** |   deleted file mode 100644\n+*** |   index 9d7e69f..0000000\n+*** |   --- a/one\n+*** |   +++ /dev/null\n+*** |   @@ -1 +0,0 @@\n+*** |   -ichi\n+*** |\n+*** * commit COMMIT_OBJECT_NAME\n+*** | Author: A U Thor <author@example.com>\n+*** |\n+*** |     second\n+*** | ---\n+*** |  one | 2 +-\n+*** |  1 file changed, 1 insertion(+), 1 deletion(-)\n+*** |\n+*** | diff --git a/one b/one\n+*** | index 5626abf..9d7e69f 100644\n+*** | --- a/one\n+*** | +++ b/one\n+*** | @@ -1 +1 @@\n+*** | -one\n+*** | +ichi\n+*** |\n+*** * commit COMMIT_OBJECT_NAME\n+***   Author: A U Thor <author@example.com>\n+***\n+***       initial\n+***   ---\n+***    one | 1 +\n+***    1 file changed, 1 insertion(+)\n+***\n+***   diff --git a/one b/one\n+***   new file mode 100644\n+***   index 0000000..5626abf\n+***   --- /dev/null\n+***   +++ b/one\n+***   @@ -0,0 +1 @@\n+***   +one\n+EOF\n+\n+test_expect_success 'log --line-prefix=\"*** \" --graph with diff and stats' '\n+\tgit log --line-prefix=\"*** \" --no-renames --graph --pretty=short --stat -p >actual &&\n+\tsanitize_output >actual.sanitized <actual &&\n+\ttest_i18ncmp expect actual.sanitized\n+'\n+\n+cat >expect <<-\\EOF\n+* reach\n+|\n+| A\treach.t\n+* Merge branch 'tangle'\n+*   Merge branch 'side'\n+|\\\n+| * side-2\n+|\n+|   A\t2\n+* Second\n+|\n+| A\tone\n+* sixth\n+\n+  D\ta/two\n+EOF\n+\n+test_expect_success 'log --graph with --name-status' '\n+\tgit log --graph --format=%s --name-status tangle..reach >actual &&\n+\tsanitize_output <actual >actual.sanitized &&\n+\ttest_cmp expect actual.sanitized\n+'\n+\n+cat >expect <<-\\EOF\n+* reach\n+|\n+| reach.t\n+* Merge branch 'tangle'\n+*   Merge branch 'side'\n+|\\\n+| * side-2\n+|\n+|   2\n+* Second\n+|\n+| one\n+* sixth\n+\n+  a/two\n+EOF\n+\n+test_expect_success 'log --graph with --name-only' '\n+\tgit log --graph --format=%s --name-only tangle..reach >actual &&\n+\tsanitize_output <actual >actual.sanitized &&\n+\ttest_cmp expect actual.sanitized\n+'\n+\n+test_expect_success 'dotdot is a parent directory' '\n+\tmkdir -p a/b &&\n+\t( echo sixth && echo fifth ) >expect &&\n+\t( cd a/b && git log --format=%s .. ) >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG 'setup signed branch' '\n+\ttest_when_finished \"git reset --hard && git checkout master\" &&\n+\tgit checkout -b signed master &&\n+\techo foo >foo &&\n+\tgit add foo &&\n+\tgit commit -S -m signed_commit\n+'\n+\n+test_expect_success GPGSM 'setup signed branch x509' '\n+\ttest_when_finished \"git reset --hard && git checkout master\" &&\n+\tgit checkout -b signed-x509 master &&\n+\techo foo >foo &&\n+\tgit add foo &&\n+\ttest_config signing.default x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\tgit commit -S -m signed_commit\n+'\n+\n+test_expect_success GPG 'log --graph --show-signature' '\n+\tgit log --graph --show-signature -n1 signed >actual &&\n+\tgrep \"^| gpg: Signature made\" actual &&\n+\tgrep \"^| gpg: Good signature\" actual\n+'\n+\n+test_expect_success GPGSM 'log --graph --show-signature x509' '\n+\tgit log --graph --show-signature -n1 signed-x509 >actual &&\n+\tgrep \"^| gpgsm: Signature made\" actual &&\n+\tgrep \"^| gpgsm: Good signature\" actual\n+'\n+\n+test_expect_success GPG 'log --graph --show-signature for merged tag' '\n+\ttest_when_finished \"git reset --hard && git checkout master\" &&\n+\tgit checkout -b plain master &&\n+\techo aaa >bar &&\n+\tgit add bar &&\n+\tgit commit -m bar_commit &&\n+\tgit checkout -b tagged master &&\n+\techo bbb >baz &&\n+\tgit add baz &&\n+\tgit commit -m baz_commit &&\n+\tgit tag -s -m signed_tag_msg signed_tag &&\n+\tgit checkout plain &&\n+\tgit merge --no-ff -m msg signed_tag &&\n+\tgit log --graph --show-signature -n1 plain >actual &&\n+\tgrep \"^|\\\\\\  merged tag\" actual &&\n+\tgrep \"^| | gpg: Signature made\" actual &&\n+\tgrep \"^| | gpg: Good signature\" actual\n+'\n+\n+test_expect_success GPGSM 'log --graph --show-signature for merged tag x509' '\n+\ttest_when_finished \"git reset --hard && git checkout master\" &&\n+\ttest_config signing.default x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\tgit checkout -b plain-x509 master &&\n+\techo aaa >bar &&\n+\tgit add bar &&\n+\tgit commit -m bar_commit &&\n+\tgit checkout -b tagged-x509 master &&\n+\techo bbb >baz &&\n+\tgit add baz &&\n+\tgit commit -m baz_commit &&\n+\tgit tag -s -m signed_tag_msg signed_tag_x509 &&\n+\tgit checkout plain-x509 &&\n+\tgit merge --no-ff -m msg signed_tag_x509 &&\n+\tgit log --graph --show-signature -n1 plain-x509 >actual &&\n+\tgrep \"^|\\\\\\  merged tag\" actual &&\n+\tgrep \"^| | gpgsm: Signature made\" actual &&\n+\tgrep \"^| | gpgsm: Good signature\" actual\n+'\n+\n+test_expect_success GPG '--no-show-signature overrides --show-signature' '\n+\tgit log -1 --show-signature --no-show-signature signed >actual &&\n+\t! grep \"^gpg:\" actual\n+'\n+\n+test_expect_success GPG 'log.showsignature=true behaves like --show-signature' '\n+\ttest_config log.showsignature true &&\n+\tgit log -1 signed >actual &&\n+\tgrep \"gpg: Signature made\" actual &&\n+\tgrep \"gpg: Good signature\" actual\n+'\n+\n+test_expect_success GPG '--no-show-signature overrides log.showsignature=true' '\n+\ttest_config log.showsignature true &&\n+\tgit log -1 --no-show-signature signed >actual &&\n+\t! grep \"^gpg:\" actual\n+'\n+\n+test_expect_success GPG '--show-signature overrides log.showsignature=false' '\n+\ttest_config log.showsignature false &&\n+\tgit log -1 --show-signature signed >actual &&\n+\tgrep \"gpg: Signature made\" actual &&\n+\tgrep \"gpg: Good signature\" actual\n+'\n+\n+test_expect_success 'log --graph --no-walk is forbidden' '\n+\ttest_must_fail git log --graph --no-walk\n+'\n+\n+test_expect_success 'log diagnoses bogus HEAD' '\n+\tgit init empty &&\n+\ttest_must_fail git -C empty log 2>stderr &&\n+\ttest_i18ngrep does.not.have.any.commits stderr &&\n+\techo 1234abcd >empty/.git/refs/heads/master &&\n+\ttest_must_fail git -C empty log 2>stderr &&\n+\ttest_i18ngrep broken stderr &&\n+\techo \"ref: refs/heads/invalid.lock\" >empty/.git/HEAD &&\n+\ttest_must_fail git -C empty log 2>stderr &&\n+\ttest_i18ngrep broken stderr &&\n+\ttest_must_fail git -C empty log --default totally-bogus 2>stderr &&\n+\ttest_i18ngrep broken stderr\n+'\n+\n+test_expect_success 'log does not default to HEAD when rev input is given' '\n+\tgit log --branches=does-not-exist >actual &&\n+\ttest_must_be_empty actual\n+'\n+\n+test_expect_success 'set up --source tests' '\n+\tgit checkout --orphan source-a &&\n+\ttest_commit one &&\n+\ttest_commit two &&\n+\tgit checkout -b source-b HEAD^ &&\n+\ttest_commit three\n+'\n+\n+test_expect_success 'log --source paints branch names' '\n+\tcat >expect <<-\\EOF &&\n+\t09e12a9\tsource-b three\n+\t8e393e1\tsource-a two\n+\t1ac6c77\tsource-b one\n+\tEOF\n+\tgit log --oneline --source source-a source-b >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'log --source paints tag names' '\n+\tgit tag -m tagged source-tag &&\n+\tcat >expect <<-\\EOF &&\n+\t09e12a9\tsource-tag three\n+\t8e393e1\tsource-a two\n+\t1ac6c77\tsource-tag one\n+\tEOF\n+\tgit log --oneline --source source-tag source-a >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'log --source paints symmetric ranges' '\n+\tcat >expect <<-\\EOF &&\n+\t09e12a9\tsource-b three\n+\t8e393e1\tsource-a two\n+\tEOF\n+\tgit log --oneline --source source-a...source-b >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--exclude-promisor-objects does not BUG-crash' '\n+\ttest_must_fail git log --exclude-promisor-objects source-a\n+'\n+\n+test_done\ndiff --git a/t/t5548-push-signed-signconfig.sh b/t/t5548-push-signed-signconfig.sh\nnew file mode 100755\nindex 000000000..f39b2e9dc\n--- /dev/null\n+++ b/t/t5548-push-signed-signconfig.sh\n@@ -0,0 +1,276 @@\n+#!/bin/sh\n+\n+test_description='signed push'\n+\n+. ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-gpg.sh\n+\n+prepare_dst () {\n+\trm -fr dst &&\n+\ttest_create_repo dst &&\n+\n+\tgit push dst master:noop master:ff master:noff\n+}\n+\n+test_expect_success setup '\n+\t# master, ff and noff branches pointing at the same commit\n+\ttest_tick &&\n+\tgit commit --allow-empty -m initial &&\n+\n+\tgit checkout -b noop &&\n+\tgit checkout -b ff &&\n+\tgit checkout -b noff &&\n+\n+\t# noop stays the same, ff advances, noff rewrites\n+\ttest_tick &&\n+\tgit commit --allow-empty --amend -m rewritten &&\n+\tgit checkout ff &&\n+\n+\ttest_tick &&\n+\tgit commit --allow-empty -m second\n+'\n+\n+test_expect_success 'unsigned push does not send push certificate' '\n+\tprepare_dst &&\n+\tmkdir -p dst/.git/hooks &&\n+\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n+\t# discard the update list\n+\tcat >/dev/null\n+\t# record the push certificate\n+\tif test -n \"${GIT_PUSH_CERT-}\"\n+\tthen\n+\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n+\tfi\n+\tEOF\n+\n+\tgit push dst noop ff +noff &&\n+\t! test -f dst/push-cert\n+'\n+\n+test_expect_success 'talking with a receiver without push certificate support' '\n+\tprepare_dst &&\n+\tmkdir -p dst/.git/hooks &&\n+\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n+\t# discard the update list\n+\tcat >/dev/null\n+\t# record the push certificate\n+\tif test -n \"${GIT_PUSH_CERT-}\"\n+\tthen\n+\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n+\tfi\n+\tEOF\n+\n+\tgit push dst noop ff +noff &&\n+\t! test -f dst/push-cert\n+'\n+\n+test_expect_success 'push --signed fails with a receiver without push certificate support' '\n+\tprepare_dst &&\n+\tmkdir -p dst/.git/hooks &&\n+\ttest_must_fail git push --signed dst noop ff +noff 2>err &&\n+\ttest_i18ngrep \"the receiving end does not support\" err\n+'\n+\n+test_expect_success 'push --signed=1 is accepted' '\n+\tprepare_dst &&\n+\tmkdir -p dst/.git/hooks &&\n+\ttest_must_fail git push --signed=1 dst noop ff +noff 2>err &&\n+\ttest_i18ngrep \"the receiving end does not support\" err\n+'\n+\n+test_expect_success GPG 'no certificate for a signed push with no update' '\n+\tprepare_dst &&\n+\tmkdir -p dst/.git/hooks &&\n+\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n+\tif test -n \"${GIT_PUSH_CERT-}\"\n+\tthen\n+\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n+\tfi\n+\tEOF\n+\tgit push dst noop &&\n+\t! test -f dst/push-cert\n+'\n+\n+test_expect_success GPG 'signed push sends push certificate' '\n+\tprepare_dst &&\n+\tmkdir -p dst/.git/hooks &&\n+\tgit -C dst config receive.certnonceseed sekrit &&\n+\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n+\t# discard the update list\n+\tcat >/dev/null\n+\t# record the push certificate\n+\tif test -n \"${GIT_PUSH_CERT-}\"\n+\tthen\n+\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n+\tfi &&\n+\n+\tcat >../push-cert-status <<E_O_F\n+\tSIGNER=${GIT_PUSH_CERT_SIGNER-nobody}\n+\tKEY=${GIT_PUSH_CERT_KEY-nokey}\n+\tSTATUS=${GIT_PUSH_CERT_STATUS-nostatus}\n+\tNONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}\n+\tNONCE=${GIT_PUSH_CERT_NONCE-nononce}\n+\tE_O_F\n+\n+\tEOF\n+\n+\tgit push --signed dst noop ff +noff &&\n+\n+\t(\n+\t\tcat <<-\\EOF &&\n+\t\tSIGNER=C O Mitter <committer@example.com>\n+\t\tKEY=13B6F51ECDDE430D\n+\t\tSTATUS=G\n+\t\tNONCE_STATUS=OK\n+\t\tEOF\n+\t\tsed -n -e \"s/^nonce /NONCE=/p\" -e \"/^$/q\" dst/push-cert\n+\t) >expect &&\n+\n+\tnoop=$(git rev-parse noop) &&\n+\tff=$(git rev-parse ff) &&\n+\tnoff=$(git rev-parse noff) &&\n+\tgrep \"$noop $ff refs/heads/ff\" dst/push-cert &&\n+\tgrep \"$noop $noff refs/heads/noff\" dst/push-cert &&\n+\ttest_cmp expect dst/push-cert-status\n+'\n+\n+test_expect_success GPG 'inconsistent push options in signed push not allowed' '\n+\t# First, invoke receive-pack with dummy input to obtain its preamble.\n+\tprepare_dst &&\n+\tgit -C dst config receive.certnonceseed sekrit &&\n+\tgit -C dst config receive.advertisepushoptions 1 &&\n+\tprintf xxxx | test_might_fail git receive-pack dst >preamble &&\n+\n+\t# Then, invoke push. Simulate a receive-pack that sends the preamble we\n+\t# obtained, followed by a dummy packet.\n+\twrite_script myscript <<-\\EOF &&\n+\t\tcat preamble &&\n+\t\tprintf xxxx &&\n+\t\tcat >push\n+\tEOF\n+\ttest_might_fail git push --push-option=\"foo\" --push-option=\"bar\" \\\n+\t\t--receive-pack=\"\\\"$(pwd)/myscript\\\"\" --signed dst --delete ff &&\n+\n+\t# Replay the push output on a fresh dst, checking that ff is truly\n+\t# deleted.\n+\tprepare_dst &&\n+\tgit -C dst config receive.certnonceseed sekrit &&\n+\tgit -C dst config receive.advertisepushoptions 1 &&\n+\tgit receive-pack dst <push &&\n+\ttest_must_fail git -C dst rev-parse ff &&\n+\n+\t# Tweak the push output to make the push option outside the cert\n+\t# different, then replay it on a fresh dst, checking that ff is not\n+\t# deleted.\n+\tperl -pe \"s/([^ ])bar/\\$1baz/\" push >push.tweak &&\n+\tprepare_dst &&\n+\tgit -C dst config receive.certnonceseed sekrit &&\n+\tgit -C dst config receive.advertisepushoptions 1 &&\n+\tgit receive-pack dst <push.tweak >out &&\n+\tgit -C dst rev-parse ff &&\n+\tgrep \"inconsistent push options\" out\n+'\n+\n+test_expect_success GPG 'fail without key and heed user.signingkey' '\n+\tprepare_dst &&\n+\tmkdir -p dst/.git/hooks &&\n+\tgit -C dst config receive.certnonceseed sekrit &&\n+\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n+\t# discard the update list\n+\tcat >/dev/null\n+\t# record the push certificate\n+\tif test -n \"${GIT_PUSH_CERT-}\"\n+\tthen\n+\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n+\tfi &&\n+\n+\tcat >../push-cert-status <<E_O_F\n+\tSIGNER=${GIT_PUSH_CERT_SIGNER-nobody}\n+\tKEY=${GIT_PUSH_CERT_KEY-nokey}\n+\tSTATUS=${GIT_PUSH_CERT_STATUS-nostatus}\n+\tNONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}\n+\tNONCE=${GIT_PUSH_CERT_NONCE-nononce}\n+\tE_O_F\n+\n+\tEOF\n+\n+\ttest_config user.email hasnokey@nowhere.com &&\n+\t(\n+\t\tsane_unset GIT_COMMITTER_EMAIL &&\n+\t\ttest_must_fail git push --signed dst noop ff +noff\n+\t) &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\tgit push --signed dst noop ff +noff &&\n+\n+\t(\n+\t\tcat <<-\\EOF &&\n+\t\tSIGNER=C O Mitter <committer@example.com>\n+\t\tKEY=13B6F51ECDDE430D\n+\t\tSTATUS=G\n+\t\tNONCE_STATUS=OK\n+\t\tEOF\n+\t\tsed -n -e \"s/^nonce /NONCE=/p\" -e \"/^$/q\" dst/push-cert\n+\t) >expect &&\n+\n+\tnoop=$(git rev-parse noop) &&\n+\tff=$(git rev-parse ff) &&\n+\tnoff=$(git rev-parse noff) &&\n+\tgrep \"$noop $ff refs/heads/ff\" dst/push-cert &&\n+\tgrep \"$noop $noff refs/heads/noff\" dst/push-cert &&\n+\ttest_cmp expect dst/push-cert-status\n+'\n+\n+test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '\n+\ttest_config signing.default x509 &&\n+\tprepare_dst &&\n+\tmkdir -p dst/.git/hooks &&\n+\tgit -C dst config receive.certnonceseed sekrit &&\n+\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n+\t# discard the update list\n+\tcat >/dev/null\n+\t# record the push certificate\n+\tif test -n \"${GIT_PUSH_CERT-}\"\n+\tthen\n+\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n+\tfi &&\n+\n+\tcat >../push-cert-status <<E_O_F\n+\tSIGNER=${GIT_PUSH_CERT_SIGNER-nobody}\n+\tKEY=${GIT_PUSH_CERT_KEY-nokey}\n+\tSTATUS=${GIT_PUSH_CERT_STATUS-nostatus}\n+\tNONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}\n+\tNONCE=${GIT_PUSH_CERT_NONCE-nononce}\n+\tE_O_F\n+\n+\tEOF\n+\n+\ttest_config user.email hasnokey@nowhere.com &&\n+\ttest_config user.signingkey \"\" &&\n+\t(\n+\t\tsane_unset GIT_COMMITTER_EMAIL &&\n+\t\ttest_must_fail git push --signed dst noop ff +noff\n+\t) &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\tgit push --signed dst noop ff +noff &&\n+\n+\t(\n+\t\tcat <<-\\EOF &&\n+\t\tSIGNER=/CN=C O Mitter/O=Example/SN=C O/GN=Mitter\n+\t\tKEY=\n+\t\tSTATUS=G\n+\t\tNONCE_STATUS=OK\n+\t\tEOF\n+\t\tsed -n -e \"s/^nonce /NONCE=/p\" -e \"/^$/q\" dst/push-cert\n+\t) >expect.in &&\n+\tkey=$(cat \"${GNUPGHOME}/trustlist.txt\" | cut -d\" \" -f1 | tr -d \":\") &&\n+\tsed -e \"s/^KEY=/KEY=${key}/\" expect.in >expect &&\n+\n+\tnoop=$(git rev-parse noop) &&\n+\tff=$(git rev-parse ff) &&\n+\tnoff=$(git rev-parse noff) &&\n+\tgrep \"$noop $ff refs/heads/ff\" dst/push-cert &&\n+\tgrep \"$noop $noff refs/heads/noff\" dst/push-cert &&\n+\ttest_cmp expect dst/push-cert-status\n+'\n+\n+test_done\ndiff --git a/t/t7013-tag-signconfig.sh b/t/t7013-tag-signconfig.sh\nnew file mode 100755\nindex 000000000..691ab7b7e\n--- /dev/null\n+++ b/t/t7013-tag-signconfig.sh\n@@ -0,0 +1,2074 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2007 Carlos Rica\n+#\n+\n+test_description='git tag\n+\n+Tests for operations with tags.'\n+\n+. ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-gpg.sh\n+. \"$TEST_DIRECTORY\"/lib-terminal.sh\n+\n+# creating and listing lightweight tags:\n+\n+tag_exists () {\n+\tgit show-ref --quiet --verify refs/tags/\"$1\"\n+}\n+\n+test_expect_success 'listing all tags in an empty tree should succeed' '\n+\tgit tag -l &&\n+\tgit tag\n+'\n+\n+test_expect_success 'listing all tags in an empty tree should output nothing' '\n+\ttest $(git tag -l | wc -l) -eq 0 &&\n+\ttest $(git tag | wc -l) -eq 0\n+'\n+\n+test_expect_success 'sort tags, ignore case' '\n+\t(\n+\t\tgit init sort &&\n+\t\tcd sort &&\n+\t\ttest_commit initial &&\n+\t\tgit tag tag-one &&\n+\t\tgit tag TAG-two &&\n+\t\tgit tag -l >actual &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\tTAG-two\n+\t\tinitial\n+\t\ttag-one\n+\t\tEOF\n+\t\ttest_cmp expected actual &&\n+\t\tgit tag -l -i >actual &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\tinitial\n+\t\ttag-one\n+\t\tTAG-two\n+\t\tEOF\n+\t\ttest_cmp expected actual\n+\t)\n+'\n+\n+test_expect_success 'looking for a tag in an empty tree should fail' \\\n+\t'! (tag_exists mytag)'\n+\n+test_expect_success 'creating a tag in an empty tree should fail' '\n+\ttest_must_fail git tag mynotag &&\n+\t! tag_exists mynotag\n+'\n+\n+test_expect_success 'creating a tag for HEAD in an empty tree should fail' '\n+\ttest_must_fail git tag mytaghead HEAD &&\n+\t! tag_exists mytaghead\n+'\n+\n+test_expect_success 'creating a tag for an unknown revision should fail' '\n+\ttest_must_fail git tag mytagnorev aaaaaaaaaaa &&\n+\t! tag_exists mytagnorev\n+'\n+\n+# commit used in the tests, test_tick is also called here to freeze the date:\n+test_expect_success 'creating a tag using default HEAD should succeed' '\n+\ttest_config core.logAllRefUpdates true &&\n+\ttest_tick &&\n+\techo foo >foo &&\n+\tgit add foo &&\n+\tgit commit -m Foo &&\n+\tgit tag mytag &&\n+\ttest_must_fail git reflog exists refs/tags/mytag\n+'\n+\n+test_expect_success 'creating a tag with --create-reflog should create reflog' '\n+\tgit log -1 \\\n+\t\t--format=\"format:tag: tagging %h (%s, %cd)%n\" \\\n+\t\t--date=format:%Y-%m-%d >expected &&\n+\ttest_when_finished \"git tag -d tag_with_reflog\" &&\n+\tgit tag --create-reflog tag_with_reflog &&\n+\tgit reflog exists refs/tags/tag_with_reflog &&\n+\tsed -e \"s/^.*\t//\" .git/logs/refs/tags/tag_with_reflog >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+test_expect_success 'annotated tag with --create-reflog has correct message' '\n+\tgit log -1 \\\n+\t\t--format=\"format:tag: tagging %h (%s, %cd)%n\" \\\n+\t\t--date=format:%Y-%m-%d >expected &&\n+\ttest_when_finished \"git tag -d tag_with_reflog\" &&\n+\tgit tag -m \"annotated tag\" --create-reflog tag_with_reflog &&\n+\tgit reflog exists refs/tags/tag_with_reflog &&\n+\tsed -e \"s/^.*\t//\" .git/logs/refs/tags/tag_with_reflog >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+test_expect_success '--create-reflog does not create reflog on failure' '\n+\ttest_must_fail git tag --create-reflog mytag &&\n+\ttest_must_fail git reflog exists refs/tags/mytag\n+'\n+\n+test_expect_success 'option core.logAllRefUpdates=always creates reflog' '\n+\ttest_when_finished \"git tag -d tag_with_reflog\" &&\n+\ttest_config core.logAllRefUpdates always &&\n+\tgit tag tag_with_reflog &&\n+\tgit reflog exists refs/tags/tag_with_reflog\n+'\n+\n+test_expect_success 'listing all tags if one exists should succeed' '\n+\tgit tag -l &&\n+\tgit tag\n+'\n+\n+cat >expect <<EOF\n+mytag\n+EOF\n+test_expect_success 'Multiple -l or --list options are equivalent to one -l option' '\n+\tgit tag -l -l >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag --list --list >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag --list -l --list >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'listing all tags if one exists should output that tag' '\n+\ttest $(git tag -l) = mytag &&\n+\ttest $(git tag) = mytag\n+'\n+\n+# pattern matching:\n+\n+test_expect_success 'listing a tag using a matching pattern should succeed' \\\n+\t'git tag -l mytag'\n+\n+test_expect_success 'listing a tag with --ignore-case' \\\n+\t'test $(git tag -l --ignore-case MYTAG) = mytag'\n+\n+test_expect_success \\\n+\t'listing a tag using a matching pattern should output that tag' \\\n+\t'test $(git tag -l mytag) = mytag'\n+\n+test_expect_success \\\n+\t'listing tags using a non-matching pattern should succeed' \\\n+\t'git tag -l xxx'\n+\n+test_expect_success \\\n+\t'listing tags using a non-matching pattern should output nothing' \\\n+\t'test $(git tag -l xxx | wc -l) -eq 0'\n+\n+# special cases for creating tags:\n+\n+test_expect_success \\\n+\t'trying to create a tag with the name of one existing should fail' \\\n+\t'test_must_fail git tag mytag'\n+\n+test_expect_success \\\n+\t'trying to create a tag with a non-valid name should fail' '\n+\ttest $(git tag -l | wc -l) -eq 1 &&\n+\ttest_must_fail git tag \"\" &&\n+\ttest_must_fail git tag .othertag &&\n+\ttest_must_fail git tag \"other tag\" &&\n+\ttest_must_fail git tag \"othertag^\" &&\n+\ttest_must_fail git tag \"other~tag\" &&\n+\ttest $(git tag -l | wc -l) -eq 1\n+'\n+\n+test_expect_success 'creating a tag using HEAD directly should succeed' '\n+\tgit tag myhead HEAD &&\n+\ttag_exists myhead\n+'\n+\n+test_expect_success '--force can create a tag with the name of one existing' '\n+\ttag_exists mytag &&\n+\tgit tag --force mytag &&\n+\ttag_exists mytag'\n+\n+test_expect_success '--force is moot with a non-existing tag name' '\n+\ttest_when_finished git tag -d newtag forcetag &&\n+\tgit tag newtag >expect &&\n+\tgit tag --force forcetag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+# deleting tags:\n+\n+test_expect_success 'trying to delete an unknown tag should fail' '\n+\t! tag_exists unknown-tag &&\n+\ttest_must_fail git tag -d unknown-tag\n+'\n+\n+cat >expect <<EOF\n+myhead\n+mytag\n+EOF\n+test_expect_success \\\n+\t'trying to delete tags without params should succeed and do nothing' '\n+\tgit tag -l > actual && test_cmp expect actual &&\n+\tgit tag -d &&\n+\tgit tag -l > actual && test_cmp expect actual\n+'\n+\n+test_expect_success \\\n+\t'deleting two existing tags in one command should succeed' '\n+\ttag_exists mytag &&\n+\ttag_exists myhead &&\n+\tgit tag -d mytag myhead &&\n+\t! tag_exists mytag &&\n+\t! tag_exists myhead\n+'\n+\n+test_expect_success \\\n+\t'creating a tag with the name of another deleted one should succeed' '\n+\t! tag_exists mytag &&\n+\tgit tag mytag &&\n+\ttag_exists mytag\n+'\n+\n+test_expect_success \\\n+\t'trying to delete two tags, existing and not, should fail in the 2nd' '\n+\ttag_exists mytag &&\n+\t! tag_exists myhead &&\n+\ttest_must_fail git tag -d mytag anothertag &&\n+\t! tag_exists mytag &&\n+\t! tag_exists myhead\n+'\n+\n+test_expect_success 'trying to delete an already deleted tag should fail' \\\n+\t'test_must_fail git tag -d mytag'\n+\n+# listing various tags with pattern matching:\n+\n+cat >expect <<EOF\n+a1\n+aa1\n+cba\n+t210\n+t211\n+v0.2.1\n+v1.0\n+v1.0.1\n+v1.1.3\n+EOF\n+test_expect_success 'listing all tags should print them ordered' '\n+\tgit tag v1.0.1 &&\n+\tgit tag t211 &&\n+\tgit tag aa1 &&\n+\tgit tag v0.2.1 &&\n+\tgit tag v1.1.3 &&\n+\tgit tag cba &&\n+\tgit tag a1 &&\n+\tgit tag v1.0 &&\n+\tgit tag t210 &&\n+\tgit tag -l > actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<EOF\n+a1\n+aa1\n+cba\n+EOF\n+test_expect_success \\\n+\t'listing tags with substring as pattern must print those matching' '\n+\trm *a* &&\n+\tgit tag -l \"*a*\" > current &&\n+\ttest_cmp expect current\n+'\n+\n+cat >expect <<EOF\n+v0.2.1\n+v1.0.1\n+EOF\n+test_expect_success \\\n+\t'listing tags with a suffix as pattern must print those matching' '\n+\tgit tag -l \"*.1\" > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<EOF\n+t210\n+t211\n+EOF\n+test_expect_success \\\n+\t'listing tags with a prefix as pattern must print those matching' '\n+\tgit tag -l \"t21*\" > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<EOF\n+a1\n+EOF\n+test_expect_success \\\n+\t'listing tags using a name as pattern must print that one matching' '\n+\tgit tag -l a1 > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<EOF\n+v1.0\n+EOF\n+test_expect_success \\\n+\t'listing tags using a name as pattern must print that one matching' '\n+\tgit tag -l v1.0 > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<EOF\n+v1.0.1\n+v1.1.3\n+EOF\n+test_expect_success \\\n+\t'listing tags with ? in the pattern should print those matching' '\n+\tgit tag -l \"v1.?.?\" > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success \\\n+\t'listing tags using v.* should print nothing because none have v.' '\n+\tgit tag -l \"v.*\" > actual &&\n+\ttest_must_be_empty actual\n+'\n+\n+cat >expect <<EOF\n+v0.2.1\n+v1.0\n+v1.0.1\n+v1.1.3\n+EOF\n+test_expect_success \\\n+\t'listing tags using v* should print only those having v' '\n+\tgit tag -l \"v*\" > actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'tag -l can accept multiple patterns' '\n+\tgit tag -l \"v1*\" \"v0*\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+# Between v1.7.7 & v2.13.0 a fair reading of the git-tag documentation\n+# could leave you with the impression that \"-l <pattern> -l <pattern>\"\n+# was how we wanted to accept multiple patterns.\n+#\n+# This test should not imply that this is a sane thing to support. but\n+# since the documentation was worded like it was let's at least find\n+# out if we're going to break this long-documented form of taking\n+# multiple patterns.\n+test_expect_success 'tag -l <pattern> -l <pattern> works, as our buggy documentation previously suggested' '\n+\tgit tag -l \"v1*\" -l \"v0*\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'listing tags in column' '\n+\tCOLUMNS=41 git tag -l --column=row >actual &&\n+\tcat >expected <<\\EOF &&\n+a1      aa1     cba     t210    t211\n+v0.2.1  v1.0    v1.0.1  v1.1.3\n+EOF\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'listing tags in column with column.*' '\n+\ttest_config column.tag row &&\n+\ttest_config column.ui dense &&\n+\tCOLUMNS=40 git tag -l >actual &&\n+\tcat >expected <<\\EOF &&\n+a1      aa1   cba     t210    t211\n+v0.2.1  v1.0  v1.0.1  v1.1.3\n+EOF\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'listing tag with -n --column should fail' '\n+\ttest_must_fail git tag --column -n\n+'\n+\n+test_expect_success 'listing tags -n in column with column.ui ignored' '\n+\ttest_config column.ui \"row dense\" &&\n+\tCOLUMNS=40 git tag -l -n >actual &&\n+\tcat >expected <<\\EOF &&\n+a1              Foo\n+aa1             Foo\n+cba             Foo\n+t210            Foo\n+t211            Foo\n+v0.2.1          Foo\n+v1.0            Foo\n+v1.0.1          Foo\n+v1.1.3          Foo\n+EOF\n+\ttest_cmp expected actual\n+'\n+\n+# creating and verifying lightweight tags:\n+\n+test_expect_success \\\n+\t'a non-annotated tag created without parameters should point to HEAD' '\n+\tgit tag non-annotated-tag &&\n+\ttest $(git cat-file -t non-annotated-tag) = commit &&\n+\ttest $(git rev-parse non-annotated-tag) = $(git rev-parse HEAD)\n+'\n+\n+test_expect_success 'trying to verify an unknown tag should fail' \\\n+\t'test_must_fail git tag -v unknown-tag'\n+\n+test_expect_success \\\n+\t'trying to verify a non-annotated and non-signed tag should fail' \\\n+\t'test_must_fail git tag -v non-annotated-tag'\n+\n+test_expect_success \\\n+\t'trying to verify many non-annotated or unknown tags, should fail' \\\n+\t'test_must_fail git tag -v unknown-tag1 non-annotated-tag unknown-tag2'\n+\n+# creating annotated tags:\n+\n+get_tag_msg () {\n+\tgit cat-file tag \"$1\" | sed -e \"/BEGIN PGP/q\"\n+}\n+\n+# run test_tick before committing always gives the time in that timezone\n+get_tag_header () {\n+cat <<EOF\n+object $2\n+type $3\n+tag $1\n+tagger C O Mitter <committer@example.com> $4 -0700\n+\n+EOF\n+}\n+\n+commit=$(git rev-parse HEAD)\n+time=$test_tick\n+\n+get_tag_header annotated-tag $commit commit $time >expect\n+echo \"A message\" >>expect\n+test_expect_success \\\n+\t'creating an annotated tag with -m message should succeed' '\n+\tgit tag -m \"A message\" annotated-tag &&\n+\tget_tag_msg annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+get_tag_header annotated-tag-edit $commit commit $time >expect\n+echo \"An edited message\" >>expect\n+test_expect_success 'set up editor' '\n+\twrite_script fakeeditor <<-\\EOF\n+\tsed -e \"s/A message/An edited message/g\" <\"$1\" >\"$1-\"\n+\tmv \"$1-\" \"$1\"\n+\tEOF\n+'\n+test_expect_success \\\n+\t'creating an annotated tag with -m message --edit should succeed' '\n+\tGIT_EDITOR=./fakeeditor git tag -m \"A message\" --edit annotated-tag-edit &&\n+\tget_tag_msg annotated-tag-edit >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >msgfile <<EOF\n+Another message\n+in a file.\n+EOF\n+get_tag_header file-annotated-tag $commit commit $time >expect\n+cat msgfile >>expect\n+test_expect_success \\\n+\t'creating an annotated tag with -F messagefile should succeed' '\n+\tgit tag -F msgfile file-annotated-tag &&\n+\tget_tag_msg file-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+get_tag_header file-annotated-tag-edit $commit commit $time >expect\n+sed -e \"s/Another message/Another edited message/g\" msgfile >>expect\n+test_expect_success 'set up editor' '\n+\twrite_script fakeeditor <<-\\EOF\n+\tsed -e \"s/Another message/Another edited message/g\" <\"$1\" >\"$1-\"\n+\tmv \"$1-\" \"$1\"\n+\tEOF\n+'\n+test_expect_success \\\n+\t'creating an annotated tag with -F messagefile --edit should succeed' '\n+\tGIT_EDITOR=./fakeeditor git tag -F msgfile --edit file-annotated-tag-edit &&\n+\tget_tag_msg file-annotated-tag-edit >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >inputmsg <<EOF\n+A message from the\n+standard input\n+EOF\n+get_tag_header stdin-annotated-tag $commit commit $time >expect\n+cat inputmsg >>expect\n+test_expect_success 'creating an annotated tag with -F - should succeed' '\n+\tgit tag -F - stdin-annotated-tag <inputmsg &&\n+\tget_tag_msg stdin-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success \\\n+\t'trying to create a tag with a non-existing -F file should fail' '\n+\t! test -f nonexistingfile &&\n+\t! tag_exists notag &&\n+\ttest_must_fail git tag -F nonexistingfile notag &&\n+\t! tag_exists notag\n+'\n+\n+test_expect_success \\\n+\t'trying to create tags giving both -m or -F options should fail' '\n+\techo \"message file 1\" >msgfile1 &&\n+\techo \"message file 2\" >msgfile2 &&\n+\t! tag_exists msgtag &&\n+\ttest_must_fail git tag -m \"message 1\" -F msgfile1 msgtag &&\n+\t! tag_exists msgtag &&\n+\ttest_must_fail git tag -F msgfile1 -m \"message 1\" msgtag &&\n+\t! tag_exists msgtag &&\n+\ttest_must_fail git tag -m \"message 1\" -F msgfile1 \\\n+\t\t-m \"message 2\" msgtag &&\n+\t! tag_exists msgtag\n+'\n+\n+# blank and empty messages:\n+\n+get_tag_header empty-annotated-tag $commit commit $time >expect\n+test_expect_success \\\n+\t'creating a tag with an empty -m message should succeed' '\n+\tgit tag -m \"\" empty-annotated-tag &&\n+\tget_tag_msg empty-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+>emptyfile\n+get_tag_header emptyfile-annotated-tag $commit commit $time >expect\n+test_expect_success \\\n+\t'creating a tag with an empty -F messagefile should succeed' '\n+\tgit tag -F emptyfile emptyfile-annotated-tag &&\n+\tget_tag_msg emptyfile-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+printf '\\n\\n  \\n\\t\\nLeading blank lines\\n' >blanksfile\n+printf '\\n\\t \\t  \\nRepeated blank lines\\n' >>blanksfile\n+printf '\\n\\n\\nTrailing spaces      \\t  \\n' >>blanksfile\n+printf '\\nTrailing blank lines\\n\\n\\t \\n\\n' >>blanksfile\n+get_tag_header blanks-annotated-tag $commit commit $time >expect\n+cat >>expect <<EOF\n+Leading blank lines\n+\n+Repeated blank lines\n+\n+Trailing spaces\n+\n+Trailing blank lines\n+EOF\n+test_expect_success \\\n+\t'extra blanks in the message for an annotated tag should be removed' '\n+\tgit tag -F blanksfile blanks-annotated-tag &&\n+\tget_tag_msg blanks-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+get_tag_header blank-annotated-tag $commit commit $time >expect\n+test_expect_success \\\n+\t'creating a tag with blank -m message with spaces should succeed' '\n+\tgit tag -m \"     \" blank-annotated-tag &&\n+\tget_tag_msg blank-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+echo '     ' >blankfile\n+echo ''      >>blankfile\n+echo '  '    >>blankfile\n+get_tag_header blankfile-annotated-tag $commit commit $time >expect\n+test_expect_success \\\n+\t'creating a tag with blank -F messagefile with spaces should succeed' '\n+\tgit tag -F blankfile blankfile-annotated-tag &&\n+\tget_tag_msg blankfile-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+printf '      ' >blanknonlfile\n+get_tag_header blanknonlfile-annotated-tag $commit commit $time >expect\n+test_expect_success \\\n+\t'creating a tag with -F file of spaces and no newline should succeed' '\n+\tgit tag -F blanknonlfile blanknonlfile-annotated-tag &&\n+\tget_tag_msg blanknonlfile-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+# messages with commented lines:\n+\n+cat >commentsfile <<EOF\n+# A comment\n+\n+############\n+The message.\n+############\n+One line.\n+\n+\n+# commented lines\n+# commented lines\n+\n+Another line.\n+# comments\n+\n+Last line.\n+EOF\n+get_tag_header comments-annotated-tag $commit commit $time >expect\n+cat >>expect <<EOF\n+The message.\n+One line.\n+\n+Another line.\n+\n+Last line.\n+EOF\n+test_expect_success \\\n+\t'creating a tag using a -F messagefile with #comments should succeed' '\n+\tgit tag -F commentsfile comments-annotated-tag &&\n+\tget_tag_msg comments-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+get_tag_header comment-annotated-tag $commit commit $time >expect\n+test_expect_success \\\n+\t'creating a tag with a #comment in the -m message should succeed' '\n+\tgit tag -m \"#comment\" comment-annotated-tag &&\n+\tget_tag_msg comment-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+echo '#comment' >commentfile\n+echo ''         >>commentfile\n+echo '####'     >>commentfile\n+get_tag_header commentfile-annotated-tag $commit commit $time >expect\n+test_expect_success \\\n+\t'creating a tag with #comments in the -F messagefile should succeed' '\n+\tgit tag -F commentfile commentfile-annotated-tag &&\n+\tget_tag_msg commentfile-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+printf '#comment' >commentnonlfile\n+get_tag_header commentnonlfile-annotated-tag $commit commit $time >expect\n+test_expect_success \\\n+\t'creating a tag with a file of #comment and no newline should succeed' '\n+\tgit tag -F commentnonlfile commentnonlfile-annotated-tag &&\n+\tget_tag_msg commentnonlfile-annotated-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+# listing messages for annotated non-signed tags:\n+\n+test_expect_success \\\n+\t'listing the one-line message of a non-signed tag should succeed' '\n+\tgit tag -m \"A msg\" tag-one-line &&\n+\n+\techo \"tag-one-line\" >expect &&\n+\tgit tag -l | grep \"^tag-one-line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l | grep \"^tag-one-line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l tag-one-line >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit tag -n0 | grep \"^tag-one-line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 tag-one-line >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo \"tag-one-line    A msg\" >expect &&\n+\tgit tag -n1 -l | grep \"^tag-one-line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n -l | grep \"^tag-one-line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n1 -l tag-one-line >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n2 -l tag-one-line >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n999 -l tag-one-line >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'The -n 100 invocation means -n --list 100, not -n100' '\n+\tgit tag -n 100 >actual &&\n+\ttest_must_be_empty actual &&\n+\n+\tgit tag -m \"A msg\" 100 &&\n+\techo \"100             A msg\" >expect &&\n+\tgit tag -n 100 >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success \\\n+\t'listing the zero-lines message of a non-signed tag should succeed' '\n+\tgit tag -m \"\" tag-zero-lines &&\n+\n+\techo \"tag-zero-lines\" >expect &&\n+\tgit tag -l | grep \"^tag-zero-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l | grep \"^tag-zero-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l tag-zero-lines >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo \"tag-zero-lines  \" >expect &&\n+\tgit tag -n1 -l | grep \"^tag-zero-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n -l | grep \"^tag-zero-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n1 -l tag-zero-lines >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n2 -l tag-zero-lines >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n999 -l tag-zero-lines >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+echo 'tag line one' >annotagmsg\n+echo 'tag line two' >>annotagmsg\n+echo 'tag line three' >>annotagmsg\n+test_expect_success \\\n+\t'listing many message lines of a non-signed tag should succeed' '\n+\tgit tag -F annotagmsg tag-lines &&\n+\n+\techo \"tag-lines\" >expect &&\n+\tgit tag -l | grep \"^tag-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l | grep \"^tag-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l tag-lines >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo \"tag-lines       tag line one\" >expect &&\n+\tgit tag -n1 -l | grep \"^tag-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n -l | grep \"^tag-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n1 -l tag-lines >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo \"    tag line two\" >>expect &&\n+\tgit tag -n2 -l | grep \"^ *tag.line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n2 -l tag-lines >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo \"    tag line three\" >>expect &&\n+\tgit tag -n3 -l | grep \"^ *tag.line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n3 -l tag-lines >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n4 -l | grep \"^ *tag.line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n4 -l tag-lines >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n99 -l | grep \"^ *tag.line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n99 -l tag-lines >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'annotations for blobs are empty' '\n+\tblob=$(git hash-object -w --stdin <<-\\EOF\n+\tBlob paragraph 1.\n+\n+\tBlob paragraph 2.\n+\tEOF\n+\t) &&\n+\tgit tag tag-blob $blob &&\n+\techo \"tag-blob        \" >expect &&\n+\tgit tag -n1 -l tag-blob >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+# trying to verify annotated non-signed tags:\n+\n+test_expect_success GPG \\\n+\t'trying to verify an annotated non-signed tag should fail' '\n+\ttag_exists annotated-tag &&\n+\ttest_must_fail git tag -v annotated-tag\n+'\n+\n+test_expect_success GPG \\\n+\t'trying to verify a file-annotated non-signed tag should fail' '\n+\ttag_exists file-annotated-tag &&\n+\ttest_must_fail git tag -v file-annotated-tag\n+'\n+\n+test_expect_success GPG \\\n+\t'trying to verify two annotated non-signed tags should fail' '\n+\ttag_exists annotated-tag file-annotated-tag &&\n+\ttest_must_fail git tag -v annotated-tag file-annotated-tag\n+'\n+\n+# creating and verifying signed tags:\n+\n+get_tag_header signed-tag $commit commit $time >expect\n+echo 'A signed tag message' >>expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG 'creating a signed tag with -m message should succeed' '\n+\tgit tag -s -m \"A signed tag message\" signed-tag &&\n+\tget_tag_msg signed-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+get_tag_header u-signed-tag $commit commit $time >expect\n+echo 'Another message' >>expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG 'sign with a given key id' '\n+\n+\tgit tag -u committer@example.com -m \"Another message\" u-signed-tag &&\n+\tget_tag_msg u-signed-tag >actual &&\n+\ttest_cmp expect actual\n+\n+'\n+\n+test_expect_success GPG 'sign with an unknown id (1)' '\n+\n+\ttest_must_fail git tag -u author@example.com \\\n+\t\t-m \"Another message\" o-signed-tag\n+\n+'\n+\n+test_expect_success GPG 'sign with an unknown id (2)' '\n+\n+\ttest_must_fail git tag -u DEADBEEF -m \"Another message\" o-signed-tag\n+\n+'\n+\n+cat >fakeeditor <<'EOF'\n+#!/bin/sh\n+test -n \"$1\" && exec >\"$1\"\n+echo A signed tag message\n+echo from a fake editor.\n+EOF\n+chmod +x fakeeditor\n+\n+get_tag_header implied-sign $commit commit $time >expect\n+./fakeeditor >>expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG '-u implies signed tag' '\n+\tGIT_EDITOR=./fakeeditor git tag -u CDDE430D implied-sign &&\n+\tget_tag_msg implied-sign >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >sigmsgfile <<EOF\n+Another signed tag\n+message in a file.\n+EOF\n+get_tag_header file-signed-tag $commit commit $time >expect\n+cat sigmsgfile >>expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag with -F messagefile should succeed' '\n+\tgit tag -s -F sigmsgfile file-signed-tag &&\n+\tget_tag_msg file-signed-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >siginputmsg <<EOF\n+A signed tag message from\n+the standard input\n+EOF\n+get_tag_header stdin-signed-tag $commit commit $time >expect\n+cat siginputmsg >>expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG 'creating a signed tag with -F - should succeed' '\n+\tgit tag -s -F - stdin-signed-tag <siginputmsg &&\n+\tget_tag_msg stdin-signed-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+get_tag_header implied-annotate $commit commit $time >expect\n+./fakeeditor >>expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG '-s implies annotated tag' '\n+\tGIT_EDITOR=./fakeeditor git tag -s implied-annotate &&\n+\tget_tag_msg implied-annotate >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+get_tag_header forcesignannotated-implied-sign $commit commit $time >expect\n+echo \"A message\" >>expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'git tag -s implied if configured with tag.forcesignannotated' \\\n+\t'test_config tag.forcesignannotated true &&\n+\tgit tag -m \"A message\" forcesignannotated-implied-sign &&\n+\tget_tag_msg forcesignannotated-implied-sign >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG \\\n+\t'lightweight with no message when configured with tag.forcesignannotated' \\\n+\t'test_config tag.forcesignannotated true &&\n+\tgit tag forcesignannotated-lightweight &&\n+\ttag_exists forcesignannotated-lightweight &&\n+\ttest_must_fail git tag -v forcesignannotated-no-message\n+'\n+\n+get_tag_header forcesignannotated-annotate $commit commit $time >expect\n+echo \"A message\" >>expect\n+test_expect_success GPG \\\n+\t'git tag -a disable configured tag.forcesignannotated' \\\n+\t'test_config tag.forcesignannotated true &&\n+\tgit tag -a -m \"A message\" forcesignannotated-annotate &&\n+\tget_tag_msg forcesignannotated-annotate >actual &&\n+\ttest_cmp expect actual &&\n+\ttest_must_fail git tag -v forcesignannotated-annotate\n+'\n+\n+get_tag_header forcesignannotated-disabled $commit commit $time >expect\n+echo \"A message\" >>expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'git tag --sign enable GPG sign' \\\n+\t'test_config tag.forcesignannotated false &&\n+\tgit tag --sign -m \"A message\" forcesignannotated-disabled &&\n+\tget_tag_msg forcesignannotated-disabled >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG \\\n+\t'trying to create a signed tag with non-existing -F file should fail' '\n+\t! test -f nonexistingfile &&\n+\t! tag_exists nosigtag &&\n+\ttest_must_fail git tag -s -F nonexistingfile nosigtag &&\n+\t! tag_exists nosigtag\n+'\n+\n+test_expect_success GPG 'verifying a signed tag should succeed' \\\n+\t'git tag -v signed-tag'\n+\n+test_expect_success GPG 'verifying two signed tags in one command should succeed' \\\n+\t'git tag -v signed-tag file-signed-tag'\n+\n+test_expect_success GPG \\\n+\t'verifying many signed and non-signed tags should fail' '\n+\ttest_must_fail git tag -v signed-tag annotated-tag &&\n+\ttest_must_fail git tag -v file-annotated-tag file-signed-tag &&\n+\ttest_must_fail git tag -v annotated-tag \\\n+\t\tfile-signed-tag file-annotated-tag &&\n+\ttest_must_fail git tag -v signed-tag annotated-tag file-signed-tag\n+'\n+\n+test_expect_success GPG 'verifying a forged tag should fail' '\n+\tforged=$(git cat-file tag signed-tag |\n+\t\tsed -e \"s/signed-tag/forged-tag/\" |\n+\t\tgit mktag) &&\n+\tgit tag forged-tag $forged &&\n+\ttest_must_fail git tag -v forged-tag\n+'\n+\n+test_expect_success GPG 'verifying a proper tag with --format pass and format accordingly' '\n+\tcat >expect <<-\\EOF &&\n+\ttagname : signed-tag\n+\tEOF\n+\tgit tag -v --format=\"tagname : %(tag)\" \"signed-tag\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG 'verifying a forged tag with --format should fail silently' '\n+\ttest_must_fail git tag -v --format=\"tagname : %(tag)\" \"forged-tag\" >actual &&\n+\ttest_must_be_empty actual\n+'\n+\n+# blank and empty messages for signed tags:\n+\n+get_tag_header empty-signed-tag $commit commit $time >expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag with an empty -m message should succeed' '\n+\tgit tag -s -m \"\" empty-signed-tag &&\n+\tget_tag_msg empty-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -v empty-signed-tag\n+'\n+\n+>sigemptyfile\n+get_tag_header emptyfile-signed-tag $commit commit $time >expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag with an empty -F messagefile should succeed' '\n+\tgit tag -s -F sigemptyfile emptyfile-signed-tag &&\n+\tget_tag_msg emptyfile-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -v emptyfile-signed-tag\n+'\n+\n+printf '\\n\\n  \\n\\t\\nLeading blank lines\\n' > sigblanksfile\n+printf '\\n\\t \\t  \\nRepeated blank lines\\n' >>sigblanksfile\n+printf '\\n\\n\\nTrailing spaces      \\t  \\n' >>sigblanksfile\n+printf '\\nTrailing blank lines\\n\\n\\t \\n\\n' >>sigblanksfile\n+get_tag_header blanks-signed-tag $commit commit $time >expect\n+cat >>expect <<EOF\n+Leading blank lines\n+\n+Repeated blank lines\n+\n+Trailing spaces\n+\n+Trailing blank lines\n+EOF\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'extra blanks in the message for a signed tag should be removed' '\n+\tgit tag -s -F sigblanksfile blanks-signed-tag &&\n+\tget_tag_msg blanks-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -v blanks-signed-tag\n+'\n+\n+get_tag_header blank-signed-tag $commit commit $time >expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag with a blank -m message should succeed' '\n+\tgit tag -s -m \"     \" blank-signed-tag &&\n+\tget_tag_msg blank-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -v blank-signed-tag\n+'\n+\n+echo '     ' >sigblankfile\n+echo ''      >>sigblankfile\n+echo '  '    >>sigblankfile\n+get_tag_header blankfile-signed-tag $commit commit $time >expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag with blank -F file with spaces should succeed' '\n+\tgit tag -s -F sigblankfile blankfile-signed-tag &&\n+\tget_tag_msg blankfile-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -v blankfile-signed-tag\n+'\n+\n+printf '      ' >sigblanknonlfile\n+get_tag_header blanknonlfile-signed-tag $commit commit $time >expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag with spaces and no newline should succeed' '\n+\tgit tag -s -F sigblanknonlfile blanknonlfile-signed-tag &&\n+\tget_tag_msg blanknonlfile-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -v blanknonlfile-signed-tag\n+'\n+\n+test_expect_success GPG 'signed tag with embedded PGP message' '\n+\tcat >msg <<-\\EOF &&\n+\t-----BEGIN PGP MESSAGE-----\n+\n+\tthis is not a real PGP message\n+\t-----END PGP MESSAGE-----\n+\tEOF\n+\tgit tag -s -F msg confusing-pgp-message &&\n+\tgit tag -v confusing-pgp-message\n+'\n+\n+# messages with commented lines for signed tags:\n+\n+cat >sigcommentsfile <<EOF\n+# A comment\n+\n+############\n+The message.\n+############\n+One line.\n+\n+\n+# commented lines\n+# commented lines\n+\n+Another line.\n+# comments\n+\n+Last line.\n+EOF\n+get_tag_header comments-signed-tag $commit commit $time >expect\n+cat >>expect <<EOF\n+The message.\n+One line.\n+\n+Another line.\n+\n+Last line.\n+EOF\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag with a -F file with #comments should succeed' '\n+\tgit tag -s -F sigcommentsfile comments-signed-tag &&\n+\tget_tag_msg comments-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -v comments-signed-tag\n+'\n+\n+get_tag_header comment-signed-tag $commit commit $time >expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag with #commented -m message should succeed' '\n+\tgit tag -s -m \"#comment\" comment-signed-tag &&\n+\tget_tag_msg comment-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -v comment-signed-tag\n+'\n+\n+echo '#comment' >sigcommentfile\n+echo ''         >>sigcommentfile\n+echo '####'     >>sigcommentfile\n+get_tag_header commentfile-signed-tag $commit commit $time >expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag with #commented -F messagefile should succeed' '\n+\tgit tag -s -F sigcommentfile commentfile-signed-tag &&\n+\tget_tag_msg commentfile-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -v commentfile-signed-tag\n+'\n+\n+printf '#comment' >sigcommentnonlfile\n+get_tag_header commentnonlfile-signed-tag $commit commit $time >expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag with a #comment and no newline should succeed' '\n+\tgit tag -s -F sigcommentnonlfile commentnonlfile-signed-tag &&\n+\tget_tag_msg commentnonlfile-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -v commentnonlfile-signed-tag\n+'\n+\n+# listing messages for signed tags:\n+\n+test_expect_success GPG \\\n+\t'listing the one-line message of a signed tag should succeed' '\n+\tgit tag -s -m \"A message line signed\" stag-one-line &&\n+\n+\techo \"stag-one-line\" >expect &&\n+\tgit tag -l | grep \"^stag-one-line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l | grep \"^stag-one-line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l stag-one-line >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo \"stag-one-line   A message line signed\" >expect &&\n+\tgit tag -n1 -l | grep \"^stag-one-line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n -l | grep \"^stag-one-line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n1 -l stag-one-line >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n2 -l stag-one-line >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n999 -l stag-one-line >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG \\\n+\t'listing the zero-lines message of a signed tag should succeed' '\n+\tgit tag -s -m \"\" stag-zero-lines &&\n+\n+\techo \"stag-zero-lines\" >expect &&\n+\tgit tag -l | grep \"^stag-zero-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l | grep \"^stag-zero-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l stag-zero-lines >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo \"stag-zero-lines \" >expect &&\n+\tgit tag -n1 -l | grep \"^stag-zero-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n -l | grep \"^stag-zero-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n1 -l stag-zero-lines >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n2 -l stag-zero-lines >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n999 -l stag-zero-lines >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+echo 'stag line one' >sigtagmsg\n+echo 'stag line two' >>sigtagmsg\n+echo 'stag line three' >>sigtagmsg\n+test_expect_success GPG \\\n+\t'listing many message lines of a signed tag should succeed' '\n+\tgit tag -s -F sigtagmsg stag-lines &&\n+\n+\techo \"stag-lines\" >expect &&\n+\tgit tag -l | grep \"^stag-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l | grep \"^stag-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n0 -l stag-lines >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo \"stag-lines      stag line one\" >expect &&\n+\tgit tag -n1 -l | grep \"^stag-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n -l | grep \"^stag-lines\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n1 -l stag-lines >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo \"    stag line two\" >>expect &&\n+\tgit tag -n2 -l | grep \"^ *stag.line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n2 -l stag-lines >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo \"    stag line three\" >>expect &&\n+\tgit tag -n3 -l | grep \"^ *stag.line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n3 -l stag-lines >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n4 -l | grep \"^ *stag.line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n4 -l stag-lines >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n99 -l | grep \"^ *stag.line\" >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -n99 -l stag-lines >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+# tags pointing to objects different from commits:\n+\n+tree=$(git rev-parse HEAD^{tree})\n+blob=$(git rev-parse HEAD:foo)\n+tag=$(git rev-parse signed-tag 2>/dev/null)\n+\n+get_tag_header tree-signed-tag $tree tree $time >expect\n+echo \"A message for a tree\" >>expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag pointing to a tree should succeed' '\n+\tgit tag -s -m \"A message for a tree\" tree-signed-tag HEAD^{tree} &&\n+\tget_tag_msg tree-signed-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+get_tag_header blob-signed-tag $blob blob $time >expect\n+echo \"A message for a blob\" >>expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag pointing to a blob should succeed' '\n+\tgit tag -s -m \"A message for a blob\" blob-signed-tag HEAD:foo &&\n+\tget_tag_msg blob-signed-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+get_tag_header tag-signed-tag $tag tag $time >expect\n+echo \"A message for another tag\" >>expect\n+echo '-----BEGIN PGP SIGNATURE-----' >>expect\n+test_expect_success GPG \\\n+\t'creating a signed tag pointing to another tag should succeed' '\n+\tgit tag -s -m \"A message for another tag\" tag-signed-tag signed-tag &&\n+\tget_tag_msg tag-signed-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+# usage with rfc1991 signatures\n+get_tag_header rfc1991-signed-tag $commit commit $time >expect\n+echo \"RFC1991 signed tag\" >>expect\n+echo '-----BEGIN PGP MESSAGE-----' >>expect\n+test_expect_success GPG,RFC1991 \\\n+\t'creating a signed tag with rfc1991' '\n+\techo \"rfc1991\" >gpghome/gpg.conf &&\n+\tgit tag -s -m \"RFC1991 signed tag\" rfc1991-signed-tag $commit &&\n+\tget_tag_msg rfc1991-signed-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >fakeeditor <<'EOF'\n+#!/bin/sh\n+cp \"$1\" actual\n+EOF\n+chmod +x fakeeditor\n+\n+test_expect_success GPG,RFC1991 \\\n+\t'reediting a signed tag body omits signature' '\n+\techo \"rfc1991\" >gpghome/gpg.conf &&\n+\techo \"RFC1991 signed tag\" >expect &&\n+\tGIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG,RFC1991 \\\n+\t'verifying rfc1991 signature' '\n+\techo \"rfc1991\" >gpghome/gpg.conf &&\n+\tgit tag -v rfc1991-signed-tag\n+'\n+\n+test_expect_success GPG,RFC1991 \\\n+\t'list tag with rfc1991 signature' '\n+\techo \"rfc1991\" >gpghome/gpg.conf &&\n+\techo \"rfc1991-signed-tag RFC1991 signed tag\" >expect &&\n+\tgit tag -l -n1 rfc1991-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -l -n2 rfc1991-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -l -n999 rfc1991-signed-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+rm -f gpghome/gpg.conf\n+\n+test_expect_success GPG,RFC1991 \\\n+\t'verifying rfc1991 signature without --rfc1991' '\n+\tgit tag -v rfc1991-signed-tag\n+'\n+\n+test_expect_success GPG,RFC1991 \\\n+\t'list tag with rfc1991 signature without --rfc1991' '\n+\techo \"rfc1991-signed-tag RFC1991 signed tag\" >expect &&\n+\tgit tag -l -n1 rfc1991-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -l -n2 rfc1991-signed-tag >actual &&\n+\ttest_cmp expect actual &&\n+\tgit tag -l -n999 rfc1991-signed-tag >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG,RFC1991 \\\n+\t'reediting a signed tag body omits signature' '\n+\techo \"RFC1991 signed tag\" >expect &&\n+\tGIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit &&\n+\ttest_cmp expect actual\n+'\n+\n+# try to sign with bad user.signingkey\n+test_expect_success GPG \\\n+\t'git tag -s fails if gpg is misconfigured (bad key)' \\\n+\t'test_config user.signingkey BobTheMouse &&\n+\ttest_must_fail git tag -s -m tail tag-gpg-failure'\n+\n+# try to produce invalid signature\n+test_expect_success GPG \\\n+\t'git tag -s fails if gpg is misconfigured (bad signature format)' \\\n+\t'test_config signing.openpgp.program echo &&\n+\t test_must_fail git tag -s -m tail tag-gpg-failure'\n+\n+# try to sign with bad user.signingkey\n+test_expect_success GPGSM \\\n+\t'git tag -s fails if gpgsm is misconfigured (bad key)' \\\n+\t'test_config user.signingkey BobTheMouse &&\n+\t test_config signing.default x509 &&\n+\t test_must_fail git tag -s -m tail tag-gpg-failure'\n+\n+# try to produce invalid signature\n+test_expect_success GPGSM \\\n+\t'git tag -s fails if gpgsm is misconfigured (bad signature format)' \\\n+\t'test_config signing.x509.program echo &&\n+\t test_config signing.default x509 &&\n+\t test_must_fail git tag -s -m tail tag-gpg-failure'\n+\n+# try to verify without gpg:\n+\n+rm -rf gpghome\n+test_expect_success GPG \\\n+\t'verify signed tag fails when public key is not present' \\\n+\t'test_must_fail git tag -v signed-tag'\n+\n+test_expect_success \\\n+\t'git tag -a fails if tag annotation is empty' '\n+\t! (GIT_EDITOR=cat git tag -a initial-comment)\n+'\n+\n+test_expect_success \\\n+\t'message in editor has initial comment' '\n+\t! (GIT_EDITOR=cat git tag -a initial-comment > actual)\n+'\n+\n+test_expect_success 'message in editor has initial comment: first line' '\n+\t# check the first line --- should be empty\n+\techo >first.expect &&\n+\tsed -e 1q <actual >first.actual &&\n+\ttest_i18ncmp first.expect first.actual\n+'\n+\n+test_expect_success \\\n+\t'message in editor has initial comment: remainder' '\n+\t# remove commented lines from the remainder -- should be empty\n+\tsed -e 1d -e \"/^#/d\" <actual >rest.actual &&\n+\ttest_must_be_empty rest.actual\n+'\n+\n+get_tag_header reuse $commit commit $time >expect\n+echo \"An annotation to be reused\" >> expect\n+test_expect_success \\\n+\t'overwriting an annoted tag should use its previous body' '\n+\tgit tag -a -m \"An annotation to be reused\" reuse &&\n+\tGIT_EDITOR=true git tag -f -a reuse &&\n+\tget_tag_msg reuse >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'filename for the message is relative to cwd' '\n+\tmkdir subdir &&\n+\techo \"Tag message in top directory\" >msgfile-5 &&\n+\techo \"Tag message in sub directory\" >subdir/msgfile-5 &&\n+\t(\n+\t\tcd subdir &&\n+\t\tgit tag -a -F msgfile-5 tag-from-subdir\n+\t) &&\n+\tgit cat-file tag tag-from-subdir | grep \"in sub directory\"\n+'\n+\n+test_expect_success 'filename for the message is relative to cwd' '\n+\techo \"Tag message in sub directory\" >subdir/msgfile-6 &&\n+\t(\n+\t\tcd subdir &&\n+\t\tgit tag -a -F msgfile-6 tag-from-subdir-2\n+\t) &&\n+\tgit cat-file tag tag-from-subdir-2 | grep \"in sub directory\"\n+'\n+\n+# create a few more commits to test --contains\n+\n+hash1=$(git rev-parse HEAD)\n+\n+test_expect_success 'creating second commit and tag' '\n+\techo foo-2.0 >foo &&\n+\tgit add foo &&\n+\tgit commit -m second &&\n+\tgit tag v2.0\n+'\n+\n+hash2=$(git rev-parse HEAD)\n+\n+test_expect_success 'creating third commit without tag' '\n+\techo foo-dev >foo &&\n+\tgit add foo &&\n+\tgit commit -m third\n+'\n+\n+hash3=$(git rev-parse HEAD)\n+\n+# simple linear checks of --continue\n+\n+cat > expected <<EOF\n+v0.2.1\n+v1.0\n+v1.0.1\n+v1.1.3\n+v2.0\n+EOF\n+\n+test_expect_success 'checking that first commit is in all tags (hash)' \"\n+\tgit tag -l --contains $hash1 v* >actual &&\n+\ttest_cmp expected actual\n+\"\n+\n+# other ways of specifying the commit\n+test_expect_success 'checking that first commit is in all tags (tag)' \"\n+\tgit tag -l --contains v1.0 v* >actual &&\n+\ttest_cmp expected actual\n+\"\n+\n+test_expect_success 'checking that first commit is in all tags (relative)' \"\n+\tgit tag -l --contains HEAD~2 v* >actual &&\n+\ttest_cmp expected actual\n+\"\n+\n+# All the --contains tests above, but with --no-contains\n+test_expect_success 'checking that first commit is not listed in any tag with --no-contains  (hash)' \"\n+\tgit tag -l --no-contains $hash1 v* >actual &&\n+\ttest_must_be_empty actual\n+\"\n+\n+test_expect_success 'checking that first commit is in all tags (tag)' \"\n+\tgit tag -l --no-contains v1.0 v* >actual &&\n+\ttest_must_be_empty actual\n+\"\n+\n+test_expect_success 'checking that first commit is in all tags (relative)' \"\n+\tgit tag -l --no-contains HEAD~2 v* >actual &&\n+\ttest_must_be_empty actual\n+\"\n+\n+cat > expected <<EOF\n+v2.0\n+EOF\n+\n+test_expect_success 'checking that second commit only has one tag' \"\n+\tgit tag -l --contains $hash2 v* >actual &&\n+\ttest_cmp expected actual\n+\"\n+\n+cat > expected <<EOF\n+v0.2.1\n+v1.0\n+v1.0.1\n+v1.1.3\n+EOF\n+\n+test_expect_success 'inverse of the last test, with --no-contains' \"\n+\tgit tag -l --no-contains $hash2 v* >actual &&\n+\ttest_cmp expected actual\n+\"\n+\n+test_expect_success 'checking that third commit has no tags' \"\n+\tgit tag -l --contains $hash3 v* >actual &&\n+\ttest_must_be_empty actual\n+\"\n+\n+cat > expected <<EOF\n+v0.2.1\n+v1.0\n+v1.0.1\n+v1.1.3\n+v2.0\n+EOF\n+\n+test_expect_success 'conversely --no-contains on the third commit lists all tags' \"\n+\tgit tag -l --no-contains $hash3 v* >actual &&\n+\ttest_cmp expected actual\n+\"\n+\n+# how about a simple merge?\n+\n+test_expect_success 'creating simple branch' '\n+\tgit branch stable v2.0 &&\n+        git checkout stable &&\n+\techo foo-3.0 > foo &&\n+\tgit commit foo -m fourth &&\n+\tgit tag v3.0\n+'\n+\n+hash4=$(git rev-parse HEAD)\n+\n+cat > expected <<EOF\n+v3.0\n+EOF\n+\n+test_expect_success 'checking that branch head only has one tag' \"\n+\tgit tag -l --contains $hash4 v* >actual &&\n+\ttest_cmp expected actual\n+\"\n+\n+cat > expected <<EOF\n+v0.2.1\n+v1.0\n+v1.0.1\n+v1.1.3\n+v2.0\n+EOF\n+\n+test_expect_success 'checking that branch head with --no-contains lists all but one tag' \"\n+\tgit tag -l --no-contains $hash4 v* >actual &&\n+\ttest_cmp expected actual\n+\"\n+\n+test_expect_success 'merging original branch into this branch' '\n+\tgit merge --strategy=ours master &&\n+        git tag v4.0\n+'\n+\n+cat > expected <<EOF\n+v4.0\n+EOF\n+\n+test_expect_success 'checking that original branch head has one tag now' \"\n+\tgit tag -l --contains $hash3 v* >actual &&\n+\ttest_cmp expected actual\n+\"\n+\n+cat > expected <<EOF\n+v0.2.1\n+v1.0\n+v1.0.1\n+v1.1.3\n+v2.0\n+v3.0\n+EOF\n+\n+test_expect_success 'checking that original branch head with --no-contains lists all but one tag now' \"\n+\tgit tag -l --no-contains $hash3 v* >actual &&\n+\ttest_cmp expected actual\n+\"\n+\n+cat > expected <<EOF\n+v0.2.1\n+v1.0\n+v1.0.1\n+v1.1.3\n+v2.0\n+v3.0\n+v4.0\n+EOF\n+\n+test_expect_success 'checking that initial commit is in all tags' \"\n+\tgit tag -l --contains $hash1 v* >actual &&\n+\ttest_cmp expected actual\n+\"\n+\n+test_expect_success 'checking that --contains can be used in non-list mode' '\n+\tgit tag --contains $hash1 v* >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'checking that initial commit is in all tags with --no-contains' \"\n+\tgit tag -l --no-contains $hash1 v* >actual &&\n+\ttest_must_be_empty actual\n+\"\n+\n+# mixing modes and options:\n+\n+test_expect_success 'mixing incompatibles modes and options is forbidden' '\n+\ttest_must_fail git tag -a &&\n+\ttest_must_fail git tag -a -l &&\n+\ttest_must_fail git tag -s &&\n+\ttest_must_fail git tag -s -l &&\n+\ttest_must_fail git tag -m &&\n+\ttest_must_fail git tag -m -l &&\n+\ttest_must_fail git tag -m \"hlagh\" &&\n+\ttest_must_fail git tag -m \"hlagh\" -l &&\n+\ttest_must_fail git tag -F &&\n+\ttest_must_fail git tag -F -l &&\n+\ttest_must_fail git tag -f &&\n+\ttest_must_fail git tag -f -l &&\n+\ttest_must_fail git tag -a -s -m -F &&\n+\ttest_must_fail git tag -a -s -m -F -l &&\n+\ttest_must_fail git tag -l -v &&\n+\ttest_must_fail git tag -l -d &&\n+\ttest_must_fail git tag -l -v -d &&\n+\ttest_must_fail git tag -n 100 -v &&\n+\ttest_must_fail git tag -l -m msg &&\n+\ttest_must_fail git tag -l -F some file &&\n+\ttest_must_fail git tag -v -s &&\n+\ttest_must_fail git tag --contains tag-tree &&\n+\ttest_must_fail git tag --contains tag-blob &&\n+\ttest_must_fail git tag --no-contains tag-tree &&\n+\ttest_must_fail git tag --no-contains tag-blob &&\n+\ttest_must_fail git tag --contains --no-contains &&\n+\ttest_must_fail git tag --no-with HEAD &&\n+\ttest_must_fail git tag --no-without HEAD\n+'\n+\n+for option in --contains --with --no-contains --without --merged --no-merged --points-at\n+do\n+\ttest_expect_success \"mixing incompatible modes with $option is forbidden\" \"\n+\t\ttest_must_fail git tag -d $option HEAD &&\n+\t\ttest_must_fail git tag -d $option HEAD some-tag &&\n+\t\ttest_must_fail git tag -v $option HEAD\n+\t\"\n+\ttest_expect_success \"Doing 'git tag --list-like $option <commit> <pattern> is permitted\" \"\n+\t\tgit tag -n $option HEAD HEAD &&\n+\t\tgit tag $option HEAD HEAD &&\n+\t\tgit tag $option\n+\t\"\n+done\n+\n+# check points-at\n+\n+test_expect_success '--points-at can be used in non-list mode' '\n+\techo v4.0 >expect &&\n+\tgit tag --points-at=v4.0 \"v*\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--points-at is a synonym for --points-at HEAD' '\n+\techo v4.0 >expect &&\n+\tgit tag --points-at >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--points-at finds lightweight tags' '\n+\techo v4.0 >expect &&\n+\tgit tag --points-at v4.0 >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--points-at finds annotated tags of commits' '\n+\tgit tag -m \"v4.0, annotated\" annotated-v4.0 v4.0 &&\n+\techo annotated-v4.0 >expect &&\n+\tgit tag -l --points-at v4.0 \"annotated*\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--points-at finds annotated tags of tags' '\n+\tgit tag -m \"describing the v4.0 tag object\" \\\n+\t\tannotated-again-v4.0 annotated-v4.0 &&\n+\tcat >expect <<-\\EOF &&\n+\tannotated-again-v4.0\n+\tannotated-v4.0\n+\tEOF\n+\tgit tag --points-at=annotated-v4.0 >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'recursive tagging should give advice' '\n+\tsed -e \"s/|$//\" <<-EOF >expect &&\n+\thint: You have created a nested tag. The object referred to by your new tag is\n+\thint: already a tag. If you meant to tag the object that it points to, use:\n+\thint: |\n+\thint: \tgit tag -f nested annotated-v4.0^{}\n+\tEOF\n+\tgit tag -m nested nested annotated-v4.0 2>actual &&\n+\ttest_i18ncmp expect actual\n+'\n+\n+test_expect_success 'multiple --points-at are OR-ed together' '\n+\tcat >expect <<-\\EOF &&\n+\tv2.0\n+\tv3.0\n+\tEOF\n+\tgit tag --points-at=v2.0 --points-at=v3.0 >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'lexical sort' '\n+\tgit tag foo1.3 &&\n+\tgit tag foo1.6 &&\n+\tgit tag foo1.10 &&\n+\tgit tag -l --sort=refname \"foo*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.10\n+\tfoo1.3\n+\tfoo1.6\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'version sort' '\n+\tgit tag -l --sort=version:refname \"foo*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.3\n+\tfoo1.6\n+\tfoo1.10\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'reverse version sort' '\n+\tgit tag -l --sort=-version:refname \"foo*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.10\n+\tfoo1.6\n+\tfoo1.3\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'reverse lexical sort' '\n+\tgit tag -l --sort=-refname \"foo*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.6\n+\tfoo1.3\n+\tfoo1.10\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'configured lexical sort' '\n+\ttest_config tag.sort \"v:refname\" &&\n+\tgit tag -l \"foo*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.3\n+\tfoo1.6\n+\tfoo1.10\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'option override configured sort' '\n+\ttest_config tag.sort \"v:refname\" &&\n+\tgit tag -l --sort=-refname \"foo*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.6\n+\tfoo1.3\n+\tfoo1.10\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'invalid sort parameter on command line' '\n+\ttest_must_fail git tag -l --sort=notvalid \"foo*\" >actual\n+'\n+\n+test_expect_success 'invalid sort parameter in configuratoin' '\n+\ttest_config tag.sort \"v:notvalid\" &&\n+\ttest_must_fail git tag -l \"foo*\"\n+'\n+\n+test_expect_success 'version sort with prerelease reordering' '\n+\ttest_config versionsort.prereleaseSuffix -rc &&\n+\tgit tag foo1.6-rc1 &&\n+\tgit tag foo1.6-rc2 &&\n+\tgit tag -l --sort=version:refname \"foo*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.3\n+\tfoo1.6-rc1\n+\tfoo1.6-rc2\n+\tfoo1.6\n+\tfoo1.10\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'reverse version sort with prerelease reordering' '\n+\ttest_config versionsort.prereleaseSuffix -rc &&\n+\tgit tag -l --sort=-version:refname \"foo*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.10\n+\tfoo1.6\n+\tfoo1.6-rc2\n+\tfoo1.6-rc1\n+\tfoo1.3\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'version sort with prerelease reordering and common leading character' '\n+\ttest_config versionsort.prereleaseSuffix -before &&\n+\tgit tag foo1.7-before1 &&\n+\tgit tag foo1.7 &&\n+\tgit tag foo1.7-after1 &&\n+\tgit tag -l --sort=version:refname \"foo1.7*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.7-before1\n+\tfoo1.7\n+\tfoo1.7-after1\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'version sort with prerelease reordering, multiple suffixes and common leading character' '\n+\ttest_config versionsort.prereleaseSuffix -before &&\n+\tgit config --add versionsort.prereleaseSuffix -after &&\n+\tgit tag -l --sort=version:refname \"foo1.7*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.7-before1\n+\tfoo1.7-after1\n+\tfoo1.7\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'version sort with prerelease reordering, multiple suffixes match the same tag' '\n+\ttest_config versionsort.prereleaseSuffix -bar &&\n+\tgit config --add versionsort.prereleaseSuffix -foo-baz &&\n+\tgit config --add versionsort.prereleaseSuffix -foo-bar &&\n+\tgit tag foo1.8-foo-bar &&\n+\tgit tag foo1.8-foo-baz &&\n+\tgit tag foo1.8 &&\n+\tgit tag -l --sort=version:refname \"foo1.8*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.8-foo-baz\n+\tfoo1.8-foo-bar\n+\tfoo1.8\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'version sort with prerelease reordering, multiple suffixes match starting at the same position' '\n+\ttest_config versionsort.prereleaseSuffix -pre &&\n+\tgit config --add versionsort.prereleaseSuffix -prerelease &&\n+\tgit tag foo1.9-pre1 &&\n+\tgit tag foo1.9-pre2 &&\n+\tgit tag foo1.9-prerelease1 &&\n+\tgit tag -l --sort=version:refname \"foo1.9*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.9-pre1\n+\tfoo1.9-pre2\n+\tfoo1.9-prerelease1\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'version sort with general suffix reordering' '\n+\ttest_config versionsort.suffix -alpha &&\n+\tgit config --add versionsort.suffix -beta &&\n+\tgit config --add versionsort.suffix \"\"  &&\n+\tgit config --add versionsort.suffix -gamma &&\n+\tgit config --add versionsort.suffix -delta &&\n+\tgit tag foo1.10-alpha &&\n+\tgit tag foo1.10-beta &&\n+\tgit tag foo1.10-gamma &&\n+\tgit tag foo1.10-delta &&\n+\tgit tag foo1.10-unlisted-suffix &&\n+\tgit tag -l --sort=version:refname \"foo1.10*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.10-alpha\n+\tfoo1.10-beta\n+\tfoo1.10\n+\tfoo1.10-unlisted-suffix\n+\tfoo1.10-gamma\n+\tfoo1.10-delta\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'versionsort.suffix overrides versionsort.prereleaseSuffix' '\n+\ttest_config versionsort.suffix -before &&\n+\ttest_config versionsort.prereleaseSuffix -after &&\n+\tgit tag -l --sort=version:refname \"foo1.7*\" >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tfoo1.7-before1\n+\tfoo1.7\n+\tfoo1.7-after1\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'version sort with very long prerelease suffix' '\n+\ttest_config versionsort.prereleaseSuffix -very-looooooooooooooooooooooooong-prerelease-suffix &&\n+\tgit tag -l --sort=version:refname\n+'\n+\n+test_expect_success ULIMIT_STACK_SIZE '--contains and --no-contains work in a deep repo' '\n+\ti=1 &&\n+\twhile test $i -lt 8000\n+\tdo\n+\t\techo \"commit refs/heads/master\n+committer A U Thor <author@example.com> $((1000000000 + $i * 100)) +0200\n+data <<EOF\n+commit #$i\n+EOF\"\n+\t\ttest $i = 1 && echo \"from refs/heads/master^0\"\n+\t\ti=$(($i + 1))\n+\tdone | git fast-import &&\n+\tgit checkout master &&\n+\tgit tag far-far-away HEAD^ &&\n+\trun_with_limited_stack git tag --contains HEAD >actual &&\n+\ttest_must_be_empty actual &&\n+\trun_with_limited_stack git tag --no-contains HEAD >actual &&\n+\ttest_line_count \"-gt\" 10 actual\n+'\n+\n+test_expect_success '--format should list tags as per format given' '\n+\tcat >expect <<-\\EOF &&\n+\trefname : refs/tags/v1.0\n+\trefname : refs/tags/v1.0.1\n+\trefname : refs/tags/v1.1.3\n+\tEOF\n+\tgit tag -l --format=\"refname : %(refname)\" \"v1*\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success \"set up color tests\" '\n+\techo \"<RED>v1.0<RESET>\" >expect.color &&\n+\techo \"v1.0\" >expect.bare &&\n+\tcolor_args=\"--format=%(color:red)%(refname:short) --list v1.0\"\n+'\n+\n+test_expect_success '%(color) omitted without tty' '\n+\tTERM=vt100 git tag $color_args >actual.raw &&\n+\ttest_decode_color <actual.raw >actual &&\n+\ttest_cmp expect.bare actual\n+'\n+\n+test_expect_success TTY '%(color) present with tty' '\n+\ttest_terminal git tag $color_args >actual.raw &&\n+\ttest_decode_color <actual.raw >actual &&\n+\ttest_cmp expect.color actual\n+'\n+\n+test_expect_success '--color overrides auto-color' '\n+\tgit tag --color $color_args >actual.raw &&\n+\ttest_decode_color <actual.raw >actual &&\n+\ttest_cmp expect.color actual\n+'\n+\n+test_expect_success 'color.ui=always overrides auto-color' '\n+\tgit -c color.ui=always tag $color_args >actual.raw &&\n+\ttest_decode_color <actual.raw >actual &&\n+\ttest_cmp expect.color actual\n+'\n+\n+test_expect_success 'setup --merged test tags' '\n+\tgit tag mergetest-1 HEAD~2 &&\n+\tgit tag mergetest-2 HEAD~1 &&\n+\tgit tag mergetest-3 HEAD\n+'\n+\n+test_expect_success '--merged can be used in non-list mode' '\n+\tcat >expect <<-\\EOF &&\n+\tmergetest-1\n+\tmergetest-2\n+\tEOF\n+\tgit tag --merged=mergetest-2 \"mergetest*\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--merged is incompatible with --no-merged' '\n+\ttest_must_fail git tag --merged HEAD --no-merged HEAD\n+'\n+\n+test_expect_success '--merged shows merged tags' '\n+\tcat >expect <<-\\EOF &&\n+\tmergetest-1\n+\tmergetest-2\n+\tEOF\n+\tgit tag -l --merged=mergetest-2 mergetest-* >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--no-merged show unmerged tags' '\n+\tcat >expect <<-\\EOF &&\n+\tmergetest-3\n+\tEOF\n+\tgit tag -l --no-merged=mergetest-2 mergetest-* >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--no-merged can be used in non-list mode' '\n+\tgit tag --no-merged=mergetest-2 mergetest-* >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'ambiguous branch/tags not marked' '\n+\tgit tag ambiguous &&\n+\tgit branch ambiguous &&\n+\techo ambiguous >expect &&\n+\tgit tag -l ambiguous >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--contains combined with --no-contains' '\n+\t(\n+\t\tgit init no-contains &&\n+\t\tcd no-contains &&\n+\t\ttest_commit v0.1 &&\n+\t\ttest_commit v0.2 &&\n+\t\ttest_commit v0.3 &&\n+\t\ttest_commit v0.4 &&\n+\t\ttest_commit v0.5 &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\tv0.2\n+\t\tv0.3\n+\t\tv0.4\n+\t\tEOF\n+\t\tgit tag --contains v0.2 --no-contains v0.5 >actual &&\n+\t\ttest_cmp expected actual\n+\t)\n+'\n+\n+# As the docs say, list tags which contain a specified *commit*. We\n+# don't recurse down to tags for trees or blobs pointed to by *those*\n+# commits.\n+test_expect_success 'Does --[no-]contains stop at commits? Yes!' '\n+\tcd no-contains &&\n+\tblob=$(git rev-parse v0.3:v0.3.t) &&\n+\ttree=$(git rev-parse v0.3^{tree}) &&\n+\tgit tag tag-blob $blob &&\n+\tgit tag tag-tree $tree &&\n+\tgit tag --contains v0.3 >actual &&\n+\tcat >expected <<-\\EOF &&\n+\tv0.3\n+\tv0.4\n+\tv0.5\n+\tEOF\n+\ttest_cmp expected actual &&\n+\tgit tag --no-contains v0.3 >actual &&\n+\tcat >expected <<-\\EOF &&\n+\tv0.1\n+\tv0.2\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n+test_done\ndiff --git a/t/t7031-verify-tag-signconfig.sh b/t/t7031-verify-tag-signconfig.sh\nnew file mode 100755\nindex 000000000..b5238585a\n--- /dev/null\n+++ b/t/t7031-verify-tag-signconfig.sh\n@@ -0,0 +1,175 @@\n+#!/bin/sh\n+\n+test_description='signed tag tests using new config'\n+. ./test-lib.sh\n+. \"$TEST_DIRECTORY/lib-gpg.sh\"\n+\n+test_expect_success GPG 'create signed tags' '\n+\techo 1 >file && git add file &&\n+\ttest_tick && git commit -m initial &&\n+\tgit tag -s -m initial initial &&\n+\tgit branch side &&\n+\n+\techo 2 >file && test_tick && git commit -a -m second &&\n+\tgit tag -s -m second second &&\n+\n+\tgit checkout side &&\n+\techo 3 >elif && git add elif &&\n+\ttest_tick && git commit -m \"third on side\" &&\n+\n+\tgit checkout master &&\n+\ttest_tick && git merge -S side &&\n+\tgit tag -s -m merge merge &&\n+\n+\techo 4 >file && test_tick && git commit -a -S -m \"fourth unsigned\" &&\n+\tgit tag -a -m fourth-unsigned fourth-unsigned &&\n+\n+\ttest_tick && git commit --amend -S -m \"fourth signed\" &&\n+\tgit tag -s -m fourth fourth-signed &&\n+\n+\techo 5 >file && test_tick && git commit -a -m \"fifth\" &&\n+\tgit tag fifth-unsigned &&\n+\n+\tgit config commit.sign true &&\n+\techo 6 >file && test_tick && git commit -a -m \"sixth\" &&\n+\tgit tag -a -m sixth sixth-unsigned &&\n+\n+\ttest_tick && git rebase -f HEAD^^ && git tag -s -m 6th sixth-signed HEAD^ &&\n+\tgit tag -m seventh -s seventh-signed &&\n+\n+\techo 8 >file && test_tick && git commit -a -m eighth &&\n+\tgit tag -uB7227189 -m eighth eighth-signed-alt\n+'\n+\n+test_expect_success GPGSM 'create signed tags x509 ' '\n+\ttest_config signing.default x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\techo 9 >file && test_tick && git commit -a -m \"nineth gpgsm-signed\" &&\n+\tgit tag -s -m nineth nineth-signed-x509\n+'\n+\n+test_expect_success GPG 'verify and show signatures' '\n+\t(\n+\t\tfor tag in initial second merge fourth-signed sixth-signed seventh-signed\n+\t\tdo\n+\t\t\tgit verify-tag $tag 2>actual &&\n+\t\t\tgrep \"Good signature from\" actual &&\n+\t\t\t! grep \"BAD signature from\" actual &&\n+\t\t\techo $tag OK || exit 1\n+\t\tdone\n+\t) &&\n+\t(\n+\t\tfor tag in fourth-unsigned fifth-unsigned sixth-unsigned\n+\t\tdo\n+\t\t\ttest_must_fail git verify-tag $tag 2>actual &&\n+\t\t\t! grep \"Good signature from\" actual &&\n+\t\t\t! grep \"BAD signature from\" actual &&\n+\t\t\techo $tag OK || exit 1\n+\t\tdone\n+\t) &&\n+\t(\n+\t\tfor tag in eighth-signed-alt\n+\t\tdo\n+\t\t\tgit verify-tag $tag 2>actual &&\n+\t\t\tgrep \"Good signature from\" actual &&\n+\t\t\t! grep \"BAD signature from\" actual &&\n+\t\t\tgrep \"not certified\" actual &&\n+\t\t\techo $tag OK || exit 1\n+\t\tdone\n+\t)\n+'\n+\n+test_expect_success GPGSM 'verify and show signatures x509' '\n+\tgit verify-tag nineth-signed-x509 2>actual &&\n+\tgrep \"Good signature from\" actual &&\n+\t! grep \"BAD signature from\" actual &&\n+\techo nineth-signed-x509 OK\n+'\n+\n+test_expect_success GPG 'detect fudged signature' '\n+\tgit cat-file tag seventh-signed >raw &&\n+\tsed -e \"/^tag / s/seventh/7th forged/\" raw >forged1 &&\n+\tgit hash-object -w -t tag forged1 >forged1.tag &&\n+\ttest_must_fail git verify-tag $(cat forged1.tag) 2>actual1 &&\n+\tgrep \"BAD signature from\" actual1 &&\n+\t! grep \"Good signature from\" actual1\n+'\n+\n+test_expect_success GPG 'verify signatures with --raw' '\n+\t(\n+\t\tfor tag in initial second merge fourth-signed sixth-signed seventh-signed\n+\t\tdo\n+\t\t\tgit verify-tag --raw $tag 2>actual &&\n+\t\t\tgrep \"GOODSIG\" actual &&\n+\t\t\t! grep \"BADSIG\" actual &&\n+\t\t\techo $tag OK || exit 1\n+\t\tdone\n+\t) &&\n+\t(\n+\t\tfor tag in fourth-unsigned fifth-unsigned sixth-unsigned\n+\t\tdo\n+\t\t\ttest_must_fail git verify-tag --raw $tag 2>actual &&\n+\t\t\t! grep \"GOODSIG\" actual &&\n+\t\t\t! grep \"BADSIG\" actual &&\n+\t\t\techo $tag OK || exit 1\n+\t\tdone\n+\t) &&\n+\t(\n+\t\tfor tag in eighth-signed-alt\n+\t\tdo\n+\t\t\tgit verify-tag --raw $tag 2>actual &&\n+\t\t\tgrep \"GOODSIG\" actual &&\n+\t\t\t! grep \"BADSIG\" actual &&\n+\t\t\tgrep \"TRUST_UNDEFINED\" actual &&\n+\t\t\techo $tag OK || exit 1\n+\t\tdone\n+\t)\n+'\n+\n+test_expect_success GPGSM 'verify signatures with --raw x509' '\n+\tgit verify-tag --raw nineth-signed-x509 2>actual &&\n+\tgrep \"GOODSIG\" actual &&\n+\t! grep \"BADSIG\" actual &&\n+\techo nineth-signed-x509 OK\n+'\n+\n+test_expect_success GPG 'verify multiple tags' '\n+\ttags=\"fourth-signed sixth-signed seventh-signed\" &&\n+\tfor i in $tags\n+\tdo\n+\t\tgit verify-tag -v --raw $i || return 1\n+\tdone >expect.stdout 2>expect.stderr.1 &&\n+\tgrep \"^.GNUPG:.\" <expect.stderr.1 >expect.stderr &&\n+\tgit verify-tag -v --raw $tags >actual.stdout 2>actual.stderr.1 &&\n+\tgrep \"^.GNUPG:.\" <actual.stderr.1 >actual.stderr &&\n+\ttest_cmp expect.stdout actual.stdout &&\n+\ttest_cmp expect.stderr actual.stderr\n+'\n+\n+test_expect_success GPGSM 'verify multiple tags x509' '\n+\ttags=\"seventh-signed nineth-signed-x509\" &&\n+\tfor i in $tags\n+\tdo\n+\t\tgit verify-tag -v --raw $i || return 1\n+\tdone >expect.stdout 2>expect.stderr.1 &&\n+\tgrep \"^.GNUPG:.\" <expect.stderr.1 >expect.stderr &&\n+\tgit verify-tag -v --raw $tags >actual.stdout 2>actual.stderr.1 &&\n+\tgrep \"^.GNUPG:.\" <actual.stderr.1 >actual.stderr &&\n+\ttest_cmp expect.stdout actual.stdout &&\n+\ttest_cmp expect.stderr actual.stderr\n+'\n+\n+test_expect_success GPG 'verifying tag with --format' '\n+\tcat >expect <<-\\EOF &&\n+\ttagname : fourth-signed\n+\tEOF\n+\tgit verify-tag --format=\"tagname : %(tag)\" \"fourth-signed\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG 'verifying a forged tag with --format should fail silently' '\n+\ttest_must_fail git verify-tag --format=\"tagname : %(tag)\" $(cat forged1.tag) >actual-forged &&\n+\ttest_must_be_empty actual-forged\n+'\n+\n+test_done\ndiff --git a/t/t7522-signed-commit-signconfig.sh b/t/t7522-signed-commit-signconfig.sh\nnew file mode 100755\nindex 000000000..682b23a06\n--- /dev/null\n+++ b/t/t7522-signed-commit-signconfig.sh\n@@ -0,0 +1,288 @@\n+#!/bin/sh\n+\n+test_description='signed commit tests'\n+. ./test-lib.sh\n+GNUPGHOME_NOT_USED=$GNUPGHOME\n+. \"$TEST_DIRECTORY/lib-gpg.sh\"\n+\n+test_expect_success GPG 'create signed commits' '\n+\ttest_when_finished \"test_unconfig commit.gpgsign\" &&\n+\n+\techo 1 >file && git add file &&\n+\ttest_tick && git commit -S -m initial &&\n+\tgit tag initial &&\n+\tgit branch side &&\n+\n+\techo 2 >file && test_tick && git commit -a -S -m second &&\n+\tgit tag second &&\n+\n+\tgit checkout side &&\n+\techo 3 >elif && git add elif &&\n+\ttest_tick && git commit -m \"third on side\" &&\n+\n+\tgit checkout master &&\n+\ttest_tick && git merge -S side &&\n+\tgit tag merge &&\n+\n+\techo 4 >file && test_tick && git commit -a -m \"fourth unsigned\" &&\n+\tgit tag fourth-unsigned &&\n+\n+\ttest_tick && git commit --amend -S -m \"fourth signed\" &&\n+\tgit tag fourth-signed &&\n+\n+\tgit config commit.gpgsign true &&\n+\techo 5 >file && test_tick && git commit -a -m \"fifth signed\" &&\n+\tgit tag fifth-signed &&\n+\n+\tgit config commit.gpgsign false &&\n+\techo 6 >file && test_tick && git commit -a -m \"sixth\" &&\n+\tgit tag sixth-unsigned &&\n+\n+\tgit config commit.gpgsign true &&\n+\techo 7 >file && test_tick && git commit -a -m \"seventh\" --no-gpg-sign &&\n+\tgit tag seventh-unsigned &&\n+\n+\ttest_tick && git rebase -f HEAD^^ && git tag sixth-signed HEAD^ &&\n+\tgit tag seventh-signed &&\n+\n+\techo 8 >file && test_tick && git commit -a -m eighth -SB7227189 &&\n+\tgit tag eighth-signed-alt &&\n+\n+\t# commit.gpgsign is still on but this must not be signed\n+\techo 9 | git commit-tree HEAD^{tree} >oid &&\n+\ttest_line_count = 1 oid &&\n+\tgit tag ninth-unsigned $(cat oid) &&\n+\t# explicit -S of course must sign.\n+\techo 10 | git commit-tree -S HEAD^{tree} >oid &&\n+\ttest_line_count = 1 oid &&\n+\tgit tag tenth-signed $(cat oid) &&\n+\n+\t# --gpg-sign[=<key-id>] must sign.\n+\techo 11 | git commit-tree --gpg-sign HEAD^{tree} >oid &&\n+\ttest_line_count = 1 oid &&\n+\tgit tag eleventh-signed $(cat oid) &&\n+\techo 12 | git commit-tree --gpg-sign=B7227189 HEAD^{tree} >oid &&\n+\ttest_line_count = 1 oid &&\n+\tgit tag twelfth-signed-alt $(cat oid)\n+'\n+\n+test_expect_success GPG 'verify and show signatures' '\n+\t(\n+\t\tfor commit in initial second merge fourth-signed \\\n+\t\t\tfifth-signed sixth-signed seventh-signed tenth-signed \\\n+\t\t\televenth-signed\n+\t\tdo\n+\t\t\tgit verify-commit $commit &&\n+\t\t\tgit show --pretty=short --show-signature $commit >actual &&\n+\t\t\tgrep \"Good signature from\" actual &&\n+\t\t\t! grep \"BAD signature from\" actual &&\n+\t\t\techo $commit OK || exit 1\n+\t\tdone\n+\t) &&\n+\t(\n+\t\tfor commit in merge^2 fourth-unsigned sixth-unsigned \\\n+\t\t\tseventh-unsigned ninth-unsigned\n+\t\tdo\n+\t\t\ttest_must_fail git verify-commit $commit &&\n+\t\t\tgit show --pretty=short --show-signature $commit >actual &&\n+\t\t\t! grep \"Good signature from\" actual &&\n+\t\t\t! grep \"BAD signature from\" actual &&\n+\t\t\techo $commit OK || exit 1\n+\t\tdone\n+\t) &&\n+\t(\n+\t\tfor commit in eighth-signed-alt twelfth-signed-alt\n+\t\tdo\n+\t\t\tgit show --pretty=short --show-signature $commit >actual &&\n+\t\t\tgrep \"Good signature from\" actual &&\n+\t\t\t! grep \"BAD signature from\" actual &&\n+\t\t\tgrep \"not certified\" actual &&\n+\t\t\techo $commit OK || exit 1\n+\t\tdone\n+\t)\n+'\n+\n+test_expect_success GPG 'verify-commit exits success on untrusted signature' '\n+\tgit verify-commit eighth-signed-alt 2>actual &&\n+\tgrep \"Good signature from\" actual &&\n+\t! grep \"BAD signature from\" actual &&\n+\tgrep \"not certified\" actual\n+'\n+\n+test_expect_success GPG 'verify signatures with --raw' '\n+\t(\n+\t\tfor commit in initial second merge fourth-signed fifth-signed sixth-signed seventh-signed\n+\t\tdo\n+\t\t\tgit verify-commit --raw $commit 2>actual &&\n+\t\t\tgrep \"GOODSIG\" actual &&\n+\t\t\t! grep \"BADSIG\" actual &&\n+\t\t\techo $commit OK || exit 1\n+\t\tdone\n+\t) &&\n+\t(\n+\t\tfor commit in merge^2 fourth-unsigned sixth-unsigned seventh-unsigned\n+\t\tdo\n+\t\t\ttest_must_fail git verify-commit --raw $commit 2>actual &&\n+\t\t\t! grep \"GOODSIG\" actual &&\n+\t\t\t! grep \"BADSIG\" actual &&\n+\t\t\techo $commit OK || exit 1\n+\t\tdone\n+\t) &&\n+\t(\n+\t\tfor commit in eighth-signed-alt\n+\t\tdo\n+\t\t\tgit verify-commit --raw $commit 2>actual &&\n+\t\t\tgrep \"GOODSIG\" actual &&\n+\t\t\t! grep \"BADSIG\" actual &&\n+\t\t\tgrep \"TRUST_UNDEFINED\" actual &&\n+\t\t\techo $commit OK || exit 1\n+\t\tdone\n+\t)\n+'\n+\n+test_expect_success GPG 'show signed commit with signature' '\n+\tgit show -s initial >commit &&\n+\tgit show -s --show-signature initial >show &&\n+\tgit verify-commit -v initial >verify.1 2>verify.2 &&\n+\tgit cat-file commit initial >cat &&\n+\tgrep -v -e \"gpg: \" -e \"Warning: \" show >show.commit &&\n+\tgrep -e \"gpg: \" -e \"Warning: \" show >show.gpg &&\n+\tgrep -v \"^ \" cat | grep -v \"^gpgsig \" >cat.commit &&\n+\ttest_cmp show.commit commit &&\n+\ttest_cmp show.gpg verify.2 &&\n+\ttest_cmp cat.commit verify.1\n+'\n+\n+test_expect_success GPG 'detect fudged signature' '\n+\tgit cat-file commit seventh-signed >raw &&\n+\tsed -e \"s/^seventh/7th forged/\" raw >forged1 &&\n+\tgit hash-object -w -t commit forged1 >forged1.commit &&\n+\ttest_must_fail git verify-commit $(cat forged1.commit) &&\n+\tgit show --pretty=short --show-signature $(cat forged1.commit) >actual1 &&\n+\tgrep \"BAD signature from\" actual1 &&\n+\t! grep \"Good signature from\" actual1\n+'\n+\n+test_expect_success GPG 'detect fudged signature with NUL' '\n+\tgit cat-file commit seventh-signed >raw &&\n+\tcat raw >forged2 &&\n+\techo Qwik | tr \"Q\" \"\\000\" >>forged2 &&\n+\tgit hash-object -w -t commit forged2 >forged2.commit &&\n+\ttest_must_fail git verify-commit $(cat forged2.commit) &&\n+\tgit show --pretty=short --show-signature $(cat forged2.commit) >actual2 &&\n+\tgrep \"BAD signature from\" actual2 &&\n+\t! grep \"Good signature from\" actual2\n+'\n+\n+test_expect_success GPG 'amending already signed commit' '\n+\tgit checkout fourth-signed^0 &&\n+\tgit commit --amend -S --no-edit &&\n+\tgit verify-commit HEAD &&\n+\tgit show -s --show-signature HEAD >actual &&\n+\tgrep \"Good signature from\" actual &&\n+\t! grep \"BAD signature from\" actual\n+'\n+\n+test_expect_success GPG 'show good signature with custom format' '\n+\tcat >expect <<-\\EOF &&\n+\tG\n+\t13B6F51ECDDE430D\n+\tC O Mitter <committer@example.com>\n+\t73D758744BE721698EC54E8713B6F51ECDDE430D\n+\t73D758744BE721698EC54E8713B6F51ECDDE430D\n+\tEOF\n+\tgit log -1 --format=\"%G?%n%GK%n%GS%n%GF%n%GP\" sixth-signed >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG 'show bad signature with custom format' '\n+\tcat >expect <<-\\EOF &&\n+\tB\n+\t13B6F51ECDDE430D\n+\tC O Mitter <committer@example.com>\n+\n+\n+\tEOF\n+\tgit log -1 --format=\"%G?%n%GK%n%GS%n%GF%n%GP\" $(cat forged1.commit) >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG 'show untrusted signature with custom format' '\n+\tcat >expect <<-\\EOF &&\n+\tU\n+\t65A0EEA02E30CAD7\n+\tEris Discordia <discord@example.net>\n+\tF8364A59E07FFE9F4D63005A65A0EEA02E30CAD7\n+\tD4BE22311AD3131E5EDA29A461092E85B7227189\n+\tEOF\n+\tgit log -1 --format=\"%G?%n%GK%n%GS%n%GF%n%GP\" eighth-signed-alt >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG 'show unknown signature with custom format' '\n+\tcat >expect <<-\\EOF &&\n+\tE\n+\t65A0EEA02E30CAD7\n+\n+\n+\n+\tEOF\n+\tGNUPGHOME=\"$GNUPGHOME_NOT_USED\" git log -1 --format=\"%G?%n%GK%n%GS%n%GF%n%GP\" eighth-signed-alt >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG 'show lack of signature with custom format' '\n+\tcat >expect <<-\\EOF &&\n+\tN\n+\n+\n+\n+\n+\tEOF\n+\tgit log -1 --format=\"%G?%n%GK%n%GS%n%GF%n%GP\" seventh-unsigned >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success GPG 'log.showsignature behaves like --show-signature' '\n+\ttest_config log.showsignature true &&\n+\tgit show initial >actual &&\n+\tgrep \"gpg: Signature made\" actual &&\n+\tgrep \"gpg: Good signature\" actual\n+'\n+\n+test_expect_success GPG 'check config gpg.format values' '\n+\ttest_config gpg.format openpgp &&\n+\tgit commit -S --amend -m \"success\" &&\n+\ttest_config gpg.format OpEnPgP &&\n+\ttest_must_fail git commit -S --amend -m \"fail\"\n+'\n+\n+test_expect_success GPG 'detect fudged commit with double signature' '\n+\tsed -e \"/gpgsig/,/END PGP/d\" forged1 >double-base &&\n+\tsed -n -e \"/gpgsig/,/END PGP/p\" forged1 | \\\n+\t\tsed -e \"s/^gpgsig//;s/^ //\" | gpg --dearmor >double-sig1.sig &&\n+\tgpg -o double-sig2.sig -u 29472784 --detach-sign double-base &&\n+\tcat double-sig1.sig double-sig2.sig | gpg --enarmor >double-combined.asc &&\n+\tsed -e \"s/^\\(-.*\\)ARMORED FILE/\\1SIGNATURE/;1s/^/gpgsig /;2,\\$s/^/ /\" \\\n+\t\tdouble-combined.asc > double-gpgsig &&\n+\tsed -e \"/committer/r double-gpgsig\" double-base >double-commit &&\n+\tgit hash-object -w -t commit double-commit >double-commit.commit &&\n+\ttest_must_fail git verify-commit $(cat double-commit.commit) &&\n+\tgit show --pretty=short --show-signature $(cat double-commit.commit) >double-actual &&\n+\tgrep \"BAD signature from\" double-actual &&\n+\tgrep \"Good signature from\" double-actual\n+'\n+\n+test_expect_success GPG 'show double signature with custom format' '\n+\tcat >expect <<-\\EOF &&\n+\tE\n+\n+\n+\n+\n+\tEOF\n+\tgit log -1 --format=\"%G?%n%GK%n%GS%n%GF%n%GP\" $(cat double-commit.commit) >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_done\n-- \n2.11.0\n\n\n"},{"id":"381261","messageId":"20190826230704.GC11334@genre.crustytoothpaste.net","threadId":"51746","inReplyTo":"xidzc1zBudSNNUInNKpDPgAw3AlwtABPT9VpKuPpAfVodvQejHn5WHIYTrqlMlJEYB11iMVhxNCQKBnx7phcHaiPQhHLaqKgeVZwPTCx4n4=@pm.me","subject":"Re: [PATCH 5/5] Signing API: Duplicated signing tests using new config aliases","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2019-08-26T23:07:04Z","receivedAt":"2019-08-26T23:07:12Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2019-08-26 at 19:58:10, Ibrahim El wrote:\n> From: Ibrahim El Rhezzali <ibrahim.el@pm.me>\n> \n> c6a1d1c21 Duplicated signing tests using new config aliases\n> \n> Duplicating existing tests that are signature related and updating them to use the new config aliases\n\nI don't think we want to duplicate all of these tests.  Perhaps we could\nadd a small number of additional tests in an existing signing test that\nmakes sure both the new and the old configuration work as expected, and\nassume that the entire codebase will honor those config settings.\n-- \nbrian m. carlson: Houston, Texas, US\nOpenPGP: https://keybase.io/bk2204\n"},{"id":"381384","messageId":"REK5vbm4i5ut8-lShrc8zcI0FhegDvy49CM2CXn4QS7prThNuwiu5J1Ae_kCh5c29Ri157tB86UXJH372WEFo_uWW9y7wf3oh1ysMZphs4c=@pm.me","threadId":"51746","inReplyTo":"20190826230704.GC11334@genre.crustytoothpaste.net","subject":"Re: [PATCH 5/5] Signing API: Duplicated signing tests using new config aliases","fromName":"Ibrahim El","fromEmail":"ibrahim.el@pm.me","sentAt":"2019-08-27T18:54:25Z","receivedAt":"2019-08-27T18:54:31Z","isPatch":true,"sender":{"key":"ibrahim.el@pm.me","avatar":null},"body":"Thx for your feedback. I will update the necessary existing tests and re-submit the patches.\n\n\nIbrahim El Rhezzali\n\n‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐\nOn Monday, August 26, 2019 11:07 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n\n> On 2019-08-26 at 19:58:10, Ibrahim El wrote:\n>\n> > From: Ibrahim El Rhezzali ibrahim.el@pm.me\n> > c6a1d1c21 Duplicated signing tests using new config aliases\n> > Duplicating existing tests that are signature related and updating them to use the new config aliases\n>\n> I don't think we want to duplicate all of these tests. Perhaps we could\n> add a small number of additional tests in an existing signing test that\n> makes sure both the new and the old configuration work as expected, and\n> assume that the entire codebase will honor those config settings.\n>\n> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n>\n> brian m. carlson: Houston, Texas, US\n> OpenPGP: https://keybase.io/bk2204\n\n\n"}]}