Git fork

tests: extend "test_hook" for "rm" and "chmod -x", convert "$HOOK"

Extend the "test_hook" function to take options to disable and remove
hooks. Using the wrapper instead of getting the path and running
"chmod -x" or "rm" will make it easier to eventually emulate the same
behavior with config-based hooks.

Not all of these tests need that new mode, but since the rest are
either closely related or use the same "$HOOK" pattern let's convert
them too.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Ævar Arnfjörð Bjarmason and committed by
Junio C Hamano
66865d12 c36c6285

+165 -163
+1 -4
t/t2400-worktree-add.sh
··· 559 559 ' 560 560 561 561 post_checkout_hook () { 562 - gitdir=${1:-.git} 563 - test_when_finished "rm -f $gitdir/hooks/post-checkout" && 564 - mkdir -p $gitdir/hooks && 565 - write_script $gitdir/hooks/post-checkout <<-\EOF 562 + test_hook -C "$1" post-checkout <<-\EOF 566 563 { 567 564 echo $* 568 565 git rev-parse --git-dir --show-toplevel
+4 -10
t/t5543-atomic-push.sh
··· 162 162 test_commit two && 163 163 git push --mirror up 164 164 ) && 165 - ( 166 - cd upstream && 167 - HOOKDIR="$(git rev-parse --git-dir)/hooks" && 168 - HOOK="$HOOKDIR/update" && 169 - mkdir -p "$HOOKDIR" && 170 - write_script "$HOOK" <<-\EOF 171 - # only allow update to main from now on 172 - test "$1" = "refs/heads/main" 173 - EOF 174 - ) && 165 + test_hook -C upstream update <<-\EOF && 166 + # only allow update to main from now on 167 + test "$1" = "refs/heads/main" 168 + EOF 175 169 ( 176 170 cd workbench && 177 171 git checkout main &&
+18 -20
t/t5571-pre-push-hook.sh
··· 6 6 7 7 . ./test-lib.sh 8 8 9 - # Setup hook that always succeeds 10 - HOOKDIR="$(git rev-parse --git-dir)/hooks" 11 - HOOK="$HOOKDIR/pre-push" 12 - mkdir -p "$HOOKDIR" 13 - write_script "$HOOK" <<EOF 14 - cat >actual 15 - exit 0 16 - EOF 9 + test_expect_success 'setup' ' 10 + test_hook pre-push <<-\EOF && 11 + cat >actual 12 + EOF 17 13 18 - test_expect_success 'setup' ' 19 14 git config push.default upstream && 20 15 git init --bare repo1 && 21 16 git remote add parent1 repo1 && ··· 28 23 git push parent1 HEAD:foreign && 29 24 test_cmp expect actual 30 25 ' 31 - write_script "$HOOK" <<EOF 32 - cat >actual 33 - exit 1 34 - EOF 35 26 36 27 COMMIT1="$(git rev-parse HEAD)" 37 28 export COMMIT1 38 29 39 30 test_expect_success 'push with failing hook' ' 31 + test_hook pre-push <<-\EOF && 32 + cat >actual && 33 + exit 1 34 + EOF 35 + 40 36 test_commit two && 41 37 cat >expect <<-EOF && 42 38 HEAD $(git rev-parse HEAD) refs/heads/main $(test_oid zero) ··· 55 51 COMMIT2="$(git rev-parse HEAD)" 56 52 export COMMIT2 57 53 58 - write_script "$HOOK" <<'EOF' 59 - echo "$1" >actual 60 - echo "$2" >>actual 61 - cat >>actual 62 - EOF 63 - 64 54 test_expect_success 'push with hook' ' 55 + test_hook --setup pre-push <<-\EOF && 56 + echo "$1" >actual 57 + echo "$2" >>actual 58 + cat >>actual 59 + EOF 60 + 65 61 cat >expect <<-EOF && 66 62 parent1 67 63 repo1 ··· 136 132 ' 137 133 138 134 test_expect_success 'sigpipe does not cause pre-push hook failure' ' 139 - echo "exit 0" | write_script "$HOOK" && 135 + test_hook --clobber pre-push <<-\EOF && 136 + exit 0 137 + EOF 140 138 git push parent1 "refs/heads/b/*:refs/heads/b/*" 141 139 ' 142 140
+74 -76
t/t7503-pre-commit-and-pre-merge-commit-hooks.sh
··· 7 7 8 8 . ./test-lib.sh 9 9 10 - HOOKDIR="$(git rev-parse --git-dir)/hooks" 11 - PRECOMMIT="$HOOKDIR/pre-commit" 12 - PREMERGE="$HOOKDIR/pre-merge-commit" 13 - 14 - # Prepare sample scripts that write their $0 to actual_hooks 15 - test_expect_success 'sample script setup' ' 16 - mkdir -p "$HOOKDIR" && 17 - write_script "$HOOKDIR/success.sample" <<-\EOF && 18 - echo $0 >>actual_hooks 19 - exit 0 20 - EOF 21 - write_script "$HOOKDIR/fail.sample" <<-\EOF && 22 - echo $0 >>actual_hooks 23 - exit 1 24 - EOF 25 - write_script "$HOOKDIR/non-exec.sample" <<-\EOF && 26 - echo $0 >>actual_hooks 27 - exit 1 28 - EOF 29 - chmod -x "$HOOKDIR/non-exec.sample" && 30 - write_script "$HOOKDIR/require-prefix.sample" <<-\EOF && 31 - echo $0 >>actual_hooks 32 - test $GIT_PREFIX = "success/" 33 - EOF 34 - write_script "$HOOKDIR/check-author.sample" <<-\EOF 35 - echo $0 >>actual_hooks 36 - test "$GIT_AUTHOR_NAME" = "New Author" && 37 - test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com" 38 - EOF 39 - ' 40 - 41 10 test_expect_success 'root commit' ' 42 11 echo "root" >file && 43 12 git add file && ··· 96 65 test_path_is_missing actual_hooks 97 66 ' 98 67 68 + setup_success_hook () { 69 + test_when_finished "rm -f actual_hooks expected_hooks" && 70 + echo "$1" >expected_hooks && 71 + test_hook "$1" <<-EOF 72 + echo $1 >>actual_hooks 73 + EOF 74 + } 75 + 99 76 test_expect_success 'with succeeding hook' ' 100 - test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && 101 - cp "$HOOKDIR/success.sample" "$PRECOMMIT" && 102 - echo "$PRECOMMIT" >expected_hooks && 77 + setup_success_hook "pre-commit" && 103 78 echo "more" >>file && 104 79 git add file && 105 80 git commit -m "more" && ··· 107 82 ' 108 83 109 84 test_expect_success 'with succeeding hook (merge)' ' 110 - test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" && 111 - cp "$HOOKDIR/success.sample" "$PREMERGE" && 112 - echo "$PREMERGE" >expected_hooks && 85 + setup_success_hook "pre-merge-commit" && 113 86 git checkout side && 114 87 git merge -m "merge main" main && 115 88 git checkout main && ··· 117 90 ' 118 91 119 92 test_expect_success 'automatic merge fails; both hooks are available' ' 120 - test_when_finished "rm -f \"$PREMERGE\" \"$PRECOMMIT\"" && 121 - test_when_finished "rm -f expected_hooks actual_hooks" && 122 - test_when_finished "git checkout main" && 123 - cp "$HOOKDIR/success.sample" "$PREMERGE" && 124 - cp "$HOOKDIR/success.sample" "$PRECOMMIT" && 93 + setup_success_hook "pre-commit" && 94 + setup_success_hook "pre-merge-commit" && 125 95 126 96 git checkout conflicting-a && 127 97 test_must_fail git merge -m "merge conflicting-b" conflicting-b && 128 98 test_path_is_missing actual_hooks && 129 99 130 - echo "$PRECOMMIT" >expected_hooks && 100 + echo "pre-commit" >expected_hooks && 131 101 echo a+b >conflicting && 132 102 git add conflicting && 133 103 git commit -m "resolve conflict" && ··· 135 105 ' 136 106 137 107 test_expect_success '--no-verify with succeeding hook' ' 138 - test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && 139 - cp "$HOOKDIR/success.sample" "$PRECOMMIT" && 108 + setup_success_hook "pre-commit" && 140 109 echo "even more" >>file && 141 110 git add file && 142 111 git commit --no-verify -m "even more" && ··· 144 113 ' 145 114 146 115 test_expect_success '--no-verify with succeeding hook (merge)' ' 147 - test_when_finished "rm -f \"$PREMERGE\" actual_hooks" && 148 - cp "$HOOKDIR/success.sample" "$PREMERGE" && 116 + setup_success_hook "pre-merge-commit" && 149 117 git branch -f side side-orig && 150 118 git checkout side && 151 119 git merge --no-verify -m "merge main" main && ··· 153 121 test_path_is_missing actual_hooks 154 122 ' 155 123 124 + setup_failing_hook () { 125 + test_when_finished "rm -f actual_hooks" && 126 + test_hook "$1" <<-EOF 127 + echo $1-failing-hook >>actual_hooks 128 + exit 1 129 + EOF 130 + } 131 + 156 132 test_expect_success 'with failing hook' ' 157 - test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && 158 - cp "$HOOKDIR/fail.sample" "$PRECOMMIT" && 159 - echo "$PRECOMMIT" >expected_hooks && 133 + setup_failing_hook "pre-commit" && 134 + test_when_finished "rm -f expected_hooks" && 135 + echo "pre-commit-failing-hook" >expected_hooks && 136 + 160 137 echo "another" >>file && 161 138 git add file && 162 139 test_must_fail git commit -m "another" && ··· 164 141 ' 165 142 166 143 test_expect_success '--no-verify with failing hook' ' 167 - test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && 168 - cp "$HOOKDIR/fail.sample" "$PRECOMMIT" && 144 + setup_failing_hook "pre-commit" && 169 145 echo "stuff" >>file && 170 146 git add file && 171 147 git commit --no-verify -m "stuff" && ··· 173 149 ' 174 150 175 151 test_expect_success 'with failing hook (merge)' ' 176 - test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" && 177 - cp "$HOOKDIR/fail.sample" "$PREMERGE" && 178 - echo "$PREMERGE" >expected_hooks && 152 + setup_failing_hook "pre-merge-commit" && 153 + echo "pre-merge-commit-failing-hook" >expected_hooks && 179 154 git checkout side && 180 155 test_must_fail git merge -m "merge main" main && 181 156 git checkout main && ··· 183 158 ' 184 159 185 160 test_expect_success '--no-verify with failing hook (merge)' ' 186 - test_when_finished "rm -f \"$PREMERGE\" actual_hooks" && 187 - cp "$HOOKDIR/fail.sample" "$PREMERGE" && 161 + setup_failing_hook "pre-merge-commit" && 162 + 188 163 git branch -f side side-orig && 189 164 git checkout side && 190 165 git merge --no-verify -m "merge main" main && ··· 192 167 test_path_is_missing actual_hooks 193 168 ' 194 169 170 + setup_non_exec_hook () { 171 + test_when_finished "rm -f actual_hooks" && 172 + test_hook "$1" <<-\EOF && 173 + echo non-exec >>actual_hooks 174 + exit 1 175 + EOF 176 + test_hook --disable "$1" 177 + } 178 + 179 + 195 180 test_expect_success POSIXPERM 'with non-executable hook' ' 196 - test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && 197 - cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" && 181 + setup_non_exec_hook "pre-commit" && 198 182 echo "content" >>file && 199 183 git add file && 200 184 git commit -m "content" && ··· 202 186 ' 203 187 204 188 test_expect_success POSIXPERM '--no-verify with non-executable hook' ' 205 - test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && 206 - cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" && 189 + setup_non_exec_hook "pre-commit" && 207 190 echo "more content" >>file && 208 191 git add file && 209 192 git commit --no-verify -m "more content" && ··· 211 194 ' 212 195 213 196 test_expect_success POSIXPERM 'with non-executable hook (merge)' ' 214 - test_when_finished "rm -f \"$PREMERGE\" actual_hooks" && 215 - cp "$HOOKDIR/non-exec.sample" "$PREMERGE" && 197 + setup_non_exec_hook "pre-merge" && 216 198 git branch -f side side-orig && 217 199 git checkout side && 218 200 git merge -m "merge main" main && ··· 221 203 ' 222 204 223 205 test_expect_success POSIXPERM '--no-verify with non-executable hook (merge)' ' 224 - test_when_finished "rm -f \"$PREMERGE\" actual_hooks" && 225 - cp "$HOOKDIR/non-exec.sample" "$PREMERGE" && 206 + setup_non_exec_hook "pre-merge" && 226 207 git branch -f side side-orig && 227 208 git checkout side && 228 209 git merge --no-verify -m "merge main" main && ··· 230 211 test_path_is_missing actual_hooks 231 212 ' 232 213 214 + setup_require_prefix_hook () { 215 + test_when_finished "rm -f expected_hooks" && 216 + echo require-prefix >expected_hooks && 217 + test_hook pre-commit <<-\EOF 218 + echo require-prefix >>actual_hooks 219 + test $GIT_PREFIX = "success/" 220 + EOF 221 + } 222 + 233 223 test_expect_success 'with hook requiring GIT_PREFIX' ' 234 - test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks success" && 235 - cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" && 236 - echo "$PRECOMMIT" >expected_hooks && 224 + test_when_finished "rm -rf actual_hooks success" && 225 + setup_require_prefix_hook && 237 226 echo "more content" >>file && 238 227 git add file && 239 228 mkdir success && ··· 245 234 ' 246 235 247 236 test_expect_success 'with failing hook requiring GIT_PREFIX' ' 248 - test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks fail" && 249 - cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" && 250 - echo "$PRECOMMIT" >expected_hooks && 237 + test_when_finished "rm -rf actual_hooks fail" && 238 + setup_require_prefix_hook && 251 239 echo "more content" >>file && 252 240 git add file && 253 241 mkdir fail && ··· 259 247 test_cmp expected_hooks actual_hooks 260 248 ' 261 249 250 + setup_require_author_hook () { 251 + test_when_finished "rm -f expected_hooks actual_hooks" && 252 + echo check-author >expected_hooks && 253 + test_hook pre-commit <<-\EOF 254 + echo check-author >>actual_hooks 255 + test "$GIT_AUTHOR_NAME" = "New Author" && 256 + test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com" 257 + EOF 258 + } 259 + 260 + 262 261 test_expect_success 'check the author in hook' ' 263 - test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && 264 - cp "$HOOKDIR/check-author.sample" "$PRECOMMIT" && 262 + setup_require_author_hook && 265 263 cat >expected_hooks <<-EOF && 266 - $PRECOMMIT 267 - $PRECOMMIT 268 - $PRECOMMIT 264 + check-author 265 + check-author 266 + check-author 269 267 EOF 270 268 test_must_fail git commit --allow-empty -m "by a.u.thor" && 271 269 (
+21 -22
t/t7504-commit-msg-hook.sh
··· 54 54 55 55 ' 56 56 57 - # now install hook that always succeeds 58 - HOOKDIR="$(git rev-parse --git-dir)/hooks" 59 - HOOK="$HOOKDIR/commit-msg" 60 - mkdir -p "$HOOKDIR" 61 - cat > "$HOOK" <<EOF 62 - #!/bin/sh 63 - exit 0 64 - EOF 65 - chmod +x "$HOOK" 57 + test_expect_success 'setup: commit-msg hook that always succeeds' ' 58 + test_hook --setup commit-msg <<-\EOF 59 + exit 0 60 + EOF 61 + ' 66 62 67 63 test_expect_success 'with succeeding hook' ' 68 64 ··· 98 94 99 95 ' 100 96 101 - # now a hook that fails 102 - cat > "$HOOK" <<EOF 103 - #!/bin/sh 104 - exit 1 105 - EOF 97 + test_expect_success 'setup: commit-msg hook that always fails' ' 98 + test_hook --clobber commit-msg <<-\EOF 99 + exit 1 100 + EOF 101 + ' 106 102 107 103 commit_msg_is () { 108 104 test "$(git log --pretty=format:%s%b -1)" = "$1" ··· 176 172 commit_msg_is "Merge branch '\''main'\'' into newbranch" 177 173 ' 178 174 175 + test_expect_success 'setup: commit-msg hook made non-executable' ' 176 + git_dir="$(git rev-parse --git-dir)" && 177 + chmod -x "$git_dir/hooks/commit-msg" 178 + ' 179 + 179 180 180 - chmod -x "$HOOK" 181 181 test_expect_success POSIXPERM 'with non-executable hook' ' 182 182 183 183 echo "content" >file && ··· 212 212 213 213 ' 214 214 215 - # now a hook that edits the commit message 216 - cat > "$HOOK" <<'EOF' 217 - #!/bin/sh 218 - echo "new message" > "$1" 219 - exit 0 220 - EOF 221 - chmod +x "$HOOK" 215 + test_expect_success 'setup: commit-msg hook that edits the commit message' ' 216 + test_hook --clobber commit-msg <<-\EOF 217 + echo "new message" >"$1" 218 + exit 0 219 + EOF 220 + ' 222 221 223 222 test_expect_success 'hook edits commit message' ' 224 223
+19 -24
t/t7505-prepare-commit-msg-hook.sh
··· 47 47 48 48 ' 49 49 50 - # set up fake editor for interactive editing 51 - cat > fake-editor <<'EOF' 52 - #!/bin/sh 53 - exit 0 54 - EOF 55 - chmod +x fake-editor 56 - 57 - ## Not using test_set_editor here so we can easily ensure the editor variable 58 - ## is only set for the editor tests 59 - FAKE_EDITOR="$(pwd)/fake-editor" 60 - export FAKE_EDITOR 50 + test_expect_success 'setup fake editor for interactive editing' ' 51 + write_script fake-editor <<-\EOF && 52 + exit 0 53 + EOF 61 54 62 - # now install hook that always succeeds and adds a message 63 - HOOKDIR="$(git rev-parse --git-dir)/hooks" 64 - HOOK="$HOOKDIR/prepare-commit-msg" 65 - mkdir -p "$HOOKDIR" 66 - echo "#!$SHELL_PATH" > "$HOOK" 67 - cat >> "$HOOK" <<'EOF' 55 + ## Not using test_set_editor here so we can easily ensure the editor variable 56 + ## is only set for the editor tests 57 + FAKE_EDITOR="$(pwd)/fake-editor" && 58 + export FAKE_EDITOR 59 + ' 68 60 61 + test_expect_success 'setup prepare-commit-msg hook' ' 62 + test_hook --setup prepare-commit-msg <<\EOF 69 63 GIT_DIR=$(git rev-parse --git-dir) 70 64 if test -d "$GIT_DIR/rebase-merge" 71 65 then ··· 103 97 fi 104 98 exit 0 105 99 EOF 106 - chmod +x "$HOOK" 100 + ' 107 101 108 102 echo dummy template > "$(git rev-parse --git-dir)/template" 109 103 ··· 265 259 test "$(git log -1 --pretty=format:%s)" = merge 266 260 ' 267 261 268 - cat > "$HOOK" <<'EOF' 269 - #!/bin/sh 270 - exit 1 271 - EOF 262 + test_expect_success 'setup: commit-msg hook that always fails' ' 263 + test_hook --setup --clobber prepare-commit-msg <<-\EOF 264 + exit 1 265 + EOF 266 + ' 272 267 273 268 test_expect_success 'with failing hook' ' 274 269 ··· 296 291 git checkout -B other HEAD@{1} && 297 292 echo "more" >> file && 298 293 git add file && 299 - rm -f "$HOOK" && 294 + test_hook --remove prepare-commit-msg && 300 295 git commit -m other && 301 - write_script "$HOOK" <<-EOF && 296 + test_hook --setup prepare-commit-msg <<-\EOF && 302 297 exit 1 303 298 EOF 304 299 git checkout - &&
+4 -7
t/t7520-ignored-hook-warning.sh
··· 5 5 . ./test-lib.sh 6 6 7 7 test_expect_success setup ' 8 - hookdir="$(git rev-parse --git-dir)/hooks" && 9 - hook="$hookdir/pre-commit" && 10 - mkdir -p "$hookdir" && 11 - write_script "$hook" <<-\EOF 8 + test_hook --setup pre-commit <<-\EOF 12 9 exit 0 13 10 EOF 14 11 ' ··· 19 16 ' 20 17 21 18 test_expect_success POSIXPERM 'warning if hook is ignored' ' 22 - chmod -x "$hook" && 19 + test_hook --disable pre-commit && 23 20 git commit --allow-empty -m "even more" 2>message && 24 21 test_i18ngrep -e "hook was ignored" message 25 22 ' 26 23 27 24 test_expect_success POSIXPERM 'no warning if advice.ignoredHook set to false' ' 28 25 test_config advice.ignoredHook false && 29 - chmod -x "$hook" && 26 + test_hook --disable pre-commit && 30 27 git commit --allow-empty -m "even more" 2>message && 31 28 test_i18ngrep ! -e "hook was ignored" message 32 29 ' 33 30 34 31 test_expect_success 'no warning if unset advice.ignoredHook and hook removed' ' 35 - rm -f "$hook" && 32 + test_hook --remove pre-commit && 36 33 test_unconfig advice.ignoredHook && 37 34 git commit --allow-empty -m "even more" 2>message && 38 35 test_i18ngrep ! -e "hook was ignored" message
+24
t/test-lib-functions.sh
··· 562 562 # Overwrite an existing <hook-name>, if it exists. Implies 563 563 # --setup (i.e. the "test_when_finished" is assumed to have been 564 564 # set up already). 565 + # --disable 566 + # Disable (chmod -x) an existing <hook-name>, which must exist. 567 + # --remove 568 + # Remove (rm -f) an existing <hook-name>, which must exist. 565 569 test_hook () { 566 570 setup= && 567 571 clobber= && 572 + disable= && 573 + remove= && 568 574 indir= && 569 575 while test $# != 0 570 576 do ··· 578 584 ;; 579 585 --clobber) 580 586 clobber=t 587 + ;; 588 + --disable) 589 + disable=t 590 + ;; 591 + --remove) 592 + remove=t 581 593 ;; 582 594 -*) 583 595 BUG "invalid argument: $1" ··· 592 604 git_dir=$(git -C "$indir" rev-parse --absolute-git-dir) && 593 605 hook_dir="$git_dir/hooks" && 594 606 hook_file="$hook_dir/$1" && 607 + if test -n "$disable$remove" 608 + then 609 + test_path_is_file "$hook_file" && 610 + if test -n "$disable" 611 + then 612 + chmod -x "$hook_file" 613 + elif test -n "$remove" 614 + then 615 + rm -f "$hook_file" 616 + fi && 617 + return 0 618 + fi && 595 619 if test -z "$clobber" 596 620 then 597 621 test_path_is_missing "$hook_file"