git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes
@ 2022-03-02 13:22 Ævar Arnfjörð Bjarmason
  2022-03-02 13:22 ` [PATCH 01/10] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
                   ` (11 more replies)
  0 siblings, 12 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-02 13:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

This series is a test-only improvement series split up and adapted
from a previous series of mine to add a "git init --no-template":
https://lore.kernel.org/git/cover-00.13-00000000000-20211212T201308Z-avarab@gmail.com/

As the range-diff to that shows (with --creation-factor=50) all but
one commit changed too much for "range-diff" to show it by default.

At the end of this series we have a "test_hook" that behaves like the
existing "test_config", i.e. cleans up after itself (by default). See
08/10.

As also explained in 08/10 this means that it'll be much easier to
thoroughly test the "config-based hooks" series, as everything that
now writes hooks will go through this wrapper, and can be made to use
the config-based hooks.

Along the way I found various issues in existing tests that tested our
hooks, and fixed those issues.there were variou

Ævar Arnfjörð Bjarmason (10):
  hook tests: turn exit code assertions into a loop
  t5540: don't rely on "hook/post-update.sample"
  tests: assume the hooks are disabled by default
  bugreport tests: tighten up "git bugreport -s hooks" test
  tests: indent and add hook setup to "test_expect_success"
  hook tests: get rid of unnecessary sub-shells
  fetch+push tests: have tests clean up their own mess
  test-lib-functions: add and use a "test_hook" wrapper
  tests: change "mkdir -p && write_script" to use "test_hook"
  tests: change "cat && chmod +x" to use "test_hook"

 t/t0029-core-unsetenvvars.sh        |   3 +-
 t/t0091-bugreport.sh                |  20 +--
 t/t1350-config-hooks-path.sh        |   4 +-
 t/t1416-ref-transaction-hooks.sh    |  27 ++--
 t/t1800-hook.sh                     |  45 +++----
 t/t3404-rebase-interactive.sh       |  10 +-
 t/t3412-rebase-root.sh              |  18 +--
 t/t3413-rebase-hook.sh              |  18 +--
 t/t3430-rebase-merges.sh            |   6 +-
 t/t4150-am.sh                       |  24 +---
 t/t5401-update-hooks.sh             |  62 ++++-----
 t/t5402-post-merge-hook.sh          |  16 ++-
 t/t5403-post-checkout-hook.sh       |   3 +-
 t/t5406-remote-rejects.sh           |   2 +-
 t/t5407-post-rewrite-hook.sh        |  14 +-
 t/t5409-colorize-remote-messages.sh |   2 +-
 t/t5411-proc-receive-hook.sh        |   4 +-
 t/t5510-fetch.sh                    |   6 +-
 t/t5516-fetch-push.sh               | 192 +++++++++++++---------------
 t/t5521-pull-options.sh             |   4 +-
 t/t5534-push-signed.sh              |  26 ++--
 t/t5540-http-push-webdav.sh         |   4 +-
 t/t5541-http-push-smart.sh          |  22 ++--
 t/t5547-push-quarantine.sh          |   4 +-
 t/t5548-push-porcelain.sh           |   2 +-
 t/t5601-clone.sh                    |   4 +-
 t/t6500-gc.sh                       |  18 +--
 t/t7113-post-index-change-hook.sh   |   7 +-
 t/t7519-status-fsmonitor.sh         |  20 ++-
 t/t9001-send-email.sh               |   4 +-
 t/t9800-git-p4-basic.sh             |  23 ++--
 t/test-lib-functions.sh             |  52 ++++++++
 32 files changed, 320 insertions(+), 346 deletions(-)

Range-diff:
 1:  5526d3dc838 <  -:  ----------- t0001: fix gaps in "TEMPLATE DIRECTORY" coverage
 2:  ef2b67768cf <  -:  ----------- init: split out template population from create_default_files()
 3:  784b7947512 <  -:  ----------- init: unconditionally create the "info" directory
 4:  3d4ea5c5d30 <  -:  ----------- t0008: don't rely on default ".git/info/exclude"
 5:  6bbb39f13fc <  -:  ----------- init & clone: add a --no-template option
 6:  2f478f7ba4a <  -:  ----------- init & clone: add init.templateDir=[bool]
 7:  9402fb23b40 <  -:  ----------- test-lib: create test data with "git init --no-template" (almost)
 8:  0c9b953dd43 <  -:  ----------- tests: don't depend on template-created .git/branches
 -:  ----------- >  1:  706460d10b9 hook tests: turn exit code assertions into a loop
 9:  d97122f5fd8 !  2:  4bee939a894 t5540: don't rely on "hook/post-update.sample"
    @@ t/t5540-http-push-webdav.sh: test_expect_success 'setup remote repository' '
      	cd test_repo.git &&
      	git --bare update-server-info &&
     -	mv hooks/post-update.sample hooks/post-update &&
    -+	write_script "hooks/post-update" <<-\EOF &&
    ++	write_script hooks/post-update <<-\EOF &&
     +	exec git update-server-info
     +	EOF
      	ORIG_HEAD=$(git rev-parse --verify HEAD) &&
10:  ca55471d134 <  -:  ----------- test-lib-functions: add and use a "write_hook" wrapper
11:  6f805f7ebac <  -:  ----------- tests: change "cat && chmod +x" to use "write_hook"
12:  2acbaa77f8d <  -:  ----------- tests: migrate miscellaneous "write_script" to "write_hooks"
13:  d021a5981a1 <  -:  ----------- tests: don't depend on template-created .git/hooks
 -:  ----------- >  3:  0519102edeb tests: assume the hooks are disabled by default
 -:  ----------- >  4:  1da2efc9886 bugreport tests: tighten up "git bugreport -s hooks" test
 -:  ----------- >  5:  8dc478460ee tests: indent and add hook setup to "test_expect_success"
 -:  ----------- >  6:  d86ee06b46e hook tests: get rid of unnecessary sub-shells
 -:  ----------- >  7:  7ce22dbe738 fetch+push tests: have tests clean up their own mess
 -:  ----------- >  8:  d4102e9b929 test-lib-functions: add and use a "test_hook" wrapper
 -:  ----------- >  9:  1802158b14d tests: change "mkdir -p && write_script" to use "test_hook"
 -:  ----------- > 10:  7fef92872f3 tests: change "cat && chmod +x" to use "test_hook"
-- 
2.35.1.1228.g56895c6ee86


^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH 01/10] hook tests: turn exit code assertions into a loop
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
@ 2022-03-02 13:22 ` Ævar Arnfjörð Bjarmason
  2022-03-02 20:55   ` Junio C Hamano
  2022-03-02 13:22 ` [PATCH 02/10] t5540: don't rely on "hook/post-update.sample" Ævar Arnfjörð Bjarmason
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-02 13:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Amend a test added in 96e7225b310 (hook: add 'run' subcommand,
2021-12-22) to use a for-loop instead of a copy/pasting the same test
for the four exit codes we test.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1800-hook.sh | 35 ++++++++++-------------------------
 1 file changed, 10 insertions(+), 25 deletions(-)

diff --git a/t/t1800-hook.sh b/t/t1800-hook.sh
index 29718aa9913..ff64597e959 100755
--- a/t/t1800-hook.sh
+++ b/t/t1800-hook.sh
@@ -53,31 +53,16 @@ test_expect_success 'git hook run: stdout and stderr both write to our stderr' '
 	test_must_be_empty stdout.actual
 '
 
-test_expect_success 'git hook run: exit codes are passed along' '
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 1
-	EOF
-
-	test_expect_code 1 git hook run test-hook &&
-
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 2
-	EOF
-
-	test_expect_code 2 git hook run test-hook &&
-
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 128
-	EOF
-
-	test_expect_code 128 git hook run test-hook &&
-
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 129
-	EOF
-
-	test_expect_code 129 git hook run test-hook
-'
+for code in 1 2 128 129
+do
+	test_expect_success "git hook run: exit code $code is passed along" '
+		write_script .git/hooks/test-hook <<-EOF &&
+		exit $code
+		EOF
+
+		test_expect_code $code git hook run test-hook
+	'
+done
 
 test_expect_success 'git hook run arg u ments without -- is not allowed' '
 	test_expect_code 129 git hook run test-hook arg u ments
-- 
2.35.1.1228.g56895c6ee86


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 02/10] t5540: don't rely on "hook/post-update.sample"
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
  2022-03-02 13:22 ` [PATCH 01/10] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
@ 2022-03-02 13:22 ` Ævar Arnfjörð Bjarmason
  2022-03-02 21:06   ` Junio C Hamano
  2022-03-02 13:22 ` [PATCH 03/10] tests: assume the hooks are disabled by default Ævar Arnfjörð Bjarmason
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-02 13:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change code added in a87679339c0 (test: rename http fetch and push
test files, 2014-02-06) to stop relying on the "exec git
update-server-info" in "templates/hooks--post-update.sample", let's
instead inline the expected hook in the test itself.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5540-http-push-webdav.sh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/t/t5540-http-push-webdav.sh b/t/t5540-http-push-webdav.sh
index b0dbacf0b9b..380e97c1762 100755
--- a/t/t5540-http-push-webdav.sh
+++ b/t/t5540-http-push-webdav.sh
@@ -42,7 +42,9 @@ test_expect_success 'setup remote repository' '
 	git clone --bare test_repo test_repo.git &&
 	cd test_repo.git &&
 	git --bare update-server-info &&
-	mv hooks/post-update.sample hooks/post-update &&
+	write_script hooks/post-update <<-\EOF &&
+	exec git update-server-info
+	EOF
 	ORIG_HEAD=$(git rev-parse --verify HEAD) &&
 	cd - &&
 	mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH"
-- 
2.35.1.1228.g56895c6ee86


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 03/10] tests: assume the hooks are disabled by default
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
  2022-03-02 13:22 ` [PATCH 01/10] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
  2022-03-02 13:22 ` [PATCH 02/10] t5540: don't rely on "hook/post-update.sample" Ævar Arnfjörð Bjarmason
@ 2022-03-02 13:22 ` Ævar Arnfjörð Bjarmason
  2022-03-02 21:13   ` Junio C Hamano
  2022-03-02 13:22 ` [PATCH 04/10] bugreport tests: tighten up "git bugreport -s hooks" test Ævar Arnfjörð Bjarmason
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-02 13:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Stop moving the .git/hooks directory out of the way, or creating it
during test setup. Instead assume that it will contain
harmless *.sample files.

That we can assume that is discussed in point #4 of
f0d4d398e28 (test-lib: split up and deprecate test_create_repo(),
2021-05-10).

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1416-ref-transaction-hooks.sh | 1 -
 t/t5516-fetch-push.sh            | 3 +--
 t/t7519-status-fsmonitor.sh      | 2 --
 3 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh
index 4e1e84a91f3..d21dd5e5df0 100755
--- a/t/t1416-ref-transaction-hooks.sh
+++ b/t/t1416-ref-transaction-hooks.sh
@@ -8,7 +8,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 . ./test-lib.sh
 
 test_expect_success setup '
-	mkdir -p .git/hooks &&
 	test_commit PRE &&
 	PRE_OID=$(git rev-parse PRE) &&
 	test_commit POST &&
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 3137eb8d4d2..1a20e54adc1 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -28,8 +28,7 @@ mk_empty () {
 	(
 		cd "$repo_name" &&
 		git init &&
-		git config receive.denyCurrentBranch warn &&
-		mv .git/hooks .git/hooks-disabled
+		git config receive.denyCurrentBranch warn
 	)
 }
 
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index a6308acf006..63a0f609866 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -56,7 +56,6 @@ test_lazy_prereq UNTRACKED_CACHE '
 '
 
 test_expect_success 'setup' '
-	mkdir -p .git/hooks &&
 	: >tracked &&
 	: >modified &&
 	mkdir dir1 &&
@@ -322,7 +321,6 @@ test_expect_success UNTRACKED_CACHE 'ignore .git changes when invalidating UNTR'
 	test_create_repo dot-git &&
 	(
 		cd dot-git &&
-		mkdir -p .git/hooks &&
 		: >tracked &&
 		: >modified &&
 		mkdir dir1 &&
-- 
2.35.1.1228.g56895c6ee86


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 04/10] bugreport tests: tighten up "git bugreport -s hooks" test
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
                   ` (2 preceding siblings ...)
  2022-03-02 13:22 ` [PATCH 03/10] tests: assume the hooks are disabled by default Ævar Arnfjörð Bjarmason
@ 2022-03-02 13:22 ` Ævar Arnfjörð Bjarmason
  2022-03-02 21:22   ` Junio C Hamano
  2022-03-02 13:22 ` [PATCH 05/10] tests: indent and add hook setup to "test_expect_success" Ævar Arnfjörð Bjarmason
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-02 13:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Amend a test added in 788a776069b (bugreport: collect list of
populated hooks, 2020-05-07) to make more sense. As noted in a
preceding commit our .git/hooks directory already contains *.sample
hooks, so we have no need to clobber the prepare-commit-msg.sample
hook in particular.

Instead we should assert that those *.sample hooks are not included in
the output, and for good measure let's add a new "unknown-hook", to
check that we only look through our own known hooks. See
cfe853e66be (hook-list.h: add a generated list of hooks, like
config-list.h, 2021-09-26) for how we generate that data.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0091-bugreport.sh | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh
index eeedbfa9193..3025e685aaa 100755
--- a/t/t0091-bugreport.sh
+++ b/t/t0091-bugreport.sh
@@ -60,18 +60,18 @@ test_expect_success 'can create leading directories outside of a git dir' '
 
 test_expect_success 'indicates populated hooks' '
 	test_when_finished rm git-bugreport-hooks.txt &&
-	test_when_finished rm -fr .git/hooks &&
-	rm -fr .git/hooks &&
-	mkdir .git/hooks &&
-	for hook in applypatch-msg prepare-commit-msg.sample
-	do
-		write_script ".git/hooks/$hook" <<-EOF || return 1
-		echo "hook $hook exists"
-		EOF
-	done &&
+
+	write_script .git/hooks/applypatch-msg <<-\EOF &&
+	true
+	EOF
+	write_script .git/hooks/unknown-hook <<-\EOF &&
+	true
+	EOF
 	git bugreport -s hooks &&
+
 	grep applypatch-msg git-bugreport-hooks.txt &&
-	! grep prepare-commit-msg git-bugreport-hooks.txt
+	! grep unknown-hook git-bugreport-hooks.txt &&
+	! grep -F .sample git-bugreport-hooks.txt
 '
 
 test_done
-- 
2.35.1.1228.g56895c6ee86


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 05/10] tests: indent and add hook setup to "test_expect_success"
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
                   ` (3 preceding siblings ...)
  2022-03-02 13:22 ` [PATCH 04/10] bugreport tests: tighten up "git bugreport -s hooks" test Ævar Arnfjörð Bjarmason
@ 2022-03-02 13:22 ` Ævar Arnfjörð Bjarmason
  2022-03-02 21:27   ` Junio C Hamano
  2022-03-02 13:22 ` [PATCH 06/10] hook tests: get rid of unnecessary sub-shells Ævar Arnfjörð Bjarmason
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-02 13:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Indent various hook setup code in the test suite that's using a manual
"cat && chmod" pattern.

These should also consistently use "#!$SHELL_PATH" instead of
"#!/bin/sh", i.e. "test_script". Let's fix that in a subsequent
commit, which will be easier to review after this smaller change.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3412-rebase-root.sh       | 16 ++++----
 t/t3413-rebase-hook.sh       | 16 ++++----
 t/t5401-update-hooks.sh      | 76 ++++++++++++++++++------------------
 t/t5407-post-rewrite-hook.sh | 16 ++++----
 t/t5541-http-push-smart.sh   | 24 ++++++------
 5 files changed, 75 insertions(+), 73 deletions(-)

diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
index 1e9f7833dd6..239a9343d34 100755
--- a/t/t3412-rebase-root.sh
+++ b/t/t3412-rebase-root.sh
@@ -32,10 +32,10 @@ test_expect_success 'rebase --root fails with too many args' '
 
 test_expect_success 'setup pre-rebase hook' '
 	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-echo "\$1,\$2" >.git/PRE-REBASE-INPUT
-EOF
+	cat >.git/hooks/pre-rebase <<-EOF &&
+	#!$SHELL_PATH
+	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+	EOF
 	chmod +x .git/hooks/pre-rebase
 '
 cat > expect <<EOF
@@ -142,10 +142,10 @@ EOF
 
 test_expect_success 'setup pre-rebase hook that fails' '
 	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-false
-EOF
+	cat >.git/hooks/pre-rebase <<-EOF &&
+	#!$SHELL_PATH
+	false
+	EOF
 	chmod +x .git/hooks/pre-rebase
 '
 
diff --git a/t/t3413-rebase-hook.sh b/t/t3413-rebase-hook.sh
index b4acb3be5cf..bb241b26b2e 100755
--- a/t/t3413-rebase-hook.sh
+++ b/t/t3413-rebase-hook.sh
@@ -42,10 +42,10 @@ test_expect_success 'rebase -i' '
 
 test_expect_success 'setup pre-rebase hook' '
 	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-echo "\$1,\$2" >.git/PRE-REBASE-INPUT
-EOF
+	cat >.git/hooks/pre-rebase <<-EOF &&
+	#!$SHELL_PATH
+	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+	EOF
 	chmod +x .git/hooks/pre-rebase
 '
 
@@ -103,10 +103,10 @@ test_expect_success 'pre-rebase hook gets correct input (6)' '
 
 test_expect_success 'setup pre-rebase hook that fails' '
 	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-false
-EOF
+	cat >.git/hooks/pre-rebase <<-EOF &&
+	#!$SHELL_PATH
+	false
+	EOF
 	chmod +x .git/hooks/pre-rebase
 '
 
diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
index 6012cc8172a..6392f71795d 100755
--- a/t/t5401-update-hooks.sh
+++ b/t/t5401-update-hooks.sh
@@ -20,46 +20,46 @@ test_expect_success setup '
 	git clone --bare ./. victim.git &&
 	GIT_DIR=victim.git git update-ref refs/heads/tofail $commit1 &&
 	git update-ref refs/heads/main $commit1 &&
-	git update-ref refs/heads/tofail $commit0
+	git update-ref refs/heads/tofail $commit0 &&
+
+	cat >victim.git/hooks/pre-receive <<-\EOF &&
+	#!/bin/sh
+	printf %s "$@" >>$GIT_DIR/pre-receive.args
+	cat - >$GIT_DIR/pre-receive.stdin
+	echo STDOUT pre-receive
+	echo STDERR pre-receive >&2
+	EOF
+	chmod u+x victim.git/hooks/pre-receive &&
+
+	cat >victim.git/hooks/update <<-\EOF &&
+	#!/bin/sh
+	echo "$@" >>$GIT_DIR/update.args
+	read x; printf %s "$x" >$GIT_DIR/update.stdin
+	echo STDOUT update $1
+	echo STDERR update $1 >&2
+	test "$1" = refs/heads/main || exit
+	EOF
+	chmod u+x victim.git/hooks/update &&
+
+	cat >victim.git/hooks/post-receive <<-\EOF &&
+	#!/bin/sh
+	printf %s "$@" >>$GIT_DIR/post-receive.args
+	cat - >$GIT_DIR/post-receive.stdin
+	echo STDOUT post-receive
+	echo STDERR post-receive >&2
+	EOF
+	chmod u+x victim.git/hooks/post-receive &&
+
+	cat >victim.git/hooks/post-update <<-\EOF &&
+	#!/bin/sh
+	echo "$@" >>$GIT_DIR/post-update.args
+	read x; printf %s "$x" >$GIT_DIR/post-update.stdin
+	echo STDOUT post-update
+	echo STDERR post-update >&2
+	EOF
+	chmod u+x victim.git/hooks/post-update
 '
 
-cat >victim.git/hooks/pre-receive <<'EOF'
-#!/bin/sh
-printf %s "$@" >>$GIT_DIR/pre-receive.args
-cat - >$GIT_DIR/pre-receive.stdin
-echo STDOUT pre-receive
-echo STDERR pre-receive >&2
-EOF
-chmod u+x victim.git/hooks/pre-receive
-
-cat >victim.git/hooks/update <<'EOF'
-#!/bin/sh
-echo "$@" >>$GIT_DIR/update.args
-read x; printf %s "$x" >$GIT_DIR/update.stdin
-echo STDOUT update $1
-echo STDERR update $1 >&2
-test "$1" = refs/heads/main || exit
-EOF
-chmod u+x victim.git/hooks/update
-
-cat >victim.git/hooks/post-receive <<'EOF'
-#!/bin/sh
-printf %s "$@" >>$GIT_DIR/post-receive.args
-cat - >$GIT_DIR/post-receive.stdin
-echo STDOUT post-receive
-echo STDERR post-receive >&2
-EOF
-chmod u+x victim.git/hooks/post-receive
-
-cat >victim.git/hooks/post-update <<'EOF'
-#!/bin/sh
-echo "$@" >>$GIT_DIR/post-update.args
-read x; printf %s "$x" >$GIT_DIR/post-update.stdin
-echo STDOUT post-update
-echo STDERR post-update >&2
-EOF
-chmod u+x victim.git/hooks/post-update
-
 test_expect_success push '
 	test_must_fail git send-pack --force ./victim.git \
 		main tofail >send.out 2>send.err
diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
index 6da8d760e28..64f40ff7776 100755
--- a/t/t5407-post-rewrite-hook.sh
+++ b/t/t5407-post-rewrite-hook.sh
@@ -17,15 +17,15 @@ test_expect_success 'setup' '
 	git checkout A^0 &&
 	test_commit E bar E &&
 	test_commit F foo F &&
-	git checkout main
-'
+	git checkout main &&
 
-cat >.git/hooks/post-rewrite <<EOF
-#!/bin/sh
-echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
-cat > "$TRASH_DIRECTORY"/post-rewrite.data
-EOF
-chmod u+x .git/hooks/post-rewrite
+	cat >.git/hooks/post-rewrite <<-EOF &&
+	#!/bin/sh
+	echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
+	cat > "$TRASH_DIRECTORY"/post-rewrite.data
+	EOF
+	chmod u+x .git/hooks/post-rewrite
+'
 
 clear_hook_input () {
 	rm -f post-rewrite.args post-rewrite.data
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index 8ca50f8b18c..0043b718f08 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -96,18 +96,20 @@ test_expect_success 'create and delete remote branch' '
 	test_must_fail git show-ref --verify refs/remotes/origin/dev
 '
 
-cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<EOF
-#!/bin/sh
-exit 1
-EOF
-chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update"
+test_expect_success 'setup rejected update hook' '
+	cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<-EOF &&
+	#!/bin/sh
+	exit 1
+	EOF
+	chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" &&
 
-cat >exp <<EOF
-remote: error: hook declined to update refs/heads/dev2
-To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git
- ! [remote rejected] dev2 -> dev2 (hook declined)
-error: failed to push some refs to 'http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'
-EOF
+	cat >exp <<-EOF
+	remote: error: hook declined to update refs/heads/dev2
+	To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git
+	 ! [remote rejected] dev2 -> dev2 (hook declined)
+	error: failed to push some refs to '\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\''
+	EOF
+'
 
 test_expect_success 'rejected update prints status' '
 	cd "$ROOT_PATH"/test_repo_clone &&
-- 
2.35.1.1228.g56895c6ee86


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 06/10] hook tests: get rid of unnecessary sub-shells
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
                   ` (4 preceding siblings ...)
  2022-03-02 13:22 ` [PATCH 05/10] tests: indent and add hook setup to "test_expect_success" Ævar Arnfjörð Bjarmason
@ 2022-03-02 13:22 ` Ævar Arnfjörð Bjarmason
  2022-03-02 21:31   ` Junio C Hamano
  2022-03-02 13:22 ` [PATCH 07/10] fetch+push tests: have tests clean up their own mess Ævar Arnfjörð Bjarmason
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-02 13:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Refactor the repository setup code for tests that test hooks the use
of sub-shells when setting up the test repository and hooks.

A subsequent commit will change the hook setup to use a helper that
makes use of "test_when_finished", which cannot be used in
sub-shells. Let's change that setup code, and the adjacent and similar
"mk_empty" code.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5516-fetch-push.sh   | 150 ++++++++++++++++++----------------------
 t/t6500-gc.sh           |  18 ++---
 t/t9800-git-p4-basic.sh |  24 ++++---
 3 files changed, 94 insertions(+), 98 deletions(-)

diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 1a20e54adc1..e4bb7581568 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -24,12 +24,8 @@ D=$(pwd)
 mk_empty () {
 	repo_name="$1"
 	rm -fr "$repo_name" &&
-	mkdir "$repo_name" &&
-	(
-		cd "$repo_name" &&
-		git init &&
-		git config receive.denyCurrentBranch warn
-	)
+	git init "$repo_name" &&
+	git -C "$repo_name" config receive.denyCurrentBranch warn
 }
 
 mk_test () {
@@ -58,36 +54,35 @@ mk_test () {
 mk_test_with_hooks() {
 	repo_name=$1
 	mk_test "$@" &&
-	(
-		cd "$repo_name" &&
-		mkdir .git/hooks &&
-		cd .git/hooks &&
-
-		cat >pre-receive <<-'EOF' &&
-		#!/bin/sh
-		cat - >>pre-receive.actual
-		EOF
 
-		cat >update <<-'EOF' &&
-		#!/bin/sh
-		printf "%s %s %s\n" "$@" >>update.actual
-		EOF
-
-		cat >post-receive <<-'EOF' &&
-		#!/bin/sh
-		cat - >>post-receive.actual
-		EOF
-
-		cat >post-update <<-'EOF' &&
-		#!/bin/sh
-		for ref in "$@"
-		do
-			printf "%s\n" "$ref" >>post-update.actual
-		done
-		EOF
-
-		chmod +x pre-receive update post-receive post-update
-	)
+	cat >"$repo_name"/.git/hooks/pre-receive <<-'EOF' &&
+	#!/bin/sh
+	cat - >>pre-receive.actual
+	EOF
+
+	cat >"$repo_name"/.git/hooks/update <<-'EOF' &&
+	#!/bin/sh
+	printf "%s %s %s\n" "$@" >>update.actual
+	EOF
+
+	cat >"$repo_name"/.git/hooks/post-receive <<-'EOF' &&
+	#!/bin/sh
+	cat - >>post-receive.actual
+	EOF
+
+	cat >"$repo_name"/.git/hooks/post-update <<-'EOF' &&
+	#!/bin/sh
+	for ref in "$@"
+	do
+		printf "%s\n" "$ref" >>post-update.actual
+	done
+	EOF
+
+	chmod +x \
+	      "$repo_name"/.git/hooks/pre-receive \
+	      "$repo_name"/.git/hooks/update \
+	      "$repo_name"/.git/hooks/post-receive \
+	      "$repo_name"/.git/hooks/post-update
 }
 
 mk_child() {
@@ -667,7 +662,6 @@ test_expect_success 'push does not update local refs on failure' '
 
 	mk_test testrepo heads/main &&
 	mk_child testrepo child &&
-	mkdir testrepo/.git/hooks &&
 	echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive &&
 	chmod +x testrepo/.git/hooks/pre-receive &&
 	(
@@ -1679,24 +1673,21 @@ test_expect_success 'receive.denyCurrentBranch = updateInstead' '
 test_expect_success 'updateInstead with push-to-checkout hook' '
 	rm -fr testrepo &&
 	git init testrepo &&
-	(
-		cd testrepo &&
-		git pull .. main &&
-		git reset --hard HEAD^^ &&
-		git tag initial &&
-		git config receive.denyCurrentBranch updateInstead &&
-		write_script .git/hooks/push-to-checkout <<-\EOF
-		echo >&2 updating from $(git rev-parse HEAD)
-		echo >&2 updating to "$1"
-
-		git update-index -q --refresh &&
-		git read-tree -u -m HEAD "$1" || {
-			status=$?
-			echo >&2 read-tree failed
-			exit $status
-		}
-		EOF
-	) &&
+	git -C testrepo pull .. main &&
+	git -C testrepo reset --hard HEAD^^ &&
+	git -C testrepo tag initial &&
+	git -C testrepo config receive.denyCurrentBranch updateInstead &&
+	write_script testrepo/.git/hooks/push-to-checkout <<-\EOF &&
+	echo >&2 updating from $(git rev-parse HEAD)
+	echo >&2 updating to "$1"
+
+	git update-index -q --refresh &&
+	git read-tree -u -m HEAD "$1" || {
+		status=$?
+		echo >&2 read-tree failed
+		exit $status
+	}
+	EOF
 
 	# Try pushing into a pristine
 	git push testrepo main &&
@@ -1741,33 +1732,30 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
 	# push into void
 	rm -fr void &&
 	git init void &&
-	(
-		cd void &&
-		git config receive.denyCurrentBranch updateInstead &&
-		write_script .git/hooks/push-to-checkout <<-\EOF
-		if git rev-parse --quiet --verify HEAD
-		then
-			has_head=yes
-			echo >&2 updating from $(git rev-parse HEAD)
-		else
-			has_head=no
-			echo >&2 pushing into void
-		fi
-		echo >&2 updating to "$1"
-
-		git update-index -q --refresh &&
-		case "$has_head" in
-		yes)
-			git read-tree -u -m HEAD "$1" ;;
-		no)
-			git read-tree -u -m "$1" ;;
-		esac || {
-			status=$?
-			echo >&2 read-tree failed
-			exit $status
-		}
-		EOF
-	) &&
+	git -C void config receive.denyCurrentBranch updateInstead &&
+	write_script void/.git/hooks/push-to-checkout <<-\EOF &&
+	if git rev-parse --quiet --verify HEAD
+	then
+		has_head=yes
+		echo >&2 updating from $(git rev-parse HEAD)
+	else
+		has_head=no
+		echo >&2 pushing into void
+	fi
+	echo >&2 updating to "$1"
+
+	git update-index -q --refresh &&
+	case "$has_head" in
+	yes)
+		git read-tree -u -m HEAD "$1" ;;
+	no)
+		git read-tree -u -m "$1" ;;
+	esac || {
+		status=$?
+		echo >&2 read-tree failed
+		exit $status
+	}
+	EOF
 
 	git push void main &&
 	(
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index c2021267f2c..a6b0db22867 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -101,12 +101,12 @@ test_expect_success 'pre-auto-gc hook can stop auto gc' '
 	EOF
 
 	git init pre-auto-gc-hook &&
+	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
+	echo >&2 no gc for you &&
+	exit 1
+	EOF
 	(
 		cd pre-auto-gc-hook &&
-		write_script ".git/hooks/pre-auto-gc" <<-\EOF &&
-		echo >&2 no gc for you &&
-		exit 1
-		EOF
 
 		git config gc.auto 3 &&
 		git config gc.autoDetach false &&
@@ -128,12 +128,14 @@ test_expect_success 'pre-auto-gc hook can stop auto gc' '
 	See "git help gc" for manual housekeeping.
 	EOF
 
+	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
+	echo >&2 will gc for you &&
+	exit 0
+	EOF
+
 	(
 		cd pre-auto-gc-hook &&
-		write_script ".git/hooks/pre-auto-gc" <<-\EOF &&
-		echo >&2 will gc for you &&
-		exit 0
-		EOF
+
 		git gc --auto >../out.actual 2>../err.actual
 	) &&
 
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index 806005a793a..3c1534c94d6 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -277,16 +277,22 @@ test_expect_success 'run hook p4-pre-submit before submit' '
 		git commit -m "add hello.txt" &&
 		git config git-p4.skipSubmitEdit true &&
 		git p4 submit --dry-run >out &&
-		grep "Would apply" out &&
-		mkdir -p .git/hooks &&
-		write_script .git/hooks/p4-pre-submit <<-\EOF &&
-		exit 0
-		EOF
+		grep "Would apply" out
+	) &&
+	mkdir -p "$git"/.git/hooks &&
+	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
+	exit 0
+	EOF
+	(
+		cd "$git" &&
 		git p4 submit --dry-run >out &&
-		grep "Would apply" out &&
-		write_script .git/hooks/p4-pre-submit <<-\EOF &&
-		exit 1
-		EOF
+		grep "Would apply" out
+	) &&
+	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
+	exit 1
+	EOF
+	(
+		cd "$git" &&
 		test_must_fail git p4 submit --dry-run >errs 2>&1 &&
 		! grep "Would apply" errs
 	)
-- 
2.35.1.1228.g56895c6ee86


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 07/10] fetch+push tests: have tests clean up their own mess
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
                   ` (5 preceding siblings ...)
  2022-03-02 13:22 ` [PATCH 06/10] hook tests: get rid of unnecessary sub-shells Ævar Arnfjörð Bjarmason
@ 2022-03-02 13:22 ` Ævar Arnfjörð Bjarmason
  2022-03-02 21:44   ` Junio C Hamano
  2022-03-02 13:22 ` [PATCH 08/10] test-lib-functions: add and use a "test_hook" wrapper Ævar Arnfjörð Bjarmason
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-02 13:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change the "t5516-fetch-push.sh" test code to make use of
"test_when_finished" to remove data instead of having tests clean up
leftover data from earlier tests, which may or may not be
there (e.g. depending on the --run=* option).

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5516-fetch-push.sh | 50 +++++++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index e4bb7581568..fbe0a72b0b2 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -23,7 +23,8 @@ D=$(pwd)
 
 mk_empty () {
 	repo_name="$1"
-	rm -fr "$repo_name" &&
+	test_when_finished "rm -rf \"$repo_name\"" &&
+	test_path_is_missing "$repo_name" &&
 	git init "$repo_name" &&
 	git -C "$repo_name" config receive.denyCurrentBranch warn
 }
@@ -86,7 +87,7 @@ mk_test_with_hooks() {
 }
 
 mk_child() {
-	rm -rf "$2" &&
+	test_when_finished "rm -rf \"$2\"" &&
 	git clone "$1" "$2"
 }
 
@@ -191,32 +192,32 @@ grep_wrote () {
 	grep 'write_pack_file/wrote.*"value":"'$1'"' $2
 }
 
-test_expect_success 'push with negotiation' '
-	# Without negotiation
+test_expect_success 'push without negotiation' '
 	mk_empty testrepo &&
 	git push testrepo $the_first_commit:refs/remotes/origin/first_commit &&
 	test_commit -C testrepo unrelated_commit &&
 	git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit &&
-	echo now pushing without negotiation &&
+	test_when_finished "rm event" &&
 	GIT_TRACE2_EVENT="$(pwd)/event" git -c protocol.version=2 push testrepo refs/heads/main:refs/remotes/origin/main &&
-	grep_wrote 5 event && # 2 commits, 2 trees, 1 blob
+	grep_wrote 5 event # 2 commits, 2 trees, 1 blob
+'
 
-	# Same commands, but with negotiation
-	rm event &&
+test_expect_success 'push with negotiation' '
 	mk_empty testrepo &&
 	git push testrepo $the_first_commit:refs/remotes/origin/first_commit &&
 	test_commit -C testrepo unrelated_commit &&
 	git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit &&
+	test_when_finished "rm event" &&
 	GIT_TRACE2_EVENT="$(pwd)/event" git -c protocol.version=2 -c push.negotiate=1 push testrepo refs/heads/main:refs/remotes/origin/main &&
 	grep_wrote 2 event # 1 commit, 1 tree
 '
 
 test_expect_success 'push with negotiation proceeds anyway even if negotiation fails' '
-	rm event &&
 	mk_empty testrepo &&
 	git push testrepo $the_first_commit:refs/remotes/origin/first_commit &&
 	test_commit -C testrepo unrelated_commit &&
 	git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit &&
+	test_when_finished "rm event" &&
 	GIT_TEST_PROTOCOL_VERSION=0 GIT_TRACE2_EVENT="$(pwd)/event" \
 		git -c push.negotiate=1 push testrepo refs/heads/main:refs/remotes/origin/main 2>err &&
 	grep_wrote 5 event && # 2 commits, 2 trees, 1 blob
@@ -1323,7 +1324,7 @@ done
 
 test_expect_success 'fetch follows tags by default' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
 	(
 		cd src &&
@@ -1333,6 +1334,7 @@ test_expect_success 'fetch follows tags by default' '
 		sed -n "p; s|refs/heads/main$|refs/remotes/origin/main|p" tmp1 |
 		sort -k 3 >../expect
 	) &&
+	test_when_finished "rm -rf dst" &&
 	git init dst &&
 	(
 		cd dst &&
@@ -1358,8 +1360,9 @@ test_expect_success 'peeled advertisements are not considered ref tips' '
 
 test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1382,8 +1385,9 @@ test_expect_success 'pushing a specific ref applies remote.$name.push as refmap'
 
 test_expect_success 'with no remote.$name.push, it is not used as refmap' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1404,8 +1408,9 @@ test_expect_success 'with no remote.$name.push, it is not used as refmap' '
 
 test_expect_success 'with no remote.$name.push, upstream mapping is used' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1433,8 +1438,9 @@ test_expect_success 'with no remote.$name.push, upstream mapping is used' '
 
 test_expect_success 'push does not follow tags by default' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1456,8 +1462,9 @@ test_expect_success 'push does not follow tags by default' '
 
 test_expect_success 'push --follow-tags only pushes relevant tags' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1495,9 +1502,9 @@ EOF
 '
 
 test_expect_success 'pushing a tag pushes the tagged object' '
-	rm -rf dst.git &&
 	blob=$(echo unreferenced | git hash-object -w --stdin) &&
 	git tag -m foo tag-of-blob $blob &&
+	test_when_finished "rm -rf dst.git" &&
 	git init --bare dst.git &&
 	git push dst.git tag-of-blob &&
 	# the receiving index-pack should have noticed
@@ -1508,7 +1515,7 @@ test_expect_success 'pushing a tag pushes the tagged object' '
 '
 
 test_expect_success 'push into bare respects core.logallrefupdates' '
-	rm -rf dst.git &&
+	test_when_finished "rm -rf dst.git" &&
 	git init --bare dst.git &&
 	git -C dst.git config core.logallrefupdates true &&
 
@@ -1526,7 +1533,7 @@ test_expect_success 'push into bare respects core.logallrefupdates' '
 '
 
 test_expect_success 'fetch into bare respects core.logallrefupdates' '
-	rm -rf dst.git &&
+	test_when_finished "rm -rf dst.git" &&
 	git init --bare dst.git &&
 	(
 		cd dst.git &&
@@ -1547,6 +1554,7 @@ test_expect_success 'fetch into bare respects core.logallrefupdates' '
 '
 
 test_expect_success 'receive.denyCurrentBranch = updateInstead' '
+	mk_empty testrepo &&
 	git push testrepo main &&
 	(
 		cd testrepo &&
@@ -1649,7 +1657,7 @@ test_expect_success 'receive.denyCurrentBranch = updateInstead' '
 	) &&
 
 	# (5) push into void
-	rm -fr void &&
+	test_when_finished "rm -rf void" &&
 	git init void &&
 	(
 		cd void &&
@@ -1671,7 +1679,7 @@ test_expect_success 'receive.denyCurrentBranch = updateInstead' '
 '
 
 test_expect_success 'updateInstead with push-to-checkout hook' '
-	rm -fr testrepo &&
+	test_when_finished "rm -rf testrepo" &&
 	git init testrepo &&
 	git -C testrepo pull .. main &&
 	git -C testrepo reset --hard HEAD^^ &&
@@ -1730,7 +1738,7 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
 	) &&
 
 	# push into void
-	rm -fr void &&
+	test_when_finished "rm -rf void" &&
 	git init void &&
 	git -C void config receive.denyCurrentBranch updateInstead &&
 	write_script void/.git/hooks/push-to-checkout <<-\EOF &&
-- 
2.35.1.1228.g56895c6ee86


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 08/10] test-lib-functions: add and use a "test_hook" wrapper
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
                   ` (6 preceding siblings ...)
  2022-03-02 13:22 ` [PATCH 07/10] fetch+push tests: have tests clean up their own mess Ævar Arnfjörð Bjarmason
@ 2022-03-02 13:22 ` Ævar Arnfjörð Bjarmason
  2022-03-02 21:59   ` Junio C Hamano
  2022-03-02 13:22 ` [PATCH 09/10] tests: change "mkdir -p && write_script" to use "test_hook" Ævar Arnfjörð Bjarmason
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-02 13:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Add a "test_hook" wrapper similar to the existing "test_config"
wrapper added in d960c47a881 (test-lib: add helper functions for
config, 2011-08-17).

This wrapper:

 - Will clean up the hook with "test_when_finished", unless --setup is
   provided.

 - Will error if we clobber a hook, unless --clobber is provided.

 - Takes a name like "update" instead of ".git/hooks/update".

 - Accepts -C <dir>, like "test_config" and "test_commit".

By using a wrapper we'll be able to easily change all the hook-related
code that assumes that the template-created ".git/hooks" directory is
created by "init", "clone" etc. once another topic follows-up and
changes the test suite to stop creating trash directories using those
templates.

In addition this will make it easy to have the hooks configured using
the "configuration-based hooks" topic, once we get around to
integrating that. I.e. we'll be able to run the tests in a mode where
we sometimes create a .git/hooks/<name>, and other times create a
script in another location, and point the relevant configuration
snippet to it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0091-bugreport.sh                |  4 +--
 t/t1416-ref-transaction-hooks.sh    | 26 +++++++--------
 t/t1800-hook.sh                     | 14 +++++---
 t/t5406-remote-rejects.sh           |  2 +-
 t/t5409-colorize-remote-messages.sh |  2 +-
 t/t5411-proc-receive-hook.sh        |  4 +--
 t/t5510-fetch.sh                    |  6 ++--
 t/t5516-fetch-push.sh               |  4 +--
 t/t5521-pull-options.sh             |  4 +--
 t/t5540-http-push-webdav.sh         |  2 +-
 t/t5547-push-quarantine.sh          |  4 +--
 t/t5548-push-porcelain.sh           |  2 +-
 t/t6500-gc.sh                       |  4 +--
 t/t7519-status-fsmonitor.sh         | 18 +++++-----
 t/test-lib-functions.sh             | 52 +++++++++++++++++++++++++++++
 15 files changed, 101 insertions(+), 47 deletions(-)

diff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh
index 3025e685aaa..e4701da26aa 100755
--- a/t/t0091-bugreport.sh
+++ b/t/t0091-bugreport.sh
@@ -61,10 +61,10 @@ test_expect_success 'can create leading directories outside of a git dir' '
 test_expect_success 'indicates populated hooks' '
 	test_when_finished rm git-bugreport-hooks.txt &&
 
-	write_script .git/hooks/applypatch-msg <<-\EOF &&
+	test_hook applypatch-msg <<-\EOF &&
 	true
 	EOF
-	write_script .git/hooks/unknown-hook <<-\EOF &&
+	test_hook unknown-hook <<-\EOF &&
 	true
 	EOF
 	git bugreport -s hooks &&
diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh
index d21dd5e5df0..085a7a46f21 100755
--- a/t/t1416-ref-transaction-hooks.sh
+++ b/t/t1416-ref-transaction-hooks.sh
@@ -15,9 +15,8 @@ test_expect_success setup '
 '
 
 test_expect_success 'hook allows updating ref if successful' '
-	test_when_finished "rm .git/hooks/reference-transaction" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		echo "$*" >>actual
 	EOF
 	cat >expect <<-EOF &&
@@ -29,9 +28,8 @@ test_expect_success 'hook allows updating ref if successful' '
 '
 
 test_expect_success 'hook aborts updating ref in prepared state' '
-	test_when_finished "rm .git/hooks/reference-transaction" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = prepared
 		then
 			exit 1
@@ -42,9 +40,9 @@ test_expect_success 'hook aborts updating ref in prepared state' '
 '
 
 test_expect_success 'hook gets all queued updates in prepared state' '
-	test_when_finished "rm .git/hooks/reference-transaction actual" &&
+	test_when_finished "rm actual" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = prepared
 		then
 			while read -r line
@@ -65,9 +63,9 @@ test_expect_success 'hook gets all queued updates in prepared state' '
 '
 
 test_expect_success 'hook gets all queued updates in committed state' '
-	test_when_finished "rm .git/hooks/reference-transaction actual" &&
+	test_when_finished "rm actual" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = committed
 		then
 			while read -r line
@@ -85,9 +83,9 @@ test_expect_success 'hook gets all queued updates in committed state' '
 '
 
 test_expect_success 'hook gets all queued updates in aborted state' '
-	test_when_finished "rm .git/hooks/reference-transaction actual" &&
+	test_when_finished "rm actual" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = aborted
 		then
 			while read -r line
@@ -114,11 +112,11 @@ test_expect_success 'interleaving hook calls succeed' '
 
 	git init --bare target-repo.git &&
 
-	write_script target-repo.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C target-repo.git reference-transaction <<-\EOF &&
 		echo $0 "$@" >>actual
 	EOF
 
-	write_script target-repo.git/hooks/update <<-\EOF &&
+	test_hook -C target-repo.git update <<-\EOF &&
 		echo $0 "$@" >>actual
 	EOF
 
@@ -139,7 +137,7 @@ test_expect_success 'hook does not get called on packing refs' '
 	# Pack references first such that we are in a known state.
 	git pack-refs --all &&
 
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		echo "$@" >>actual
 		cat >>actual
 	EOF
@@ -165,7 +163,7 @@ test_expect_success 'deleting packed ref calls hook once' '
 	git update-ref refs/heads/to-be-deleted $POST_OID &&
 	git pack-refs --all &&
 
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		echo "$@" >>actual
 		cat >>actual
 	EOF
diff --git a/t/t1800-hook.sh b/t/t1800-hook.sh
index ff64597e959..26ed5e11bc8 100755
--- a/t/t1800-hook.sh
+++ b/t/t1800-hook.sh
@@ -27,7 +27,7 @@ test_expect_success 'git hook run: nonexistent hook with --ignore-missing' '
 '
 
 test_expect_success 'git hook run: basic' '
-	write_script .git/hooks/test-hook <<-EOF &&
+	test_hook test-hook <<-EOF &&
 	echo Test hook
 	EOF
 
@@ -39,7 +39,7 @@ test_expect_success 'git hook run: basic' '
 '
 
 test_expect_success 'git hook run: stdout and stderr both write to our stderr' '
-	write_script .git/hooks/test-hook <<-EOF &&
+	test_hook test-hook <<-EOF &&
 	echo >&1 Will end up on stderr
 	echo >&2 Will end up on stderr
 	EOF
@@ -56,7 +56,7 @@ test_expect_success 'git hook run: stdout and stderr both write to our stderr' '
 for code in 1 2 128 129
 do
 	test_expect_success "git hook run: exit code $code is passed along" '
-		write_script .git/hooks/test-hook <<-EOF &&
+		test_hook test-hook <<-EOF &&
 		exit $code
 		EOF
 
@@ -69,7 +69,7 @@ test_expect_success 'git hook run arg u ments without -- is not allowed' '
 '
 
 test_expect_success 'git hook run -- pass arguments' '
-	write_script .git/hooks/test-hook <<-\EOF &&
+	test_hook test-hook <<-\EOF &&
 	echo $1
 	echo $2
 	EOF
@@ -84,7 +84,7 @@ test_expect_success 'git hook run -- pass arguments' '
 '
 
 test_expect_success 'git hook run -- out-of-repo runs excluded' '
-	write_script .git/hooks/test-hook <<-EOF &&
+	test_hook test-hook <<-EOF &&
 	echo Test hook
 	EOF
 
@@ -105,6 +105,10 @@ test_expect_success 'git -c core.hooksPath=<PATH> hook run' '
 	Hook ran four
 	EOF
 
+	test_hook test-hook <<-EOF &&
+	echo Test hook
+	EOF
+
 	# Test various ways of specifying the path. See also
 	# t1350-config-hooks-path.sh
 	>actual &&
diff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh
index 5c509db6fc3..dcbeb420827 100755
--- a/t/t5406-remote-rejects.sh
+++ b/t/t5406-remote-rejects.sh
@@ -5,7 +5,7 @@ test_description='remote push rejects are reported by client'
 . ./test-lib.sh
 
 test_expect_success 'setup' '
-	write_script .git/hooks/update <<-\EOF &&
+	test_hook update <<-\EOF &&
 	exit 1
 	EOF
 	echo 1 >file &&
diff --git a/t/t5409-colorize-remote-messages.sh b/t/t5409-colorize-remote-messages.sh
index 9f1a483f426..fa5de4500a4 100755
--- a/t/t5409-colorize-remote-messages.sh
+++ b/t/t5409-colorize-remote-messages.sh
@@ -5,7 +5,7 @@ test_description='remote messages are colorized on the client'
 . ./test-lib.sh
 
 test_expect_success 'setup' '
-	write_script .git/hooks/update <<-\EOF &&
+	test_hook --setup update <<-\EOF &&
 	echo error: error
 	echo ERROR: also highlighted
 	echo hint: hint
diff --git a/t/t5411-proc-receive-hook.sh b/t/t5411-proc-receive-hook.sh
index 98b0e812082..92cf52c6d4a 100755
--- a/t/t5411-proc-receive-hook.sh
+++ b/t/t5411-proc-receive-hook.sh
@@ -36,7 +36,7 @@ setup_upstream_and_workbench () {
 		TAG=$(git -C workbench rev-parse v123) &&
 
 		# setup pre-receive hook
-		write_script upstream.git/hooks/pre-receive <<-\EOF &&
+		test_hook --setup -C upstream.git pre-receive <<-\EOF &&
 		exec >&2
 		echo "# pre-receive hook"
 		while read old new ref
@@ -46,7 +46,7 @@ setup_upstream_and_workbench () {
 		EOF
 
 		# setup post-receive hook
-		write_script upstream.git/hooks/post-receive <<-\EOF &&
+		test_hook --setup -C upstream.git post-receive <<-\EOF &&
 		exec >&2
 		echo "# post-receive hook"
 		while read old new ref
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index ef0da0a63b5..4620f0ca7fa 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -273,7 +273,7 @@ test_expect_success 'fetch --atomic executes a single reference transaction only
 	EOF
 
 	rm -f atomic/actual &&
-	write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C atomic reference-transaction <<-\EOF &&
 		( echo "$*" && cat ) >>actual
 	EOF
 
@@ -306,7 +306,7 @@ test_expect_success 'fetch --atomic aborts all reference updates if hook aborts'
 	EOF
 
 	rm -f atomic/actual &&
-	write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C atomic/.git reference-transaction <<-\EOF &&
 		( echo "$*" && cat ) >>actual
 		exit 1
 	EOF
@@ -334,7 +334,7 @@ test_expect_success 'fetch --atomic --append appends to FETCH_HEAD' '
 	test_line_count = 2 atomic/.git/FETCH_HEAD &&
 	cp atomic/.git/FETCH_HEAD expected &&
 
-	write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C atomic reference-transaction <<-\EOF &&
 		exit 1
 	EOF
 
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index fbe0a72b0b2..b689baf01a9 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1685,7 +1685,7 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
 	git -C testrepo reset --hard HEAD^^ &&
 	git -C testrepo tag initial &&
 	git -C testrepo config receive.denyCurrentBranch updateInstead &&
-	write_script testrepo/.git/hooks/push-to-checkout <<-\EOF &&
+	test_hook -C testrepo push-to-checkout <<-\EOF &&
 	echo >&2 updating from $(git rev-parse HEAD)
 	echo >&2 updating to "$1"
 
@@ -1741,7 +1741,7 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
 	test_when_finished "rm -rf void" &&
 	git init void &&
 	git -C void config receive.denyCurrentBranch updateInstead &&
-	write_script void/.git/hooks/push-to-checkout <<-\EOF &&
+	test_hook -C void push-to-checkout <<-\EOF &&
 	if git rev-parse --quiet --verify HEAD
 	then
 		has_head=yes
diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh
index 66cfcb09c55..264de29c35c 100755
--- a/t/t5521-pull-options.sh
+++ b/t/t5521-pull-options.sh
@@ -233,7 +233,7 @@ test_expect_success 'git pull --no-verify flag passed to merge' '
 	git init src &&
 	test_commit -C src one &&
 	git clone src dst &&
-	write_script dst/.git/hooks/commit-msg <<-\EOF &&
+	test_hook -C dst commit-msg <<-\EOF &&
 	false
 	EOF
 	test_commit -C src two &&
@@ -245,7 +245,7 @@ test_expect_success 'git pull --no-verify --verify passed to merge' '
 	git init src &&
 	test_commit -C src one &&
 	git clone src dst &&
-	write_script dst/.git/hooks/commit-msg <<-\EOF &&
+	test_hook -C dst commit-msg <<-\EOF &&
 	false
 	EOF
 	test_commit -C src two &&
diff --git a/t/t5540-http-push-webdav.sh b/t/t5540-http-push-webdav.sh
index 380e97c1762..37db3dec0c5 100755
--- a/t/t5540-http-push-webdav.sh
+++ b/t/t5540-http-push-webdav.sh
@@ -42,7 +42,7 @@ test_expect_success 'setup remote repository' '
 	git clone --bare test_repo test_repo.git &&
 	cd test_repo.git &&
 	git --bare update-server-info &&
-	write_script hooks/post-update <<-\EOF &&
+	test_hook --setup post-update <<-\EOF &&
 	exec git update-server-info
 	EOF
 	ORIG_HEAD=$(git rev-parse --verify HEAD) &&
diff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh
index faaa51ccc56..1876fb34e51 100755
--- a/t/t5547-push-quarantine.sh
+++ b/t/t5547-push-quarantine.sh
@@ -5,7 +5,7 @@ test_description='check quarantine of objects during push'
 
 test_expect_success 'create picky dest repo' '
 	git init --bare dest.git &&
-	write_script dest.git/hooks/pre-receive <<-\EOF
+	test_hook --setup -C dest.git pre-receive <<-\EOF
 	while read old new ref; do
 		test "$(git log -1 --format=%s $new)" = reject && exit 1
 	done
@@ -60,7 +60,7 @@ test_expect_success 'push to repo path with path separator (colon)' '
 
 test_expect_success 'updating a ref from quarantine is forbidden' '
 	git init --bare update.git &&
-	write_script update.git/hooks/pre-receive <<-\EOF &&
+	test_hook -C update.git pre-receive <<-\EOF &&
 	read old new refname
 	git update-ref refs/heads/unrelated $new
 	exit 1
diff --git a/t/t5548-push-porcelain.sh b/t/t5548-push-porcelain.sh
index f11ff57e549..6282728eaf3 100755
--- a/t/t5548-push-porcelain.sh
+++ b/t/t5548-push-porcelain.sh
@@ -168,7 +168,7 @@ run_git_push_porcelain_output_test() {
 	'
 
 	test_expect_success "prepare pre-receive hook ($PROTOCOL)" '
-		write_script "$upstream/hooks/pre-receive" <<-EOF
+		test_hook --setup -C "$upstream" pre-receive <<-EOF
 		exit 1
 		EOF
 	'
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index a6b0db22867..39871b9901e 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -101,7 +101,7 @@ test_expect_success 'pre-auto-gc hook can stop auto gc' '
 	EOF
 
 	git init pre-auto-gc-hook &&
-	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
+	test_hook -C pre-auto-gc-hook pre-auto-gc <<-\EOF &&
 	echo >&2 no gc for you &&
 	exit 1
 	EOF
@@ -128,7 +128,7 @@ test_expect_success 'pre-auto-gc hook can stop auto gc' '
 	See "git help gc" for manual housekeeping.
 	EOF
 
-	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
+	test_hook -C pre-auto-gc-hook --clobber pre-auto-gc <<-\EOF &&
 	echo >&2 will gc for you &&
 	exit 0
 	EOF
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index 63a0f609866..d8b0fc4681c 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -26,7 +26,7 @@ dirty_repo () {
 }
 
 write_integration_script () {
-	write_script .git/hooks/fsmonitor-test<<-\EOF
+	test_hook --setup --clobber fsmonitor-test<<-\EOF
 	if test "$#" -ne 2
 	then
 		echo "$0: exactly 2 arguments expected"
@@ -107,7 +107,7 @@ EOF
 
 # test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit
 test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' '
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook fsmonitor-test<<-\EOF &&
 		printf "last_update_token\0"
 	EOF
 	git update-index --fsmonitor &&
@@ -168,7 +168,7 @@ EOF
 
 # test that newly added files are marked valid
 test_expect_success 'newly added files are marked valid' '
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook --setup --clobber fsmonitor-test<<-\EOF &&
 		printf "last_update_token\0"
 	EOF
 	git add new &&
@@ -209,7 +209,7 @@ EOF
 
 # test that *only* files returned by the integration script get flagged as invalid
 test_expect_success '*only* files returned by the integration script get flagged as invalid' '
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook --clobber fsmonitor-test<<-\EOF &&
 	printf "last_update_token\0"
 	printf "dir1/modified\0"
 	EOF
@@ -230,7 +230,7 @@ test_expect_success 'refresh_index() invalidates fsmonitor cache' '
 	dirty_repo &&
 	write_integration_script &&
 	git add . &&
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook --clobber fsmonitor-test<<-\EOF &&
 	EOF
 	git commit -m "to reset" &&
 	git reset HEAD~1 &&
@@ -279,7 +279,7 @@ do
 		# Make sure it's actually skipping the check for modified and untracked
 		# (if enabled) files unless it is told about them.
 		test_expect_success "status doesn't detect unreported modifications" '
-			write_script .git/hooks/fsmonitor-test<<-\EOF &&
+			test_hook --clobber fsmonitor-test<<-\EOF &&
 			printf "last_update_token\0"
 			:>marker
 			EOF
@@ -405,14 +405,14 @@ test_expect_success 'status succeeds with sparse index' '
 		git -C sparse sparse-checkout init --cone --sparse-index &&
 		git -C sparse sparse-checkout set dir1 dir2 &&
 
-		write_script .git/hooks/fsmonitor-test <<-\EOF &&
+		test_hook --clobber fsmonitor-test <<-\EOF &&
 			printf "last_update_token\0"
 		EOF
 		git -C full config core.fsmonitor ../.git/hooks/fsmonitor-test &&
 		git -C sparse config core.fsmonitor ../.git/hooks/fsmonitor-test &&
 		check_sparse_index_behavior ! &&
 
-		write_script .git/hooks/fsmonitor-test <<-\EOF &&
+		test_hook --clobber fsmonitor-test <<-\EOF &&
 			printf "last_update_token\0"
 			printf "dir1/modified\0"
 		EOF
@@ -430,7 +430,7 @@ test_expect_success 'status succeeds with sparse index' '
 
 		# This one modifies outside the sparse-checkout definition
 		# and hence we expect to expand the sparse-index.
-		write_script .git/hooks/fsmonitor-test <<-\EOF &&
+		test_hook --clobber fsmonitor-test <<-\EOF &&
 			printf "last_update_token\0"
 			printf "dir1a/modified\0"
 		EOF
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 85385d2ede7..0bef5913100 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -551,6 +551,58 @@ write_script () {
 	chmod +x "$1"
 }
 
+# Usage: test_hook [options] <hook-name> <<-\EOF
+#
+#   -C <dir>:
+#	Run all git commands in directory <dir>
+#   --setup
+#	Setup a hook for subsequent tests, i.e. don't remove it in a
+#	"test_when_finished"
+#   --clobber
+#	Overwrite an existing <hook-name>, if it exists. Implies
+#	--setup (i.e. the "test_when_finished" is assumed to have been
+#	set up already).
+test_hook () {
+	setup= &&
+	clobber= &&
+	indir= &&
+	while test $# != 0
+	do
+		case "$1" in
+		-C)
+			indir="$2" &&
+			shift
+			;;
+		--setup)
+			setup=t
+			;;
+		--clobber)
+			clobber=t
+			;;
+		-*)
+			BUG "invalid argument: $1"
+			;;
+		*)
+			break
+			;;
+		esac &&
+		shift
+	done &&
+
+	git_dir=$(git -C "$indir" rev-parse --absolute-git-dir) &&
+	hook_dir="$git_dir/hooks" &&
+	hook_file="$hook_dir/$1" &&
+	if test -z "$clobber"
+	then
+		test_path_is_missing "$hook_file"
+	fi &&
+	if test -z "$setup$clobber"
+	then
+		test_when_finished "rm \"$hook_file\""
+	fi &&
+	write_script "$hook_file"
+}
+
 # Use test_set_prereq to tell that a particular prerequisite is available.
 # The prerequisite can later be checked for in two ways:
 #
-- 
2.35.1.1228.g56895c6ee86


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 09/10] tests: change "mkdir -p && write_script" to use "test_hook"
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
                   ` (7 preceding siblings ...)
  2022-03-02 13:22 ` [PATCH 08/10] test-lib-functions: add and use a "test_hook" wrapper Ævar Arnfjörð Bjarmason
@ 2022-03-02 13:22 ` Ævar Arnfjörð Bjarmason
  2022-03-02 22:06   ` Junio C Hamano
  2022-03-02 13:22 ` [PATCH 10/10] tests: change "cat && chmod +x" " Ævar Arnfjörð Bjarmason
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-02 13:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change tests that used a "mkdir -p .git/hooks && write_script" pattern
to use the new "test_hook" helper instead. The new helper does not
create the .git/hooks directory, rather we assume that the default
template will do so for us.

An upcoming series[1] will extend "test_hook" to operate in a
"--template=" mode, but for now assuming that we have a .git/hooks
already is a safe assumption. If that assumption becomes false in the
future we'll only need to change 'test_hook", instead of all of these
callsites.

1. https://lore.kernel.org/git/cover-00.13-00000000000-20211212T201308Z-avarab@gmail.com/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0029-core-unsetenvvars.sh      |  3 +--
 t/t1350-config-hooks-path.sh      |  4 ++--
 t/t3404-rebase-interactive.sh     | 10 ++--------
 t/t3430-rebase-merges.sh          |  6 +++---
 t/t4150-am.sh                     | 24 ++++++------------------
 t/t5403-post-checkout-hook.sh     |  3 +--
 t/t5534-push-signed.sh            | 26 ++++++++------------------
 t/t7113-post-index-change-hook.sh |  7 +++----
 t/t9001-send-email.sh             |  4 +---
 t/t9800-git-p4-basic.sh           |  5 ++---
 10 files changed, 29 insertions(+), 63 deletions(-)

diff --git a/t/t0029-core-unsetenvvars.sh b/t/t0029-core-unsetenvvars.sh
index b138e1d9cbc..4e8e90dd982 100755
--- a/t/t0029-core-unsetenvvars.sh
+++ b/t/t0029-core-unsetenvvars.sh
@@ -12,8 +12,7 @@ then
 fi
 
 test_expect_success 'setup' '
-	mkdir -p "$TRASH_DIRECTORY/.git/hooks" &&
-	write_script "$TRASH_DIRECTORY/.git/hooks/pre-commit" <<-\EOF
+	test_hook --setup pre-commit <<-\EOF
 	echo $HOBBES >&2
 	EOF
 '
diff --git a/t/t1350-config-hooks-path.sh b/t/t1350-config-hooks-path.sh
index fa9647a7c0b..f6dc83e2aab 100755
--- a/t/t1350-config-hooks-path.sh
+++ b/t/t1350-config-hooks-path.sh
@@ -6,11 +6,11 @@ test_description='Test the core.hooksPath configuration variable'
 
 test_expect_success 'set up a pre-commit hook in core.hooksPath' '
 	>actual &&
-	mkdir -p .git/custom-hooks .git/hooks &&
+	mkdir -p .git/custom-hooks &&
 	write_script .git/custom-hooks/pre-commit <<-\EOF &&
 	echo CUSTOM >>actual
 	EOF
-	write_script .git/hooks/pre-commit <<-\EOF
+	test_hook --setup pre-commit <<-\EOF
 	echo NORMAL >>actual
 	EOF
 '
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index a38f2da7691..f31afd4a547 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -619,9 +619,7 @@ test_expect_success 'rebase a detached HEAD' '
 '
 
 test_expect_success 'rebase a commit violating pre-commit' '
-
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/pre-commit <<-\EOF &&
+	test_hook pre-commit <<-\EOF &&
 	test -z "$(git diff --cached --check)"
 	EOF
 	echo "monde! " >> file1 &&
@@ -636,8 +634,6 @@ test_expect_success 'rebase a commit violating pre-commit' '
 '
 
 test_expect_success 'rebase with a file named HEAD in worktree' '
-
-	rm -fr .git/hooks &&
 	git reset --hard &&
 	git checkout -b branch3 A &&
 
@@ -1688,10 +1684,8 @@ test_expect_success 'valid author header when author contains single quote' '
 '
 
 test_expect_success 'post-commit hook is called' '
-	test_when_finished "rm -f .git/hooks/post-commit" &&
 	>actual &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-commit <<-\EOS &&
+	test_hook post-commit <<-\EOS &&
 	git rev-parse HEAD >>actual
 	EOS
 	(
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index 43c82d9a33b..f351701fec2 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -292,9 +292,9 @@ test_expect_success 'post-rewrite hook and fixups work for merges' '
 	git commit --fixup HEAD same2.t &&
 	fixup="$(git rev-parse HEAD)" &&
 
-	mkdir -p .git/hooks &&
-	test_when_finished "rm .git/hooks/post-rewrite" &&
-	echo "cat >actual" | write_script .git/hooks/post-rewrite &&
+	test_hook post-rewrite <<-\EOF &&
+	cat >actual
+	EOF
 
 	test_tick &&
 	git rebase -i --autosquash -r HEAD^^^ &&
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index 159fae8d016..cdad4b68807 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -315,12 +315,10 @@ test_expect_success 'am --patch-format=hg applies hg patch' '
 '
 
 test_expect_success 'am with applypatch-msg hook' '
-	test_when_finished "rm -f .git/hooks/applypatch-msg" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/applypatch-msg <<-\EOF &&
+	test_hook applypatch-msg <<-\EOF &&
 	cat "$1" >actual-msg &&
 	echo hook-message >"$1"
 	EOF
@@ -335,12 +333,10 @@ test_expect_success 'am with applypatch-msg hook' '
 '
 
 test_expect_success 'am with failing applypatch-msg hook' '
-	test_when_finished "rm -f .git/hooks/applypatch-msg" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/applypatch-msg <<-\EOF &&
+	test_hook applypatch-msg <<-\EOF &&
 	exit 1
 	EOF
 	test_must_fail git am patch1 &&
@@ -350,12 +346,10 @@ test_expect_success 'am with failing applypatch-msg hook' '
 '
 
 test_expect_success 'am with pre-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/pre-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/pre-applypatch <<-\EOF &&
+	test_hook pre-applypatch <<-\EOF &&
 	git diff first >diff.actual
 	exit 0
 	EOF
@@ -368,12 +362,10 @@ test_expect_success 'am with pre-applypatch hook' '
 '
 
 test_expect_success 'am with failing pre-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/pre-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/pre-applypatch <<-\EOF &&
+	test_hook pre-applypatch <<-\EOF &&
 	exit 1
 	EOF
 	test_must_fail git am patch1 &&
@@ -383,12 +375,10 @@ test_expect_success 'am with failing pre-applypatch hook' '
 '
 
 test_expect_success 'am with post-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/post-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-applypatch <<-\EOF &&
+	test_hook post-applypatch <<-\EOF &&
 	git rev-parse HEAD >head.actual
 	git diff second >diff.actual
 	exit 0
@@ -403,12 +393,10 @@ test_expect_success 'am with post-applypatch hook' '
 '
 
 test_expect_success 'am with failing post-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/post-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-applypatch <<-\EOF &&
+	test_hook post-applypatch <<-\EOF &&
 	git rev-parse HEAD >head.actual
 	exit 1
 	EOF
diff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh
index d1181816906..978f240cdac 100755
--- a/t/t5403-post-checkout-hook.sh
+++ b/t/t5403-post-checkout-hook.sh
@@ -10,8 +10,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 . ./test-lib.sh
 
 test_expect_success setup '
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-checkout <<-\EOF &&
+	test_hook --setup post-checkout <<-\EOF &&
 	echo "$@" >.git/post-checkout.args
 	EOF
 	test_commit one &&
diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh
index 24d374adbae..7c0a148e73c 100755
--- a/t/t5534-push-signed.sh
+++ b/t/t5534-push-signed.sh
@@ -35,8 +35,7 @@ test_expect_success setup '
 
 test_expect_success 'unsigned push does not send push certificate' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -52,8 +51,7 @@ test_expect_success 'unsigned push does not send push certificate' '
 
 test_expect_success 'talking with a receiver without push certificate support' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -69,22 +67,19 @@ test_expect_success 'talking with a receiver without push certificate support' '
 
 test_expect_success 'push --signed fails with a receiver without push certificate support' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	test_must_fail git push --signed dst noop ff +noff 2>err &&
 	test_i18ngrep "the receiving end does not support" err
 '
 
 test_expect_success 'push --signed=1 is accepted' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	test_must_fail git push --signed=1 dst noop ff +noff 2>err &&
 	test_i18ngrep "the receiving end does not support" err
 '
 
 test_expect_success GPG 'no certificate for a signed push with no update' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	if test -n "${GIT_PUSH_CERT-}"
 	then
 		git cat-file blob $GIT_PUSH_CERT >../push-cert
@@ -96,9 +91,8 @@ test_expect_success GPG 'no certificate for a signed push with no update' '
 
 test_expect_success GPG 'signed push sends push certificate' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -139,10 +133,9 @@ test_expect_success GPG 'signed push sends push certificate' '
 
 test_expect_success GPGSSH 'ssh signed push sends push certificate' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -223,9 +216,8 @@ test_expect_success GPG 'inconsistent push options in signed push not allowed' '
 
 test_expect_success GPG 'fail without key and heed user.signingkey' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -273,9 +265,8 @@ test_expect_success GPG 'fail without key and heed user.signingkey' '
 test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '
 	test_config gpg.format x509 &&
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -326,10 +317,9 @@ test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '
 test_expect_success GPGSSH 'fail without key and heed user.signingkey ssh' '
 	test_config gpg.format ssh &&
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
diff --git a/t/t7113-post-index-change-hook.sh b/t/t7113-post-index-change-hook.sh
index a21781d68a1..58e55a7c779 100755
--- a/t/t7113-post-index-change-hook.sh
+++ b/t/t7113-post-index-change-hook.sh
@@ -17,8 +17,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'test status, add, commit, others trigger hook without flags set' '
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-index-change <<-\EOF &&
+	test_hook post-index-change <<-\EOF &&
 		if test "$1" -eq 1; then
 			echo "Invalid combination of flags passed to hook; updated_workdir is set." >testfailure
 			exit 1
@@ -63,7 +62,7 @@ test_expect_success 'test status, add, commit, others trigger hook without flags
 '
 
 test_expect_success 'test checkout and reset trigger the hook' '
-	write_script .git/hooks/post-index-change <<-\EOF &&
+	test_hook post-index-change <<-\EOF &&
 		if test "$1" -eq 1 && test "$2" -eq 1; then
 			echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
 			exit 1
@@ -106,7 +105,7 @@ test_expect_success 'test checkout and reset trigger the hook' '
 '
 
 test_expect_success 'test reset --mixed and update-index triggers the hook' '
-	write_script .git/hooks/post-index-change <<-\EOF &&
+	test_hook post-index-change <<-\EOF &&
 		if test "$1" -eq 1 && test "$2" -eq 1; then
 			echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
 			exit 1
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 84d0f40d76a..42694fe5841 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -2288,9 +2288,7 @@ test_expect_success $PREREQ 'cmdline in-reply-to used with --no-thread' '
 '
 
 test_expect_success $PREREQ 'invoke hook' '
-	mkdir -p .git/hooks &&
-
-	write_script .git/hooks/sendemail-validate <<-\EOF &&
+	test_hook sendemail-validate <<-\EOF &&
 	# test that we have the correct environment variable, pwd, and
 	# argument
 	case "$GIT_DIR" in
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index 3c1534c94d6..8b30062c0cf 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -279,8 +279,7 @@ test_expect_success 'run hook p4-pre-submit before submit' '
 		git p4 submit --dry-run >out &&
 		grep "Would apply" out
 	) &&
-	mkdir -p "$git"/.git/hooks &&
-	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
+	test_hook -C "$git" p4-pre-submit <<-\EOF &&
 	exit 0
 	EOF
 	(
@@ -288,7 +287,7 @@ test_expect_success 'run hook p4-pre-submit before submit' '
 		git p4 submit --dry-run >out &&
 		grep "Would apply" out
 	) &&
-	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
+	test_hook -C "$git" --clobber p4-pre-submit <<-\EOF &&
 	exit 1
 	EOF
 	(
-- 
2.35.1.1228.g56895c6ee86


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 10/10] tests: change "cat && chmod +x" to use "test_hook"
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
                   ` (8 preceding siblings ...)
  2022-03-02 13:22 ` [PATCH 09/10] tests: change "mkdir -p && write_script" to use "test_hook" Ævar Arnfjörð Bjarmason
@ 2022-03-02 13:22 ` Ævar Arnfjörð Bjarmason
  2022-03-03  5:46   ` Eric Sunshine
  2022-03-02 22:38 ` [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Junio C Hamano
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
  11 siblings, 1 reply; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-02 13:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Refactor various test code to use the "test_hook" helper. This change:

 - Fixes the long-standing issues with those tests using "#!/bin/sh"
   instead of "#!$SHELL_PATH". Using "#!/bin/sh" here happened to work
   because this code was so simply that it e.g. worked on Solaris
   /bin/sh.

 - Removes the "mkdir .git/hooks" invocation, as explained in a
   preceding commit we'll rely on the default templates to create that
   directory for us.

For the test in "t5402-post-merge-hook.sh" it's easier and more
correct to unroll the for-loop into a test_expect_success, so let's do
that.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3412-rebase-root.sh       | 12 +++---------
 t/t3413-rebase-hook.sh       | 12 +++---------
 t/t5401-update-hooks.sh      | 16 ++++------------
 t/t5402-post-merge-hook.sh   | 16 +++++++++-------
 t/t5407-post-rewrite-hook.sh |  4 +---
 t/t5516-fetch-push.sh        | 19 ++++---------------
 t/t5541-http-push-smart.sh   |  4 +---
 t/t5601-clone.sh             |  4 +---
 8 files changed, 26 insertions(+), 61 deletions(-)

diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
index 239a9343d34..58371d8a547 100755
--- a/t/t3412-rebase-root.sh
+++ b/t/t3412-rebase-root.sh
@@ -31,12 +31,9 @@ test_expect_success 'rebase --root fails with too many args' '
 '
 
 test_expect_success 'setup pre-rebase hook' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<-EOF &&
-	#!$SHELL_PATH
-	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+	test_hook --setup pre-rebase <<-\EOF
+	echo "$1,$2" >.git/PRE-REBASE-INPUT
 	EOF
-	chmod +x .git/hooks/pre-rebase
 '
 cat > expect <<EOF
 4
@@ -141,12 +138,9 @@ commit work7~5
 EOF
 
 test_expect_success 'setup pre-rebase hook that fails' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<-EOF &&
-	#!$SHELL_PATH
+	test_hook --setup --clobber pre-rebase <<-\EOF
 	false
 	EOF
-	chmod +x .git/hooks/pre-rebase
 '
 
 test_expect_success 'pre-rebase hook stops rebase' '
diff --git a/t/t3413-rebase-hook.sh b/t/t3413-rebase-hook.sh
index bb241b26b2e..9fab0d779bb 100755
--- a/t/t3413-rebase-hook.sh
+++ b/t/t3413-rebase-hook.sh
@@ -41,12 +41,9 @@ test_expect_success 'rebase -i' '
 '
 
 test_expect_success 'setup pre-rebase hook' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<-EOF &&
-	#!$SHELL_PATH
-	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+	test_hook --setup pre-rebase <<-\EOF
+	echo "$1,$2" >.git/PRE-REBASE-INPUT
 	EOF
-	chmod +x .git/hooks/pre-rebase
 '
 
 test_expect_success 'pre-rebase hook gets correct input (1)' '
@@ -102,12 +99,9 @@ test_expect_success 'pre-rebase hook gets correct input (6)' '
 '
 
 test_expect_success 'setup pre-rebase hook that fails' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<-EOF &&
-	#!$SHELL_PATH
+	test_hook --setup --clobber pre-rebase <<-\EOF
 	false
 	EOF
-	chmod +x .git/hooks/pre-rebase
 '
 
 test_expect_success 'pre-rebase hook stops rebase (1)' '
diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
index 6392f71795d..d5771b96114 100755
--- a/t/t5401-update-hooks.sh
+++ b/t/t5401-update-hooks.sh
@@ -22,42 +22,34 @@ test_expect_success setup '
 	git update-ref refs/heads/main $commit1 &&
 	git update-ref refs/heads/tofail $commit0 &&
 
-	cat >victim.git/hooks/pre-receive <<-\EOF &&
-	#!/bin/sh
+	test_hook --setup -C victim.git pre-receive <<-\EOF &&
 	printf %s "$@" >>$GIT_DIR/pre-receive.args
 	cat - >$GIT_DIR/pre-receive.stdin
 	echo STDOUT pre-receive
 	echo STDERR pre-receive >&2
 	EOF
-	chmod u+x victim.git/hooks/pre-receive &&
 
-	cat >victim.git/hooks/update <<-\EOF &&
-	#!/bin/sh
+	test_hook --setup -C victim.git update <<-\EOF &&
 	echo "$@" >>$GIT_DIR/update.args
 	read x; printf %s "$x" >$GIT_DIR/update.stdin
 	echo STDOUT update $1
 	echo STDERR update $1 >&2
 	test "$1" = refs/heads/main || exit
 	EOF
-	chmod u+x victim.git/hooks/update &&
 
-	cat >victim.git/hooks/post-receive <<-\EOF &&
-	#!/bin/sh
+	test_hook --setup -C victim.git post-receive <<-\EOF &&
 	printf %s "$@" >>$GIT_DIR/post-receive.args
 	cat - >$GIT_DIR/post-receive.stdin
 	echo STDOUT post-receive
 	echo STDERR post-receive >&2
 	EOF
-	chmod u+x victim.git/hooks/post-receive &&
 
-	cat >victim.git/hooks/post-update <<-\EOF &&
-	#!/bin/sh
+	test_hook --setup -C victim.git post-update <<-\EOF
 	echo "$@" >>$GIT_DIR/post-update.args
 	read x; printf %s "$x" >$GIT_DIR/post-update.stdin
 	echo STDOUT post-update
 	echo STDERR post-update >&2
 	EOF
-	chmod u+x victim.git/hooks/post-update
 '
 
 test_expect_success push '
diff --git a/t/t5402-post-merge-hook.sh b/t/t5402-post-merge-hook.sh
index 3e5e19c7191..915af2de95e 100755
--- a/t/t5402-post-merge-hook.sh
+++ b/t/t5402-post-merge-hook.sh
@@ -25,13 +25,15 @@ test_expect_success setup '
 	GIT_DIR=clone2/.git git update-index --add a
 '
 
-for clone in 1 2; do
-	cat >clone${clone}/.git/hooks/post-merge <<'EOF'
-#!/bin/sh
-echo $@ >> $GIT_DIR/post-merge.args
-EOF
-	chmod u+x clone${clone}/.git/hooks/post-merge
-done
+test_expect_success 'setup clone hooks' '
+	test_when_finished "rm -f hook" &&
+	cat >hook <<-\EOF &&
+	echo $@ >>$GIT_DIR/post-merge.args
+	EOF
+
+	test_hook --setup -C clone1 post-merge <hook &&
+	test_hook --setup -C clone2 post-merge <hook
+'
 
 test_expect_success 'post-merge does not run for up-to-date ' '
 	GIT_DIR=clone1/.git git merge $commit0 &&
diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
index 64f40ff7776..5f3ff051ca2 100755
--- a/t/t5407-post-rewrite-hook.sh
+++ b/t/t5407-post-rewrite-hook.sh
@@ -19,12 +19,10 @@ test_expect_success 'setup' '
 	test_commit F foo F &&
 	git checkout main &&
 
-	cat >.git/hooks/post-rewrite <<-EOF &&
-	#!/bin/sh
+	test_hook --setup post-rewrite <<-EOF
 	echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
 	cat > "$TRASH_DIRECTORY"/post-rewrite.data
 	EOF
-	chmod u+x .git/hooks/post-rewrite
 '
 
 clear_hook_input () {
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index b689baf01a9..4dfb080433e 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -55,35 +55,24 @@ mk_test () {
 mk_test_with_hooks() {
 	repo_name=$1
 	mk_test "$@" &&
-
-	cat >"$repo_name"/.git/hooks/pre-receive <<-'EOF' &&
-	#!/bin/sh
+	test_hook -C "$repo_name" pre-receive <<-'EOF' &&
 	cat - >>pre-receive.actual
 	EOF
 
-	cat >"$repo_name"/.git/hooks/update <<-'EOF' &&
-	#!/bin/sh
+	test_hook -C "$repo_name" update <<-'EOF' &&
 	printf "%s %s %s\n" "$@" >>update.actual
 	EOF
 
-	cat >"$repo_name"/.git/hooks/post-receive <<-'EOF' &&
-	#!/bin/sh
+	test_hook -C "$repo_name" post-receive <<-'EOF' &&
 	cat - >>post-receive.actual
 	EOF
 
-	cat >"$repo_name"/.git/hooks/post-update <<-'EOF' &&
-	#!/bin/sh
+	test_hook -C "$repo_name" post-update <<-'EOF'
 	for ref in "$@"
 	do
 		printf "%s\n" "$ref" >>post-update.actual
 	done
 	EOF
-
-	chmod +x \
-	      "$repo_name"/.git/hooks/pre-receive \
-	      "$repo_name"/.git/hooks/update \
-	      "$repo_name"/.git/hooks/post-receive \
-	      "$repo_name"/.git/hooks/post-update
 }
 
 mk_child() {
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index 0043b718f08..ab4b5cfcd11 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -97,11 +97,9 @@ test_expect_success 'create and delete remote branch' '
 '
 
 test_expect_success 'setup rejected update hook' '
-	cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<-EOF &&
-	#!/bin/sh
+	test_hook --setup -C "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" update <<-\EOF &&
 	exit 1
 	EOF
-	chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" &&
 
 	cat >exp <<-EOF
 	remote: error: hook declined to update refs/heads/dev2
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 83c24fc97a7..4a61f2c901e 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -79,12 +79,10 @@ test_expect_success 'clone from hooks' '
 	cd .. &&
 	git init r1 &&
 	cd r1 &&
-	cat >.git/hooks/pre-commit <<-\EOF &&
-	#!/bin/sh
+	test_hook pre-commit <<-\EOF &&
 	git clone ../r0 ../r2
 	exit 1
 	EOF
-	chmod u+x .git/hooks/pre-commit &&
 	: >file &&
 	git add file &&
 	test_must_fail git commit -m invoke-hook &&
-- 
2.35.1.1228.g56895c6ee86


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH 01/10] hook tests: turn exit code assertions into a loop
  2022-03-02 13:22 ` [PATCH 01/10] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
@ 2022-03-02 20:55   ` Junio C Hamano
  0 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-02 20:55 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Amend a test added in 96e7225b310 (hook: add 'run' subcommand,
> 2021-12-22) to use a for-loop instead of a copy/pasting the same test
> for the four exit codes we test.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t1800-hook.sh | 35 ++++++++++-------------------------
>  1 file changed, 10 insertions(+), 25 deletions(-)
> ...
> +for code in 1 2 128 129
> +do
> +	test_expect_success "git hook run: exit code $code is passed along" '
> +		write_script .git/hooks/test-hook <<-EOF &&
> +		exit $code
> +		EOF
> +
> +		test_expect_code $code git hook run test-hook
> +	'
> +done

Looks good.  Each being separate test_expect_success means we do not
have to worry about breaking out of the loop upon a failure, which
is much cleaner than I would have thought ;-)

It also illustrates a good use of unquoted here document.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 02/10] t5540: don't rely on "hook/post-update.sample"
  2022-03-02 13:22 ` [PATCH 02/10] t5540: don't rely on "hook/post-update.sample" Ævar Arnfjörð Bjarmason
@ 2022-03-02 21:06   ` Junio C Hamano
  0 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-02 21:06 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change code added in a87679339c0 (test: rename http fetch and push
> test files, 2014-02-06) to stop relying on the "exec git
> update-server-info" in "templates/hooks--post-update.sample", let's
> instead inline the expected hook in the test itself.

For this particular hook, it indeed is a good change, as future
post-update samples we ship may have something quite different.

I do not know if it is a good idea in general, though.  We want
to promise shipping certain sample scripts as part of the default
install, and the default install is what our tests check.  We want
to keep something that ensures the default install does ship the
sample we want to include, and such tests do need to rely on the
presence of .sample files.  But this script does not need to be
the one to do so.

>  	git --bare update-server-info &&
> -	mv hooks/post-update.sample hooks/post-update &&
> +	write_script hooks/post-update <<-\EOF &&
> +	exec git update-server-info
> +	EOF
>  	ORIG_HEAD=$(git rev-parse --verify HEAD) &&
>  	cd - &&
>  	mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH"

OK.

We might want to deprecate and remove the support for dumb walkers,
but until then, this looks superb.

Thanks.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 03/10] tests: assume the hooks are disabled by default
  2022-03-02 13:22 ` [PATCH 03/10] tests: assume the hooks are disabled by default Ævar Arnfjörð Bjarmason
@ 2022-03-02 21:13   ` Junio C Hamano
  0 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-02 21:13 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Stop moving the .git/hooks directory out of the way, or creating it
> during test setup. Instead assume that it will contain
> harmless *.sample files.

Makes sense.  We ship sample files and no activated hooks in the
default install, and we do want to assume that in most of our tests
(except for ones that validate that asssumptions, of course).

> diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh
> index 4e1e84a91f3..d21dd5e5df0 100755
> --- a/t/t1416-ref-transaction-hooks.sh
> +++ b/t/t1416-ref-transaction-hooks.sh
> @@ -8,7 +8,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
>  . ./test-lib.sh
>  
>  test_expect_success setup '
> -	mkdir -p .git/hooks &&

Interesting.  This becomes part of the tests that validate the
assumption that we do ship the hooks/ directory with sample files
;-)

>  	test_commit PRE &&
>  	PRE_OID=$(git rev-parse PRE) &&
>  	test_commit POST &&
> diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
> index 3137eb8d4d2..1a20e54adc1 100755
> --- a/t/t5516-fetch-push.sh
> +++ b/t/t5516-fetch-push.sh
> @@ -28,8 +28,7 @@ mk_empty () {
>  	(
>  		cd "$repo_name" &&
>  		git init &&
> -		git config receive.denyCurrentBranch warn &&
> -		mv .git/hooks .git/hooks-disabled
> +		git config receive.denyCurrentBranch warn
>  	)
>  }

Good.

> diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
> index a6308acf006..63a0f609866 100755
> --- a/t/t7519-status-fsmonitor.sh
> +++ b/t/t7519-status-fsmonitor.sh
> @@ -56,7 +56,6 @@ test_lazy_prereq UNTRACKED_CACHE '
>  '
>  
>  test_expect_success 'setup' '
> -	mkdir -p .git/hooks &&
>  	: >tracked &&
>  	: >modified &&
>  	mkdir dir1 &&
> @@ -322,7 +321,6 @@ test_expect_success UNTRACKED_CACHE 'ignore .git changes when invalidating UNTR'
>  	test_create_repo dot-git &&
>  	(
>  		cd dot-git &&
> -		mkdir -p .git/hooks &&
>  		: >tracked &&
>  		: >modified &&
>  		mkdir dir1 &&

Nice.  Presumably these should have been done when we stopped
mucking with hooks-disabled in test_create_repo helper but we
forgot to do so, and these are the only remaining bits?

Thanks for tying the loose ends.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 04/10] bugreport tests: tighten up "git bugreport -s hooks" test
  2022-03-02 13:22 ` [PATCH 04/10] bugreport tests: tighten up "git bugreport -s hooks" test Ævar Arnfjörð Bjarmason
@ 2022-03-02 21:22   ` Junio C Hamano
  0 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-02 21:22 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> +	write_script .git/hooks/applypatch-msg <<-\EOF &&
> +	true
> +	EOF
> +	write_script .git/hooks/unknown-hook <<-\EOF &&
> +	true
> +	EOF
>  	git bugreport -s hooks &&
> +
>  	grep applypatch-msg git-bugreport-hooks.txt &&
> -	! grep prepare-commit-msg git-bugreport-hooks.txt
> +	! grep unknown-hook git-bugreport-hooks.txt &&
> +	! grep -F .sample git-bugreport-hooks.txt
>  '

The above is not wrong per-se, but because we control which hooks
are and are not visible to "git bugreport" we run in this test, I
wonder if we should do

	git bugreport -s tmp &&
	sed -ne '/^\[Enabled Hooks\]$/,/^$/p' git-bugreport-tmp.txt |
	sort >actual &&
	sort >expect <<-\EOF &&
	[Enabled Hooks]
	applypatch-msg
	EOF
	test_cmp expect actual

instead.  It is not like checking the "git help -a" output for list
of commands, which may grow or shrink as the system evolves.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 05/10] tests: indent and add hook setup to "test_expect_success"
  2022-03-02 13:22 ` [PATCH 05/10] tests: indent and add hook setup to "test_expect_success" Ævar Arnfjörð Bjarmason
@ 2022-03-02 21:27   ` Junio C Hamano
  0 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-02 21:27 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Indent various hook setup code in the test suite that's using a manual
> "cat && chmod" pattern.
>
> These should also consistently use "#!$SHELL_PATH" instead of
> "#!/bin/sh", i.e. "test_script". Let's fix that in a subsequent
> commit, which will be easier to review after this smaller change.

These do move them in the right direction, but I am not sure if a
step-wise "first we do <<- trick to kill unindented mess, and then
another "use write_script" to touch the same places, consuming twice
the reviewer bandwidth.  I certainly would hate to have to see these
lines twice X-<.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 06/10] hook tests: get rid of unnecessary sub-shells
  2022-03-02 13:22 ` [PATCH 06/10] hook tests: get rid of unnecessary sub-shells Ævar Arnfjörð Bjarmason
@ 2022-03-02 21:31   ` Junio C Hamano
  0 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-02 21:31 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Refactor the repository setup code for tests that test hooks the use
> of sub-shells when setting up the test repository and hooks.
>
> A subsequent commit will change the hook setup to use a helper that
> makes use of "test_when_finished", which cannot be used in
> sub-shells. Let's change that setup code, and the adjacent and similar
> "mk_empty" code.

Makes sense.

> diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
> index 1a20e54adc1..e4bb7581568 100755
> --- a/t/t5516-fetch-push.sh
> +++ b/t/t5516-fetch-push.sh
> @@ -24,12 +24,8 @@ D=$(pwd)
>  mk_empty () {
>  	repo_name="$1"
>  	rm -fr "$repo_name" &&
> -	mkdir "$repo_name" &&
> -	(
> -		cd "$repo_name" &&
> -		git init &&
> -		git config receive.denyCurrentBranch warn
> -	)
> +	git init "$repo_name" &&
> +	git -C "$repo_name" config receive.denyCurrentBranch warn
>  }

I thought of this exact change when I saw a change to this part in
this series in an earlier step.  Excellent.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 07/10] fetch+push tests: have tests clean up their own mess
  2022-03-02 13:22 ` [PATCH 07/10] fetch+push tests: have tests clean up their own mess Ævar Arnfjörð Bjarmason
@ 2022-03-02 21:44   ` Junio C Hamano
  0 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-02 21:44 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change the "t5516-fetch-push.sh" test code to make use of
> "test_when_finished" to remove data instead of having tests clean up
> leftover data from earlier tests, which may or may not be
> there (e.g. depending on the --run=* option).
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t5516-fetch-push.sh | 50 +++++++++++++++++++++++++------------------
>  1 file changed, 29 insertions(+), 21 deletions(-)
>
> diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
> index e4bb7581568..fbe0a72b0b2 100755
> --- a/t/t5516-fetch-push.sh
> +++ b/t/t5516-fetch-push.sh
> @@ -23,7 +23,8 @@ D=$(pwd)
>  
>  mk_empty () {
>  	repo_name="$1"
> -	rm -fr "$repo_name" &&
> +	test_when_finished "rm -rf \"$repo_name\"" &&

Any justification to swap between fr and rf?

> +	test_path_is_missing "$repo_name" &&

So, the idea is that the philosophy so far was that each test clears
whatever the mess the previous ones created and empties what it cares
to be empty with "rm -fr", but now in the new world order, each test
relies on test_when_finished to clear any and all effects it leaves
to the environment?

OK.  Since the clearing the "effects" is to remove the whole thing,
there is little room for such a plan to go wrong.

> @@ -191,32 +192,32 @@ grep_wrote () {
>  	grep 'write_pack_file/wrote.*"value":"'$1'"' $2
>  }
>  
> -test_expect_success 'push with negotiation' '
> -	# Without negotiation

;-)

> +test_expect_success 'push without negotiation' '
>  	mk_empty testrepo &&
>  	git push testrepo $the_first_commit:refs/remotes/origin/first_commit &&
>  	test_commit -C testrepo unrelated_commit &&
>  	git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit &&
> -	echo now pushing without negotiation &&
> +	test_when_finished "rm event" &&
>  	GIT_TRACE2_EVENT="$(pwd)/event" git -c protocol.version=2 push testrepo refs/heads/main:refs/remotes/origin/main &&
> -	grep_wrote 5 event && # 2 commits, 2 trees, 1 blob
> +	grep_wrote 5 event # 2 commits, 2 trees, 1 blob
> +'
>  
> -	# Same commands, but with negotiation
> -	rm event &&

Good to split them into two.  Presumably the later part wasn't
relying on the leftover side effects created by the early part?

Thanks.  Looking good.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 08/10] test-lib-functions: add and use a "test_hook" wrapper
  2022-03-02 13:22 ` [PATCH 08/10] test-lib-functions: add and use a "test_hook" wrapper Ævar Arnfjörð Bjarmason
@ 2022-03-02 21:59   ` Junio C Hamano
  0 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-02 21:59 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> @@ -430,7 +430,7 @@ test_expect_success 'status succeeds with sparse index' '
>  
>  		# This one modifies outside the sparse-checkout definition
>  		# and hence we expect to expand the sparse-index.
> -		write_script .git/hooks/fsmonitor-test <<-\EOF &&
> +		test_hook --clobber fsmonitor-test <<-\EOF &&
>  			printf "last_update_token\0"
>  			printf "dir1a/modified\0"
>  		EOF

These look almost trivial (the --setup part is somewhat trickier
than the rest), thanks to the use of write_script.

It would have been even cleaner if we jumped from "unindented
cat && chmod +x" directly to "use write_script" in one of the
earlier steps, which would have reduced the need for the last step
in the series.

> diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> index 85385d2ede7..0bef5913100 100644
> --- a/t/test-lib-functions.sh
> +++ b/t/test-lib-functions.sh
> @@ -551,6 +551,58 @@ write_script () {
>  	chmod +x "$1"
>  }
>  
> +# Usage: test_hook [options] <hook-name> <<-\EOF
> +#
> +#   -C <dir>:
> +#	Run all git commands in directory <dir>
> +#   --setup
> +#	Setup a hook for subsequent tests, i.e. don't remove it in a
> +#	"test_when_finished"
> +#   --clobber
> +#	Overwrite an existing <hook-name>, if it exists. Implies
> +#	--setup (i.e. the "test_when_finished" is assumed to have been
> +#	set up already).

OK.

We aspire to make everybody use test_hook, so the fact that we have
to clobber means somebody else made the right choice to either use
or not use --setup to create it, and we do not have to (re)arrange
it to be removed later, hence it makes perfect sense for --clobber
to imply --setup.

Looking good.


> +test_hook () {
> +	setup= &&
> +	clobber= &&
> +	indir= &&
> +	while test $# != 0
> +	do
> +		case "$1" in
> +		-C)
> +			indir="$2" &&
> +			shift
> +			;;
> +		--setup)
> +			setup=t
> +			;;
> +		--clobber)
> +			clobber=t
> +			;;
> +		-*)
> +			BUG "invalid argument: $1"
> +			;;
> +		*)
> +			break
> +			;;
> +		esac &&
> +		shift
> +	done &&
> +
> +	git_dir=$(git -C "$indir" rev-parse --absolute-git-dir) &&
> +	hook_dir="$git_dir/hooks" &&
> +	hook_file="$hook_dir/$1" &&
> +	if test -z "$clobber"
> +	then
> +		test_path_is_missing "$hook_file"
> +	fi &&
> +	if test -z "$setup$clobber"
> +	then
> +		test_when_finished "rm \"$hook_file\""
> +	fi &&
> +	write_script "$hook_file"
> +}
> +
>  # Use test_set_prereq to tell that a particular prerequisite is available.
>  # The prerequisite can later be checked for in two ways:
>  #

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 09/10] tests: change "mkdir -p && write_script" to use "test_hook"
  2022-03-02 13:22 ` [PATCH 09/10] tests: change "mkdir -p && write_script" to use "test_hook" Ævar Arnfjörð Bjarmason
@ 2022-03-02 22:06   ` Junio C Hamano
  0 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-02 22:06 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change tests that used a "mkdir -p .git/hooks && write_script" pattern

Hmph, it is a bit sad that "mkdir -p" weren't removed as part of
an earlier [03/10].

The end result looked sensible.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
                   ` (9 preceding siblings ...)
  2022-03-02 13:22 ` [PATCH 10/10] tests: change "cat && chmod +x" " Ævar Arnfjörð Bjarmason
@ 2022-03-02 22:38 ` Junio C Hamano
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
  11 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-02 22:38 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> This series is a test-only improvement series split up and adapted
> from a previous series of mine to add a "git init --no-template":
> https://lore.kernel.org/git/cover-00.13-00000000000-20211212T201308Z-avarab@gmail.com/

I looked at all the steps and left some comments; overall the end
result was a pleasant read, even though the progression felt some
improvements were needed.

Thanks.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 10/10] tests: change "cat && chmod +x" to use "test_hook"
  2022-03-02 13:22 ` [PATCH 10/10] tests: change "cat && chmod +x" " Ævar Arnfjörð Bjarmason
@ 2022-03-03  5:46   ` Eric Sunshine
  0 siblings, 0 replies; 51+ messages in thread
From: Eric Sunshine @ 2022-03-03  5:46 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Git List, Junio C Hamano, Emily Shaffer

On Wed, Mar 2, 2022 at 8:22 AM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
> Refactor various test code to use the "test_hook" helper. This change:
>
>  - Fixes the long-standing issues with those tests using "#!/bin/sh"
>    instead of "#!$SHELL_PATH". Using "#!/bin/sh" here happened to work
>    because this code was so simply that it e.g. worked on Solaris
>    /bin/sh.

s/simply/simple/

>  - Removes the "mkdir .git/hooks" invocation, as explained in a
>    preceding commit we'll rely on the default templates to create that
>    directory for us.
>
> For the test in "t5402-post-merge-hook.sh" it's easier and more
> correct to unroll the for-loop into a test_expect_success, so let's do
> that.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v2 00/10] tests: add and use a "test_hook" wrapper + hook fixes
  2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
                   ` (10 preceding siblings ...)
  2022-03-02 22:38 ` [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Junio C Hamano
@ 2022-03-07 12:43 ` Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 01/10] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
                     ` (11 more replies)
  11 siblings, 12 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-07 12:43 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

This series is a test-only improvement series split up and adapted
from a previous series of mine to add a "git init --no-template":
https://lore.kernel.org/git/cover-00.13-00000000000-20211212T201308Z-avarab@gmail.com/;
For v1 see:
https://lore.kernel.org/git/cover-00.10-00000000000-20220302T131859Z-avarab@gmail.com/

Changes since v1:

 * Fixed typo/grammer pointed out by Eric Sunshine.
 * Various commit message fixes/clarifications etc. to address Junio's
   comments.
 * Tightened up the "git bugreport test" even more

Junio also suggested re-arranging this to do this migration in fewer
steps. I started doing that but doing so would have taken a lot of
time solving conflicts, re-writing commits etc. I think given that
there's agreement on the end-state that doing so wasn't worth the time
I'd spend on it, or for reviewers in having to review the really large
resulting range-diff. So hopefully this version is acceptable to
advance...

Ævar Arnfjörð Bjarmason (10):
  hook tests: turn exit code assertions into a loop
  t5540: don't rely on "hook/post-update.sample"
  tests: assume the hooks are disabled by default
  bugreport tests: tighten up "git bugreport -s hooks" test
  tests: indent and add hook setup to "test_expect_success"
  hook tests: get rid of unnecessary sub-shells
  fetch+push tests: have tests clean up their own mess
  test-lib-functions: add and use a "test_hook" wrapper
  tests: change "mkdir -p && write_script" to use "test_hook"
  tests: change "cat && chmod +x" to use "test_hook"

 t/t0029-core-unsetenvvars.sh        |   3 +-
 t/t0091-bugreport.sh                |  26 ++--
 t/t1350-config-hooks-path.sh        |   4 +-
 t/t1416-ref-transaction-hooks.sh    |  27 ++--
 t/t1800-hook.sh                     |  45 +++----
 t/t3404-rebase-interactive.sh       |  10 +-
 t/t3412-rebase-root.sh              |  18 +--
 t/t3413-rebase-hook.sh              |  18 +--
 t/t3430-rebase-merges.sh            |   6 +-
 t/t4150-am.sh                       |  24 +---
 t/t5401-update-hooks.sh             |  62 ++++-----
 t/t5402-post-merge-hook.sh          |  16 ++-
 t/t5403-post-checkout-hook.sh       |   3 +-
 t/t5406-remote-rejects.sh           |   2 +-
 t/t5407-post-rewrite-hook.sh        |  14 +-
 t/t5409-colorize-remote-messages.sh |   2 +-
 t/t5411-proc-receive-hook.sh        |   4 +-
 t/t5510-fetch.sh                    |   6 +-
 t/t5516-fetch-push.sh               | 192 +++++++++++++---------------
 t/t5521-pull-options.sh             |   4 +-
 t/t5534-push-signed.sh              |  26 ++--
 t/t5540-http-push-webdav.sh         |   4 +-
 t/t5541-http-push-smart.sh          |  22 ++--
 t/t5547-push-quarantine.sh          |   4 +-
 t/t5548-push-porcelain.sh           |   2 +-
 t/t5601-clone.sh                    |   4 +-
 t/t6500-gc.sh                       |  18 +--
 t/t7113-post-index-change-hook.sh   |   7 +-
 t/t7519-status-fsmonitor.sh         |  20 ++-
 t/t9001-send-email.sh               |   4 +-
 t/t9800-git-p4-basic.sh             |  23 ++--
 t/test-lib-functions.sh             |  52 ++++++++
 32 files changed, 325 insertions(+), 347 deletions(-)

Range-diff against v1:
 1:  706460d10b9 =  1:  706460d10b9 hook tests: turn exit code assertions into a loop
 2:  4bee939a894 =  2:  4bee939a894 t5540: don't rely on "hook/post-update.sample"
 3:  0519102edeb !  3:  fc1a9d4d55b tests: assume the hooks are disabled by default
    @@ Commit message
     
         That we can assume that is discussed in point #4 of
         f0d4d398e28 (test-lib: split up and deprecate test_create_repo(),
    -    2021-05-10).
    +    2021-05-10), those parts of this could and should have been done in
    +    that change.
    +
    +    Removing the "mkdir -p" here will then validate that our templates are
    +    being used, since we'd subsequently fail to create a hook in that
    +    directory if it didn't exist. Subsequent commits will have those hooks
    +    created by a "test_hook" wrapper, which will then being doing that
    +    same validation.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
 4:  1da2efc9886 !  4:  8dd7b40e510 bugreport tests: tighten up "git bugreport -s hooks" test
    @@ Commit message
         bugreport tests: tighten up "git bugreport -s hooks" test
     
         Amend a test added in 788a776069b (bugreport: collect list of
    -    populated hooks, 2020-05-07) to make more sense. As noted in a
    -    preceding commit our .git/hooks directory already contains *.sample
    -    hooks, so we have no need to clobber the prepare-commit-msg.sample
    -    hook in particular.
    +    populated hooks, 2020-05-07) to "test_cmp" for the expected output,
    +    instead of selectively using "grep" to check for specific things we
    +    either expect or don't expect in the output.
    +
    +    As noted in a preceding commit our .git/hooks directory already
    +    contains *.sample hooks, so we have no need to clobber the
    +    prepare-commit-msg.sample hook in particular.
     
         Instead we should assert that those *.sample hooks are not included in
         the output, and for good measure let's add a new "unknown-hook", to
    @@ Commit message
         cfe853e66be (hook-list.h: add a generated list of hooks, like
         config-list.h, 2021-09-26) for how we generate that data.
     
    +    We're intentionally not piping the "actual" output through "sort" or
    +    similar, we'd also like to check that our reported hooks are sorted.
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/t0091-bugreport.sh ##
    @@ t/t0091-bugreport.sh: test_expect_success 'can create leading directories outsid
     +	true
     +	EOF
      	git bugreport -s hooks &&
    -+
    - 	grep applypatch-msg git-bugreport-hooks.txt &&
    +-	grep applypatch-msg git-bugreport-hooks.txt &&
     -	! grep prepare-commit-msg git-bugreport-hooks.txt
    -+	! grep unknown-hook git-bugreport-hooks.txt &&
    -+	! grep -F .sample git-bugreport-hooks.txt
    ++
    ++	sort >expect <<-\EOF &&
    ++	[Enabled Hooks]
    ++	applypatch-msg
    ++	EOF
    ++
    ++	sed -ne "/^\[Enabled Hooks\]$/,/^$/p" <git-bugreport-hooks.txt >actual &&
    ++	test_cmp expect actual
      '
      
      test_done
 5:  8dc478460ee =  5:  19db5b2d7c2 tests: indent and add hook setup to "test_expect_success"
 6:  d86ee06b46e =  6:  08bd1629d65 hook tests: get rid of unnecessary sub-shells
 7:  7ce22dbe738 !  7:  0ac75ed062f fetch+push tests: have tests clean up their own mess
    @@ Commit message
         leftover data from earlier tests, which may or may not be
         there (e.g. depending on the --run=* option).
     
    +    Before this each test would have been responsible for cleaning up
    +    after a preceding test (which may or may not have run, e.g. if --run
    +    or "GIT_SKIP_TESTS" was used), now each test will instead clean up
    +    after itself.
    +
    +    When doing this split up the "push with negotiation" test, now the
    +    middle of the test doesn't need to "rm event", and since it delimited
    +    two halves that were testing two different things the end-state is
    +    easier to read and reason about.
    +
    +    While changing these lines make the minor change from "-fr" to "-rf"
    +    as the "rm" argument, some of them used it already, it's more common
    +    in the test suite, and it leaves the end-state of the file with more
    +    consistency.
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/t5516-fetch-push.sh ##
 8:  d4102e9b929 =  8:  1fce2d8855a test-lib-functions: add and use a "test_hook" wrapper
 9:  1802158b14d =  9:  121ca23db37 tests: change "mkdir -p && write_script" to use "test_hook"
10:  7fef92872f3 ! 10:  db27fa32bbd tests: change "cat && chmod +x" to use "test_hook"
    @@ Commit message
     
          - Fixes the long-standing issues with those tests using "#!/bin/sh"
            instead of "#!$SHELL_PATH". Using "#!/bin/sh" here happened to work
    -       because this code was so simply that it e.g. worked on Solaris
    +       because this code was so simple that it e.g. worked on Solaris
            /bin/sh.
     
          - Removes the "mkdir .git/hooks" invocation, as explained in a
-- 
2.35.1.1242.gfeba0eae32b


^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v2 01/10] hook tests: turn exit code assertions into a loop
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
@ 2022-03-07 12:43   ` Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 02/10] t5540: don't rely on "hook/post-update.sample" Ævar Arnfjörð Bjarmason
                     ` (10 subsequent siblings)
  11 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-07 12:43 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Amend a test added in 96e7225b310 (hook: add 'run' subcommand,
2021-12-22) to use a for-loop instead of a copy/pasting the same test
for the four exit codes we test.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1800-hook.sh | 35 ++++++++++-------------------------
 1 file changed, 10 insertions(+), 25 deletions(-)

diff --git a/t/t1800-hook.sh b/t/t1800-hook.sh
index 29718aa9913..ff64597e959 100755
--- a/t/t1800-hook.sh
+++ b/t/t1800-hook.sh
@@ -53,31 +53,16 @@ test_expect_success 'git hook run: stdout and stderr both write to our stderr' '
 	test_must_be_empty stdout.actual
 '
 
-test_expect_success 'git hook run: exit codes are passed along' '
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 1
-	EOF
-
-	test_expect_code 1 git hook run test-hook &&
-
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 2
-	EOF
-
-	test_expect_code 2 git hook run test-hook &&
-
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 128
-	EOF
-
-	test_expect_code 128 git hook run test-hook &&
-
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 129
-	EOF
-
-	test_expect_code 129 git hook run test-hook
-'
+for code in 1 2 128 129
+do
+	test_expect_success "git hook run: exit code $code is passed along" '
+		write_script .git/hooks/test-hook <<-EOF &&
+		exit $code
+		EOF
+
+		test_expect_code $code git hook run test-hook
+	'
+done
 
 test_expect_success 'git hook run arg u ments without -- is not allowed' '
 	test_expect_code 129 git hook run test-hook arg u ments
-- 
2.35.1.1242.gfeba0eae32b


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 02/10] t5540: don't rely on "hook/post-update.sample"
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 01/10] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
@ 2022-03-07 12:43   ` Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 03/10] tests: assume the hooks are disabled by default Ævar Arnfjörð Bjarmason
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-07 12:43 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change code added in a87679339c0 (test: rename http fetch and push
test files, 2014-02-06) to stop relying on the "exec git
update-server-info" in "templates/hooks--post-update.sample", let's
instead inline the expected hook in the test itself.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5540-http-push-webdav.sh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/t/t5540-http-push-webdav.sh b/t/t5540-http-push-webdav.sh
index b0dbacf0b9b..380e97c1762 100755
--- a/t/t5540-http-push-webdav.sh
+++ b/t/t5540-http-push-webdav.sh
@@ -42,7 +42,9 @@ test_expect_success 'setup remote repository' '
 	git clone --bare test_repo test_repo.git &&
 	cd test_repo.git &&
 	git --bare update-server-info &&
-	mv hooks/post-update.sample hooks/post-update &&
+	write_script hooks/post-update <<-\EOF &&
+	exec git update-server-info
+	EOF
 	ORIG_HEAD=$(git rev-parse --verify HEAD) &&
 	cd - &&
 	mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH"
-- 
2.35.1.1242.gfeba0eae32b


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 03/10] tests: assume the hooks are disabled by default
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 01/10] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 02/10] t5540: don't rely on "hook/post-update.sample" Ævar Arnfjörð Bjarmason
@ 2022-03-07 12:43   ` Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 04/10] bugreport tests: tighten up "git bugreport -s hooks" test Ævar Arnfjörð Bjarmason
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-07 12:43 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Stop moving the .git/hooks directory out of the way, or creating it
during test setup. Instead assume that it will contain
harmless *.sample files.

That we can assume that is discussed in point #4 of
f0d4d398e28 (test-lib: split up and deprecate test_create_repo(),
2021-05-10), those parts of this could and should have been done in
that change.

Removing the "mkdir -p" here will then validate that our templates are
being used, since we'd subsequently fail to create a hook in that
directory if it didn't exist. Subsequent commits will have those hooks
created by a "test_hook" wrapper, which will then being doing that
same validation.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1416-ref-transaction-hooks.sh | 1 -
 t/t5516-fetch-push.sh            | 3 +--
 t/t7519-status-fsmonitor.sh      | 2 --
 3 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh
index 4e1e84a91f3..d21dd5e5df0 100755
--- a/t/t1416-ref-transaction-hooks.sh
+++ b/t/t1416-ref-transaction-hooks.sh
@@ -8,7 +8,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 . ./test-lib.sh
 
 test_expect_success setup '
-	mkdir -p .git/hooks &&
 	test_commit PRE &&
 	PRE_OID=$(git rev-parse PRE) &&
 	test_commit POST &&
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 3137eb8d4d2..1a20e54adc1 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -28,8 +28,7 @@ mk_empty () {
 	(
 		cd "$repo_name" &&
 		git init &&
-		git config receive.denyCurrentBranch warn &&
-		mv .git/hooks .git/hooks-disabled
+		git config receive.denyCurrentBranch warn
 	)
 }
 
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index a6308acf006..63a0f609866 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -56,7 +56,6 @@ test_lazy_prereq UNTRACKED_CACHE '
 '
 
 test_expect_success 'setup' '
-	mkdir -p .git/hooks &&
 	: >tracked &&
 	: >modified &&
 	mkdir dir1 &&
@@ -322,7 +321,6 @@ test_expect_success UNTRACKED_CACHE 'ignore .git changes when invalidating UNTR'
 	test_create_repo dot-git &&
 	(
 		cd dot-git &&
-		mkdir -p .git/hooks &&
 		: >tracked &&
 		: >modified &&
 		mkdir dir1 &&
-- 
2.35.1.1242.gfeba0eae32b


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 04/10] bugreport tests: tighten up "git bugreport -s hooks" test
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
                     ` (2 preceding siblings ...)
  2022-03-07 12:43   ` [PATCH v2 03/10] tests: assume the hooks are disabled by default Ævar Arnfjörð Bjarmason
@ 2022-03-07 12:43   ` Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 05/10] tests: indent and add hook setup to "test_expect_success" Ævar Arnfjörð Bjarmason
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-07 12:43 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Amend a test added in 788a776069b (bugreport: collect list of
populated hooks, 2020-05-07) to "test_cmp" for the expected output,
instead of selectively using "grep" to check for specific things we
either expect or don't expect in the output.

As noted in a preceding commit our .git/hooks directory already
contains *.sample hooks, so we have no need to clobber the
prepare-commit-msg.sample hook in particular.

Instead we should assert that those *.sample hooks are not included in
the output, and for good measure let's add a new "unknown-hook", to
check that we only look through our own known hooks. See
cfe853e66be (hook-list.h: add a generated list of hooks, like
config-list.h, 2021-09-26) for how we generate that data.

We're intentionally not piping the "actual" output through "sort" or
similar, we'd also like to check that our reported hooks are sorted.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0091-bugreport.sh | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh
index eeedbfa9193..d51e18b0bb9 100755
--- a/t/t0091-bugreport.sh
+++ b/t/t0091-bugreport.sh
@@ -60,18 +60,22 @@ test_expect_success 'can create leading directories outside of a git dir' '
 
 test_expect_success 'indicates populated hooks' '
 	test_when_finished rm git-bugreport-hooks.txt &&
-	test_when_finished rm -fr .git/hooks &&
-	rm -fr .git/hooks &&
-	mkdir .git/hooks &&
-	for hook in applypatch-msg prepare-commit-msg.sample
-	do
-		write_script ".git/hooks/$hook" <<-EOF || return 1
-		echo "hook $hook exists"
-		EOF
-	done &&
+
+	write_script .git/hooks/applypatch-msg <<-\EOF &&
+	true
+	EOF
+	write_script .git/hooks/unknown-hook <<-\EOF &&
+	true
+	EOF
 	git bugreport -s hooks &&
-	grep applypatch-msg git-bugreport-hooks.txt &&
-	! grep prepare-commit-msg git-bugreport-hooks.txt
+
+	sort >expect <<-\EOF &&
+	[Enabled Hooks]
+	applypatch-msg
+	EOF
+
+	sed -ne "/^\[Enabled Hooks\]$/,/^$/p" <git-bugreport-hooks.txt >actual &&
+	test_cmp expect actual
 '
 
 test_done
-- 
2.35.1.1242.gfeba0eae32b


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 05/10] tests: indent and add hook setup to "test_expect_success"
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
                     ` (3 preceding siblings ...)
  2022-03-07 12:43   ` [PATCH v2 04/10] bugreport tests: tighten up "git bugreport -s hooks" test Ævar Arnfjörð Bjarmason
@ 2022-03-07 12:43   ` Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 06/10] hook tests: get rid of unnecessary sub-shells Ævar Arnfjörð Bjarmason
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-07 12:43 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Indent various hook setup code in the test suite that's using a manual
"cat && chmod" pattern.

These should also consistently use "#!$SHELL_PATH" instead of
"#!/bin/sh", i.e. "test_script". Let's fix that in a subsequent
commit, which will be easier to review after this smaller change.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3412-rebase-root.sh       | 16 ++++----
 t/t3413-rebase-hook.sh       | 16 ++++----
 t/t5401-update-hooks.sh      | 76 ++++++++++++++++++------------------
 t/t5407-post-rewrite-hook.sh | 16 ++++----
 t/t5541-http-push-smart.sh   | 24 ++++++------
 5 files changed, 75 insertions(+), 73 deletions(-)

diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
index 1e9f7833dd6..239a9343d34 100755
--- a/t/t3412-rebase-root.sh
+++ b/t/t3412-rebase-root.sh
@@ -32,10 +32,10 @@ test_expect_success 'rebase --root fails with too many args' '
 
 test_expect_success 'setup pre-rebase hook' '
 	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-echo "\$1,\$2" >.git/PRE-REBASE-INPUT
-EOF
+	cat >.git/hooks/pre-rebase <<-EOF &&
+	#!$SHELL_PATH
+	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+	EOF
 	chmod +x .git/hooks/pre-rebase
 '
 cat > expect <<EOF
@@ -142,10 +142,10 @@ EOF
 
 test_expect_success 'setup pre-rebase hook that fails' '
 	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-false
-EOF
+	cat >.git/hooks/pre-rebase <<-EOF &&
+	#!$SHELL_PATH
+	false
+	EOF
 	chmod +x .git/hooks/pre-rebase
 '
 
diff --git a/t/t3413-rebase-hook.sh b/t/t3413-rebase-hook.sh
index b4acb3be5cf..bb241b26b2e 100755
--- a/t/t3413-rebase-hook.sh
+++ b/t/t3413-rebase-hook.sh
@@ -42,10 +42,10 @@ test_expect_success 'rebase -i' '
 
 test_expect_success 'setup pre-rebase hook' '
 	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-echo "\$1,\$2" >.git/PRE-REBASE-INPUT
-EOF
+	cat >.git/hooks/pre-rebase <<-EOF &&
+	#!$SHELL_PATH
+	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+	EOF
 	chmod +x .git/hooks/pre-rebase
 '
 
@@ -103,10 +103,10 @@ test_expect_success 'pre-rebase hook gets correct input (6)' '
 
 test_expect_success 'setup pre-rebase hook that fails' '
 	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-false
-EOF
+	cat >.git/hooks/pre-rebase <<-EOF &&
+	#!$SHELL_PATH
+	false
+	EOF
 	chmod +x .git/hooks/pre-rebase
 '
 
diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
index 6012cc8172a..6392f71795d 100755
--- a/t/t5401-update-hooks.sh
+++ b/t/t5401-update-hooks.sh
@@ -20,46 +20,46 @@ test_expect_success setup '
 	git clone --bare ./. victim.git &&
 	GIT_DIR=victim.git git update-ref refs/heads/tofail $commit1 &&
 	git update-ref refs/heads/main $commit1 &&
-	git update-ref refs/heads/tofail $commit0
+	git update-ref refs/heads/tofail $commit0 &&
+
+	cat >victim.git/hooks/pre-receive <<-\EOF &&
+	#!/bin/sh
+	printf %s "$@" >>$GIT_DIR/pre-receive.args
+	cat - >$GIT_DIR/pre-receive.stdin
+	echo STDOUT pre-receive
+	echo STDERR pre-receive >&2
+	EOF
+	chmod u+x victim.git/hooks/pre-receive &&
+
+	cat >victim.git/hooks/update <<-\EOF &&
+	#!/bin/sh
+	echo "$@" >>$GIT_DIR/update.args
+	read x; printf %s "$x" >$GIT_DIR/update.stdin
+	echo STDOUT update $1
+	echo STDERR update $1 >&2
+	test "$1" = refs/heads/main || exit
+	EOF
+	chmod u+x victim.git/hooks/update &&
+
+	cat >victim.git/hooks/post-receive <<-\EOF &&
+	#!/bin/sh
+	printf %s "$@" >>$GIT_DIR/post-receive.args
+	cat - >$GIT_DIR/post-receive.stdin
+	echo STDOUT post-receive
+	echo STDERR post-receive >&2
+	EOF
+	chmod u+x victim.git/hooks/post-receive &&
+
+	cat >victim.git/hooks/post-update <<-\EOF &&
+	#!/bin/sh
+	echo "$@" >>$GIT_DIR/post-update.args
+	read x; printf %s "$x" >$GIT_DIR/post-update.stdin
+	echo STDOUT post-update
+	echo STDERR post-update >&2
+	EOF
+	chmod u+x victim.git/hooks/post-update
 '
 
-cat >victim.git/hooks/pre-receive <<'EOF'
-#!/bin/sh
-printf %s "$@" >>$GIT_DIR/pre-receive.args
-cat - >$GIT_DIR/pre-receive.stdin
-echo STDOUT pre-receive
-echo STDERR pre-receive >&2
-EOF
-chmod u+x victim.git/hooks/pre-receive
-
-cat >victim.git/hooks/update <<'EOF'
-#!/bin/sh
-echo "$@" >>$GIT_DIR/update.args
-read x; printf %s "$x" >$GIT_DIR/update.stdin
-echo STDOUT update $1
-echo STDERR update $1 >&2
-test "$1" = refs/heads/main || exit
-EOF
-chmod u+x victim.git/hooks/update
-
-cat >victim.git/hooks/post-receive <<'EOF'
-#!/bin/sh
-printf %s "$@" >>$GIT_DIR/post-receive.args
-cat - >$GIT_DIR/post-receive.stdin
-echo STDOUT post-receive
-echo STDERR post-receive >&2
-EOF
-chmod u+x victim.git/hooks/post-receive
-
-cat >victim.git/hooks/post-update <<'EOF'
-#!/bin/sh
-echo "$@" >>$GIT_DIR/post-update.args
-read x; printf %s "$x" >$GIT_DIR/post-update.stdin
-echo STDOUT post-update
-echo STDERR post-update >&2
-EOF
-chmod u+x victim.git/hooks/post-update
-
 test_expect_success push '
 	test_must_fail git send-pack --force ./victim.git \
 		main tofail >send.out 2>send.err
diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
index 6da8d760e28..64f40ff7776 100755
--- a/t/t5407-post-rewrite-hook.sh
+++ b/t/t5407-post-rewrite-hook.sh
@@ -17,15 +17,15 @@ test_expect_success 'setup' '
 	git checkout A^0 &&
 	test_commit E bar E &&
 	test_commit F foo F &&
-	git checkout main
-'
+	git checkout main &&
 
-cat >.git/hooks/post-rewrite <<EOF
-#!/bin/sh
-echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
-cat > "$TRASH_DIRECTORY"/post-rewrite.data
-EOF
-chmod u+x .git/hooks/post-rewrite
+	cat >.git/hooks/post-rewrite <<-EOF &&
+	#!/bin/sh
+	echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
+	cat > "$TRASH_DIRECTORY"/post-rewrite.data
+	EOF
+	chmod u+x .git/hooks/post-rewrite
+'
 
 clear_hook_input () {
 	rm -f post-rewrite.args post-rewrite.data
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index 8ca50f8b18c..0043b718f08 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -96,18 +96,20 @@ test_expect_success 'create and delete remote branch' '
 	test_must_fail git show-ref --verify refs/remotes/origin/dev
 '
 
-cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<EOF
-#!/bin/sh
-exit 1
-EOF
-chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update"
+test_expect_success 'setup rejected update hook' '
+	cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<-EOF &&
+	#!/bin/sh
+	exit 1
+	EOF
+	chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" &&
 
-cat >exp <<EOF
-remote: error: hook declined to update refs/heads/dev2
-To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git
- ! [remote rejected] dev2 -> dev2 (hook declined)
-error: failed to push some refs to 'http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'
-EOF
+	cat >exp <<-EOF
+	remote: error: hook declined to update refs/heads/dev2
+	To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git
+	 ! [remote rejected] dev2 -> dev2 (hook declined)
+	error: failed to push some refs to '\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\''
+	EOF
+'
 
 test_expect_success 'rejected update prints status' '
 	cd "$ROOT_PATH"/test_repo_clone &&
-- 
2.35.1.1242.gfeba0eae32b


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 06/10] hook tests: get rid of unnecessary sub-shells
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
                     ` (4 preceding siblings ...)
  2022-03-07 12:43   ` [PATCH v2 05/10] tests: indent and add hook setup to "test_expect_success" Ævar Arnfjörð Bjarmason
@ 2022-03-07 12:43   ` Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 07/10] fetch+push tests: have tests clean up their own mess Ævar Arnfjörð Bjarmason
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-07 12:43 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Refactor the repository setup code for tests that test hooks the use
of sub-shells when setting up the test repository and hooks.

A subsequent commit will change the hook setup to use a helper that
makes use of "test_when_finished", which cannot be used in
sub-shells. Let's change that setup code, and the adjacent and similar
"mk_empty" code.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5516-fetch-push.sh   | 150 ++++++++++++++++++----------------------
 t/t6500-gc.sh           |  18 ++---
 t/t9800-git-p4-basic.sh |  24 ++++---
 3 files changed, 94 insertions(+), 98 deletions(-)

diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 1a20e54adc1..e4bb7581568 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -24,12 +24,8 @@ D=$(pwd)
 mk_empty () {
 	repo_name="$1"
 	rm -fr "$repo_name" &&
-	mkdir "$repo_name" &&
-	(
-		cd "$repo_name" &&
-		git init &&
-		git config receive.denyCurrentBranch warn
-	)
+	git init "$repo_name" &&
+	git -C "$repo_name" config receive.denyCurrentBranch warn
 }
 
 mk_test () {
@@ -58,36 +54,35 @@ mk_test () {
 mk_test_with_hooks() {
 	repo_name=$1
 	mk_test "$@" &&
-	(
-		cd "$repo_name" &&
-		mkdir .git/hooks &&
-		cd .git/hooks &&
-
-		cat >pre-receive <<-'EOF' &&
-		#!/bin/sh
-		cat - >>pre-receive.actual
-		EOF
 
-		cat >update <<-'EOF' &&
-		#!/bin/sh
-		printf "%s %s %s\n" "$@" >>update.actual
-		EOF
-
-		cat >post-receive <<-'EOF' &&
-		#!/bin/sh
-		cat - >>post-receive.actual
-		EOF
-
-		cat >post-update <<-'EOF' &&
-		#!/bin/sh
-		for ref in "$@"
-		do
-			printf "%s\n" "$ref" >>post-update.actual
-		done
-		EOF
-
-		chmod +x pre-receive update post-receive post-update
-	)
+	cat >"$repo_name"/.git/hooks/pre-receive <<-'EOF' &&
+	#!/bin/sh
+	cat - >>pre-receive.actual
+	EOF
+
+	cat >"$repo_name"/.git/hooks/update <<-'EOF' &&
+	#!/bin/sh
+	printf "%s %s %s\n" "$@" >>update.actual
+	EOF
+
+	cat >"$repo_name"/.git/hooks/post-receive <<-'EOF' &&
+	#!/bin/sh
+	cat - >>post-receive.actual
+	EOF
+
+	cat >"$repo_name"/.git/hooks/post-update <<-'EOF' &&
+	#!/bin/sh
+	for ref in "$@"
+	do
+		printf "%s\n" "$ref" >>post-update.actual
+	done
+	EOF
+
+	chmod +x \
+	      "$repo_name"/.git/hooks/pre-receive \
+	      "$repo_name"/.git/hooks/update \
+	      "$repo_name"/.git/hooks/post-receive \
+	      "$repo_name"/.git/hooks/post-update
 }
 
 mk_child() {
@@ -667,7 +662,6 @@ test_expect_success 'push does not update local refs on failure' '
 
 	mk_test testrepo heads/main &&
 	mk_child testrepo child &&
-	mkdir testrepo/.git/hooks &&
 	echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive &&
 	chmod +x testrepo/.git/hooks/pre-receive &&
 	(
@@ -1679,24 +1673,21 @@ test_expect_success 'receive.denyCurrentBranch = updateInstead' '
 test_expect_success 'updateInstead with push-to-checkout hook' '
 	rm -fr testrepo &&
 	git init testrepo &&
-	(
-		cd testrepo &&
-		git pull .. main &&
-		git reset --hard HEAD^^ &&
-		git tag initial &&
-		git config receive.denyCurrentBranch updateInstead &&
-		write_script .git/hooks/push-to-checkout <<-\EOF
-		echo >&2 updating from $(git rev-parse HEAD)
-		echo >&2 updating to "$1"
-
-		git update-index -q --refresh &&
-		git read-tree -u -m HEAD "$1" || {
-			status=$?
-			echo >&2 read-tree failed
-			exit $status
-		}
-		EOF
-	) &&
+	git -C testrepo pull .. main &&
+	git -C testrepo reset --hard HEAD^^ &&
+	git -C testrepo tag initial &&
+	git -C testrepo config receive.denyCurrentBranch updateInstead &&
+	write_script testrepo/.git/hooks/push-to-checkout <<-\EOF &&
+	echo >&2 updating from $(git rev-parse HEAD)
+	echo >&2 updating to "$1"
+
+	git update-index -q --refresh &&
+	git read-tree -u -m HEAD "$1" || {
+		status=$?
+		echo >&2 read-tree failed
+		exit $status
+	}
+	EOF
 
 	# Try pushing into a pristine
 	git push testrepo main &&
@@ -1741,33 +1732,30 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
 	# push into void
 	rm -fr void &&
 	git init void &&
-	(
-		cd void &&
-		git config receive.denyCurrentBranch updateInstead &&
-		write_script .git/hooks/push-to-checkout <<-\EOF
-		if git rev-parse --quiet --verify HEAD
-		then
-			has_head=yes
-			echo >&2 updating from $(git rev-parse HEAD)
-		else
-			has_head=no
-			echo >&2 pushing into void
-		fi
-		echo >&2 updating to "$1"
-
-		git update-index -q --refresh &&
-		case "$has_head" in
-		yes)
-			git read-tree -u -m HEAD "$1" ;;
-		no)
-			git read-tree -u -m "$1" ;;
-		esac || {
-			status=$?
-			echo >&2 read-tree failed
-			exit $status
-		}
-		EOF
-	) &&
+	git -C void config receive.denyCurrentBranch updateInstead &&
+	write_script void/.git/hooks/push-to-checkout <<-\EOF &&
+	if git rev-parse --quiet --verify HEAD
+	then
+		has_head=yes
+		echo >&2 updating from $(git rev-parse HEAD)
+	else
+		has_head=no
+		echo >&2 pushing into void
+	fi
+	echo >&2 updating to "$1"
+
+	git update-index -q --refresh &&
+	case "$has_head" in
+	yes)
+		git read-tree -u -m HEAD "$1" ;;
+	no)
+		git read-tree -u -m "$1" ;;
+	esac || {
+		status=$?
+		echo >&2 read-tree failed
+		exit $status
+	}
+	EOF
 
 	git push void main &&
 	(
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index c2021267f2c..a6b0db22867 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -101,12 +101,12 @@ test_expect_success 'pre-auto-gc hook can stop auto gc' '
 	EOF
 
 	git init pre-auto-gc-hook &&
+	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
+	echo >&2 no gc for you &&
+	exit 1
+	EOF
 	(
 		cd pre-auto-gc-hook &&
-		write_script ".git/hooks/pre-auto-gc" <<-\EOF &&
-		echo >&2 no gc for you &&
-		exit 1
-		EOF
 
 		git config gc.auto 3 &&
 		git config gc.autoDetach false &&
@@ -128,12 +128,14 @@ test_expect_success 'pre-auto-gc hook can stop auto gc' '
 	See "git help gc" for manual housekeeping.
 	EOF
 
+	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
+	echo >&2 will gc for you &&
+	exit 0
+	EOF
+
 	(
 		cd pre-auto-gc-hook &&
-		write_script ".git/hooks/pre-auto-gc" <<-\EOF &&
-		echo >&2 will gc for you &&
-		exit 0
-		EOF
+
 		git gc --auto >../out.actual 2>../err.actual
 	) &&
 
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index 806005a793a..3c1534c94d6 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -277,16 +277,22 @@ test_expect_success 'run hook p4-pre-submit before submit' '
 		git commit -m "add hello.txt" &&
 		git config git-p4.skipSubmitEdit true &&
 		git p4 submit --dry-run >out &&
-		grep "Would apply" out &&
-		mkdir -p .git/hooks &&
-		write_script .git/hooks/p4-pre-submit <<-\EOF &&
-		exit 0
-		EOF
+		grep "Would apply" out
+	) &&
+	mkdir -p "$git"/.git/hooks &&
+	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
+	exit 0
+	EOF
+	(
+		cd "$git" &&
 		git p4 submit --dry-run >out &&
-		grep "Would apply" out &&
-		write_script .git/hooks/p4-pre-submit <<-\EOF &&
-		exit 1
-		EOF
+		grep "Would apply" out
+	) &&
+	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
+	exit 1
+	EOF
+	(
+		cd "$git" &&
 		test_must_fail git p4 submit --dry-run >errs 2>&1 &&
 		! grep "Would apply" errs
 	)
-- 
2.35.1.1242.gfeba0eae32b


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 07/10] fetch+push tests: have tests clean up their own mess
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
                     ` (5 preceding siblings ...)
  2022-03-07 12:43   ` [PATCH v2 06/10] hook tests: get rid of unnecessary sub-shells Ævar Arnfjörð Bjarmason
@ 2022-03-07 12:43   ` Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 08/10] test-lib-functions: add and use a "test_hook" wrapper Ævar Arnfjörð Bjarmason
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-07 12:43 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change the "t5516-fetch-push.sh" test code to make use of
"test_when_finished" to remove data instead of having tests clean up
leftover data from earlier tests, which may or may not be
there (e.g. depending on the --run=* option).

Before this each test would have been responsible for cleaning up
after a preceding test (which may or may not have run, e.g. if --run
or "GIT_SKIP_TESTS" was used), now each test will instead clean up
after itself.

When doing this split up the "push with negotiation" test, now the
middle of the test doesn't need to "rm event", and since it delimited
two halves that were testing two different things the end-state is
easier to read and reason about.

While changing these lines make the minor change from "-fr" to "-rf"
as the "rm" argument, some of them used it already, it's more common
in the test suite, and it leaves the end-state of the file with more
consistency.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5516-fetch-push.sh | 50 +++++++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index e4bb7581568..fbe0a72b0b2 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -23,7 +23,8 @@ D=$(pwd)
 
 mk_empty () {
 	repo_name="$1"
-	rm -fr "$repo_name" &&
+	test_when_finished "rm -rf \"$repo_name\"" &&
+	test_path_is_missing "$repo_name" &&
 	git init "$repo_name" &&
 	git -C "$repo_name" config receive.denyCurrentBranch warn
 }
@@ -86,7 +87,7 @@ mk_test_with_hooks() {
 }
 
 mk_child() {
-	rm -rf "$2" &&
+	test_when_finished "rm -rf \"$2\"" &&
 	git clone "$1" "$2"
 }
 
@@ -191,32 +192,32 @@ grep_wrote () {
 	grep 'write_pack_file/wrote.*"value":"'$1'"' $2
 }
 
-test_expect_success 'push with negotiation' '
-	# Without negotiation
+test_expect_success 'push without negotiation' '
 	mk_empty testrepo &&
 	git push testrepo $the_first_commit:refs/remotes/origin/first_commit &&
 	test_commit -C testrepo unrelated_commit &&
 	git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit &&
-	echo now pushing without negotiation &&
+	test_when_finished "rm event" &&
 	GIT_TRACE2_EVENT="$(pwd)/event" git -c protocol.version=2 push testrepo refs/heads/main:refs/remotes/origin/main &&
-	grep_wrote 5 event && # 2 commits, 2 trees, 1 blob
+	grep_wrote 5 event # 2 commits, 2 trees, 1 blob
+'
 
-	# Same commands, but with negotiation
-	rm event &&
+test_expect_success 'push with negotiation' '
 	mk_empty testrepo &&
 	git push testrepo $the_first_commit:refs/remotes/origin/first_commit &&
 	test_commit -C testrepo unrelated_commit &&
 	git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit &&
+	test_when_finished "rm event" &&
 	GIT_TRACE2_EVENT="$(pwd)/event" git -c protocol.version=2 -c push.negotiate=1 push testrepo refs/heads/main:refs/remotes/origin/main &&
 	grep_wrote 2 event # 1 commit, 1 tree
 '
 
 test_expect_success 'push with negotiation proceeds anyway even if negotiation fails' '
-	rm event &&
 	mk_empty testrepo &&
 	git push testrepo $the_first_commit:refs/remotes/origin/first_commit &&
 	test_commit -C testrepo unrelated_commit &&
 	git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit &&
+	test_when_finished "rm event" &&
 	GIT_TEST_PROTOCOL_VERSION=0 GIT_TRACE2_EVENT="$(pwd)/event" \
 		git -c push.negotiate=1 push testrepo refs/heads/main:refs/remotes/origin/main 2>err &&
 	grep_wrote 5 event && # 2 commits, 2 trees, 1 blob
@@ -1323,7 +1324,7 @@ done
 
 test_expect_success 'fetch follows tags by default' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
 	(
 		cd src &&
@@ -1333,6 +1334,7 @@ test_expect_success 'fetch follows tags by default' '
 		sed -n "p; s|refs/heads/main$|refs/remotes/origin/main|p" tmp1 |
 		sort -k 3 >../expect
 	) &&
+	test_when_finished "rm -rf dst" &&
 	git init dst &&
 	(
 		cd dst &&
@@ -1358,8 +1360,9 @@ test_expect_success 'peeled advertisements are not considered ref tips' '
 
 test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1382,8 +1385,9 @@ test_expect_success 'pushing a specific ref applies remote.$name.push as refmap'
 
 test_expect_success 'with no remote.$name.push, it is not used as refmap' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1404,8 +1408,9 @@ test_expect_success 'with no remote.$name.push, it is not used as refmap' '
 
 test_expect_success 'with no remote.$name.push, upstream mapping is used' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1433,8 +1438,9 @@ test_expect_success 'with no remote.$name.push, upstream mapping is used' '
 
 test_expect_success 'push does not follow tags by default' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1456,8 +1462,9 @@ test_expect_success 'push does not follow tags by default' '
 
 test_expect_success 'push --follow-tags only pushes relevant tags' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1495,9 +1502,9 @@ EOF
 '
 
 test_expect_success 'pushing a tag pushes the tagged object' '
-	rm -rf dst.git &&
 	blob=$(echo unreferenced | git hash-object -w --stdin) &&
 	git tag -m foo tag-of-blob $blob &&
+	test_when_finished "rm -rf dst.git" &&
 	git init --bare dst.git &&
 	git push dst.git tag-of-blob &&
 	# the receiving index-pack should have noticed
@@ -1508,7 +1515,7 @@ test_expect_success 'pushing a tag pushes the tagged object' '
 '
 
 test_expect_success 'push into bare respects core.logallrefupdates' '
-	rm -rf dst.git &&
+	test_when_finished "rm -rf dst.git" &&
 	git init --bare dst.git &&
 	git -C dst.git config core.logallrefupdates true &&
 
@@ -1526,7 +1533,7 @@ test_expect_success 'push into bare respects core.logallrefupdates' '
 '
 
 test_expect_success 'fetch into bare respects core.logallrefupdates' '
-	rm -rf dst.git &&
+	test_when_finished "rm -rf dst.git" &&
 	git init --bare dst.git &&
 	(
 		cd dst.git &&
@@ -1547,6 +1554,7 @@ test_expect_success 'fetch into bare respects core.logallrefupdates' '
 '
 
 test_expect_success 'receive.denyCurrentBranch = updateInstead' '
+	mk_empty testrepo &&
 	git push testrepo main &&
 	(
 		cd testrepo &&
@@ -1649,7 +1657,7 @@ test_expect_success 'receive.denyCurrentBranch = updateInstead' '
 	) &&
 
 	# (5) push into void
-	rm -fr void &&
+	test_when_finished "rm -rf void" &&
 	git init void &&
 	(
 		cd void &&
@@ -1671,7 +1679,7 @@ test_expect_success 'receive.denyCurrentBranch = updateInstead' '
 '
 
 test_expect_success 'updateInstead with push-to-checkout hook' '
-	rm -fr testrepo &&
+	test_when_finished "rm -rf testrepo" &&
 	git init testrepo &&
 	git -C testrepo pull .. main &&
 	git -C testrepo reset --hard HEAD^^ &&
@@ -1730,7 +1738,7 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
 	) &&
 
 	# push into void
-	rm -fr void &&
+	test_when_finished "rm -rf void" &&
 	git init void &&
 	git -C void config receive.denyCurrentBranch updateInstead &&
 	write_script void/.git/hooks/push-to-checkout <<-\EOF &&
-- 
2.35.1.1242.gfeba0eae32b


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 08/10] test-lib-functions: add and use a "test_hook" wrapper
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
                     ` (6 preceding siblings ...)
  2022-03-07 12:43   ` [PATCH v2 07/10] fetch+push tests: have tests clean up their own mess Ævar Arnfjörð Bjarmason
@ 2022-03-07 12:43   ` Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 09/10] tests: change "mkdir -p && write_script" to use "test_hook" Ævar Arnfjörð Bjarmason
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-07 12:43 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Add a "test_hook" wrapper similar to the existing "test_config"
wrapper added in d960c47a881 (test-lib: add helper functions for
config, 2011-08-17).

This wrapper:

 - Will clean up the hook with "test_when_finished", unless --setup is
   provided.

 - Will error if we clobber a hook, unless --clobber is provided.

 - Takes a name like "update" instead of ".git/hooks/update".

 - Accepts -C <dir>, like "test_config" and "test_commit".

By using a wrapper we'll be able to easily change all the hook-related
code that assumes that the template-created ".git/hooks" directory is
created by "init", "clone" etc. once another topic follows-up and
changes the test suite to stop creating trash directories using those
templates.

In addition this will make it easy to have the hooks configured using
the "configuration-based hooks" topic, once we get around to
integrating that. I.e. we'll be able to run the tests in a mode where
we sometimes create a .git/hooks/<name>, and other times create a
script in another location, and point the relevant configuration
snippet to it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0091-bugreport.sh                |  4 +--
 t/t1416-ref-transaction-hooks.sh    | 26 +++++++--------
 t/t1800-hook.sh                     | 14 +++++---
 t/t5406-remote-rejects.sh           |  2 +-
 t/t5409-colorize-remote-messages.sh |  2 +-
 t/t5411-proc-receive-hook.sh        |  4 +--
 t/t5510-fetch.sh                    |  6 ++--
 t/t5516-fetch-push.sh               |  4 +--
 t/t5521-pull-options.sh             |  4 +--
 t/t5540-http-push-webdav.sh         |  2 +-
 t/t5547-push-quarantine.sh          |  4 +--
 t/t5548-push-porcelain.sh           |  2 +-
 t/t6500-gc.sh                       |  4 +--
 t/t7519-status-fsmonitor.sh         | 18 +++++-----
 t/test-lib-functions.sh             | 52 +++++++++++++++++++++++++++++
 15 files changed, 101 insertions(+), 47 deletions(-)

diff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh
index d51e18b0bb9..08f5fe9caef 100755
--- a/t/t0091-bugreport.sh
+++ b/t/t0091-bugreport.sh
@@ -61,10 +61,10 @@ test_expect_success 'can create leading directories outside of a git dir' '
 test_expect_success 'indicates populated hooks' '
 	test_when_finished rm git-bugreport-hooks.txt &&
 
-	write_script .git/hooks/applypatch-msg <<-\EOF &&
+	test_hook applypatch-msg <<-\EOF &&
 	true
 	EOF
-	write_script .git/hooks/unknown-hook <<-\EOF &&
+	test_hook unknown-hook <<-\EOF &&
 	true
 	EOF
 	git bugreport -s hooks &&
diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh
index d21dd5e5df0..085a7a46f21 100755
--- a/t/t1416-ref-transaction-hooks.sh
+++ b/t/t1416-ref-transaction-hooks.sh
@@ -15,9 +15,8 @@ test_expect_success setup '
 '
 
 test_expect_success 'hook allows updating ref if successful' '
-	test_when_finished "rm .git/hooks/reference-transaction" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		echo "$*" >>actual
 	EOF
 	cat >expect <<-EOF &&
@@ -29,9 +28,8 @@ test_expect_success 'hook allows updating ref if successful' '
 '
 
 test_expect_success 'hook aborts updating ref in prepared state' '
-	test_when_finished "rm .git/hooks/reference-transaction" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = prepared
 		then
 			exit 1
@@ -42,9 +40,9 @@ test_expect_success 'hook aborts updating ref in prepared state' '
 '
 
 test_expect_success 'hook gets all queued updates in prepared state' '
-	test_when_finished "rm .git/hooks/reference-transaction actual" &&
+	test_when_finished "rm actual" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = prepared
 		then
 			while read -r line
@@ -65,9 +63,9 @@ test_expect_success 'hook gets all queued updates in prepared state' '
 '
 
 test_expect_success 'hook gets all queued updates in committed state' '
-	test_when_finished "rm .git/hooks/reference-transaction actual" &&
+	test_when_finished "rm actual" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = committed
 		then
 			while read -r line
@@ -85,9 +83,9 @@ test_expect_success 'hook gets all queued updates in committed state' '
 '
 
 test_expect_success 'hook gets all queued updates in aborted state' '
-	test_when_finished "rm .git/hooks/reference-transaction actual" &&
+	test_when_finished "rm actual" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = aborted
 		then
 			while read -r line
@@ -114,11 +112,11 @@ test_expect_success 'interleaving hook calls succeed' '
 
 	git init --bare target-repo.git &&
 
-	write_script target-repo.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C target-repo.git reference-transaction <<-\EOF &&
 		echo $0 "$@" >>actual
 	EOF
 
-	write_script target-repo.git/hooks/update <<-\EOF &&
+	test_hook -C target-repo.git update <<-\EOF &&
 		echo $0 "$@" >>actual
 	EOF
 
@@ -139,7 +137,7 @@ test_expect_success 'hook does not get called on packing refs' '
 	# Pack references first such that we are in a known state.
 	git pack-refs --all &&
 
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		echo "$@" >>actual
 		cat >>actual
 	EOF
@@ -165,7 +163,7 @@ test_expect_success 'deleting packed ref calls hook once' '
 	git update-ref refs/heads/to-be-deleted $POST_OID &&
 	git pack-refs --all &&
 
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		echo "$@" >>actual
 		cat >>actual
 	EOF
diff --git a/t/t1800-hook.sh b/t/t1800-hook.sh
index ff64597e959..26ed5e11bc8 100755
--- a/t/t1800-hook.sh
+++ b/t/t1800-hook.sh
@@ -27,7 +27,7 @@ test_expect_success 'git hook run: nonexistent hook with --ignore-missing' '
 '
 
 test_expect_success 'git hook run: basic' '
-	write_script .git/hooks/test-hook <<-EOF &&
+	test_hook test-hook <<-EOF &&
 	echo Test hook
 	EOF
 
@@ -39,7 +39,7 @@ test_expect_success 'git hook run: basic' '
 '
 
 test_expect_success 'git hook run: stdout and stderr both write to our stderr' '
-	write_script .git/hooks/test-hook <<-EOF &&
+	test_hook test-hook <<-EOF &&
 	echo >&1 Will end up on stderr
 	echo >&2 Will end up on stderr
 	EOF
@@ -56,7 +56,7 @@ test_expect_success 'git hook run: stdout and stderr both write to our stderr' '
 for code in 1 2 128 129
 do
 	test_expect_success "git hook run: exit code $code is passed along" '
-		write_script .git/hooks/test-hook <<-EOF &&
+		test_hook test-hook <<-EOF &&
 		exit $code
 		EOF
 
@@ -69,7 +69,7 @@ test_expect_success 'git hook run arg u ments without -- is not allowed' '
 '
 
 test_expect_success 'git hook run -- pass arguments' '
-	write_script .git/hooks/test-hook <<-\EOF &&
+	test_hook test-hook <<-\EOF &&
 	echo $1
 	echo $2
 	EOF
@@ -84,7 +84,7 @@ test_expect_success 'git hook run -- pass arguments' '
 '
 
 test_expect_success 'git hook run -- out-of-repo runs excluded' '
-	write_script .git/hooks/test-hook <<-EOF &&
+	test_hook test-hook <<-EOF &&
 	echo Test hook
 	EOF
 
@@ -105,6 +105,10 @@ test_expect_success 'git -c core.hooksPath=<PATH> hook run' '
 	Hook ran four
 	EOF
 
+	test_hook test-hook <<-EOF &&
+	echo Test hook
+	EOF
+
 	# Test various ways of specifying the path. See also
 	# t1350-config-hooks-path.sh
 	>actual &&
diff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh
index 5c509db6fc3..dcbeb420827 100755
--- a/t/t5406-remote-rejects.sh
+++ b/t/t5406-remote-rejects.sh
@@ -5,7 +5,7 @@ test_description='remote push rejects are reported by client'
 . ./test-lib.sh
 
 test_expect_success 'setup' '
-	write_script .git/hooks/update <<-\EOF &&
+	test_hook update <<-\EOF &&
 	exit 1
 	EOF
 	echo 1 >file &&
diff --git a/t/t5409-colorize-remote-messages.sh b/t/t5409-colorize-remote-messages.sh
index 9f1a483f426..fa5de4500a4 100755
--- a/t/t5409-colorize-remote-messages.sh
+++ b/t/t5409-colorize-remote-messages.sh
@@ -5,7 +5,7 @@ test_description='remote messages are colorized on the client'
 . ./test-lib.sh
 
 test_expect_success 'setup' '
-	write_script .git/hooks/update <<-\EOF &&
+	test_hook --setup update <<-\EOF &&
 	echo error: error
 	echo ERROR: also highlighted
 	echo hint: hint
diff --git a/t/t5411-proc-receive-hook.sh b/t/t5411-proc-receive-hook.sh
index 98b0e812082..92cf52c6d4a 100755
--- a/t/t5411-proc-receive-hook.sh
+++ b/t/t5411-proc-receive-hook.sh
@@ -36,7 +36,7 @@ setup_upstream_and_workbench () {
 		TAG=$(git -C workbench rev-parse v123) &&
 
 		# setup pre-receive hook
-		write_script upstream.git/hooks/pre-receive <<-\EOF &&
+		test_hook --setup -C upstream.git pre-receive <<-\EOF &&
 		exec >&2
 		echo "# pre-receive hook"
 		while read old new ref
@@ -46,7 +46,7 @@ setup_upstream_and_workbench () {
 		EOF
 
 		# setup post-receive hook
-		write_script upstream.git/hooks/post-receive <<-\EOF &&
+		test_hook --setup -C upstream.git post-receive <<-\EOF &&
 		exec >&2
 		echo "# post-receive hook"
 		while read old new ref
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index ef0da0a63b5..4620f0ca7fa 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -273,7 +273,7 @@ test_expect_success 'fetch --atomic executes a single reference transaction only
 	EOF
 
 	rm -f atomic/actual &&
-	write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C atomic reference-transaction <<-\EOF &&
 		( echo "$*" && cat ) >>actual
 	EOF
 
@@ -306,7 +306,7 @@ test_expect_success 'fetch --atomic aborts all reference updates if hook aborts'
 	EOF
 
 	rm -f atomic/actual &&
-	write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C atomic/.git reference-transaction <<-\EOF &&
 		( echo "$*" && cat ) >>actual
 		exit 1
 	EOF
@@ -334,7 +334,7 @@ test_expect_success 'fetch --atomic --append appends to FETCH_HEAD' '
 	test_line_count = 2 atomic/.git/FETCH_HEAD &&
 	cp atomic/.git/FETCH_HEAD expected &&
 
-	write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C atomic reference-transaction <<-\EOF &&
 		exit 1
 	EOF
 
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index fbe0a72b0b2..b689baf01a9 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1685,7 +1685,7 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
 	git -C testrepo reset --hard HEAD^^ &&
 	git -C testrepo tag initial &&
 	git -C testrepo config receive.denyCurrentBranch updateInstead &&
-	write_script testrepo/.git/hooks/push-to-checkout <<-\EOF &&
+	test_hook -C testrepo push-to-checkout <<-\EOF &&
 	echo >&2 updating from $(git rev-parse HEAD)
 	echo >&2 updating to "$1"
 
@@ -1741,7 +1741,7 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
 	test_when_finished "rm -rf void" &&
 	git init void &&
 	git -C void config receive.denyCurrentBranch updateInstead &&
-	write_script void/.git/hooks/push-to-checkout <<-\EOF &&
+	test_hook -C void push-to-checkout <<-\EOF &&
 	if git rev-parse --quiet --verify HEAD
 	then
 		has_head=yes
diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh
index 66cfcb09c55..264de29c35c 100755
--- a/t/t5521-pull-options.sh
+++ b/t/t5521-pull-options.sh
@@ -233,7 +233,7 @@ test_expect_success 'git pull --no-verify flag passed to merge' '
 	git init src &&
 	test_commit -C src one &&
 	git clone src dst &&
-	write_script dst/.git/hooks/commit-msg <<-\EOF &&
+	test_hook -C dst commit-msg <<-\EOF &&
 	false
 	EOF
 	test_commit -C src two &&
@@ -245,7 +245,7 @@ test_expect_success 'git pull --no-verify --verify passed to merge' '
 	git init src &&
 	test_commit -C src one &&
 	git clone src dst &&
-	write_script dst/.git/hooks/commit-msg <<-\EOF &&
+	test_hook -C dst commit-msg <<-\EOF &&
 	false
 	EOF
 	test_commit -C src two &&
diff --git a/t/t5540-http-push-webdav.sh b/t/t5540-http-push-webdav.sh
index 380e97c1762..37db3dec0c5 100755
--- a/t/t5540-http-push-webdav.sh
+++ b/t/t5540-http-push-webdav.sh
@@ -42,7 +42,7 @@ test_expect_success 'setup remote repository' '
 	git clone --bare test_repo test_repo.git &&
 	cd test_repo.git &&
 	git --bare update-server-info &&
-	write_script hooks/post-update <<-\EOF &&
+	test_hook --setup post-update <<-\EOF &&
 	exec git update-server-info
 	EOF
 	ORIG_HEAD=$(git rev-parse --verify HEAD) &&
diff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh
index faaa51ccc56..1876fb34e51 100755
--- a/t/t5547-push-quarantine.sh
+++ b/t/t5547-push-quarantine.sh
@@ -5,7 +5,7 @@ test_description='check quarantine of objects during push'
 
 test_expect_success 'create picky dest repo' '
 	git init --bare dest.git &&
-	write_script dest.git/hooks/pre-receive <<-\EOF
+	test_hook --setup -C dest.git pre-receive <<-\EOF
 	while read old new ref; do
 		test "$(git log -1 --format=%s $new)" = reject && exit 1
 	done
@@ -60,7 +60,7 @@ test_expect_success 'push to repo path with path separator (colon)' '
 
 test_expect_success 'updating a ref from quarantine is forbidden' '
 	git init --bare update.git &&
-	write_script update.git/hooks/pre-receive <<-\EOF &&
+	test_hook -C update.git pre-receive <<-\EOF &&
 	read old new refname
 	git update-ref refs/heads/unrelated $new
 	exit 1
diff --git a/t/t5548-push-porcelain.sh b/t/t5548-push-porcelain.sh
index f11ff57e549..6282728eaf3 100755
--- a/t/t5548-push-porcelain.sh
+++ b/t/t5548-push-porcelain.sh
@@ -168,7 +168,7 @@ run_git_push_porcelain_output_test() {
 	'
 
 	test_expect_success "prepare pre-receive hook ($PROTOCOL)" '
-		write_script "$upstream/hooks/pre-receive" <<-EOF
+		test_hook --setup -C "$upstream" pre-receive <<-EOF
 		exit 1
 		EOF
 	'
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index a6b0db22867..39871b9901e 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -101,7 +101,7 @@ test_expect_success 'pre-auto-gc hook can stop auto gc' '
 	EOF
 
 	git init pre-auto-gc-hook &&
-	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
+	test_hook -C pre-auto-gc-hook pre-auto-gc <<-\EOF &&
 	echo >&2 no gc for you &&
 	exit 1
 	EOF
@@ -128,7 +128,7 @@ test_expect_success 'pre-auto-gc hook can stop auto gc' '
 	See "git help gc" for manual housekeeping.
 	EOF
 
-	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
+	test_hook -C pre-auto-gc-hook --clobber pre-auto-gc <<-\EOF &&
 	echo >&2 will gc for you &&
 	exit 0
 	EOF
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index 63a0f609866..d8b0fc4681c 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -26,7 +26,7 @@ dirty_repo () {
 }
 
 write_integration_script () {
-	write_script .git/hooks/fsmonitor-test<<-\EOF
+	test_hook --setup --clobber fsmonitor-test<<-\EOF
 	if test "$#" -ne 2
 	then
 		echo "$0: exactly 2 arguments expected"
@@ -107,7 +107,7 @@ EOF
 
 # test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit
 test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' '
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook fsmonitor-test<<-\EOF &&
 		printf "last_update_token\0"
 	EOF
 	git update-index --fsmonitor &&
@@ -168,7 +168,7 @@ EOF
 
 # test that newly added files are marked valid
 test_expect_success 'newly added files are marked valid' '
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook --setup --clobber fsmonitor-test<<-\EOF &&
 		printf "last_update_token\0"
 	EOF
 	git add new &&
@@ -209,7 +209,7 @@ EOF
 
 # test that *only* files returned by the integration script get flagged as invalid
 test_expect_success '*only* files returned by the integration script get flagged as invalid' '
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook --clobber fsmonitor-test<<-\EOF &&
 	printf "last_update_token\0"
 	printf "dir1/modified\0"
 	EOF
@@ -230,7 +230,7 @@ test_expect_success 'refresh_index() invalidates fsmonitor cache' '
 	dirty_repo &&
 	write_integration_script &&
 	git add . &&
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook --clobber fsmonitor-test<<-\EOF &&
 	EOF
 	git commit -m "to reset" &&
 	git reset HEAD~1 &&
@@ -279,7 +279,7 @@ do
 		# Make sure it's actually skipping the check for modified and untracked
 		# (if enabled) files unless it is told about them.
 		test_expect_success "status doesn't detect unreported modifications" '
-			write_script .git/hooks/fsmonitor-test<<-\EOF &&
+			test_hook --clobber fsmonitor-test<<-\EOF &&
 			printf "last_update_token\0"
 			:>marker
 			EOF
@@ -405,14 +405,14 @@ test_expect_success 'status succeeds with sparse index' '
 		git -C sparse sparse-checkout init --cone --sparse-index &&
 		git -C sparse sparse-checkout set dir1 dir2 &&
 
-		write_script .git/hooks/fsmonitor-test <<-\EOF &&
+		test_hook --clobber fsmonitor-test <<-\EOF &&
 			printf "last_update_token\0"
 		EOF
 		git -C full config core.fsmonitor ../.git/hooks/fsmonitor-test &&
 		git -C sparse config core.fsmonitor ../.git/hooks/fsmonitor-test &&
 		check_sparse_index_behavior ! &&
 
-		write_script .git/hooks/fsmonitor-test <<-\EOF &&
+		test_hook --clobber fsmonitor-test <<-\EOF &&
 			printf "last_update_token\0"
 			printf "dir1/modified\0"
 		EOF
@@ -430,7 +430,7 @@ test_expect_success 'status succeeds with sparse index' '
 
 		# This one modifies outside the sparse-checkout definition
 		# and hence we expect to expand the sparse-index.
-		write_script .git/hooks/fsmonitor-test <<-\EOF &&
+		test_hook --clobber fsmonitor-test <<-\EOF &&
 			printf "last_update_token\0"
 			printf "dir1a/modified\0"
 		EOF
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 85385d2ede7..0bef5913100 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -551,6 +551,58 @@ write_script () {
 	chmod +x "$1"
 }
 
+# Usage: test_hook [options] <hook-name> <<-\EOF
+#
+#   -C <dir>:
+#	Run all git commands in directory <dir>
+#   --setup
+#	Setup a hook for subsequent tests, i.e. don't remove it in a
+#	"test_when_finished"
+#   --clobber
+#	Overwrite an existing <hook-name>, if it exists. Implies
+#	--setup (i.e. the "test_when_finished" is assumed to have been
+#	set up already).
+test_hook () {
+	setup= &&
+	clobber= &&
+	indir= &&
+	while test $# != 0
+	do
+		case "$1" in
+		-C)
+			indir="$2" &&
+			shift
+			;;
+		--setup)
+			setup=t
+			;;
+		--clobber)
+			clobber=t
+			;;
+		-*)
+			BUG "invalid argument: $1"
+			;;
+		*)
+			break
+			;;
+		esac &&
+		shift
+	done &&
+
+	git_dir=$(git -C "$indir" rev-parse --absolute-git-dir) &&
+	hook_dir="$git_dir/hooks" &&
+	hook_file="$hook_dir/$1" &&
+	if test -z "$clobber"
+	then
+		test_path_is_missing "$hook_file"
+	fi &&
+	if test -z "$setup$clobber"
+	then
+		test_when_finished "rm \"$hook_file\""
+	fi &&
+	write_script "$hook_file"
+}
+
 # Use test_set_prereq to tell that a particular prerequisite is available.
 # The prerequisite can later be checked for in two ways:
 #
-- 
2.35.1.1242.gfeba0eae32b


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 09/10] tests: change "mkdir -p && write_script" to use "test_hook"
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
                     ` (7 preceding siblings ...)
  2022-03-07 12:43   ` [PATCH v2 08/10] test-lib-functions: add and use a "test_hook" wrapper Ævar Arnfjörð Bjarmason
@ 2022-03-07 12:43   ` Ævar Arnfjörð Bjarmason
  2022-03-07 12:43   ` [PATCH v2 10/10] tests: change "cat && chmod +x" " Ævar Arnfjörð Bjarmason
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-07 12:43 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change tests that used a "mkdir -p .git/hooks && write_script" pattern
to use the new "test_hook" helper instead. The new helper does not
create the .git/hooks directory, rather we assume that the default
template will do so for us.

An upcoming series[1] will extend "test_hook" to operate in a
"--template=" mode, but for now assuming that we have a .git/hooks
already is a safe assumption. If that assumption becomes false in the
future we'll only need to change 'test_hook", instead of all of these
callsites.

1. https://lore.kernel.org/git/cover-00.13-00000000000-20211212T201308Z-avarab@gmail.com/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0029-core-unsetenvvars.sh      |  3 +--
 t/t1350-config-hooks-path.sh      |  4 ++--
 t/t3404-rebase-interactive.sh     | 10 ++--------
 t/t3430-rebase-merges.sh          |  6 +++---
 t/t4150-am.sh                     | 24 ++++++------------------
 t/t5403-post-checkout-hook.sh     |  3 +--
 t/t5534-push-signed.sh            | 26 ++++++++------------------
 t/t7113-post-index-change-hook.sh |  7 +++----
 t/t9001-send-email.sh             |  4 +---
 t/t9800-git-p4-basic.sh           |  5 ++---
 10 files changed, 29 insertions(+), 63 deletions(-)

diff --git a/t/t0029-core-unsetenvvars.sh b/t/t0029-core-unsetenvvars.sh
index b138e1d9cbc..4e8e90dd982 100755
--- a/t/t0029-core-unsetenvvars.sh
+++ b/t/t0029-core-unsetenvvars.sh
@@ -12,8 +12,7 @@ then
 fi
 
 test_expect_success 'setup' '
-	mkdir -p "$TRASH_DIRECTORY/.git/hooks" &&
-	write_script "$TRASH_DIRECTORY/.git/hooks/pre-commit" <<-\EOF
+	test_hook --setup pre-commit <<-\EOF
 	echo $HOBBES >&2
 	EOF
 '
diff --git a/t/t1350-config-hooks-path.sh b/t/t1350-config-hooks-path.sh
index fa9647a7c0b..f6dc83e2aab 100755
--- a/t/t1350-config-hooks-path.sh
+++ b/t/t1350-config-hooks-path.sh
@@ -6,11 +6,11 @@ test_description='Test the core.hooksPath configuration variable'
 
 test_expect_success 'set up a pre-commit hook in core.hooksPath' '
 	>actual &&
-	mkdir -p .git/custom-hooks .git/hooks &&
+	mkdir -p .git/custom-hooks &&
 	write_script .git/custom-hooks/pre-commit <<-\EOF &&
 	echo CUSTOM >>actual
 	EOF
-	write_script .git/hooks/pre-commit <<-\EOF
+	test_hook --setup pre-commit <<-\EOF
 	echo NORMAL >>actual
 	EOF
 '
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index a38f2da7691..f31afd4a547 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -619,9 +619,7 @@ test_expect_success 'rebase a detached HEAD' '
 '
 
 test_expect_success 'rebase a commit violating pre-commit' '
-
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/pre-commit <<-\EOF &&
+	test_hook pre-commit <<-\EOF &&
 	test -z "$(git diff --cached --check)"
 	EOF
 	echo "monde! " >> file1 &&
@@ -636,8 +634,6 @@ test_expect_success 'rebase a commit violating pre-commit' '
 '
 
 test_expect_success 'rebase with a file named HEAD in worktree' '
-
-	rm -fr .git/hooks &&
 	git reset --hard &&
 	git checkout -b branch3 A &&
 
@@ -1688,10 +1684,8 @@ test_expect_success 'valid author header when author contains single quote' '
 '
 
 test_expect_success 'post-commit hook is called' '
-	test_when_finished "rm -f .git/hooks/post-commit" &&
 	>actual &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-commit <<-\EOS &&
+	test_hook post-commit <<-\EOS &&
 	git rev-parse HEAD >>actual
 	EOS
 	(
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index 43c82d9a33b..f351701fec2 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -292,9 +292,9 @@ test_expect_success 'post-rewrite hook and fixups work for merges' '
 	git commit --fixup HEAD same2.t &&
 	fixup="$(git rev-parse HEAD)" &&
 
-	mkdir -p .git/hooks &&
-	test_when_finished "rm .git/hooks/post-rewrite" &&
-	echo "cat >actual" | write_script .git/hooks/post-rewrite &&
+	test_hook post-rewrite <<-\EOF &&
+	cat >actual
+	EOF
 
 	test_tick &&
 	git rebase -i --autosquash -r HEAD^^^ &&
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index 159fae8d016..cdad4b68807 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -315,12 +315,10 @@ test_expect_success 'am --patch-format=hg applies hg patch' '
 '
 
 test_expect_success 'am with applypatch-msg hook' '
-	test_when_finished "rm -f .git/hooks/applypatch-msg" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/applypatch-msg <<-\EOF &&
+	test_hook applypatch-msg <<-\EOF &&
 	cat "$1" >actual-msg &&
 	echo hook-message >"$1"
 	EOF
@@ -335,12 +333,10 @@ test_expect_success 'am with applypatch-msg hook' '
 '
 
 test_expect_success 'am with failing applypatch-msg hook' '
-	test_when_finished "rm -f .git/hooks/applypatch-msg" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/applypatch-msg <<-\EOF &&
+	test_hook applypatch-msg <<-\EOF &&
 	exit 1
 	EOF
 	test_must_fail git am patch1 &&
@@ -350,12 +346,10 @@ test_expect_success 'am with failing applypatch-msg hook' '
 '
 
 test_expect_success 'am with pre-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/pre-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/pre-applypatch <<-\EOF &&
+	test_hook pre-applypatch <<-\EOF &&
 	git diff first >diff.actual
 	exit 0
 	EOF
@@ -368,12 +362,10 @@ test_expect_success 'am with pre-applypatch hook' '
 '
 
 test_expect_success 'am with failing pre-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/pre-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/pre-applypatch <<-\EOF &&
+	test_hook pre-applypatch <<-\EOF &&
 	exit 1
 	EOF
 	test_must_fail git am patch1 &&
@@ -383,12 +375,10 @@ test_expect_success 'am with failing pre-applypatch hook' '
 '
 
 test_expect_success 'am with post-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/post-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-applypatch <<-\EOF &&
+	test_hook post-applypatch <<-\EOF &&
 	git rev-parse HEAD >head.actual
 	git diff second >diff.actual
 	exit 0
@@ -403,12 +393,10 @@ test_expect_success 'am with post-applypatch hook' '
 '
 
 test_expect_success 'am with failing post-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/post-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-applypatch <<-\EOF &&
+	test_hook post-applypatch <<-\EOF &&
 	git rev-parse HEAD >head.actual
 	exit 1
 	EOF
diff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh
index d1181816906..978f240cdac 100755
--- a/t/t5403-post-checkout-hook.sh
+++ b/t/t5403-post-checkout-hook.sh
@@ -10,8 +10,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 . ./test-lib.sh
 
 test_expect_success setup '
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-checkout <<-\EOF &&
+	test_hook --setup post-checkout <<-\EOF &&
 	echo "$@" >.git/post-checkout.args
 	EOF
 	test_commit one &&
diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh
index 24d374adbae..7c0a148e73c 100755
--- a/t/t5534-push-signed.sh
+++ b/t/t5534-push-signed.sh
@@ -35,8 +35,7 @@ test_expect_success setup '
 
 test_expect_success 'unsigned push does not send push certificate' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -52,8 +51,7 @@ test_expect_success 'unsigned push does not send push certificate' '
 
 test_expect_success 'talking with a receiver without push certificate support' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -69,22 +67,19 @@ test_expect_success 'talking with a receiver without push certificate support' '
 
 test_expect_success 'push --signed fails with a receiver without push certificate support' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	test_must_fail git push --signed dst noop ff +noff 2>err &&
 	test_i18ngrep "the receiving end does not support" err
 '
 
 test_expect_success 'push --signed=1 is accepted' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	test_must_fail git push --signed=1 dst noop ff +noff 2>err &&
 	test_i18ngrep "the receiving end does not support" err
 '
 
 test_expect_success GPG 'no certificate for a signed push with no update' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	if test -n "${GIT_PUSH_CERT-}"
 	then
 		git cat-file blob $GIT_PUSH_CERT >../push-cert
@@ -96,9 +91,8 @@ test_expect_success GPG 'no certificate for a signed push with no update' '
 
 test_expect_success GPG 'signed push sends push certificate' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -139,10 +133,9 @@ test_expect_success GPG 'signed push sends push certificate' '
 
 test_expect_success GPGSSH 'ssh signed push sends push certificate' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -223,9 +216,8 @@ test_expect_success GPG 'inconsistent push options in signed push not allowed' '
 
 test_expect_success GPG 'fail without key and heed user.signingkey' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -273,9 +265,8 @@ test_expect_success GPG 'fail without key and heed user.signingkey' '
 test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '
 	test_config gpg.format x509 &&
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -326,10 +317,9 @@ test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '
 test_expect_success GPGSSH 'fail without key and heed user.signingkey ssh' '
 	test_config gpg.format ssh &&
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
diff --git a/t/t7113-post-index-change-hook.sh b/t/t7113-post-index-change-hook.sh
index a21781d68a1..58e55a7c779 100755
--- a/t/t7113-post-index-change-hook.sh
+++ b/t/t7113-post-index-change-hook.sh
@@ -17,8 +17,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'test status, add, commit, others trigger hook without flags set' '
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-index-change <<-\EOF &&
+	test_hook post-index-change <<-\EOF &&
 		if test "$1" -eq 1; then
 			echo "Invalid combination of flags passed to hook; updated_workdir is set." >testfailure
 			exit 1
@@ -63,7 +62,7 @@ test_expect_success 'test status, add, commit, others trigger hook without flags
 '
 
 test_expect_success 'test checkout and reset trigger the hook' '
-	write_script .git/hooks/post-index-change <<-\EOF &&
+	test_hook post-index-change <<-\EOF &&
 		if test "$1" -eq 1 && test "$2" -eq 1; then
 			echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
 			exit 1
@@ -106,7 +105,7 @@ test_expect_success 'test checkout and reset trigger the hook' '
 '
 
 test_expect_success 'test reset --mixed and update-index triggers the hook' '
-	write_script .git/hooks/post-index-change <<-\EOF &&
+	test_hook post-index-change <<-\EOF &&
 		if test "$1" -eq 1 && test "$2" -eq 1; then
 			echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
 			exit 1
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 84d0f40d76a..42694fe5841 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -2288,9 +2288,7 @@ test_expect_success $PREREQ 'cmdline in-reply-to used with --no-thread' '
 '
 
 test_expect_success $PREREQ 'invoke hook' '
-	mkdir -p .git/hooks &&
-
-	write_script .git/hooks/sendemail-validate <<-\EOF &&
+	test_hook sendemail-validate <<-\EOF &&
 	# test that we have the correct environment variable, pwd, and
 	# argument
 	case "$GIT_DIR" in
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index 3c1534c94d6..8b30062c0cf 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -279,8 +279,7 @@ test_expect_success 'run hook p4-pre-submit before submit' '
 		git p4 submit --dry-run >out &&
 		grep "Would apply" out
 	) &&
-	mkdir -p "$git"/.git/hooks &&
-	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
+	test_hook -C "$git" p4-pre-submit <<-\EOF &&
 	exit 0
 	EOF
 	(
@@ -288,7 +287,7 @@ test_expect_success 'run hook p4-pre-submit before submit' '
 		git p4 submit --dry-run >out &&
 		grep "Would apply" out
 	) &&
-	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
+	test_hook -C "$git" --clobber p4-pre-submit <<-\EOF &&
 	exit 1
 	EOF
 	(
-- 
2.35.1.1242.gfeba0eae32b


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 10/10] tests: change "cat && chmod +x" to use "test_hook"
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
                     ` (8 preceding siblings ...)
  2022-03-07 12:43   ` [PATCH v2 09/10] tests: change "mkdir -p && write_script" to use "test_hook" Ævar Arnfjörð Bjarmason
@ 2022-03-07 12:43   ` Ævar Arnfjörð Bjarmason
  2022-03-07 21:26   ` [PATCH v2 00/10] tests: add and use a "test_hook" wrapper + hook fixes Junio C Hamano
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
  11 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-07 12:43 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Refactor various test code to use the "test_hook" helper. This change:

 - Fixes the long-standing issues with those tests using "#!/bin/sh"
   instead of "#!$SHELL_PATH". Using "#!/bin/sh" here happened to work
   because this code was so simple that it e.g. worked on Solaris
   /bin/sh.

 - Removes the "mkdir .git/hooks" invocation, as explained in a
   preceding commit we'll rely on the default templates to create that
   directory for us.

For the test in "t5402-post-merge-hook.sh" it's easier and more
correct to unroll the for-loop into a test_expect_success, so let's do
that.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3412-rebase-root.sh       | 12 +++---------
 t/t3413-rebase-hook.sh       | 12 +++---------
 t/t5401-update-hooks.sh      | 16 ++++------------
 t/t5402-post-merge-hook.sh   | 16 +++++++++-------
 t/t5407-post-rewrite-hook.sh |  4 +---
 t/t5516-fetch-push.sh        | 19 ++++---------------
 t/t5541-http-push-smart.sh   |  4 +---
 t/t5601-clone.sh             |  4 +---
 8 files changed, 26 insertions(+), 61 deletions(-)

diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
index 239a9343d34..58371d8a547 100755
--- a/t/t3412-rebase-root.sh
+++ b/t/t3412-rebase-root.sh
@@ -31,12 +31,9 @@ test_expect_success 'rebase --root fails with too many args' '
 '
 
 test_expect_success 'setup pre-rebase hook' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<-EOF &&
-	#!$SHELL_PATH
-	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+	test_hook --setup pre-rebase <<-\EOF
+	echo "$1,$2" >.git/PRE-REBASE-INPUT
 	EOF
-	chmod +x .git/hooks/pre-rebase
 '
 cat > expect <<EOF
 4
@@ -141,12 +138,9 @@ commit work7~5
 EOF
 
 test_expect_success 'setup pre-rebase hook that fails' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<-EOF &&
-	#!$SHELL_PATH
+	test_hook --setup --clobber pre-rebase <<-\EOF
 	false
 	EOF
-	chmod +x .git/hooks/pre-rebase
 '
 
 test_expect_success 'pre-rebase hook stops rebase' '
diff --git a/t/t3413-rebase-hook.sh b/t/t3413-rebase-hook.sh
index bb241b26b2e..9fab0d779bb 100755
--- a/t/t3413-rebase-hook.sh
+++ b/t/t3413-rebase-hook.sh
@@ -41,12 +41,9 @@ test_expect_success 'rebase -i' '
 '
 
 test_expect_success 'setup pre-rebase hook' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<-EOF &&
-	#!$SHELL_PATH
-	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+	test_hook --setup pre-rebase <<-\EOF
+	echo "$1,$2" >.git/PRE-REBASE-INPUT
 	EOF
-	chmod +x .git/hooks/pre-rebase
 '
 
 test_expect_success 'pre-rebase hook gets correct input (1)' '
@@ -102,12 +99,9 @@ test_expect_success 'pre-rebase hook gets correct input (6)' '
 '
 
 test_expect_success 'setup pre-rebase hook that fails' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<-EOF &&
-	#!$SHELL_PATH
+	test_hook --setup --clobber pre-rebase <<-\EOF
 	false
 	EOF
-	chmod +x .git/hooks/pre-rebase
 '
 
 test_expect_success 'pre-rebase hook stops rebase (1)' '
diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
index 6392f71795d..d5771b96114 100755
--- a/t/t5401-update-hooks.sh
+++ b/t/t5401-update-hooks.sh
@@ -22,42 +22,34 @@ test_expect_success setup '
 	git update-ref refs/heads/main $commit1 &&
 	git update-ref refs/heads/tofail $commit0 &&
 
-	cat >victim.git/hooks/pre-receive <<-\EOF &&
-	#!/bin/sh
+	test_hook --setup -C victim.git pre-receive <<-\EOF &&
 	printf %s "$@" >>$GIT_DIR/pre-receive.args
 	cat - >$GIT_DIR/pre-receive.stdin
 	echo STDOUT pre-receive
 	echo STDERR pre-receive >&2
 	EOF
-	chmod u+x victim.git/hooks/pre-receive &&
 
-	cat >victim.git/hooks/update <<-\EOF &&
-	#!/bin/sh
+	test_hook --setup -C victim.git update <<-\EOF &&
 	echo "$@" >>$GIT_DIR/update.args
 	read x; printf %s "$x" >$GIT_DIR/update.stdin
 	echo STDOUT update $1
 	echo STDERR update $1 >&2
 	test "$1" = refs/heads/main || exit
 	EOF
-	chmod u+x victim.git/hooks/update &&
 
-	cat >victim.git/hooks/post-receive <<-\EOF &&
-	#!/bin/sh
+	test_hook --setup -C victim.git post-receive <<-\EOF &&
 	printf %s "$@" >>$GIT_DIR/post-receive.args
 	cat - >$GIT_DIR/post-receive.stdin
 	echo STDOUT post-receive
 	echo STDERR post-receive >&2
 	EOF
-	chmod u+x victim.git/hooks/post-receive &&
 
-	cat >victim.git/hooks/post-update <<-\EOF &&
-	#!/bin/sh
+	test_hook --setup -C victim.git post-update <<-\EOF
 	echo "$@" >>$GIT_DIR/post-update.args
 	read x; printf %s "$x" >$GIT_DIR/post-update.stdin
 	echo STDOUT post-update
 	echo STDERR post-update >&2
 	EOF
-	chmod u+x victim.git/hooks/post-update
 '
 
 test_expect_success push '
diff --git a/t/t5402-post-merge-hook.sh b/t/t5402-post-merge-hook.sh
index 3e5e19c7191..915af2de95e 100755
--- a/t/t5402-post-merge-hook.sh
+++ b/t/t5402-post-merge-hook.sh
@@ -25,13 +25,15 @@ test_expect_success setup '
 	GIT_DIR=clone2/.git git update-index --add a
 '
 
-for clone in 1 2; do
-	cat >clone${clone}/.git/hooks/post-merge <<'EOF'
-#!/bin/sh
-echo $@ >> $GIT_DIR/post-merge.args
-EOF
-	chmod u+x clone${clone}/.git/hooks/post-merge
-done
+test_expect_success 'setup clone hooks' '
+	test_when_finished "rm -f hook" &&
+	cat >hook <<-\EOF &&
+	echo $@ >>$GIT_DIR/post-merge.args
+	EOF
+
+	test_hook --setup -C clone1 post-merge <hook &&
+	test_hook --setup -C clone2 post-merge <hook
+'
 
 test_expect_success 'post-merge does not run for up-to-date ' '
 	GIT_DIR=clone1/.git git merge $commit0 &&
diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
index 64f40ff7776..5f3ff051ca2 100755
--- a/t/t5407-post-rewrite-hook.sh
+++ b/t/t5407-post-rewrite-hook.sh
@@ -19,12 +19,10 @@ test_expect_success 'setup' '
 	test_commit F foo F &&
 	git checkout main &&
 
-	cat >.git/hooks/post-rewrite <<-EOF &&
-	#!/bin/sh
+	test_hook --setup post-rewrite <<-EOF
 	echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
 	cat > "$TRASH_DIRECTORY"/post-rewrite.data
 	EOF
-	chmod u+x .git/hooks/post-rewrite
 '
 
 clear_hook_input () {
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index b689baf01a9..4dfb080433e 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -55,35 +55,24 @@ mk_test () {
 mk_test_with_hooks() {
 	repo_name=$1
 	mk_test "$@" &&
-
-	cat >"$repo_name"/.git/hooks/pre-receive <<-'EOF' &&
-	#!/bin/sh
+	test_hook -C "$repo_name" pre-receive <<-'EOF' &&
 	cat - >>pre-receive.actual
 	EOF
 
-	cat >"$repo_name"/.git/hooks/update <<-'EOF' &&
-	#!/bin/sh
+	test_hook -C "$repo_name" update <<-'EOF' &&
 	printf "%s %s %s\n" "$@" >>update.actual
 	EOF
 
-	cat >"$repo_name"/.git/hooks/post-receive <<-'EOF' &&
-	#!/bin/sh
+	test_hook -C "$repo_name" post-receive <<-'EOF' &&
 	cat - >>post-receive.actual
 	EOF
 
-	cat >"$repo_name"/.git/hooks/post-update <<-'EOF' &&
-	#!/bin/sh
+	test_hook -C "$repo_name" post-update <<-'EOF'
 	for ref in "$@"
 	do
 		printf "%s\n" "$ref" >>post-update.actual
 	done
 	EOF
-
-	chmod +x \
-	      "$repo_name"/.git/hooks/pre-receive \
-	      "$repo_name"/.git/hooks/update \
-	      "$repo_name"/.git/hooks/post-receive \
-	      "$repo_name"/.git/hooks/post-update
 }
 
 mk_child() {
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index 0043b718f08..ab4b5cfcd11 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -97,11 +97,9 @@ test_expect_success 'create and delete remote branch' '
 '
 
 test_expect_success 'setup rejected update hook' '
-	cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<-EOF &&
-	#!/bin/sh
+	test_hook --setup -C "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" update <<-\EOF &&
 	exit 1
 	EOF
-	chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" &&
 
 	cat >exp <<-EOF
 	remote: error: hook declined to update refs/heads/dev2
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 83c24fc97a7..4a61f2c901e 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -79,12 +79,10 @@ test_expect_success 'clone from hooks' '
 	cd .. &&
 	git init r1 &&
 	cd r1 &&
-	cat >.git/hooks/pre-commit <<-\EOF &&
-	#!/bin/sh
+	test_hook pre-commit <<-\EOF &&
 	git clone ../r0 ../r2
 	exit 1
 	EOF
-	chmod u+x .git/hooks/pre-commit &&
 	: >file &&
 	git add file &&
 	test_must_fail git commit -m invoke-hook &&
-- 
2.35.1.1242.gfeba0eae32b


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 00/10] tests: add and use a "test_hook" wrapper + hook fixes
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
                     ` (9 preceding siblings ...)
  2022-03-07 12:43   ` [PATCH v2 10/10] tests: change "cat && chmod +x" " Ævar Arnfjörð Bjarmason
@ 2022-03-07 21:26   ` Junio C Hamano
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
  11 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-07 21:26 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Junio also suggested re-arranging this to do this migration in fewer
> steps. I started doing that but doing so would have taken a lot of
> time solving conflicts, re-writing commits etc. I think given that

Given how much reviewer bandwidth you consume, it may be a good
thing to slow you down, I would have to say ;-)

> there's agreement on the end-state that doing so wasn't worth the time


Somebody needs to take another look at the end-state, as I do not
recall if there was any firm agreement, but in any case the series
must bisect well.

In any case, the new "test_hook" helper, together with many places
converted to use it by this patch, look quite nicely done.

Will replace.

Thanks.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v3 00/13] tests: add and use a "test_hook" wrapper + hook fixes
  2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
                     ` (10 preceding siblings ...)
  2022-03-07 21:26   ` [PATCH v2 00/10] tests: add and use a "test_hook" wrapper + hook fixes Junio C Hamano
@ 2022-03-17 10:13   ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 01/13] test-lib-functions: add and use a "test_hook" wrapper Ævar Arnfjörð Bjarmason
                       ` (13 more replies)
  11 siblings, 14 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

This series is a test-only improvement series split up and adapted
from a previous series of mine to add a "git init --no-template":
https://lore.kernel.org/git/cover-00.13-00000000000-20211212T201308Z-avarab@gmail.com/;
For v1 and v2 see:
https://lore.kernel.org/git/cover-00.10-00000000000-20220302T131859Z-avarab@gmail.com/
and
https://lore.kernel.org/git/cover-v2-00.10-00000000000-20220307T123909Z-avarab@gmail.com/

Changes since v2:

 * A large rewrite to hopefully make Junio happy. I.e. I rewrote &
   rebased the churn of changing certain tests in several
   commit. Before it was first indentation changes, then getting rid
   of sub-shells etc.

   Now the first commit introduces the test_hook wrapper, and all
   subsequent commits use it directly.

 * I added new commits to convert the test of the test suite, e.g. the
   proc-receive tests.

   Before (v2):  32 files changed, 325 insertions(+), 347 deletions(-)
   After  (v3): 67 files changed, 572 insertions(+), 600 deletions(-)

Ævar Arnfjörð Bjarmason (13):
  test-lib-functions: add and use a "test_hook" wrapper
  hook tests: turn exit code assertions into a loop
  http tests: don't rely on "hook/post-update.sample"
  tests: assume the hooks are disabled by default
  bugreport tests: tighten up "git bugreport -s hooks" test
  fetch+push tests: use "test_hook" and "test_when_finished" pattern
  gc + p4 tests: use "test_hook", remove sub-shells
  tests: change "cat && chmod +x" to use "test_hook"
  tests: change "mkdir -p && write_script" to use "test_hook"
  tests: use "test_hook" for misc "mkdir -p" and "chmod" cases
  tests: extend "test_hook" for "rm" and "chmod -x", convert "$HOOK"
  proc-receive hook tests: use "test_hook" instead of "write_script"
  http tests: use "test_hook" for "smart" and "dumb" http tests

 t/t0029-core-unsetenvvars.sh                  |   3 +-
 t/t0091-bugreport.sh                          |  26 ++-
 t/t1350-config-hooks-path.sh                  |   4 +-
 t/t1416-ref-transaction-hooks.sh              |  27 ++-
 t/t1800-hook.sh                               |  45 ++--
 t/t2400-worktree-add.sh                       |   5 +-
 t/t3404-rebase-interactive.sh                 |  10 +-
 t/t3412-rebase-root.sh                        |  18 +-
 t/t3413-rebase-hook.sh                        |  18 +-
 t/t3430-rebase-merges.sh                      |   6 +-
 t/t4150-am.sh                                 |  24 +--
 t/t5401-update-hooks.sh                       |  64 +++---
 t/t5402-post-merge-hook.sh                    |  16 +-
 t/t5403-post-checkout-hook.sh                 |   3 +-
 t/t5406-remote-rejects.sh                     |   2 +-
 t/t5407-post-rewrite-hook.sh                  |  14 +-
 t/t5409-colorize-remote-messages.sh           |   2 +-
 t/t5411-proc-receive-hook.sh                  |   4 +-
 t/t5411/once-0010-report-status-v1.sh         |   2 +-
 t/t5411/test-0002-pre-receive-declined.sh     |   4 +-
 ...st-0003-pre-receive-declined--porcelain.sh |   2 +-
 t/t5411/test-0013-bad-protocol.sh             |  20 +-
 t/t5411/test-0014-bad-protocol--porcelain.sh  |  18 +-
 t/t5411/test-0020-report-ng.sh                |   4 +-
 t/t5411/test-0021-report-ng--porcelain.sh     |   4 +-
 t/t5411/test-0022-report-unexpect-ref.sh      |   2 +-
 ...est-0023-report-unexpect-ref--porcelain.sh |   2 +-
 t/t5411/test-0024-report-unknown-ref.sh       |   2 +-
 ...test-0025-report-unknown-ref--porcelain.sh |   2 +-
 t/t5411/test-0026-push-options.sh             |   6 +-
 t/t5411/test-0027-push-options--porcelain.sh  |   6 +-
 t/t5411/test-0030-report-ok.sh                |   2 +-
 t/t5411/test-0031-report-ok--porcelain.sh     |   2 +-
 t/t5411/test-0032-report-with-options.sh      |  14 +-
 ...est-0033-report-with-options--porcelain.sh |  14 +-
 t/t5411/test-0034-report-ft.sh                |   2 +-
 t/t5411/test-0035-report-ft--porcelain.sh     |   2 +-
 ...t-0036-report-multi-rewrite-for-one-ref.sh |   6 +-
 ...rt-multi-rewrite-for-one-ref--porcelain.sh |   6 +-
 t/t5411/test-0038-report-mixed-refs.sh        |   2 +-
 .../test-0039-report-mixed-refs--porcelain.sh |   2 +-
 t/t5411/test-0040-process-all-refs.sh         |   2 +-
 .../test-0041-process-all-refs--porcelain.sh  |   2 +-
 ...t-0050-proc-receive-refs-with-modifiers.sh |   4 +-
 t/t5503-tagfollow.sh                          |   4 +-
 t/t5510-fetch.sh                              |   8 +-
 t/t5516-fetch-push.sh                         | 192 ++++++++----------
 t/t5521-pull-options.sh                       |   4 +-
 t/t5534-push-signed.sh                        |  26 +--
 t/t5540-http-push-webdav.sh                   |   4 +-
 t/t5541-http-push-smart.sh                    |  32 ++-
 t/t5543-atomic-push.sh                        |   5 +-
 t/t5547-push-quarantine.sh                    |   4 +-
 t/t5548-push-porcelain.sh                     |   2 +-
 t/t5550-http-fetch-dumb.sh                    |  25 +--
 t/t5571-pre-push-hook.sh                      |  38 ++--
 t/t5601-clone.sh                              |   4 +-
 t/t6500-gc.sh                                 |  22 +-
 t/t7113-post-index-change-hook.sh             |   7 +-
 ...3-pre-commit-and-pre-merge-commit-hooks.sh | 150 +++++++-------
 t/t7504-commit-msg-hook.sh                    |  43 ++--
 t/t7505-prepare-commit-msg-hook.sh            |  43 ++--
 t/t7519-status-fsmonitor.sh                   |  20 +-
 t/t7520-ignored-hook-warning.sh               |  11 +-
 t/t9001-send-email.sh                         |   4 +-
 t/t9800-git-p4-basic.sh                       |  23 ++-
 t/test-lib-functions.sh                       |  76 +++++++
 67 files changed, 572 insertions(+), 600 deletions(-)

Range-diff against v2:
 8:  1fce2d8855a !  1:  7761d777e9c test-lib-functions: add and use a "test_hook" wrapper
    @@ Commit message
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    - ## t/t0091-bugreport.sh ##
    -@@ t/t0091-bugreport.sh: test_expect_success 'can create leading directories outside of a git dir' '
    - test_expect_success 'indicates populated hooks' '
    - 	test_when_finished rm git-bugreport-hooks.txt &&
    - 
    --	write_script .git/hooks/applypatch-msg <<-\EOF &&
    -+	test_hook applypatch-msg <<-\EOF &&
    - 	true
    - 	EOF
    --	write_script .git/hooks/unknown-hook <<-\EOF &&
    -+	test_hook unknown-hook <<-\EOF &&
    - 	true
    - 	EOF
    - 	git bugreport -s hooks &&
    -
      ## t/t1416-ref-transaction-hooks.sh ##
     @@ t/t1416-ref-transaction-hooks.sh: test_expect_success setup '
      '
    @@ t/t1800-hook.sh: test_expect_success 'git hook run: basic' '
      	echo >&1 Will end up on stderr
      	echo >&2 Will end up on stderr
      	EOF
    -@@ t/t1800-hook.sh: test_expect_success 'git hook run: stdout and stderr both write to our stderr' '
    - for code in 1 2 128 129
    - do
    - 	test_expect_success "git hook run: exit code $code is passed along" '
    --		write_script .git/hooks/test-hook <<-EOF &&
    -+		test_hook test-hook <<-EOF &&
    - 		exit $code
    - 		EOF
    - 
     @@ t/t1800-hook.sh: test_expect_success 'git hook run arg u ments without -- is not allowed' '
      '
      
    @@ t/t1800-hook.sh: test_expect_success 'git -c core.hooksPath=<PATH> hook run' '
      	# t1350-config-hooks-path.sh
      	>actual &&
     
    + ## t/t5401-update-hooks.sh ##
    +@@ t/t5401-update-hooks.sh: test_expect_success 'send-pack stderr contains hook messages' '
    + '
    + 
    + test_expect_success 'pre-receive hook that forgets to read its input' '
    +-	write_script victim.git/hooks/pre-receive <<-\EOF &&
    ++	test_hook --clobber -C victim.git pre-receive <<-\EOF &&
    + 	exit 0
    + 	EOF
    + 	rm -f victim.git/hooks/update victim.git/hooks/post-update &&
    +
      ## t/t5406-remote-rejects.sh ##
     @@ t/t5406-remote-rejects.sh: test_description='remote push rejects are reported by client'
      . ./test-lib.sh
    @@ t/t5411-proc-receive-hook.sh: setup_upstream_and_workbench () {
      		echo "# post-receive hook"
      		while read old new ref
     
    + ## t/t5503-tagfollow.sh ##
    +@@ t/t5503-tagfollow.sh: test_expect_success 'atomic fetch with failing backfill' '
    + 	# one of both fails to update correctly.
    + 	#
    + 	# To trigger failure we simply abort when backfilling a tag.
    +-	write_script clone3/.git/hooks/reference-transaction <<-\EOF &&
    ++	test_hook -C clone3 reference-transaction <<-\EOF &&
    + 		while read oldrev newrev reference
    + 		do
    + 			if test "$reference" = refs/tags/tag1
    +@@ t/t5503-tagfollow.sh: test_expect_success 'atomic fetch with backfill should use single transaction' '
    + 		$ZERO_OID $T refs/tags/tag1
    + 	EOF
    + 
    +-	write_script clone4/.git/hooks/reference-transaction <<-\EOF &&
    ++	test_hook -C clone4 reference-transaction <<-\EOF &&
    + 		( echo "$*" && cat ) >>actual
    + 	EOF
    + 
    +
      ## t/t5510-fetch.sh ##
     @@ t/t5510-fetch.sh: test_expect_success 'fetch --atomic executes a single reference transaction only
      	EOF
    @@ t/t5510-fetch.sh: test_expect_success 'fetch --atomic --append appends to FETCH_
      		exit 1
      	EOF
      
    -
    - ## t/t5516-fetch-push.sh ##
    -@@ t/t5516-fetch-push.sh: test_expect_success 'updateInstead with push-to-checkout hook' '
    - 	git -C testrepo reset --hard HEAD^^ &&
    - 	git -C testrepo tag initial &&
    - 	git -C testrepo config receive.denyCurrentBranch updateInstead &&
    --	write_script testrepo/.git/hooks/push-to-checkout <<-\EOF &&
    -+	test_hook -C testrepo push-to-checkout <<-\EOF &&
    - 	echo >&2 updating from $(git rev-parse HEAD)
    - 	echo >&2 updating to "$1"
    - 
    -@@ t/t5516-fetch-push.sh: test_expect_success 'updateInstead with push-to-checkout hook' '
    - 	test_when_finished "rm -rf void" &&
    - 	git init void &&
    - 	git -C void config receive.denyCurrentBranch updateInstead &&
    --	write_script void/.git/hooks/push-to-checkout <<-\EOF &&
    -+	test_hook -C void push-to-checkout <<-\EOF &&
    - 	if git rev-parse --quiet --verify HEAD
    - 	then
    - 		has_head=yes
    +@@ t/t5510-fetch.sh: test_expect_success 'fetch --atomic --prune executes a single reference transact
    + 		$ZERO_OID $head_oid refs/remotes/origin/new-branch
    + 	EOF
    + 
    +-	write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
    ++	test_hook -C atomic reference-transaction <<-\EOF &&
    + 		( echo "$*" && cat ) >>actual
    + 	EOF
    + 
     
      ## t/t5521-pull-options.sh ##
     @@ t/t5521-pull-options.sh: test_expect_success 'git pull --no-verify flag passed to merge' '
    @@ t/t5521-pull-options.sh: test_expect_success 'git pull --no-verify --verify pass
      	EOF
      	test_commit -C src two &&
     
    - ## t/t5540-http-push-webdav.sh ##
    -@@ t/t5540-http-push-webdav.sh: test_expect_success 'setup remote repository' '
    - 	git clone --bare test_repo test_repo.git &&
    - 	cd test_repo.git &&
    - 	git --bare update-server-info &&
    --	write_script hooks/post-update <<-\EOF &&
    -+	test_hook --setup post-update <<-\EOF &&
    - 	exec git update-server-info
    - 	EOF
    - 	ORIG_HEAD=$(git rev-parse --verify HEAD) &&
    -
      ## t/t5547-push-quarantine.sh ##
     @@ t/t5547-push-quarantine.sh: test_description='check quarantine of objects during push'
      
    @@ t/t5548-push-porcelain.sh: run_git_push_porcelain_output_test() {
      		EOF
      	'
     
    - ## t/t6500-gc.sh ##
    -@@ t/t6500-gc.sh: test_expect_success 'pre-auto-gc hook can stop auto gc' '
    - 	EOF
    - 
    - 	git init pre-auto-gc-hook &&
    --	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
    -+	test_hook -C pre-auto-gc-hook pre-auto-gc <<-\EOF &&
    - 	echo >&2 no gc for you &&
    - 	exit 1
    - 	EOF
    -@@ t/t6500-gc.sh: test_expect_success 'pre-auto-gc hook can stop auto gc' '
    - 	See "git help gc" for manual housekeeping.
    - 	EOF
    - 
    --	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
    -+	test_hook -C pre-auto-gc-hook --clobber pre-auto-gc <<-\EOF &&
    - 	echo >&2 will gc for you &&
    - 	exit 0
    - 	EOF
    -
      ## t/t7519-status-fsmonitor.sh ##
     @@ t/t7519-status-fsmonitor.sh: dirty_repo () {
      }
 1:  706460d10b9 !  2:  aa4ee4da289 hook tests: turn exit code assertions into a loop
    @@ t/t1800-hook.sh: test_expect_success 'git hook run: stdout and stderr both write
     +for code in 1 2 128 129
     +do
     +	test_expect_success "git hook run: exit code $code is passed along" '
    -+		write_script .git/hooks/test-hook <<-EOF &&
    ++		test_hook test-hook <<-EOF &&
     +		exit $code
     +		EOF
     +
 2:  4bee939a894 !  3:  8451c31911d t5540: don't rely on "hook/post-update.sample"
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    t5540: don't rely on "hook/post-update.sample"
    +    http tests: don't rely on "hook/post-update.sample"
     
         Change code added in a87679339c0 (test: rename http fetch and push
         test files, 2014-02-06) to stop relying on the "exec git
    @@ t/t5540-http-push-webdav.sh: test_expect_success 'setup remote repository' '
      	cd test_repo.git &&
      	git --bare update-server-info &&
     -	mv hooks/post-update.sample hooks/post-update &&
    -+	write_script hooks/post-update <<-\EOF &&
    ++	test_hook --setup post-update <<-\EOF &&
     +	exec git update-server-info
     +	EOF
      	ORIG_HEAD=$(git rev-parse --verify HEAD) &&
 3:  fc1a9d4d55b !  4:  3a3289afd80 tests: assume the hooks are disabled by default
    @@ t/t7519-status-fsmonitor.sh: test_expect_success UNTRACKED_CACHE 'ignore .git ch
      		cd dot-git &&
     -		mkdir -p .git/hooks &&
      		: >tracked &&
    + 		test-tool chmtime =-60 tracked &&
      		: >modified &&
    - 		mkdir dir1 &&
 4:  8dd7b40e510 !  5:  c21e3e43a55 bugreport tests: tighten up "git bugreport -s hooks" test
    @@ t/t0091-bugreport.sh: test_expect_success 'can create leading directories outsid
     -		EOF
     -	done &&
     +
    -+	write_script .git/hooks/applypatch-msg <<-\EOF &&
    ++	test_hook applypatch-msg <<-\EOF &&
     +	true
     +	EOF
    -+	write_script .git/hooks/unknown-hook <<-\EOF &&
    ++	test_hook unknown-hook <<-\EOF &&
     +	true
     +	EOF
      	git bugreport -s hooks &&
 7:  0ac75ed062f !  6:  0cf152dfca7 fetch+push tests: have tests clean up their own mess
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    fetch+push tests: have tests clean up their own mess
    +    fetch+push tests: use "test_hook" and "test_when_finished" pattern
     
    -    Change the "t5516-fetch-push.sh" test code to make use of
    -    "test_when_finished" to remove data instead of having tests clean up
    -    leftover data from earlier tests, which may or may not be
    -    there (e.g. depending on the --run=* option).
    +    Change the "t5516-fetch-push.sh" test code to make use of the new
    +    "test_hook" helper, and to use "test_when_finished" to have tests
    +    clean up their own state, instead of relying on subsequent tests to
    +    clean the trash directory.
     
         Before this each test would have been responsible for cleaning up
         after a preceding test (which may or may not have run, e.g. if --run
         or "GIT_SKIP_TESTS" was used), now each test will instead clean up
         after itself.
     
    -    When doing this split up the "push with negotiation" test, now the
    +    In order to use both "test_hook" and "test_when_finished" we need to
    +    move them out of sub-shells, which requires some refactoring.
    +
    +    While we're at it split up the "push with negotiation" test, now the
         middle of the test doesn't need to "rm event", and since it delimited
         two halves that were testing two different things the end-state is
         easier to read and reason about.
    @@ t/t5516-fetch-push.sh: D=$(pwd)
      mk_empty () {
      	repo_name="$1"
     -	rm -fr "$repo_name" &&
    +-	mkdir "$repo_name" &&
    +-	(
    +-		cd "$repo_name" &&
    +-		git init &&
    +-		git config receive.denyCurrentBranch warn
    +-	)
     +	test_when_finished "rm -rf \"$repo_name\"" &&
     +	test_path_is_missing "$repo_name" &&
    - 	git init "$repo_name" &&
    - 	git -C "$repo_name" config receive.denyCurrentBranch warn
    ++	git init "$repo_name" &&
    ++	git -C "$repo_name" config receive.denyCurrentBranch warn
      }
    -@@ t/t5516-fetch-push.sh: mk_test_with_hooks() {
    + 
    + mk_test () {
    +@@ t/t5516-fetch-push.sh: mk_test () {
    + mk_test_with_hooks() {
    + 	repo_name=$1
    + 	mk_test "$@" &&
    +-	(
    +-		cd "$repo_name" &&
    +-		mkdir .git/hooks &&
    +-		cd .git/hooks &&
    +-
    +-		cat >pre-receive <<-'EOF' &&
    +-		#!/bin/sh
    +-		cat - >>pre-receive.actual
    +-		EOF
    +-
    +-		cat >update <<-'EOF' &&
    +-		#!/bin/sh
    +-		printf "%s %s %s\n" "$@" >>update.actual
    +-		EOF
    +-
    +-		cat >post-receive <<-'EOF' &&
    +-		#!/bin/sh
    +-		cat - >>post-receive.actual
    +-		EOF
    +-
    +-		cat >post-update <<-'EOF' &&
    +-		#!/bin/sh
    +-		for ref in "$@"
    +-		do
    +-			printf "%s\n" "$ref" >>post-update.actual
    +-		done
    +-		EOF
    +-
    +-		chmod +x pre-receive update post-receive post-update
    +-	)
    ++	test_hook -C "$repo_name" pre-receive <<-'EOF' &&
    ++	cat - >>pre-receive.actual
    ++	EOF
    ++
    ++	test_hook -C "$repo_name" update <<-'EOF' &&
    ++	printf "%s %s %s\n" "$@" >>update.actual
    ++	EOF
    ++
    ++	test_hook -C "$repo_name" post-receive <<-'EOF' &&
    ++	cat - >>post-receive.actual
    ++	EOF
    ++
    ++	test_hook -C "$repo_name" post-update <<-'EOF'
    ++	for ref in "$@"
    ++	do
    ++		printf "%s\n" "$ref" >>post-update.actual
    ++	done
    ++	EOF
      }
      
      mk_child() {
    @@ t/t5516-fetch-push.sh: grep_wrote () {
      	GIT_TEST_PROTOCOL_VERSION=0 GIT_TRACE2_EVENT="$(pwd)/event" \
      		git -c push.negotiate=1 push testrepo refs/heads/main:refs/remotes/origin/main 2>err &&
      	grep_wrote 5 event && # 2 commits, 2 trees, 1 blob
    +@@ t/t5516-fetch-push.sh: test_expect_success 'push does not update local refs on failure' '
    + 
    + 	mk_test testrepo heads/main &&
    + 	mk_child testrepo child &&
    +-	mkdir testrepo/.git/hooks &&
    + 	echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive &&
    + 	chmod +x testrepo/.git/hooks/pre-receive &&
    + 	(
     @@ t/t5516-fetch-push.sh: done
      
      test_expect_success 'fetch follows tags by default' '
    @@ t/t5516-fetch-push.sh: test_expect_success 'receive.denyCurrentBranch = updateIn
     -	rm -fr testrepo &&
     +	test_when_finished "rm -rf testrepo" &&
      	git init testrepo &&
    - 	git -C testrepo pull .. main &&
    - 	git -C testrepo reset --hard HEAD^^ &&
    +-	(
    +-		cd testrepo &&
    +-		git pull .. main &&
    +-		git reset --hard HEAD^^ &&
    +-		git tag initial &&
    +-		git config receive.denyCurrentBranch updateInstead &&
    +-		write_script .git/hooks/push-to-checkout <<-\EOF
    +-		echo >&2 updating from $(git rev-parse HEAD)
    +-		echo >&2 updating to "$1"
    +-
    +-		git update-index -q --refresh &&
    +-		git read-tree -u -m HEAD "$1" || {
    +-			status=$?
    +-			echo >&2 read-tree failed
    +-			exit $status
    +-		}
    +-		EOF
    +-	) &&
    ++	git -C testrepo pull .. main &&
    ++	git -C testrepo reset --hard HEAD^^ &&
    ++	git -C testrepo tag initial &&
    ++	git -C testrepo config receive.denyCurrentBranch updateInstead &&
    ++	test_hook -C testrepo push-to-checkout <<-\EOF &&
    ++	echo >&2 updating from $(git rev-parse HEAD)
    ++	echo >&2 updating to "$1"
    ++
    ++	git update-index -q --refresh &&
    ++	git read-tree -u -m HEAD "$1" || {
    ++		status=$?
    ++		echo >&2 read-tree failed
    ++		exit $status
    ++	}
    ++	EOF
    + 
    + 	# Try pushing into a pristine
    + 	git push testrepo main &&
     @@ t/t5516-fetch-push.sh: test_expect_success 'updateInstead with push-to-checkout hook' '
      	) &&
      
    @@ t/t5516-fetch-push.sh: test_expect_success 'updateInstead with push-to-checkout
     -	rm -fr void &&
     +	test_when_finished "rm -rf void" &&
      	git init void &&
    - 	git -C void config receive.denyCurrentBranch updateInstead &&
    - 	write_script void/.git/hooks/push-to-checkout <<-\EOF &&
    +-	(
    +-		cd void &&
    +-		git config receive.denyCurrentBranch updateInstead &&
    +-		write_script .git/hooks/push-to-checkout <<-\EOF
    +-		if git rev-parse --quiet --verify HEAD
    +-		then
    +-			has_head=yes
    +-			echo >&2 updating from $(git rev-parse HEAD)
    +-		else
    +-			has_head=no
    +-			echo >&2 pushing into void
    +-		fi
    +-		echo >&2 updating to "$1"
    +-
    +-		git update-index -q --refresh &&
    +-		case "$has_head" in
    +-		yes)
    +-			git read-tree -u -m HEAD "$1" ;;
    +-		no)
    +-			git read-tree -u -m "$1" ;;
    +-		esac || {
    +-			status=$?
    +-			echo >&2 read-tree failed
    +-			exit $status
    +-		}
    +-		EOF
    +-	) &&
    ++	git -C void config receive.denyCurrentBranch updateInstead &&
    ++	test_hook -C void push-to-checkout <<-\EOF &&
    ++	if git rev-parse --quiet --verify HEAD
    ++	then
    ++		has_head=yes
    ++		echo >&2 updating from $(git rev-parse HEAD)
    ++	else
    ++		has_head=no
    ++		echo >&2 pushing into void
    ++	fi
    ++	echo >&2 updating to "$1"
    ++
    ++	git update-index -q --refresh &&
    ++	case "$has_head" in
    ++	yes)
    ++		git read-tree -u -m HEAD "$1" ;;
    ++	no)
    ++		git read-tree -u -m "$1" ;;
    ++	esac || {
    ++		status=$?
    ++		echo >&2 read-tree failed
    ++		exit $status
    ++	}
    ++	EOF
    + 
    + 	git push void main &&
    + 	(
 6:  08bd1629d65 !  7:  bb57b298598 hook tests: get rid of unnecessary sub-shells
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    hook tests: get rid of unnecessary sub-shells
    +    gc + p4 tests: use "test_hook", remove sub-shells
     
         Refactor the repository setup code for tests that test hooks the use
    -    of sub-shells when setting up the test repository and hooks.
    -
    -    A subsequent commit will change the hook setup to use a helper that
    -    makes use of "test_when_finished", which cannot be used in
    -    sub-shells. Let's change that setup code, and the adjacent and similar
    -    "mk_empty" code.
    +    of sub-shells when setting up the test repository and hooks, and use
    +    the "test_hook" wrapper instead of "write_scripts".
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    - ## t/t5516-fetch-push.sh ##
    -@@ t/t5516-fetch-push.sh: D=$(pwd)
    - mk_empty () {
    - 	repo_name="$1"
    - 	rm -fr "$repo_name" &&
    --	mkdir "$repo_name" &&
    --	(
    --		cd "$repo_name" &&
    --		git init &&
    --		git config receive.denyCurrentBranch warn
    --	)
    -+	git init "$repo_name" &&
    -+	git -C "$repo_name" config receive.denyCurrentBranch warn
    - }
    - 
    - mk_test () {
    -@@ t/t5516-fetch-push.sh: mk_test () {
    - mk_test_with_hooks() {
    - 	repo_name=$1
    - 	mk_test "$@" &&
    --	(
    --		cd "$repo_name" &&
    --		mkdir .git/hooks &&
    --		cd .git/hooks &&
    --
    --		cat >pre-receive <<-'EOF' &&
    --		#!/bin/sh
    --		cat - >>pre-receive.actual
    --		EOF
    - 
    --		cat >update <<-'EOF' &&
    --		#!/bin/sh
    --		printf "%s %s %s\n" "$@" >>update.actual
    --		EOF
    --
    --		cat >post-receive <<-'EOF' &&
    --		#!/bin/sh
    --		cat - >>post-receive.actual
    --		EOF
    --
    --		cat >post-update <<-'EOF' &&
    --		#!/bin/sh
    --		for ref in "$@"
    --		do
    --			printf "%s\n" "$ref" >>post-update.actual
    --		done
    --		EOF
    --
    --		chmod +x pre-receive update post-receive post-update
    --	)
    -+	cat >"$repo_name"/.git/hooks/pre-receive <<-'EOF' &&
    -+	#!/bin/sh
    -+	cat - >>pre-receive.actual
    -+	EOF
    -+
    -+	cat >"$repo_name"/.git/hooks/update <<-'EOF' &&
    -+	#!/bin/sh
    -+	printf "%s %s %s\n" "$@" >>update.actual
    -+	EOF
    -+
    -+	cat >"$repo_name"/.git/hooks/post-receive <<-'EOF' &&
    -+	#!/bin/sh
    -+	cat - >>post-receive.actual
    -+	EOF
    -+
    -+	cat >"$repo_name"/.git/hooks/post-update <<-'EOF' &&
    -+	#!/bin/sh
    -+	for ref in "$@"
    -+	do
    -+		printf "%s\n" "$ref" >>post-update.actual
    -+	done
    -+	EOF
    -+
    -+	chmod +x \
    -+	      "$repo_name"/.git/hooks/pre-receive \
    -+	      "$repo_name"/.git/hooks/update \
    -+	      "$repo_name"/.git/hooks/post-receive \
    -+	      "$repo_name"/.git/hooks/post-update
    - }
    - 
    - mk_child() {
    -@@ t/t5516-fetch-push.sh: test_expect_success 'push does not update local refs on failure' '
    - 
    - 	mk_test testrepo heads/main &&
    - 	mk_child testrepo child &&
    --	mkdir testrepo/.git/hooks &&
    - 	echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive &&
    - 	chmod +x testrepo/.git/hooks/pre-receive &&
    - 	(
    -@@ t/t5516-fetch-push.sh: test_expect_success 'receive.denyCurrentBranch = updateInstead' '
    - test_expect_success 'updateInstead with push-to-checkout hook' '
    - 	rm -fr testrepo &&
    - 	git init testrepo &&
    --	(
    --		cd testrepo &&
    --		git pull .. main &&
    --		git reset --hard HEAD^^ &&
    --		git tag initial &&
    --		git config receive.denyCurrentBranch updateInstead &&
    --		write_script .git/hooks/push-to-checkout <<-\EOF
    --		echo >&2 updating from $(git rev-parse HEAD)
    --		echo >&2 updating to "$1"
    --
    --		git update-index -q --refresh &&
    --		git read-tree -u -m HEAD "$1" || {
    --			status=$?
    --			echo >&2 read-tree failed
    --			exit $status
    --		}
    --		EOF
    --	) &&
    -+	git -C testrepo pull .. main &&
    -+	git -C testrepo reset --hard HEAD^^ &&
    -+	git -C testrepo tag initial &&
    -+	git -C testrepo config receive.denyCurrentBranch updateInstead &&
    -+	write_script testrepo/.git/hooks/push-to-checkout <<-\EOF &&
    -+	echo >&2 updating from $(git rev-parse HEAD)
    -+	echo >&2 updating to "$1"
    -+
    -+	git update-index -q --refresh &&
    -+	git read-tree -u -m HEAD "$1" || {
    -+		status=$?
    -+		echo >&2 read-tree failed
    -+		exit $status
    -+	}
    -+	EOF
    - 
    - 	# Try pushing into a pristine
    - 	git push testrepo main &&
    -@@ t/t5516-fetch-push.sh: test_expect_success 'updateInstead with push-to-checkout hook' '
    - 	# push into void
    - 	rm -fr void &&
    - 	git init void &&
    --	(
    --		cd void &&
    --		git config receive.denyCurrentBranch updateInstead &&
    --		write_script .git/hooks/push-to-checkout <<-\EOF
    --		if git rev-parse --quiet --verify HEAD
    --		then
    --			has_head=yes
    --			echo >&2 updating from $(git rev-parse HEAD)
    --		else
    --			has_head=no
    --			echo >&2 pushing into void
    --		fi
    --		echo >&2 updating to "$1"
    --
    --		git update-index -q --refresh &&
    --		case "$has_head" in
    --		yes)
    --			git read-tree -u -m HEAD "$1" ;;
    --		no)
    --			git read-tree -u -m "$1" ;;
    --		esac || {
    --			status=$?
    --			echo >&2 read-tree failed
    --			exit $status
    --		}
    --		EOF
    --	) &&
    -+	git -C void config receive.denyCurrentBranch updateInstead &&
    -+	write_script void/.git/hooks/push-to-checkout <<-\EOF &&
    -+	if git rev-parse --quiet --verify HEAD
    -+	then
    -+		has_head=yes
    -+		echo >&2 updating from $(git rev-parse HEAD)
    -+	else
    -+		has_head=no
    -+		echo >&2 pushing into void
    -+	fi
    -+	echo >&2 updating to "$1"
    -+
    -+	git update-index -q --refresh &&
    -+	case "$has_head" in
    -+	yes)
    -+		git read-tree -u -m HEAD "$1" ;;
    -+	no)
    -+		git read-tree -u -m "$1" ;;
    -+	esac || {
    -+		status=$?
    -+		echo >&2 read-tree failed
    -+		exit $status
    -+	}
    -+	EOF
    - 
    - 	git push void main &&
    - 	(
    -
      ## t/t6500-gc.sh ##
     @@ t/t6500-gc.sh: test_expect_success 'pre-auto-gc hook can stop auto gc' '
      	EOF
      
      	git init pre-auto-gc-hook &&
    -+	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
    ++	test_hook -C pre-auto-gc-hook pre-auto-gc <<-\EOF &&
     +	echo >&2 no gc for you &&
     +	exit 1
     +	EOF
    @@ t/t6500-gc.sh: test_expect_success 'pre-auto-gc hook can stop auto gc' '
      	See "git help gc" for manual housekeeping.
      	EOF
      
    -+	write_script "pre-auto-gc-hook/.git/hooks/pre-auto-gc" <<-\EOF &&
    -+	echo >&2 will gc for you &&
    -+	exit 0
    -+	EOF
    -+
    - 	(
    - 		cd pre-auto-gc-hook &&
    +-	(
    +-		cd pre-auto-gc-hook &&
     -		write_script ".git/hooks/pre-auto-gc" <<-\EOF &&
     -		echo >&2 will gc for you &&
     -		exit 0
     -		EOF
    +-		git gc --auto >../out.actual 2>../err.actual
    +-	) &&
    ++	test_hook -C pre-auto-gc-hook --clobber pre-auto-gc <<-\EOF &&
    ++	echo >&2 will gc for you &&
    ++	exit 0
    ++	EOF
     +
    - 		git gc --auto >../out.actual 2>../err.actual
    - 	) &&
    ++	git -C pre-auto-gc-hook gc --auto >out.actual 2>err.actual &&
      
    + 	test_must_be_empty out.actual &&
    + 	test_cmp err.expect err.actual
     
      ## t/t9800-git-p4-basic.sh ##
     @@ t/t9800-git-p4-basic.sh: test_expect_success 'run hook p4-pre-submit before submit' '
    @@ t/t9800-git-p4-basic.sh: test_expect_success 'run hook p4-pre-submit before subm
     -		EOF
     +		grep "Would apply" out
     +	) &&
    -+	mkdir -p "$git"/.git/hooks &&
    -+	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
    ++	test_hook -C "$git" p4-pre-submit <<-\EOF &&
     +	exit 0
     +	EOF
     +	(
    @@ t/t9800-git-p4-basic.sh: test_expect_success 'run hook p4-pre-submit before subm
     -		EOF
     +		grep "Would apply" out
     +	) &&
    -+	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
    ++	test_hook -C "$git" --clobber p4-pre-submit <<-\EOF &&
     +	exit 1
     +	EOF
     +	(
10:  db27fa32bbd !  8:  bb25560d432 tests: change "cat && chmod +x" to use "test_hook"
    @@ Commit message
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    - ## t/t3412-rebase-root.sh ##
    -@@ t/t3412-rebase-root.sh: test_expect_success 'rebase --root fails with too many args' '
    - '
    - 
    - test_expect_success 'setup pre-rebase hook' '
    --	mkdir -p .git/hooks &&
    --	cat >.git/hooks/pre-rebase <<-EOF &&
    --	#!$SHELL_PATH
    --	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
    -+	test_hook --setup pre-rebase <<-\EOF
    -+	echo "$1,$2" >.git/PRE-REBASE-INPUT
    - 	EOF
    --	chmod +x .git/hooks/pre-rebase
    - '
    - cat > expect <<EOF
    - 4
    -@@ t/t3412-rebase-root.sh: commit work7~5
    - EOF
    - 
    - test_expect_success 'setup pre-rebase hook that fails' '
    --	mkdir -p .git/hooks &&
    --	cat >.git/hooks/pre-rebase <<-EOF &&
    --	#!$SHELL_PATH
    -+	test_hook --setup --clobber pre-rebase <<-\EOF
    - 	false
    - 	EOF
    --	chmod +x .git/hooks/pre-rebase
    - '
    - 
    - test_expect_success 'pre-rebase hook stops rebase' '
    -
    - ## t/t3413-rebase-hook.sh ##
    -@@ t/t3413-rebase-hook.sh: test_expect_success 'rebase -i' '
    - '
    - 
    - test_expect_success 'setup pre-rebase hook' '
    --	mkdir -p .git/hooks &&
    --	cat >.git/hooks/pre-rebase <<-EOF &&
    --	#!$SHELL_PATH
    --	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
    -+	test_hook --setup pre-rebase <<-\EOF
    -+	echo "$1,$2" >.git/PRE-REBASE-INPUT
    - 	EOF
    --	chmod +x .git/hooks/pre-rebase
    - '
    - 
    - test_expect_success 'pre-rebase hook gets correct input (1)' '
    -@@ t/t3413-rebase-hook.sh: test_expect_success 'pre-rebase hook gets correct input (6)' '
    - '
    - 
    - test_expect_success 'setup pre-rebase hook that fails' '
    --	mkdir -p .git/hooks &&
    --	cat >.git/hooks/pre-rebase <<-EOF &&
    --	#!$SHELL_PATH
    -+	test_hook --setup --clobber pre-rebase <<-\EOF
    - 	false
    - 	EOF
    --	chmod +x .git/hooks/pre-rebase
    - '
    - 
    - test_expect_success 'pre-rebase hook stops rebase (1)' '
    -
    - ## t/t5401-update-hooks.sh ##
    -@@ t/t5401-update-hooks.sh: test_expect_success setup '
    - 	git update-ref refs/heads/main $commit1 &&
    - 	git update-ref refs/heads/tofail $commit0 &&
    - 
    --	cat >victim.git/hooks/pre-receive <<-\EOF &&
    --	#!/bin/sh
    -+	test_hook --setup -C victim.git pre-receive <<-\EOF &&
    - 	printf %s "$@" >>$GIT_DIR/pre-receive.args
    - 	cat - >$GIT_DIR/pre-receive.stdin
    - 	echo STDOUT pre-receive
    - 	echo STDERR pre-receive >&2
    - 	EOF
    --	chmod u+x victim.git/hooks/pre-receive &&
    - 
    --	cat >victim.git/hooks/update <<-\EOF &&
    --	#!/bin/sh
    -+	test_hook --setup -C victim.git update <<-\EOF &&
    - 	echo "$@" >>$GIT_DIR/update.args
    - 	read x; printf %s "$x" >$GIT_DIR/update.stdin
    - 	echo STDOUT update $1
    - 	echo STDERR update $1 >&2
    - 	test "$1" = refs/heads/main || exit
    - 	EOF
    --	chmod u+x victim.git/hooks/update &&
    - 
    --	cat >victim.git/hooks/post-receive <<-\EOF &&
    --	#!/bin/sh
    -+	test_hook --setup -C victim.git post-receive <<-\EOF &&
    - 	printf %s "$@" >>$GIT_DIR/post-receive.args
    - 	cat - >$GIT_DIR/post-receive.stdin
    - 	echo STDOUT post-receive
    - 	echo STDERR post-receive >&2
    - 	EOF
    --	chmod u+x victim.git/hooks/post-receive &&
    - 
    --	cat >victim.git/hooks/post-update <<-\EOF &&
    --	#!/bin/sh
    -+	test_hook --setup -C victim.git post-update <<-\EOF
    - 	echo "$@" >>$GIT_DIR/post-update.args
    - 	read x; printf %s "$x" >$GIT_DIR/post-update.stdin
    - 	echo STDOUT post-update
    - 	echo STDERR post-update >&2
    - 	EOF
    --	chmod u+x victim.git/hooks/post-update
    - '
    - 
    - test_expect_success push '
    -
      ## t/t5402-post-merge-hook.sh ##
     @@ t/t5402-post-merge-hook.sh: test_expect_success setup '
      	GIT_DIR=clone2/.git git update-index --add a
    @@ t/t5402-post-merge-hook.sh: test_expect_success setup '
      test_expect_success 'post-merge does not run for up-to-date ' '
      	GIT_DIR=clone1/.git git merge $commit0 &&
     
    - ## t/t5407-post-rewrite-hook.sh ##
    -@@ t/t5407-post-rewrite-hook.sh: test_expect_success 'setup' '
    - 	test_commit F foo F &&
    - 	git checkout main &&
    - 
    --	cat >.git/hooks/post-rewrite <<-EOF &&
    --	#!/bin/sh
    -+	test_hook --setup post-rewrite <<-EOF
    - 	echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
    - 	cat > "$TRASH_DIRECTORY"/post-rewrite.data
    - 	EOF
    --	chmod u+x .git/hooks/post-rewrite
    - '
    - 
    - clear_hook_input () {
    -
    - ## t/t5516-fetch-push.sh ##
    -@@ t/t5516-fetch-push.sh: mk_test () {
    - mk_test_with_hooks() {
    - 	repo_name=$1
    - 	mk_test "$@" &&
    --
    --	cat >"$repo_name"/.git/hooks/pre-receive <<-'EOF' &&
    --	#!/bin/sh
    -+	test_hook -C "$repo_name" pre-receive <<-'EOF' &&
    - 	cat - >>pre-receive.actual
    - 	EOF
    - 
    --	cat >"$repo_name"/.git/hooks/update <<-'EOF' &&
    --	#!/bin/sh
    -+	test_hook -C "$repo_name" update <<-'EOF' &&
    - 	printf "%s %s %s\n" "$@" >>update.actual
    - 	EOF
    - 
    --	cat >"$repo_name"/.git/hooks/post-receive <<-'EOF' &&
    --	#!/bin/sh
    -+	test_hook -C "$repo_name" post-receive <<-'EOF' &&
    - 	cat - >>post-receive.actual
    - 	EOF
    - 
    --	cat >"$repo_name"/.git/hooks/post-update <<-'EOF' &&
    --	#!/bin/sh
    -+	test_hook -C "$repo_name" post-update <<-'EOF'
    - 	for ref in "$@"
    - 	do
    - 		printf "%s\n" "$ref" >>post-update.actual
    - 	done
    - 	EOF
    --
    --	chmod +x \
    --	      "$repo_name"/.git/hooks/pre-receive \
    --	      "$repo_name"/.git/hooks/update \
    --	      "$repo_name"/.git/hooks/post-receive \
    --	      "$repo_name"/.git/hooks/post-update
    - }
    - 
    - mk_child() {
    -
    - ## t/t5541-http-push-smart.sh ##
    -@@ t/t5541-http-push-smart.sh: test_expect_success 'create and delete remote branch' '
    - '
    - 
    - test_expect_success 'setup rejected update hook' '
    --	cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<-EOF &&
    --	#!/bin/sh
    -+	test_hook --setup -C "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" update <<-\EOF &&
    - 	exit 1
    - 	EOF
    --	chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" &&
    - 
    - 	cat >exp <<-EOF
    - 	remote: error: hook declined to update refs/heads/dev2
    -
      ## t/t5601-clone.sh ##
     @@ t/t5601-clone.sh: test_expect_success 'clone from hooks' '
      	cd .. &&
 9:  121ca23db37 !  9:  f908e27da82 tests: change "mkdir -p && write_script" to use "test_hook"
    @@ t/t9001-send-email.sh: test_expect_success $PREREQ 'cmdline in-reply-to used wit
      	# test that we have the correct environment variable, pwd, and
      	# argument
      	case "$GIT_DIR" in
    -
    - ## t/t9800-git-p4-basic.sh ##
    -@@ t/t9800-git-p4-basic.sh: test_expect_success 'run hook p4-pre-submit before submit' '
    - 		git p4 submit --dry-run >out &&
    - 		grep "Would apply" out
    - 	) &&
    --	mkdir -p "$git"/.git/hooks &&
    --	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
    -+	test_hook -C "$git" p4-pre-submit <<-\EOF &&
    - 	exit 0
    - 	EOF
    - 	(
    -@@ t/t9800-git-p4-basic.sh: test_expect_success 'run hook p4-pre-submit before submit' '
    - 		git p4 submit --dry-run >out &&
    - 		grep "Would apply" out
    - 	) &&
    --	write_script "$git"/.git/hooks/p4-pre-submit <<-\EOF &&
    -+	test_hook -C "$git" --clobber p4-pre-submit <<-\EOF &&
    - 	exit 1
    - 	EOF
    - 	(
 5:  19db5b2d7c2 ! 10:  dab99b8359d tests: indent and add hook setup to "test_expect_success"
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    tests: indent and add hook setup to "test_expect_success"
    +    tests: use "test_hook" for misc "mkdir -p" and "chmod" cases
     
    -    Indent various hook setup code in the test suite that's using a manual
    -    "cat && chmod" pattern.
    -
    -    These should also consistently use "#!$SHELL_PATH" instead of
    -    "#!/bin/sh", i.e. "test_script". Let's fix that in a subsequent
    -    commit, which will be easier to review after this smaller change.
    +    Make use of "test_hook" in various cases that didn't fit neatly into
    +    preceding commits. Here we need to indent blocks in addition to
    +    changing the test code, or to make other small cosmetic changes.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/t3412-rebase-root.sh ##
     @@ t/t3412-rebase-root.sh: test_expect_success 'rebase --root fails with too many args' '
    + '
      
      test_expect_success 'setup pre-rebase hook' '
    - 	mkdir -p .git/hooks &&
    +-	mkdir -p .git/hooks &&
     -	cat >.git/hooks/pre-rebase <<EOF &&
     -#!$SHELL_PATH
     -echo "\$1,\$2" >.git/PRE-REBASE-INPUT
     -EOF
    -+	cat >.git/hooks/pre-rebase <<-EOF &&
    -+	#!$SHELL_PATH
    -+	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
    +-	chmod +x .git/hooks/pre-rebase
    ++	test_hook --setup pre-rebase <<-\EOF
    ++	echo "$1,$2" >.git/PRE-REBASE-INPUT
     +	EOF
    - 	chmod +x .git/hooks/pre-rebase
      '
      cat > expect <<EOF
    -@@ t/t3412-rebase-root.sh: EOF
    + 4
    +@@ t/t3412-rebase-root.sh: commit work7~5
    + EOF
      
      test_expect_success 'setup pre-rebase hook that fails' '
    - 	mkdir -p .git/hooks &&
    +-	mkdir -p .git/hooks &&
     -	cat >.git/hooks/pre-rebase <<EOF &&
     -#!$SHELL_PATH
     -false
     -EOF
    -+	cat >.git/hooks/pre-rebase <<-EOF &&
    -+	#!$SHELL_PATH
    +-	chmod +x .git/hooks/pre-rebase
    ++	test_hook --setup --clobber pre-rebase <<-\EOF
     +	false
     +	EOF
    - 	chmod +x .git/hooks/pre-rebase
      '
      
    + test_expect_success 'pre-rebase hook stops rebase' '
     
      ## t/t3413-rebase-hook.sh ##
     @@ t/t3413-rebase-hook.sh: test_expect_success 'rebase -i' '
    + '
      
      test_expect_success 'setup pre-rebase hook' '
    - 	mkdir -p .git/hooks &&
    +-	mkdir -p .git/hooks &&
     -	cat >.git/hooks/pre-rebase <<EOF &&
     -#!$SHELL_PATH
     -echo "\$1,\$2" >.git/PRE-REBASE-INPUT
     -EOF
    -+	cat >.git/hooks/pre-rebase <<-EOF &&
    -+	#!$SHELL_PATH
    -+	echo "\$1,\$2" >.git/PRE-REBASE-INPUT
    +-	chmod +x .git/hooks/pre-rebase
    ++	test_hook --setup pre-rebase <<-\EOF
    ++	echo "$1,$2" >.git/PRE-REBASE-INPUT
     +	EOF
    - 	chmod +x .git/hooks/pre-rebase
      '
      
    + test_expect_success 'pre-rebase hook gets correct input (1)' '
     @@ t/t3413-rebase-hook.sh: test_expect_success 'pre-rebase hook gets correct input (6)' '
    + '
      
      test_expect_success 'setup pre-rebase hook that fails' '
    - 	mkdir -p .git/hooks &&
    +-	mkdir -p .git/hooks &&
     -	cat >.git/hooks/pre-rebase <<EOF &&
     -#!$SHELL_PATH
     -false
     -EOF
    -+	cat >.git/hooks/pre-rebase <<-EOF &&
    -+	#!$SHELL_PATH
    +-	chmod +x .git/hooks/pre-rebase
    ++	test_hook --setup --clobber pre-rebase <<-\EOF
     +	false
     +	EOF
    - 	chmod +x .git/hooks/pre-rebase
      '
      
    + test_expect_success 'pre-rebase hook stops rebase (1)' '
     
      ## t/t5401-update-hooks.sh ##
     @@ t/t5401-update-hooks.sh: test_expect_success setup '
    @@ t/t5401-update-hooks.sh: test_expect_success setup '
      	GIT_DIR=victim.git git update-ref refs/heads/tofail $commit1 &&
      	git update-ref refs/heads/main $commit1 &&
     -	git update-ref refs/heads/tofail $commit0
    +-'
     +	git update-ref refs/heads/tofail $commit0 &&
    -+
    -+	cat >victim.git/hooks/pre-receive <<-\EOF &&
    -+	#!/bin/sh
    -+	printf %s "$@" >>$GIT_DIR/pre-receive.args
    -+	cat - >$GIT_DIR/pre-receive.stdin
    -+	echo STDOUT pre-receive
    -+	echo STDERR pre-receive >&2
    -+	EOF
    -+	chmod u+x victim.git/hooks/pre-receive &&
    -+
    -+	cat >victim.git/hooks/update <<-\EOF &&
    -+	#!/bin/sh
    -+	echo "$@" >>$GIT_DIR/update.args
    -+	read x; printf %s "$x" >$GIT_DIR/update.stdin
    -+	echo STDOUT update $1
    -+	echo STDERR update $1 >&2
    -+	test "$1" = refs/heads/main || exit
    -+	EOF
    -+	chmod u+x victim.git/hooks/update &&
    -+
    -+	cat >victim.git/hooks/post-receive <<-\EOF &&
    -+	#!/bin/sh
    -+	printf %s "$@" >>$GIT_DIR/post-receive.args
    -+	cat - >$GIT_DIR/post-receive.stdin
    -+	echo STDOUT post-receive
    -+	echo STDERR post-receive >&2
    -+	EOF
    -+	chmod u+x victim.git/hooks/post-receive &&
    -+
    -+	cat >victim.git/hooks/post-update <<-\EOF &&
    -+	#!/bin/sh
    -+	echo "$@" >>$GIT_DIR/post-update.args
    -+	read x; printf %s "$x" >$GIT_DIR/post-update.stdin
    -+	echo STDOUT post-update
    -+	echo STDERR post-update >&2
    -+	EOF
    -+	chmod u+x victim.git/hooks/post-update
    - '
      
     -cat >victim.git/hooks/pre-receive <<'EOF'
     -#!/bin/sh
    @@ t/t5401-update-hooks.sh: test_expect_success setup '
     -echo STDERR pre-receive >&2
     -EOF
     -chmod u+x victim.git/hooks/pre-receive
    --
    ++	test_hook --setup -C victim.git pre-receive <<-\EOF &&
    ++	printf %s "$@" >>$GIT_DIR/pre-receive.args
    ++	cat - >$GIT_DIR/pre-receive.stdin
    ++	echo STDOUT pre-receive
    ++	echo STDERR pre-receive >&2
    ++	EOF
    + 
     -cat >victim.git/hooks/update <<'EOF'
     -#!/bin/sh
     -echo "$@" >>$GIT_DIR/update.args
    @@ t/t5401-update-hooks.sh: test_expect_success setup '
     -test "$1" = refs/heads/main || exit
     -EOF
     -chmod u+x victim.git/hooks/update
    --
    ++	test_hook --setup -C victim.git update <<-\EOF &&
    ++	echo "$@" >>$GIT_DIR/update.args
    ++	read x; printf %s "$x" >$GIT_DIR/update.stdin
    ++	echo STDOUT update $1
    ++	echo STDERR update $1 >&2
    ++	test "$1" = refs/heads/main || exit
    ++	EOF
    + 
     -cat >victim.git/hooks/post-receive <<'EOF'
     -#!/bin/sh
     -printf %s "$@" >>$GIT_DIR/post-receive.args
    @@ t/t5401-update-hooks.sh: test_expect_success setup '
     -echo STDERR post-receive >&2
     -EOF
     -chmod u+x victim.git/hooks/post-receive
    --
    ++	test_hook --setup -C victim.git post-receive <<-\EOF &&
    ++	printf %s "$@" >>$GIT_DIR/post-receive.args
    ++	cat - >$GIT_DIR/post-receive.stdin
    ++	echo STDOUT post-receive
    ++	echo STDERR post-receive >&2
    ++	EOF
    + 
     -cat >victim.git/hooks/post-update <<'EOF'
     -#!/bin/sh
     -echo "$@" >>$GIT_DIR/post-update.args
    @@ t/t5401-update-hooks.sh: test_expect_success setup '
     -echo STDERR post-update >&2
     -EOF
     -chmod u+x victim.git/hooks/post-update
    --
    ++	test_hook --setup -C victim.git post-update <<-\EOF
    ++	echo "$@" >>$GIT_DIR/post-update.args
    ++	read x; printf %s "$x" >$GIT_DIR/post-update.stdin
    ++	echo STDOUT post-update
    ++	echo STDERR post-update >&2
    ++	EOF
    ++'
    + 
      test_expect_success push '
      	test_must_fail git send-pack --force ./victim.git \
    - 		main tofail >send.out 2>send.err
     
      ## t/t5407-post-rewrite-hook.sh ##
     @@ t/t5407-post-rewrite-hook.sh: test_expect_success 'setup' '
    @@ t/t5407-post-rewrite-hook.sh: test_expect_success 'setup' '
     -cat > "$TRASH_DIRECTORY"/post-rewrite.data
     -EOF
     -chmod u+x .git/hooks/post-rewrite
    -+	cat >.git/hooks/post-rewrite <<-EOF &&
    -+	#!/bin/sh
    ++	test_hook --setup post-rewrite <<-EOF
     +	echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
     +	cat > "$TRASH_DIRECTORY"/post-rewrite.data
     +	EOF
    -+	chmod u+x .git/hooks/post-rewrite
     +'
      
      clear_hook_input () {
    @@ t/t5541-http-push-smart.sh: test_expect_success 'create and delete remote branch
     -EOF
     -chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update"
     +test_expect_success 'setup rejected update hook' '
    -+	cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<-EOF &&
    -+	#!/bin/sh
    ++	test_hook --setup -C "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" update <<-\EOF &&
     +	exit 1
     +	EOF
    -+	chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" &&
      
     -cat >exp <<EOF
     -remote: error: hook declined to update refs/heads/dev2
 -:  ----------- > 11:  f541b0b2d70 tests: extend "test_hook" for "rm" and "chmod -x", convert "$HOOK"
 -:  ----------- > 12:  5b764ffc65a proc-receive hook tests: use "test_hook" instead of "write_script"
 -:  ----------- > 13:  2dffde32036 http tests: use "test_hook" for "smart" and "dumb" http tests
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v3 01/13] test-lib-functions: add and use a "test_hook" wrapper
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 02/13] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
                       ` (12 subsequent siblings)
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Add a "test_hook" wrapper similar to the existing "test_config"
wrapper added in d960c47a881 (test-lib: add helper functions for
config, 2011-08-17).

This wrapper:

 - Will clean up the hook with "test_when_finished", unless --setup is
   provided.

 - Will error if we clobber a hook, unless --clobber is provided.

 - Takes a name like "update" instead of ".git/hooks/update".

 - Accepts -C <dir>, like "test_config" and "test_commit".

By using a wrapper we'll be able to easily change all the hook-related
code that assumes that the template-created ".git/hooks" directory is
created by "init", "clone" etc. once another topic follows-up and
changes the test suite to stop creating trash directories using those
templates.

In addition this will make it easy to have the hooks configured using
the "configuration-based hooks" topic, once we get around to
integrating that. I.e. we'll be able to run the tests in a mode where
we sometimes create a .git/hooks/<name>, and other times create a
script in another location, and point the relevant configuration
snippet to it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1416-ref-transaction-hooks.sh    | 26 +++++++--------
 t/t1800-hook.sh                     | 12 ++++---
 t/t5401-update-hooks.sh             |  2 +-
 t/t5406-remote-rejects.sh           |  2 +-
 t/t5409-colorize-remote-messages.sh |  2 +-
 t/t5411-proc-receive-hook.sh        |  4 +--
 t/t5503-tagfollow.sh                |  4 +--
 t/t5510-fetch.sh                    |  8 ++---
 t/t5521-pull-options.sh             |  4 +--
 t/t5547-push-quarantine.sh          |  4 +--
 t/t5548-push-porcelain.sh           |  2 +-
 t/t7519-status-fsmonitor.sh         | 18 +++++-----
 t/test-lib-functions.sh             | 52 +++++++++++++++++++++++++++++
 13 files changed, 97 insertions(+), 43 deletions(-)

diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh
index 4e1e84a91f3..6fca1f08d9a 100755
--- a/t/t1416-ref-transaction-hooks.sh
+++ b/t/t1416-ref-transaction-hooks.sh
@@ -16,9 +16,8 @@ test_expect_success setup '
 '
 
 test_expect_success 'hook allows updating ref if successful' '
-	test_when_finished "rm .git/hooks/reference-transaction" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		echo "$*" >>actual
 	EOF
 	cat >expect <<-EOF &&
@@ -30,9 +29,8 @@ test_expect_success 'hook allows updating ref if successful' '
 '
 
 test_expect_success 'hook aborts updating ref in prepared state' '
-	test_when_finished "rm .git/hooks/reference-transaction" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = prepared
 		then
 			exit 1
@@ -43,9 +41,9 @@ test_expect_success 'hook aborts updating ref in prepared state' '
 '
 
 test_expect_success 'hook gets all queued updates in prepared state' '
-	test_when_finished "rm .git/hooks/reference-transaction actual" &&
+	test_when_finished "rm actual" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = prepared
 		then
 			while read -r line
@@ -66,9 +64,9 @@ test_expect_success 'hook gets all queued updates in prepared state' '
 '
 
 test_expect_success 'hook gets all queued updates in committed state' '
-	test_when_finished "rm .git/hooks/reference-transaction actual" &&
+	test_when_finished "rm actual" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = committed
 		then
 			while read -r line
@@ -86,9 +84,9 @@ test_expect_success 'hook gets all queued updates in committed state' '
 '
 
 test_expect_success 'hook gets all queued updates in aborted state' '
-	test_when_finished "rm .git/hooks/reference-transaction actual" &&
+	test_when_finished "rm actual" &&
 	git reset --hard PRE &&
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		if test "$1" = aborted
 		then
 			while read -r line
@@ -115,11 +113,11 @@ test_expect_success 'interleaving hook calls succeed' '
 
 	git init --bare target-repo.git &&
 
-	write_script target-repo.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C target-repo.git reference-transaction <<-\EOF &&
 		echo $0 "$@" >>actual
 	EOF
 
-	write_script target-repo.git/hooks/update <<-\EOF &&
+	test_hook -C target-repo.git update <<-\EOF &&
 		echo $0 "$@" >>actual
 	EOF
 
@@ -140,7 +138,7 @@ test_expect_success 'hook does not get called on packing refs' '
 	# Pack references first such that we are in a known state.
 	git pack-refs --all &&
 
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		echo "$@" >>actual
 		cat >>actual
 	EOF
@@ -166,7 +164,7 @@ test_expect_success 'deleting packed ref calls hook once' '
 	git update-ref refs/heads/to-be-deleted $POST_OID &&
 	git pack-refs --all &&
 
-	write_script .git/hooks/reference-transaction <<-\EOF &&
+	test_hook reference-transaction <<-\EOF &&
 		echo "$@" >>actual
 		cat >>actual
 	EOF
diff --git a/t/t1800-hook.sh b/t/t1800-hook.sh
index 29718aa9913..93540b1fa12 100755
--- a/t/t1800-hook.sh
+++ b/t/t1800-hook.sh
@@ -27,7 +27,7 @@ test_expect_success 'git hook run: nonexistent hook with --ignore-missing' '
 '
 
 test_expect_success 'git hook run: basic' '
-	write_script .git/hooks/test-hook <<-EOF &&
+	test_hook test-hook <<-EOF &&
 	echo Test hook
 	EOF
 
@@ -39,7 +39,7 @@ test_expect_success 'git hook run: basic' '
 '
 
 test_expect_success 'git hook run: stdout and stderr both write to our stderr' '
-	write_script .git/hooks/test-hook <<-EOF &&
+	test_hook test-hook <<-EOF &&
 	echo >&1 Will end up on stderr
 	echo >&2 Will end up on stderr
 	EOF
@@ -84,7 +84,7 @@ test_expect_success 'git hook run arg u ments without -- is not allowed' '
 '
 
 test_expect_success 'git hook run -- pass arguments' '
-	write_script .git/hooks/test-hook <<-\EOF &&
+	test_hook test-hook <<-\EOF &&
 	echo $1
 	echo $2
 	EOF
@@ -99,7 +99,7 @@ test_expect_success 'git hook run -- pass arguments' '
 '
 
 test_expect_success 'git hook run -- out-of-repo runs excluded' '
-	write_script .git/hooks/test-hook <<-EOF &&
+	test_hook test-hook <<-EOF &&
 	echo Test hook
 	EOF
 
@@ -120,6 +120,10 @@ test_expect_success 'git -c core.hooksPath=<PATH> hook run' '
 	Hook ran four
 	EOF
 
+	test_hook test-hook <<-EOF &&
+	echo Test hook
+	EOF
+
 	# Test various ways of specifying the path. See also
 	# t1350-config-hooks-path.sh
 	>actual &&
diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
index 6012cc8172a..799349a416c 100755
--- a/t/t5401-update-hooks.sh
+++ b/t/t5401-update-hooks.sh
@@ -136,7 +136,7 @@ test_expect_success 'send-pack stderr contains hook messages' '
 '
 
 test_expect_success 'pre-receive hook that forgets to read its input' '
-	write_script victim.git/hooks/pre-receive <<-\EOF &&
+	test_hook --clobber -C victim.git pre-receive <<-\EOF &&
 	exit 0
 	EOF
 	rm -f victim.git/hooks/update victim.git/hooks/post-update &&
diff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh
index 5c509db6fc3..dcbeb420827 100755
--- a/t/t5406-remote-rejects.sh
+++ b/t/t5406-remote-rejects.sh
@@ -5,7 +5,7 @@ test_description='remote push rejects are reported by client'
 . ./test-lib.sh
 
 test_expect_success 'setup' '
-	write_script .git/hooks/update <<-\EOF &&
+	test_hook update <<-\EOF &&
 	exit 1
 	EOF
 	echo 1 >file &&
diff --git a/t/t5409-colorize-remote-messages.sh b/t/t5409-colorize-remote-messages.sh
index 9f1a483f426..fa5de4500a4 100755
--- a/t/t5409-colorize-remote-messages.sh
+++ b/t/t5409-colorize-remote-messages.sh
@@ -5,7 +5,7 @@ test_description='remote messages are colorized on the client'
 . ./test-lib.sh
 
 test_expect_success 'setup' '
-	write_script .git/hooks/update <<-\EOF &&
+	test_hook --setup update <<-\EOF &&
 	echo error: error
 	echo ERROR: also highlighted
 	echo hint: hint
diff --git a/t/t5411-proc-receive-hook.sh b/t/t5411-proc-receive-hook.sh
index 98b0e812082..92cf52c6d4a 100755
--- a/t/t5411-proc-receive-hook.sh
+++ b/t/t5411-proc-receive-hook.sh
@@ -36,7 +36,7 @@ setup_upstream_and_workbench () {
 		TAG=$(git -C workbench rev-parse v123) &&
 
 		# setup pre-receive hook
-		write_script upstream.git/hooks/pre-receive <<-\EOF &&
+		test_hook --setup -C upstream.git pre-receive <<-\EOF &&
 		exec >&2
 		echo "# pre-receive hook"
 		while read old new ref
@@ -46,7 +46,7 @@ setup_upstream_and_workbench () {
 		EOF
 
 		# setup post-receive hook
-		write_script upstream.git/hooks/post-receive <<-\EOF &&
+		test_hook --setup -C upstream.git post-receive <<-\EOF &&
 		exec >&2
 		echo "# post-receive hook"
 		while read old new ref
diff --git a/t/t5503-tagfollow.sh b/t/t5503-tagfollow.sh
index a3c01014b7e..acdb731edfe 100755
--- a/t/t5503-tagfollow.sh
+++ b/t/t5503-tagfollow.sh
@@ -169,7 +169,7 @@ test_expect_success 'atomic fetch with failing backfill' '
 	# one of both fails to update correctly.
 	#
 	# To trigger failure we simply abort when backfilling a tag.
-	write_script clone3/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C clone3 reference-transaction <<-\EOF &&
 		while read oldrev newrev reference
 		do
 			if test "$reference" = refs/tags/tag1
@@ -201,7 +201,7 @@ test_expect_success 'atomic fetch with backfill should use single transaction' '
 		$ZERO_OID $T refs/tags/tag1
 	EOF
 
-	write_script clone4/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C clone4 reference-transaction <<-\EOF &&
 		( echo "$*" && cat ) >>actual
 	EOF
 
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 48e14e2dab1..6f38a69fbb2 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -273,7 +273,7 @@ test_expect_success 'fetch --atomic executes a single reference transaction only
 	EOF
 
 	rm -f atomic/actual &&
-	write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C atomic reference-transaction <<-\EOF &&
 		( echo "$*" && cat ) >>actual
 	EOF
 
@@ -306,7 +306,7 @@ test_expect_success 'fetch --atomic aborts all reference updates if hook aborts'
 	EOF
 
 	rm -f atomic/actual &&
-	write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C atomic/.git reference-transaction <<-\EOF &&
 		( echo "$*" && cat ) >>actual
 		exit 1
 	EOF
@@ -334,7 +334,7 @@ test_expect_success 'fetch --atomic --append appends to FETCH_HEAD' '
 	test_line_count = 2 atomic/.git/FETCH_HEAD &&
 	cp atomic/.git/FETCH_HEAD expected &&
 
-	write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C atomic reference-transaction <<-\EOF &&
 		exit 1
 	EOF
 
@@ -364,7 +364,7 @@ test_expect_success 'fetch --atomic --prune executes a single reference transact
 		$ZERO_OID $head_oid refs/remotes/origin/new-branch
 	EOF
 
-	write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+	test_hook -C atomic reference-transaction <<-\EOF &&
 		( echo "$*" && cat ) >>actual
 	EOF
 
diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh
index 66cfcb09c55..264de29c35c 100755
--- a/t/t5521-pull-options.sh
+++ b/t/t5521-pull-options.sh
@@ -233,7 +233,7 @@ test_expect_success 'git pull --no-verify flag passed to merge' '
 	git init src &&
 	test_commit -C src one &&
 	git clone src dst &&
-	write_script dst/.git/hooks/commit-msg <<-\EOF &&
+	test_hook -C dst commit-msg <<-\EOF &&
 	false
 	EOF
 	test_commit -C src two &&
@@ -245,7 +245,7 @@ test_expect_success 'git pull --no-verify --verify passed to merge' '
 	git init src &&
 	test_commit -C src one &&
 	git clone src dst &&
-	write_script dst/.git/hooks/commit-msg <<-\EOF &&
+	test_hook -C dst commit-msg <<-\EOF &&
 	false
 	EOF
 	test_commit -C src two &&
diff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh
index faaa51ccc56..1876fb34e51 100755
--- a/t/t5547-push-quarantine.sh
+++ b/t/t5547-push-quarantine.sh
@@ -5,7 +5,7 @@ test_description='check quarantine of objects during push'
 
 test_expect_success 'create picky dest repo' '
 	git init --bare dest.git &&
-	write_script dest.git/hooks/pre-receive <<-\EOF
+	test_hook --setup -C dest.git pre-receive <<-\EOF
 	while read old new ref; do
 		test "$(git log -1 --format=%s $new)" = reject && exit 1
 	done
@@ -60,7 +60,7 @@ test_expect_success 'push to repo path with path separator (colon)' '
 
 test_expect_success 'updating a ref from quarantine is forbidden' '
 	git init --bare update.git &&
-	write_script update.git/hooks/pre-receive <<-\EOF &&
+	test_hook -C update.git pre-receive <<-\EOF &&
 	read old new refname
 	git update-ref refs/heads/unrelated $new
 	exit 1
diff --git a/t/t5548-push-porcelain.sh b/t/t5548-push-porcelain.sh
index f11ff57e549..6282728eaf3 100755
--- a/t/t5548-push-porcelain.sh
+++ b/t/t5548-push-porcelain.sh
@@ -168,7 +168,7 @@ run_git_push_porcelain_output_test() {
 	'
 
 	test_expect_success "prepare pre-receive hook ($PROTOCOL)" '
-		write_script "$upstream/hooks/pre-receive" <<-EOF
+		test_hook --setup -C "$upstream" pre-receive <<-EOF
 		exit 1
 		EOF
 	'
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index fffc57120d6..4c7c00c94f1 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -26,7 +26,7 @@ dirty_repo () {
 }
 
 write_integration_script () {
-	write_script .git/hooks/fsmonitor-test<<-\EOF
+	test_hook --setup --clobber fsmonitor-test<<-\EOF
 	if test "$#" -ne 2
 	then
 		echo "$0: exactly 2 arguments expected"
@@ -108,7 +108,7 @@ EOF
 
 # test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit
 test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' '
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook fsmonitor-test<<-\EOF &&
 		printf "last_update_token\0"
 	EOF
 	git update-index --fsmonitor &&
@@ -169,7 +169,7 @@ EOF
 
 # test that newly added files are marked valid
 test_expect_success 'newly added files are marked valid' '
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook --setup --clobber fsmonitor-test<<-\EOF &&
 		printf "last_update_token\0"
 	EOF
 	git add new &&
@@ -210,7 +210,7 @@ EOF
 
 # test that *only* files returned by the integration script get flagged as invalid
 test_expect_success '*only* files returned by the integration script get flagged as invalid' '
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook --clobber fsmonitor-test<<-\EOF &&
 	printf "last_update_token\0"
 	printf "dir1/modified\0"
 	EOF
@@ -231,7 +231,7 @@ test_expect_success 'refresh_index() invalidates fsmonitor cache' '
 	dirty_repo &&
 	write_integration_script &&
 	git add . &&
-	write_script .git/hooks/fsmonitor-test<<-\EOF &&
+	test_hook --clobber fsmonitor-test<<-\EOF &&
 	EOF
 	git commit -m "to reset" &&
 	git reset HEAD~1 &&
@@ -280,7 +280,7 @@ do
 		# Make sure it's actually skipping the check for modified and untracked
 		# (if enabled) files unless it is told about them.
 		test_expect_success "status doesn't detect unreported modifications" '
-			write_script .git/hooks/fsmonitor-test<<-\EOF &&
+			test_hook --clobber fsmonitor-test<<-\EOF &&
 			printf "last_update_token\0"
 			:>marker
 			EOF
@@ -414,14 +414,14 @@ test_expect_success 'status succeeds with sparse index' '
 		git -C sparse sparse-checkout init --cone --sparse-index &&
 		git -C sparse sparse-checkout set dir1 dir2 &&
 
-		write_script .git/hooks/fsmonitor-test <<-\EOF &&
+		test_hook --clobber fsmonitor-test <<-\EOF &&
 			printf "last_update_token\0"
 		EOF
 		git -C full config core.fsmonitor ../.git/hooks/fsmonitor-test &&
 		git -C sparse config core.fsmonitor ../.git/hooks/fsmonitor-test &&
 		check_sparse_index_behavior ! &&
 
-		write_script .git/hooks/fsmonitor-test <<-\EOF &&
+		test_hook --clobber fsmonitor-test <<-\EOF &&
 			printf "last_update_token\0"
 			printf "dir1/modified\0"
 		EOF
@@ -439,7 +439,7 @@ test_expect_success 'status succeeds with sparse index' '
 
 		# This one modifies outside the sparse-checkout definition
 		# and hence we expect to expand the sparse-index.
-		write_script .git/hooks/fsmonitor-test <<-\EOF &&
+		test_hook --clobber fsmonitor-test <<-\EOF &&
 			printf "last_update_token\0"
 			printf "dir1a/modified\0"
 		EOF
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 0f439c99d61..6c9c61c79c2 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -551,6 +551,58 @@ write_script () {
 	chmod +x "$1"
 }
 
+# Usage: test_hook [options] <hook-name> <<-\EOF
+#
+#   -C <dir>:
+#	Run all git commands in directory <dir>
+#   --setup
+#	Setup a hook for subsequent tests, i.e. don't remove it in a
+#	"test_when_finished"
+#   --clobber
+#	Overwrite an existing <hook-name>, if it exists. Implies
+#	--setup (i.e. the "test_when_finished" is assumed to have been
+#	set up already).
+test_hook () {
+	setup= &&
+	clobber= &&
+	indir= &&
+	while test $# != 0
+	do
+		case "$1" in
+		-C)
+			indir="$2" &&
+			shift
+			;;
+		--setup)
+			setup=t
+			;;
+		--clobber)
+			clobber=t
+			;;
+		-*)
+			BUG "invalid argument: $1"
+			;;
+		*)
+			break
+			;;
+		esac &&
+		shift
+	done &&
+
+	git_dir=$(git -C "$indir" rev-parse --absolute-git-dir) &&
+	hook_dir="$git_dir/hooks" &&
+	hook_file="$hook_dir/$1" &&
+	if test -z "$clobber"
+	then
+		test_path_is_missing "$hook_file"
+	fi &&
+	if test -z "$setup$clobber"
+	then
+		test_when_finished "rm \"$hook_file\""
+	fi &&
+	write_script "$hook_file"
+}
+
 # Use test_set_prereq to tell that a particular prerequisite is available.
 # The prerequisite can later be checked for in two ways:
 #
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 02/13] hook tests: turn exit code assertions into a loop
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 01/13] test-lib-functions: add and use a "test_hook" wrapper Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 03/13] http tests: don't rely on "hook/post-update.sample" Ævar Arnfjörð Bjarmason
                       ` (11 subsequent siblings)
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Amend a test added in 96e7225b310 (hook: add 'run' subcommand,
2021-12-22) to use a for-loop instead of a copy/pasting the same test
for the four exit codes we test.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1800-hook.sh | 35 ++++++++++-------------------------
 1 file changed, 10 insertions(+), 25 deletions(-)

diff --git a/t/t1800-hook.sh b/t/t1800-hook.sh
index 93540b1fa12..26ed5e11bc8 100755
--- a/t/t1800-hook.sh
+++ b/t/t1800-hook.sh
@@ -53,31 +53,16 @@ test_expect_success 'git hook run: stdout and stderr both write to our stderr' '
 	test_must_be_empty stdout.actual
 '
 
-test_expect_success 'git hook run: exit codes are passed along' '
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 1
-	EOF
-
-	test_expect_code 1 git hook run test-hook &&
-
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 2
-	EOF
-
-	test_expect_code 2 git hook run test-hook &&
-
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 128
-	EOF
-
-	test_expect_code 128 git hook run test-hook &&
-
-	write_script .git/hooks/test-hook <<-EOF &&
-	exit 129
-	EOF
-
-	test_expect_code 129 git hook run test-hook
-'
+for code in 1 2 128 129
+do
+	test_expect_success "git hook run: exit code $code is passed along" '
+		test_hook test-hook <<-EOF &&
+		exit $code
+		EOF
+
+		test_expect_code $code git hook run test-hook
+	'
+done
 
 test_expect_success 'git hook run arg u ments without -- is not allowed' '
 	test_expect_code 129 git hook run test-hook arg u ments
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 03/13] http tests: don't rely on "hook/post-update.sample"
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 01/13] test-lib-functions: add and use a "test_hook" wrapper Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 02/13] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 04/13] tests: assume the hooks are disabled by default Ævar Arnfjörð Bjarmason
                       ` (10 subsequent siblings)
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change code added in a87679339c0 (test: rename http fetch and push
test files, 2014-02-06) to stop relying on the "exec git
update-server-info" in "templates/hooks--post-update.sample", let's
instead inline the expected hook in the test itself.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5540-http-push-webdav.sh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/t/t5540-http-push-webdav.sh b/t/t5540-http-push-webdav.sh
index b0dbacf0b9b..37db3dec0c5 100755
--- a/t/t5540-http-push-webdav.sh
+++ b/t/t5540-http-push-webdav.sh
@@ -42,7 +42,9 @@ test_expect_success 'setup remote repository' '
 	git clone --bare test_repo test_repo.git &&
 	cd test_repo.git &&
 	git --bare update-server-info &&
-	mv hooks/post-update.sample hooks/post-update &&
+	test_hook --setup post-update <<-\EOF &&
+	exec git update-server-info
+	EOF
 	ORIG_HEAD=$(git rev-parse --verify HEAD) &&
 	cd - &&
 	mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH"
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 04/13] tests: assume the hooks are disabled by default
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
                       ` (2 preceding siblings ...)
  2022-03-17 10:13     ` [PATCH v3 03/13] http tests: don't rely on "hook/post-update.sample" Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 05/13] bugreport tests: tighten up "git bugreport -s hooks" test Ævar Arnfjörð Bjarmason
                       ` (9 subsequent siblings)
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Stop moving the .git/hooks directory out of the way, or creating it
during test setup. Instead assume that it will contain
harmless *.sample files.

That we can assume that is discussed in point #4 of
f0d4d398e28 (test-lib: split up and deprecate test_create_repo(),
2021-05-10), those parts of this could and should have been done in
that change.

Removing the "mkdir -p" here will then validate that our templates are
being used, since we'd subsequently fail to create a hook in that
directory if it didn't exist. Subsequent commits will have those hooks
created by a "test_hook" wrapper, which will then being doing that
same validation.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1416-ref-transaction-hooks.sh | 1 -
 t/t5516-fetch-push.sh            | 3 +--
 t/t7519-status-fsmonitor.sh      | 2 --
 3 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh
index 6fca1f08d9a..085a7a46f21 100755
--- a/t/t1416-ref-transaction-hooks.sh
+++ b/t/t1416-ref-transaction-hooks.sh
@@ -8,7 +8,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 . ./test-lib.sh
 
 test_expect_success setup '
-	mkdir -p .git/hooks &&
 	test_commit PRE &&
 	PRE_OID=$(git rev-parse PRE) &&
 	test_commit POST &&
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 3137eb8d4d2..1a20e54adc1 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -28,8 +28,7 @@ mk_empty () {
 	(
 		cd "$repo_name" &&
 		git init &&
-		git config receive.denyCurrentBranch warn &&
-		mv .git/hooks .git/hooks-disabled
+		git config receive.denyCurrentBranch warn
 	)
 }
 
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index 4c7c00c94f1..d4f9c6a837b 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -56,7 +56,6 @@ test_lazy_prereq UNTRACKED_CACHE '
 '
 
 test_expect_success 'setup' '
-	mkdir -p .git/hooks &&
 	: >tracked &&
 	: >modified &&
 	mkdir dir1 &&
@@ -322,7 +321,6 @@ test_expect_success UNTRACKED_CACHE 'ignore .git changes when invalidating UNTR'
 	test_create_repo dot-git &&
 	(
 		cd dot-git &&
-		mkdir -p .git/hooks &&
 		: >tracked &&
 		test-tool chmtime =-60 tracked &&
 		: >modified &&
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 05/13] bugreport tests: tighten up "git bugreport -s hooks" test
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
                       ` (3 preceding siblings ...)
  2022-03-17 10:13     ` [PATCH v3 04/13] tests: assume the hooks are disabled by default Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 06/13] fetch+push tests: use "test_hook" and "test_when_finished" pattern Ævar Arnfjörð Bjarmason
                       ` (8 subsequent siblings)
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Amend a test added in 788a776069b (bugreport: collect list of
populated hooks, 2020-05-07) to "test_cmp" for the expected output,
instead of selectively using "grep" to check for specific things we
either expect or don't expect in the output.

As noted in a preceding commit our .git/hooks directory already
contains *.sample hooks, so we have no need to clobber the
prepare-commit-msg.sample hook in particular.

Instead we should assert that those *.sample hooks are not included in
the output, and for good measure let's add a new "unknown-hook", to
check that we only look through our own known hooks. See
cfe853e66be (hook-list.h: add a generated list of hooks, like
config-list.h, 2021-09-26) for how we generate that data.

We're intentionally not piping the "actual" output through "sort" or
similar, we'd also like to check that our reported hooks are sorted.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0091-bugreport.sh | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh
index eeedbfa9193..08f5fe9caef 100755
--- a/t/t0091-bugreport.sh
+++ b/t/t0091-bugreport.sh
@@ -60,18 +60,22 @@ test_expect_success 'can create leading directories outside of a git dir' '
 
 test_expect_success 'indicates populated hooks' '
 	test_when_finished rm git-bugreport-hooks.txt &&
-	test_when_finished rm -fr .git/hooks &&
-	rm -fr .git/hooks &&
-	mkdir .git/hooks &&
-	for hook in applypatch-msg prepare-commit-msg.sample
-	do
-		write_script ".git/hooks/$hook" <<-EOF || return 1
-		echo "hook $hook exists"
-		EOF
-	done &&
+
+	test_hook applypatch-msg <<-\EOF &&
+	true
+	EOF
+	test_hook unknown-hook <<-\EOF &&
+	true
+	EOF
 	git bugreport -s hooks &&
-	grep applypatch-msg git-bugreport-hooks.txt &&
-	! grep prepare-commit-msg git-bugreport-hooks.txt
+
+	sort >expect <<-\EOF &&
+	[Enabled Hooks]
+	applypatch-msg
+	EOF
+
+	sed -ne "/^\[Enabled Hooks\]$/,/^$/p" <git-bugreport-hooks.txt >actual &&
+	test_cmp expect actual
 '
 
 test_done
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 06/13] fetch+push tests: use "test_hook" and "test_when_finished" pattern
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
                       ` (4 preceding siblings ...)
  2022-03-17 10:13     ` [PATCH v3 05/13] bugreport tests: tighten up "git bugreport -s hooks" test Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 07/13] gc + p4 tests: use "test_hook", remove sub-shells Ævar Arnfjörð Bjarmason
                       ` (7 subsequent siblings)
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change the "t5516-fetch-push.sh" test code to make use of the new
"test_hook" helper, and to use "test_when_finished" to have tests
clean up their own state, instead of relying on subsequent tests to
clean the trash directory.

Before this each test would have been responsible for cleaning up
after a preceding test (which may or may not have run, e.g. if --run
or "GIT_SKIP_TESTS" was used), now each test will instead clean up
after itself.

In order to use both "test_hook" and "test_when_finished" we need to
move them out of sub-shells, which requires some refactoring.

While we're at it split up the "push with negotiation" test, now the
middle of the test doesn't need to "rm event", and since it delimited
two halves that were testing two different things the end-state is
easier to read and reason about.

While changing these lines make the minor change from "-fr" to "-rf"
as the "rm" argument, some of them used it already, it's more common
in the test suite, and it leaves the end-state of the file with more
consistency.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5516-fetch-push.sh | 191 +++++++++++++++++++-----------------------
 1 file changed, 88 insertions(+), 103 deletions(-)

diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 1a20e54adc1..4dfb080433e 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -23,13 +23,10 @@ D=$(pwd)
 
 mk_empty () {
 	repo_name="$1"
-	rm -fr "$repo_name" &&
-	mkdir "$repo_name" &&
-	(
-		cd "$repo_name" &&
-		git init &&
-		git config receive.denyCurrentBranch warn
-	)
+	test_when_finished "rm -rf \"$repo_name\"" &&
+	test_path_is_missing "$repo_name" &&
+	git init "$repo_name" &&
+	git -C "$repo_name" config receive.denyCurrentBranch warn
 }
 
 mk_test () {
@@ -58,40 +55,28 @@ mk_test () {
 mk_test_with_hooks() {
 	repo_name=$1
 	mk_test "$@" &&
-	(
-		cd "$repo_name" &&
-		mkdir .git/hooks &&
-		cd .git/hooks &&
-
-		cat >pre-receive <<-'EOF' &&
-		#!/bin/sh
-		cat - >>pre-receive.actual
-		EOF
-
-		cat >update <<-'EOF' &&
-		#!/bin/sh
-		printf "%s %s %s\n" "$@" >>update.actual
-		EOF
-
-		cat >post-receive <<-'EOF' &&
-		#!/bin/sh
-		cat - >>post-receive.actual
-		EOF
-
-		cat >post-update <<-'EOF' &&
-		#!/bin/sh
-		for ref in "$@"
-		do
-			printf "%s\n" "$ref" >>post-update.actual
-		done
-		EOF
-
-		chmod +x pre-receive update post-receive post-update
-	)
+	test_hook -C "$repo_name" pre-receive <<-'EOF' &&
+	cat - >>pre-receive.actual
+	EOF
+
+	test_hook -C "$repo_name" update <<-'EOF' &&
+	printf "%s %s %s\n" "$@" >>update.actual
+	EOF
+
+	test_hook -C "$repo_name" post-receive <<-'EOF' &&
+	cat - >>post-receive.actual
+	EOF
+
+	test_hook -C "$repo_name" post-update <<-'EOF'
+	for ref in "$@"
+	do
+		printf "%s\n" "$ref" >>post-update.actual
+	done
+	EOF
 }
 
 mk_child() {
-	rm -rf "$2" &&
+	test_when_finished "rm -rf \"$2\"" &&
 	git clone "$1" "$2"
 }
 
@@ -196,32 +181,32 @@ grep_wrote () {
 	grep 'write_pack_file/wrote.*"value":"'$1'"' $2
 }
 
-test_expect_success 'push with negotiation' '
-	# Without negotiation
+test_expect_success 'push without negotiation' '
 	mk_empty testrepo &&
 	git push testrepo $the_first_commit:refs/remotes/origin/first_commit &&
 	test_commit -C testrepo unrelated_commit &&
 	git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit &&
-	echo now pushing without negotiation &&
+	test_when_finished "rm event" &&
 	GIT_TRACE2_EVENT="$(pwd)/event" git -c protocol.version=2 push testrepo refs/heads/main:refs/remotes/origin/main &&
-	grep_wrote 5 event && # 2 commits, 2 trees, 1 blob
+	grep_wrote 5 event # 2 commits, 2 trees, 1 blob
+'
 
-	# Same commands, but with negotiation
-	rm event &&
+test_expect_success 'push with negotiation' '
 	mk_empty testrepo &&
 	git push testrepo $the_first_commit:refs/remotes/origin/first_commit &&
 	test_commit -C testrepo unrelated_commit &&
 	git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit &&
+	test_when_finished "rm event" &&
 	GIT_TRACE2_EVENT="$(pwd)/event" git -c protocol.version=2 -c push.negotiate=1 push testrepo refs/heads/main:refs/remotes/origin/main &&
 	grep_wrote 2 event # 1 commit, 1 tree
 '
 
 test_expect_success 'push with negotiation proceeds anyway even if negotiation fails' '
-	rm event &&
 	mk_empty testrepo &&
 	git push testrepo $the_first_commit:refs/remotes/origin/first_commit &&
 	test_commit -C testrepo unrelated_commit &&
 	git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit &&
+	test_when_finished "rm event" &&
 	GIT_TEST_PROTOCOL_VERSION=0 GIT_TRACE2_EVENT="$(pwd)/event" \
 		git -c push.negotiate=1 push testrepo refs/heads/main:refs/remotes/origin/main 2>err &&
 	grep_wrote 5 event && # 2 commits, 2 trees, 1 blob
@@ -667,7 +652,6 @@ test_expect_success 'push does not update local refs on failure' '
 
 	mk_test testrepo heads/main &&
 	mk_child testrepo child &&
-	mkdir testrepo/.git/hooks &&
 	echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive &&
 	chmod +x testrepo/.git/hooks/pre-receive &&
 	(
@@ -1329,7 +1313,7 @@ done
 
 test_expect_success 'fetch follows tags by default' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
 	(
 		cd src &&
@@ -1339,6 +1323,7 @@ test_expect_success 'fetch follows tags by default' '
 		sed -n "p; s|refs/heads/main$|refs/remotes/origin/main|p" tmp1 |
 		sort -k 3 >../expect
 	) &&
+	test_when_finished "rm -rf dst" &&
 	git init dst &&
 	(
 		cd dst &&
@@ -1364,8 +1349,9 @@ test_expect_success 'peeled advertisements are not considered ref tips' '
 
 test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1388,8 +1374,9 @@ test_expect_success 'pushing a specific ref applies remote.$name.push as refmap'
 
 test_expect_success 'with no remote.$name.push, it is not used as refmap' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1410,8 +1397,9 @@ test_expect_success 'with no remote.$name.push, it is not used as refmap' '
 
 test_expect_success 'with no remote.$name.push, upstream mapping is used' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1439,8 +1427,9 @@ test_expect_success 'with no remote.$name.push, upstream mapping is used' '
 
 test_expect_success 'push does not follow tags by default' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1462,8 +1451,9 @@ test_expect_success 'push does not follow tags by default' '
 
 test_expect_success 'push --follow-tags only pushes relevant tags' '
 	mk_test testrepo heads/main &&
-	rm -fr src dst &&
+	test_when_finished "rm -rf src" &&
 	git init src &&
+	test_when_finished "rm -rf dst" &&
 	git init --bare dst &&
 	(
 		cd src &&
@@ -1501,9 +1491,9 @@ EOF
 '
 
 test_expect_success 'pushing a tag pushes the tagged object' '
-	rm -rf dst.git &&
 	blob=$(echo unreferenced | git hash-object -w --stdin) &&
 	git tag -m foo tag-of-blob $blob &&
+	test_when_finished "rm -rf dst.git" &&
 	git init --bare dst.git &&
 	git push dst.git tag-of-blob &&
 	# the receiving index-pack should have noticed
@@ -1514,7 +1504,7 @@ test_expect_success 'pushing a tag pushes the tagged object' '
 '
 
 test_expect_success 'push into bare respects core.logallrefupdates' '
-	rm -rf dst.git &&
+	test_when_finished "rm -rf dst.git" &&
 	git init --bare dst.git &&
 	git -C dst.git config core.logallrefupdates true &&
 
@@ -1532,7 +1522,7 @@ test_expect_success 'push into bare respects core.logallrefupdates' '
 '
 
 test_expect_success 'fetch into bare respects core.logallrefupdates' '
-	rm -rf dst.git &&
+	test_when_finished "rm -rf dst.git" &&
 	git init --bare dst.git &&
 	(
 		cd dst.git &&
@@ -1553,6 +1543,7 @@ test_expect_success 'fetch into bare respects core.logallrefupdates' '
 '
 
 test_expect_success 'receive.denyCurrentBranch = updateInstead' '
+	mk_empty testrepo &&
 	git push testrepo main &&
 	(
 		cd testrepo &&
@@ -1655,7 +1646,7 @@ test_expect_success 'receive.denyCurrentBranch = updateInstead' '
 	) &&
 
 	# (5) push into void
-	rm -fr void &&
+	test_when_finished "rm -rf void" &&
 	git init void &&
 	(
 		cd void &&
@@ -1677,26 +1668,23 @@ test_expect_success 'receive.denyCurrentBranch = updateInstead' '
 '
 
 test_expect_success 'updateInstead with push-to-checkout hook' '
-	rm -fr testrepo &&
+	test_when_finished "rm -rf testrepo" &&
 	git init testrepo &&
-	(
-		cd testrepo &&
-		git pull .. main &&
-		git reset --hard HEAD^^ &&
-		git tag initial &&
-		git config receive.denyCurrentBranch updateInstead &&
-		write_script .git/hooks/push-to-checkout <<-\EOF
-		echo >&2 updating from $(git rev-parse HEAD)
-		echo >&2 updating to "$1"
-
-		git update-index -q --refresh &&
-		git read-tree -u -m HEAD "$1" || {
-			status=$?
-			echo >&2 read-tree failed
-			exit $status
-		}
-		EOF
-	) &&
+	git -C testrepo pull .. main &&
+	git -C testrepo reset --hard HEAD^^ &&
+	git -C testrepo tag initial &&
+	git -C testrepo config receive.denyCurrentBranch updateInstead &&
+	test_hook -C testrepo push-to-checkout <<-\EOF &&
+	echo >&2 updating from $(git rev-parse HEAD)
+	echo >&2 updating to "$1"
+
+	git update-index -q --refresh &&
+	git read-tree -u -m HEAD "$1" || {
+		status=$?
+		echo >&2 read-tree failed
+		exit $status
+	}
+	EOF
 
 	# Try pushing into a pristine
 	git push testrepo main &&
@@ -1739,35 +1727,32 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
 	) &&
 
 	# push into void
-	rm -fr void &&
+	test_when_finished "rm -rf void" &&
 	git init void &&
-	(
-		cd void &&
-		git config receive.denyCurrentBranch updateInstead &&
-		write_script .git/hooks/push-to-checkout <<-\EOF
-		if git rev-parse --quiet --verify HEAD
-		then
-			has_head=yes
-			echo >&2 updating from $(git rev-parse HEAD)
-		else
-			has_head=no
-			echo >&2 pushing into void
-		fi
-		echo >&2 updating to "$1"
-
-		git update-index -q --refresh &&
-		case "$has_head" in
-		yes)
-			git read-tree -u -m HEAD "$1" ;;
-		no)
-			git read-tree -u -m "$1" ;;
-		esac || {
-			status=$?
-			echo >&2 read-tree failed
-			exit $status
-		}
-		EOF
-	) &&
+	git -C void config receive.denyCurrentBranch updateInstead &&
+	test_hook -C void push-to-checkout <<-\EOF &&
+	if git rev-parse --quiet --verify HEAD
+	then
+		has_head=yes
+		echo >&2 updating from $(git rev-parse HEAD)
+	else
+		has_head=no
+		echo >&2 pushing into void
+	fi
+	echo >&2 updating to "$1"
+
+	git update-index -q --refresh &&
+	case "$has_head" in
+	yes)
+		git read-tree -u -m HEAD "$1" ;;
+	no)
+		git read-tree -u -m "$1" ;;
+	esac || {
+		status=$?
+		echo >&2 read-tree failed
+		exit $status
+	}
+	EOF
 
 	git push void main &&
 	(
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 07/13] gc + p4 tests: use "test_hook", remove sub-shells
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
                       ` (5 preceding siblings ...)
  2022-03-17 10:13     ` [PATCH v3 06/13] fetch+push tests: use "test_hook" and "test_when_finished" pattern Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 08/13] tests: change "cat && chmod +x" to use "test_hook" Ævar Arnfjörð Bjarmason
                       ` (6 subsequent siblings)
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Refactor the repository setup code for tests that test hooks the use
of sub-shells when setting up the test repository and hooks, and use
the "test_hook" wrapper instead of "write_scripts".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t6500-gc.sh           | 22 ++++++++++------------
 t/t9800-git-p4-basic.sh | 23 ++++++++++++++---------
 2 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index c2021267f2c..cd6c53360d2 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -101,12 +101,12 @@ test_expect_success 'pre-auto-gc hook can stop auto gc' '
 	EOF
 
 	git init pre-auto-gc-hook &&
+	test_hook -C pre-auto-gc-hook pre-auto-gc <<-\EOF &&
+	echo >&2 no gc for you &&
+	exit 1
+	EOF
 	(
 		cd pre-auto-gc-hook &&
-		write_script ".git/hooks/pre-auto-gc" <<-\EOF &&
-		echo >&2 no gc for you &&
-		exit 1
-		EOF
 
 		git config gc.auto 3 &&
 		git config gc.autoDetach false &&
@@ -128,14 +128,12 @@ test_expect_success 'pre-auto-gc hook can stop auto gc' '
 	See "git help gc" for manual housekeeping.
 	EOF
 
-	(
-		cd pre-auto-gc-hook &&
-		write_script ".git/hooks/pre-auto-gc" <<-\EOF &&
-		echo >&2 will gc for you &&
-		exit 0
-		EOF
-		git gc --auto >../out.actual 2>../err.actual
-	) &&
+	test_hook -C pre-auto-gc-hook --clobber pre-auto-gc <<-\EOF &&
+	echo >&2 will gc for you &&
+	exit 0
+	EOF
+
+	git -C pre-auto-gc-hook gc --auto >out.actual 2>err.actual &&
 
 	test_must_be_empty out.actual &&
 	test_cmp err.expect err.actual
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index 806005a793a..8b30062c0cf 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -277,16 +277,21 @@ test_expect_success 'run hook p4-pre-submit before submit' '
 		git commit -m "add hello.txt" &&
 		git config git-p4.skipSubmitEdit true &&
 		git p4 submit --dry-run >out &&
-		grep "Would apply" out &&
-		mkdir -p .git/hooks &&
-		write_script .git/hooks/p4-pre-submit <<-\EOF &&
-		exit 0
-		EOF
+		grep "Would apply" out
+	) &&
+	test_hook -C "$git" p4-pre-submit <<-\EOF &&
+	exit 0
+	EOF
+	(
+		cd "$git" &&
 		git p4 submit --dry-run >out &&
-		grep "Would apply" out &&
-		write_script .git/hooks/p4-pre-submit <<-\EOF &&
-		exit 1
-		EOF
+		grep "Would apply" out
+	) &&
+	test_hook -C "$git" --clobber p4-pre-submit <<-\EOF &&
+	exit 1
+	EOF
+	(
+		cd "$git" &&
 		test_must_fail git p4 submit --dry-run >errs 2>&1 &&
 		! grep "Would apply" errs
 	)
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 08/13] tests: change "cat && chmod +x" to use "test_hook"
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
                       ` (6 preceding siblings ...)
  2022-03-17 10:13     ` [PATCH v3 07/13] gc + p4 tests: use "test_hook", remove sub-shells Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 09/13] tests: change "mkdir -p && write_script" " Ævar Arnfjörð Bjarmason
                       ` (5 subsequent siblings)
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Refactor various test code to use the "test_hook" helper. This change:

 - Fixes the long-standing issues with those tests using "#!/bin/sh"
   instead of "#!$SHELL_PATH". Using "#!/bin/sh" here happened to work
   because this code was so simple that it e.g. worked on Solaris
   /bin/sh.

 - Removes the "mkdir .git/hooks" invocation, as explained in a
   preceding commit we'll rely on the default templates to create that
   directory for us.

For the test in "t5402-post-merge-hook.sh" it's easier and more
correct to unroll the for-loop into a test_expect_success, so let's do
that.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5402-post-merge-hook.sh | 16 +++++++++-------
 t/t5601-clone.sh           |  4 +---
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/t/t5402-post-merge-hook.sh b/t/t5402-post-merge-hook.sh
index 3e5e19c7191..915af2de95e 100755
--- a/t/t5402-post-merge-hook.sh
+++ b/t/t5402-post-merge-hook.sh
@@ -25,13 +25,15 @@ test_expect_success setup '
 	GIT_DIR=clone2/.git git update-index --add a
 '
 
-for clone in 1 2; do
-	cat >clone${clone}/.git/hooks/post-merge <<'EOF'
-#!/bin/sh
-echo $@ >> $GIT_DIR/post-merge.args
-EOF
-	chmod u+x clone${clone}/.git/hooks/post-merge
-done
+test_expect_success 'setup clone hooks' '
+	test_when_finished "rm -f hook" &&
+	cat >hook <<-\EOF &&
+	echo $@ >>$GIT_DIR/post-merge.args
+	EOF
+
+	test_hook --setup -C clone1 post-merge <hook &&
+	test_hook --setup -C clone2 post-merge <hook
+'
 
 test_expect_success 'post-merge does not run for up-to-date ' '
 	GIT_DIR=clone1/.git git merge $commit0 &&
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 83c24fc97a7..4a61f2c901e 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -79,12 +79,10 @@ test_expect_success 'clone from hooks' '
 	cd .. &&
 	git init r1 &&
 	cd r1 &&
-	cat >.git/hooks/pre-commit <<-\EOF &&
-	#!/bin/sh
+	test_hook pre-commit <<-\EOF &&
 	git clone ../r0 ../r2
 	exit 1
 	EOF
-	chmod u+x .git/hooks/pre-commit &&
 	: >file &&
 	git add file &&
 	test_must_fail git commit -m invoke-hook &&
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 09/13] tests: change "mkdir -p && write_script" to use "test_hook"
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
                       ` (7 preceding siblings ...)
  2022-03-17 10:13     ` [PATCH v3 08/13] tests: change "cat && chmod +x" to use "test_hook" Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 10/13] tests: use "test_hook" for misc "mkdir -p" and "chmod" cases Ævar Arnfjörð Bjarmason
                       ` (4 subsequent siblings)
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change tests that used a "mkdir -p .git/hooks && write_script" pattern
to use the new "test_hook" helper instead. The new helper does not
create the .git/hooks directory, rather we assume that the default
template will do so for us.

An upcoming series[1] will extend "test_hook" to operate in a
"--template=" mode, but for now assuming that we have a .git/hooks
already is a safe assumption. If that assumption becomes false in the
future we'll only need to change 'test_hook", instead of all of these
callsites.

1. https://lore.kernel.org/git/cover-00.13-00000000000-20211212T201308Z-avarab@gmail.com/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0029-core-unsetenvvars.sh      |  3 +--
 t/t1350-config-hooks-path.sh      |  4 ++--
 t/t3404-rebase-interactive.sh     | 10 ++--------
 t/t3430-rebase-merges.sh          |  6 +++---
 t/t4150-am.sh                     | 24 ++++++------------------
 t/t5403-post-checkout-hook.sh     |  3 +--
 t/t5534-push-signed.sh            | 26 ++++++++------------------
 t/t7113-post-index-change-hook.sh |  7 +++----
 t/t9001-send-email.sh             |  4 +---
 9 files changed, 27 insertions(+), 60 deletions(-)

diff --git a/t/t0029-core-unsetenvvars.sh b/t/t0029-core-unsetenvvars.sh
index b138e1d9cbc..4e8e90dd982 100755
--- a/t/t0029-core-unsetenvvars.sh
+++ b/t/t0029-core-unsetenvvars.sh
@@ -12,8 +12,7 @@ then
 fi
 
 test_expect_success 'setup' '
-	mkdir -p "$TRASH_DIRECTORY/.git/hooks" &&
-	write_script "$TRASH_DIRECTORY/.git/hooks/pre-commit" <<-\EOF
+	test_hook --setup pre-commit <<-\EOF
 	echo $HOBBES >&2
 	EOF
 '
diff --git a/t/t1350-config-hooks-path.sh b/t/t1350-config-hooks-path.sh
index fa9647a7c0b..f6dc83e2aab 100755
--- a/t/t1350-config-hooks-path.sh
+++ b/t/t1350-config-hooks-path.sh
@@ -6,11 +6,11 @@ test_description='Test the core.hooksPath configuration variable'
 
 test_expect_success 'set up a pre-commit hook in core.hooksPath' '
 	>actual &&
-	mkdir -p .git/custom-hooks .git/hooks &&
+	mkdir -p .git/custom-hooks &&
 	write_script .git/custom-hooks/pre-commit <<-\EOF &&
 	echo CUSTOM >>actual
 	EOF
-	write_script .git/hooks/pre-commit <<-\EOF
+	test_hook --setup pre-commit <<-\EOF
 	echo NORMAL >>actual
 	EOF
 '
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index a38f2da7691..f31afd4a547 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -619,9 +619,7 @@ test_expect_success 'rebase a detached HEAD' '
 '
 
 test_expect_success 'rebase a commit violating pre-commit' '
-
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/pre-commit <<-\EOF &&
+	test_hook pre-commit <<-\EOF &&
 	test -z "$(git diff --cached --check)"
 	EOF
 	echo "monde! " >> file1 &&
@@ -636,8 +634,6 @@ test_expect_success 'rebase a commit violating pre-commit' '
 '
 
 test_expect_success 'rebase with a file named HEAD in worktree' '
-
-	rm -fr .git/hooks &&
 	git reset --hard &&
 	git checkout -b branch3 A &&
 
@@ -1688,10 +1684,8 @@ test_expect_success 'valid author header when author contains single quote' '
 '
 
 test_expect_success 'post-commit hook is called' '
-	test_when_finished "rm -f .git/hooks/post-commit" &&
 	>actual &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-commit <<-\EOS &&
+	test_hook post-commit <<-\EOS &&
 	git rev-parse HEAD >>actual
 	EOS
 	(
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index 43c82d9a33b..f351701fec2 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -292,9 +292,9 @@ test_expect_success 'post-rewrite hook and fixups work for merges' '
 	git commit --fixup HEAD same2.t &&
 	fixup="$(git rev-parse HEAD)" &&
 
-	mkdir -p .git/hooks &&
-	test_when_finished "rm .git/hooks/post-rewrite" &&
-	echo "cat >actual" | write_script .git/hooks/post-rewrite &&
+	test_hook post-rewrite <<-\EOF &&
+	cat >actual
+	EOF
 
 	test_tick &&
 	git rebase -i --autosquash -r HEAD^^^ &&
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index 159fae8d016..cdad4b68807 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -315,12 +315,10 @@ test_expect_success 'am --patch-format=hg applies hg patch' '
 '
 
 test_expect_success 'am with applypatch-msg hook' '
-	test_when_finished "rm -f .git/hooks/applypatch-msg" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/applypatch-msg <<-\EOF &&
+	test_hook applypatch-msg <<-\EOF &&
 	cat "$1" >actual-msg &&
 	echo hook-message >"$1"
 	EOF
@@ -335,12 +333,10 @@ test_expect_success 'am with applypatch-msg hook' '
 '
 
 test_expect_success 'am with failing applypatch-msg hook' '
-	test_when_finished "rm -f .git/hooks/applypatch-msg" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/applypatch-msg <<-\EOF &&
+	test_hook applypatch-msg <<-\EOF &&
 	exit 1
 	EOF
 	test_must_fail git am patch1 &&
@@ -350,12 +346,10 @@ test_expect_success 'am with failing applypatch-msg hook' '
 '
 
 test_expect_success 'am with pre-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/pre-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/pre-applypatch <<-\EOF &&
+	test_hook pre-applypatch <<-\EOF &&
 	git diff first >diff.actual
 	exit 0
 	EOF
@@ -368,12 +362,10 @@ test_expect_success 'am with pre-applypatch hook' '
 '
 
 test_expect_success 'am with failing pre-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/pre-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/pre-applypatch <<-\EOF &&
+	test_hook pre-applypatch <<-\EOF &&
 	exit 1
 	EOF
 	test_must_fail git am patch1 &&
@@ -383,12 +375,10 @@ test_expect_success 'am with failing pre-applypatch hook' '
 '
 
 test_expect_success 'am with post-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/post-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-applypatch <<-\EOF &&
+	test_hook post-applypatch <<-\EOF &&
 	git rev-parse HEAD >head.actual
 	git diff second >diff.actual
 	exit 0
@@ -403,12 +393,10 @@ test_expect_success 'am with post-applypatch hook' '
 '
 
 test_expect_success 'am with failing post-applypatch hook' '
-	test_when_finished "rm -f .git/hooks/post-applypatch" &&
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
 	git checkout first &&
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-applypatch <<-\EOF &&
+	test_hook post-applypatch <<-\EOF &&
 	git rev-parse HEAD >head.actual
 	exit 1
 	EOF
diff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh
index d1181816906..978f240cdac 100755
--- a/t/t5403-post-checkout-hook.sh
+++ b/t/t5403-post-checkout-hook.sh
@@ -10,8 +10,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 . ./test-lib.sh
 
 test_expect_success setup '
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-checkout <<-\EOF &&
+	test_hook --setup post-checkout <<-\EOF &&
 	echo "$@" >.git/post-checkout.args
 	EOF
 	test_commit one &&
diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh
index 24d374adbae..7c0a148e73c 100755
--- a/t/t5534-push-signed.sh
+++ b/t/t5534-push-signed.sh
@@ -35,8 +35,7 @@ test_expect_success setup '
 
 test_expect_success 'unsigned push does not send push certificate' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -52,8 +51,7 @@ test_expect_success 'unsigned push does not send push certificate' '
 
 test_expect_success 'talking with a receiver without push certificate support' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -69,22 +67,19 @@ test_expect_success 'talking with a receiver without push certificate support' '
 
 test_expect_success 'push --signed fails with a receiver without push certificate support' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	test_must_fail git push --signed dst noop ff +noff 2>err &&
 	test_i18ngrep "the receiving end does not support" err
 '
 
 test_expect_success 'push --signed=1 is accepted' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	test_must_fail git push --signed=1 dst noop ff +noff 2>err &&
 	test_i18ngrep "the receiving end does not support" err
 '
 
 test_expect_success GPG 'no certificate for a signed push with no update' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	if test -n "${GIT_PUSH_CERT-}"
 	then
 		git cat-file blob $GIT_PUSH_CERT >../push-cert
@@ -96,9 +91,8 @@ test_expect_success GPG 'no certificate for a signed push with no update' '
 
 test_expect_success GPG 'signed push sends push certificate' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -139,10 +133,9 @@ test_expect_success GPG 'signed push sends push certificate' '
 
 test_expect_success GPGSSH 'ssh signed push sends push certificate' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -223,9 +216,8 @@ test_expect_success GPG 'inconsistent push options in signed push not allowed' '
 
 test_expect_success GPG 'fail without key and heed user.signingkey' '
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -273,9 +265,8 @@ test_expect_success GPG 'fail without key and heed user.signingkey' '
 test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '
 	test_config gpg.format x509 &&
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
@@ -326,10 +317,9 @@ test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '
 test_expect_success GPGSSH 'fail without key and heed user.signingkey ssh' '
 	test_config gpg.format ssh &&
 	prepare_dst &&
-	mkdir -p dst/.git/hooks &&
 	git -C dst config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
 	git -C dst config receive.certnonceseed sekrit &&
-	write_script dst/.git/hooks/post-receive <<-\EOF &&
+	test_hook -C dst post-receive <<-\EOF &&
 	# discard the update list
 	cat >/dev/null
 	# record the push certificate
diff --git a/t/t7113-post-index-change-hook.sh b/t/t7113-post-index-change-hook.sh
index a21781d68a1..58e55a7c779 100755
--- a/t/t7113-post-index-change-hook.sh
+++ b/t/t7113-post-index-change-hook.sh
@@ -17,8 +17,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'test status, add, commit, others trigger hook without flags set' '
-	mkdir -p .git/hooks &&
-	write_script .git/hooks/post-index-change <<-\EOF &&
+	test_hook post-index-change <<-\EOF &&
 		if test "$1" -eq 1; then
 			echo "Invalid combination of flags passed to hook; updated_workdir is set." >testfailure
 			exit 1
@@ -63,7 +62,7 @@ test_expect_success 'test status, add, commit, others trigger hook without flags
 '
 
 test_expect_success 'test checkout and reset trigger the hook' '
-	write_script .git/hooks/post-index-change <<-\EOF &&
+	test_hook post-index-change <<-\EOF &&
 		if test "$1" -eq 1 && test "$2" -eq 1; then
 			echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
 			exit 1
@@ -106,7 +105,7 @@ test_expect_success 'test checkout and reset trigger the hook' '
 '
 
 test_expect_success 'test reset --mixed and update-index triggers the hook' '
-	write_script .git/hooks/post-index-change <<-\EOF &&
+	test_hook post-index-change <<-\EOF &&
 		if test "$1" -eq 1 && test "$2" -eq 1; then
 			echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
 			exit 1
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 84d0f40d76a..42694fe5841 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -2288,9 +2288,7 @@ test_expect_success $PREREQ 'cmdline in-reply-to used with --no-thread' '
 '
 
 test_expect_success $PREREQ 'invoke hook' '
-	mkdir -p .git/hooks &&
-
-	write_script .git/hooks/sendemail-validate <<-\EOF &&
+	test_hook sendemail-validate <<-\EOF &&
 	# test that we have the correct environment variable, pwd, and
 	# argument
 	case "$GIT_DIR" in
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 10/13] tests: use "test_hook" for misc "mkdir -p" and "chmod" cases
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
                       ` (8 preceding siblings ...)
  2022-03-17 10:13     ` [PATCH v3 09/13] tests: change "mkdir -p && write_script" " Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 11/13] tests: extend "test_hook" for "rm" and "chmod -x", convert "$HOOK" Ævar Arnfjörð Bjarmason
                       ` (3 subsequent siblings)
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Make use of "test_hook" in various cases that didn't fit neatly into
preceding commits. Here we need to indent blocks in addition to
changing the test code, or to make other small cosmetic changes.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3412-rebase-root.sh       | 18 ++++-------
 t/t3413-rebase-hook.sh       | 18 ++++-------
 t/t5401-update-hooks.sh      | 62 ++++++++++++++++--------------------
 t/t5407-post-rewrite-hook.sh | 14 ++++----
 t/t5541-http-push-smart.sh   | 22 ++++++-------
 5 files changed, 56 insertions(+), 78 deletions(-)

diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
index 1e9f7833dd6..58371d8a547 100755
--- a/t/t3412-rebase-root.sh
+++ b/t/t3412-rebase-root.sh
@@ -31,12 +31,9 @@ test_expect_success 'rebase --root fails with too many args' '
 '
 
 test_expect_success 'setup pre-rebase hook' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-echo "\$1,\$2" >.git/PRE-REBASE-INPUT
-EOF
-	chmod +x .git/hooks/pre-rebase
+	test_hook --setup pre-rebase <<-\EOF
+	echo "$1,$2" >.git/PRE-REBASE-INPUT
+	EOF
 '
 cat > expect <<EOF
 4
@@ -141,12 +138,9 @@ commit work7~5
 EOF
 
 test_expect_success 'setup pre-rebase hook that fails' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-false
-EOF
-	chmod +x .git/hooks/pre-rebase
+	test_hook --setup --clobber pre-rebase <<-\EOF
+	false
+	EOF
 '
 
 test_expect_success 'pre-rebase hook stops rebase' '
diff --git a/t/t3413-rebase-hook.sh b/t/t3413-rebase-hook.sh
index b4acb3be5cf..9fab0d779bb 100755
--- a/t/t3413-rebase-hook.sh
+++ b/t/t3413-rebase-hook.sh
@@ -41,12 +41,9 @@ test_expect_success 'rebase -i' '
 '
 
 test_expect_success 'setup pre-rebase hook' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-echo "\$1,\$2" >.git/PRE-REBASE-INPUT
-EOF
-	chmod +x .git/hooks/pre-rebase
+	test_hook --setup pre-rebase <<-\EOF
+	echo "$1,$2" >.git/PRE-REBASE-INPUT
+	EOF
 '
 
 test_expect_success 'pre-rebase hook gets correct input (1)' '
@@ -102,12 +99,9 @@ test_expect_success 'pre-rebase hook gets correct input (6)' '
 '
 
 test_expect_success 'setup pre-rebase hook that fails' '
-	mkdir -p .git/hooks &&
-	cat >.git/hooks/pre-rebase <<EOF &&
-#!$SHELL_PATH
-false
-EOF
-	chmod +x .git/hooks/pre-rebase
+	test_hook --setup --clobber pre-rebase <<-\EOF
+	false
+	EOF
 '
 
 test_expect_success 'pre-rebase hook stops rebase (1)' '
diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
index 799349a416c..001b7a17ad2 100755
--- a/t/t5401-update-hooks.sh
+++ b/t/t5401-update-hooks.sh
@@ -20,45 +20,37 @@ test_expect_success setup '
 	git clone --bare ./. victim.git &&
 	GIT_DIR=victim.git git update-ref refs/heads/tofail $commit1 &&
 	git update-ref refs/heads/main $commit1 &&
-	git update-ref refs/heads/tofail $commit0
-'
+	git update-ref refs/heads/tofail $commit0 &&
 
-cat >victim.git/hooks/pre-receive <<'EOF'
-#!/bin/sh
-printf %s "$@" >>$GIT_DIR/pre-receive.args
-cat - >$GIT_DIR/pre-receive.stdin
-echo STDOUT pre-receive
-echo STDERR pre-receive >&2
-EOF
-chmod u+x victim.git/hooks/pre-receive
+	test_hook --setup -C victim.git pre-receive <<-\EOF &&
+	printf %s "$@" >>$GIT_DIR/pre-receive.args
+	cat - >$GIT_DIR/pre-receive.stdin
+	echo STDOUT pre-receive
+	echo STDERR pre-receive >&2
+	EOF
 
-cat >victim.git/hooks/update <<'EOF'
-#!/bin/sh
-echo "$@" >>$GIT_DIR/update.args
-read x; printf %s "$x" >$GIT_DIR/update.stdin
-echo STDOUT update $1
-echo STDERR update $1 >&2
-test "$1" = refs/heads/main || exit
-EOF
-chmod u+x victim.git/hooks/update
+	test_hook --setup -C victim.git update <<-\EOF &&
+	echo "$@" >>$GIT_DIR/update.args
+	read x; printf %s "$x" >$GIT_DIR/update.stdin
+	echo STDOUT update $1
+	echo STDERR update $1 >&2
+	test "$1" = refs/heads/main || exit
+	EOF
 
-cat >victim.git/hooks/post-receive <<'EOF'
-#!/bin/sh
-printf %s "$@" >>$GIT_DIR/post-receive.args
-cat - >$GIT_DIR/post-receive.stdin
-echo STDOUT post-receive
-echo STDERR post-receive >&2
-EOF
-chmod u+x victim.git/hooks/post-receive
+	test_hook --setup -C victim.git post-receive <<-\EOF &&
+	printf %s "$@" >>$GIT_DIR/post-receive.args
+	cat - >$GIT_DIR/post-receive.stdin
+	echo STDOUT post-receive
+	echo STDERR post-receive >&2
+	EOF
 
-cat >victim.git/hooks/post-update <<'EOF'
-#!/bin/sh
-echo "$@" >>$GIT_DIR/post-update.args
-read x; printf %s "$x" >$GIT_DIR/post-update.stdin
-echo STDOUT post-update
-echo STDERR post-update >&2
-EOF
-chmod u+x victim.git/hooks/post-update
+	test_hook --setup -C victim.git post-update <<-\EOF
+	echo "$@" >>$GIT_DIR/post-update.args
+	read x; printf %s "$x" >$GIT_DIR/post-update.stdin
+	echo STDOUT post-update
+	echo STDERR post-update >&2
+	EOF
+'
 
 test_expect_success push '
 	test_must_fail git send-pack --force ./victim.git \
diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
index 6da8d760e28..5f3ff051ca2 100755
--- a/t/t5407-post-rewrite-hook.sh
+++ b/t/t5407-post-rewrite-hook.sh
@@ -17,15 +17,13 @@ test_expect_success 'setup' '
 	git checkout A^0 &&
 	test_commit E bar E &&
 	test_commit F foo F &&
-	git checkout main
-'
+	git checkout main &&
 
-cat >.git/hooks/post-rewrite <<EOF
-#!/bin/sh
-echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
-cat > "$TRASH_DIRECTORY"/post-rewrite.data
-EOF
-chmod u+x .git/hooks/post-rewrite
+	test_hook --setup post-rewrite <<-EOF
+	echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
+	cat > "$TRASH_DIRECTORY"/post-rewrite.data
+	EOF
+'
 
 clear_hook_input () {
 	rm -f post-rewrite.args post-rewrite.data
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index 8ca50f8b18c..ab4b5cfcd11 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -96,18 +96,18 @@ test_expect_success 'create and delete remote branch' '
 	test_must_fail git show-ref --verify refs/remotes/origin/dev
 '
 
-cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<EOF
-#!/bin/sh
-exit 1
-EOF
-chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update"
+test_expect_success 'setup rejected update hook' '
+	test_hook --setup -C "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" update <<-\EOF &&
+	exit 1
+	EOF
 
-cat >exp <<EOF
-remote: error: hook declined to update refs/heads/dev2
-To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git
- ! [remote rejected] dev2 -> dev2 (hook declined)
-error: failed to push some refs to 'http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'
-EOF
+	cat >exp <<-EOF
+	remote: error: hook declined to update refs/heads/dev2
+	To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git
+	 ! [remote rejected] dev2 -> dev2 (hook declined)
+	error: failed to push some refs to '\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\''
+	EOF
+'
 
 test_expect_success 'rejected update prints status' '
 	cd "$ROOT_PATH"/test_repo_clone &&
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 11/13] tests: extend "test_hook" for "rm" and "chmod -x", convert "$HOOK"
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
                       ` (9 preceding siblings ...)
  2022-03-17 10:13     ` [PATCH v3 10/13] tests: use "test_hook" for misc "mkdir -p" and "chmod" cases Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 12/13] proc-receive hook tests: use "test_hook" instead of "write_script" Ævar Arnfjörð Bjarmason
                       ` (2 subsequent siblings)
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

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>
---
 t/t2400-worktree-add.sh                       |   5 +-
 t/t5543-atomic-push.sh                        |   5 +-
 t/t5571-pre-push-hook.sh                      |  38 +++--
 ...3-pre-commit-and-pre-merge-commit-hooks.sh | 150 +++++++++---------
 t/t7504-commit-msg-hook.sh                    |  43 +++--
 t/t7505-prepare-commit-msg-hook.sh            |  43 +++--
 t/t7520-ignored-hook-warning.sh               |  11 +-
 t/test-lib-functions.sh                       |  24 +++
 8 files changed, 162 insertions(+), 157 deletions(-)

diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh
index 43139af08fc..2f564d533d0 100755
--- a/t/t2400-worktree-add.sh
+++ b/t/t2400-worktree-add.sh
@@ -559,10 +559,7 @@ test_expect_success 'git worktree --no-guess-remote option overrides config' '
 '
 
 post_checkout_hook () {
-	gitdir=${1:-.git}
-	test_when_finished "rm -f $gitdir/hooks/post-checkout" &&
-	mkdir -p $gitdir/hooks &&
-	write_script $gitdir/hooks/post-checkout <<-\EOF
+	test_hook -C "$1" post-checkout <<-\EOF
 	{
 		echo $*
 		git rev-parse --git-dir --show-toplevel
diff --git a/t/t5543-atomic-push.sh b/t/t5543-atomic-push.sh
index bfee461861e..90676365471 100755
--- a/t/t5543-atomic-push.sh
+++ b/t/t5543-atomic-push.sh
@@ -164,10 +164,7 @@ test_expect_success 'atomic push obeys update hook preventing a branch to be pus
 	) &&
 	(
 		cd upstream &&
-		HOOKDIR="$(git rev-parse --git-dir)/hooks" &&
-		HOOK="$HOOKDIR/update" &&
-		mkdir -p "$HOOKDIR" &&
-		write_script "$HOOK" <<-\EOF
+		test_hook update <<-\EOF
 			# only allow update to main from now on
 			test "$1" = "refs/heads/main"
 		EOF
diff --git a/t/t5571-pre-push-hook.sh b/t/t5571-pre-push-hook.sh
index 96d6ecc0af7..a11b20e3782 100755
--- a/t/t5571-pre-push-hook.sh
+++ b/t/t5571-pre-push-hook.sh
@@ -6,16 +6,11 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
 . ./test-lib.sh
 
-# Setup hook that always succeeds
-HOOKDIR="$(git rev-parse --git-dir)/hooks"
-HOOK="$HOOKDIR/pre-push"
-mkdir -p "$HOOKDIR"
-write_script "$HOOK" <<EOF
-cat >actual
-exit 0
-EOF
-
 test_expect_success 'setup' '
+	test_hook pre-push <<-\EOF &&
+	cat >actual
+	EOF
+
 	git config push.default upstream &&
 	git init --bare repo1 &&
 	git remote add parent1 repo1 &&
@@ -28,15 +23,16 @@ test_expect_success 'setup' '
 	git push parent1 HEAD:foreign &&
 	test_cmp expect actual
 '
-write_script "$HOOK" <<EOF
-cat >actual
-exit 1
-EOF
 
 COMMIT1="$(git rev-parse HEAD)"
 export COMMIT1
 
 test_expect_success 'push with failing hook' '
+	test_hook pre-push <<-\EOF &&
+	cat >actual &&
+	exit 1
+	EOF
+
 	test_commit two &&
 	cat >expect <<-EOF &&
 	HEAD $(git rev-parse HEAD) refs/heads/main $(test_oid zero)
@@ -55,13 +51,13 @@ test_expect_success '--no-verify bypasses hook' '
 COMMIT2="$(git rev-parse HEAD)"
 export COMMIT2
 
-write_script "$HOOK" <<'EOF'
-echo "$1" >actual
-echo "$2" >>actual
-cat >>actual
-EOF
-
 test_expect_success 'push with hook' '
+	test_hook --setup pre-push <<-\EOF &&
+	echo "$1" >actual
+	echo "$2" >>actual
+	cat >>actual
+	EOF
+
 	cat >expect <<-EOF &&
 	parent1
 	repo1
@@ -136,7 +132,9 @@ test_expect_success 'set up many-ref tests' '
 '
 
 test_expect_success 'sigpipe does not cause pre-push hook failure' '
-	echo "exit 0" | write_script "$HOOK" &&
+	test_hook --clobber pre-push <<-\EOF &&
+	exit 0
+	EOF
 	git push parent1 "refs/heads/b/*:refs/heads/b/*"
 '
 
diff --git a/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh
index 606d8d0f089..ad1eb64ba0d 100755
--- a/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh
+++ b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh
@@ -7,37 +7,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
 . ./test-lib.sh
 
-HOOKDIR="$(git rev-parse --git-dir)/hooks"
-PRECOMMIT="$HOOKDIR/pre-commit"
-PREMERGE="$HOOKDIR/pre-merge-commit"
-
-# Prepare sample scripts that write their $0 to actual_hooks
-test_expect_success 'sample script setup' '
-	mkdir -p "$HOOKDIR" &&
-	write_script "$HOOKDIR/success.sample" <<-\EOF &&
-	echo $0 >>actual_hooks
-	exit 0
-	EOF
-	write_script "$HOOKDIR/fail.sample" <<-\EOF &&
-	echo $0 >>actual_hooks
-	exit 1
-	EOF
-	write_script "$HOOKDIR/non-exec.sample" <<-\EOF &&
-	echo $0 >>actual_hooks
-	exit 1
-	EOF
-	chmod -x "$HOOKDIR/non-exec.sample" &&
-	write_script "$HOOKDIR/require-prefix.sample" <<-\EOF &&
-	echo $0 >>actual_hooks
-	test $GIT_PREFIX = "success/"
-	EOF
-	write_script "$HOOKDIR/check-author.sample" <<-\EOF
-	echo $0 >>actual_hooks
-	test "$GIT_AUTHOR_NAME" = "New Author" &&
-	test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
-	EOF
-'
-
 test_expect_success 'root commit' '
 	echo "root" >file &&
 	git add file &&
@@ -96,10 +65,16 @@ test_expect_success '--no-verify with no hook (merge)' '
 	test_path_is_missing actual_hooks
 '
 
+setup_success_hook () {
+	test_when_finished "rm -f actual_hooks expected_hooks" &&
+	echo "$1" >expected_hooks &&
+	test_hook "$1" <<-EOF
+	echo $1 >>actual_hooks
+	EOF
+}
+
 test_expect_success 'with succeeding hook' '
-	test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
-	cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
-	echo "$PRECOMMIT" >expected_hooks &&
+	setup_success_hook "pre-commit" &&
 	echo "more" >>file &&
 	git add file &&
 	git commit -m "more" &&
@@ -107,9 +82,7 @@ test_expect_success 'with succeeding hook' '
 '
 
 test_expect_success 'with succeeding hook (merge)' '
-	test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
-	cp "$HOOKDIR/success.sample" "$PREMERGE" &&
-	echo "$PREMERGE" >expected_hooks &&
+	setup_success_hook "pre-merge-commit" &&
 	git checkout side &&
 	git merge -m "merge main" main &&
 	git checkout main &&
@@ -117,17 +90,14 @@ test_expect_success 'with succeeding hook (merge)' '
 '
 
 test_expect_success 'automatic merge fails; both hooks are available' '
-	test_when_finished "rm -f \"$PREMERGE\" \"$PRECOMMIT\"" &&
-	test_when_finished "rm -f expected_hooks actual_hooks" &&
-	test_when_finished "git checkout main" &&
-	cp "$HOOKDIR/success.sample" "$PREMERGE" &&
-	cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
+	setup_success_hook "pre-commit" &&
+	setup_success_hook "pre-merge-commit" &&
 
 	git checkout conflicting-a &&
 	test_must_fail git merge -m "merge conflicting-b" conflicting-b &&
 	test_path_is_missing actual_hooks &&
 
-	echo "$PRECOMMIT" >expected_hooks &&
+	echo "pre-commit" >expected_hooks &&
 	echo a+b >conflicting &&
 	git add conflicting &&
 	git commit -m "resolve conflict" &&
@@ -135,8 +105,7 @@ test_expect_success 'automatic merge fails; both hooks are available' '
 '
 
 test_expect_success '--no-verify with succeeding hook' '
-	test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
-	cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
+	setup_success_hook "pre-commit" &&
 	echo "even more" >>file &&
 	git add file &&
 	git commit --no-verify -m "even more" &&
@@ -144,8 +113,7 @@ test_expect_success '--no-verify with succeeding hook' '
 '
 
 test_expect_success '--no-verify with succeeding hook (merge)' '
-	test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
-	cp "$HOOKDIR/success.sample" "$PREMERGE" &&
+	setup_success_hook "pre-merge-commit" &&
 	git branch -f side side-orig &&
 	git checkout side &&
 	git merge --no-verify -m "merge main" main &&
@@ -153,10 +121,19 @@ test_expect_success '--no-verify with succeeding hook (merge)' '
 	test_path_is_missing actual_hooks
 '
 
+setup_failing_hook () {
+	test_when_finished "rm -f actual_hooks" &&
+	test_hook "$1" <<-EOF
+	echo $1-failing-hook >>actual_hooks
+	exit 1
+	EOF
+}
+
 test_expect_success 'with failing hook' '
-	test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
-	cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
-	echo "$PRECOMMIT" >expected_hooks &&
+	setup_failing_hook "pre-commit" &&
+	test_when_finished "rm -f expected_hooks" &&
+	echo "pre-commit-failing-hook" >expected_hooks &&
+
 	echo "another" >>file &&
 	git add file &&
 	test_must_fail git commit -m "another" &&
@@ -164,8 +141,7 @@ test_expect_success 'with failing hook' '
 '
 
 test_expect_success '--no-verify with failing hook' '
-	test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
-	cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
+	setup_failing_hook "pre-commit" &&
 	echo "stuff" >>file &&
 	git add file &&
 	git commit --no-verify -m "stuff" &&
@@ -173,9 +149,8 @@ test_expect_success '--no-verify with failing hook' '
 '
 
 test_expect_success 'with failing hook (merge)' '
-	test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
-	cp "$HOOKDIR/fail.sample" "$PREMERGE" &&
-	echo "$PREMERGE" >expected_hooks &&
+	setup_failing_hook "pre-merge-commit" &&
+	echo "pre-merge-commit-failing-hook" >expected_hooks &&
 	git checkout side &&
 	test_must_fail git merge -m "merge main" main &&
 	git checkout main &&
@@ -183,8 +158,8 @@ test_expect_success 'with failing hook (merge)' '
 '
 
 test_expect_success '--no-verify with failing hook (merge)' '
-	test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
-	cp "$HOOKDIR/fail.sample" "$PREMERGE" &&
+	setup_failing_hook "pre-merge-commit" &&
+
 	git branch -f side side-orig &&
 	git checkout side &&
 	git merge --no-verify -m "merge main" main &&
@@ -192,9 +167,18 @@ test_expect_success '--no-verify with failing hook (merge)' '
 	test_path_is_missing actual_hooks
 '
 
+setup_non_exec_hook () {
+	test_when_finished "rm -f actual_hooks" &&
+	test_hook "$1" <<-\EOF &&
+	echo non-exec >>actual_hooks
+	exit 1
+	EOF
+	test_hook --disable "$1"
+}
+
+
 test_expect_success POSIXPERM 'with non-executable hook' '
-	test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
-	cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
+	setup_non_exec_hook "pre-commit" &&
 	echo "content" >>file &&
 	git add file &&
 	git commit -m "content" &&
@@ -202,8 +186,7 @@ test_expect_success POSIXPERM 'with non-executable hook' '
 '
 
 test_expect_success POSIXPERM '--no-verify with non-executable hook' '
-	test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
-	cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
+	setup_non_exec_hook "pre-commit" &&
 	echo "more content" >>file &&
 	git add file &&
 	git commit --no-verify -m "more content" &&
@@ -211,8 +194,7 @@ test_expect_success POSIXPERM '--no-verify with non-executable hook' '
 '
 
 test_expect_success POSIXPERM 'with non-executable hook (merge)' '
-	test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
-	cp "$HOOKDIR/non-exec.sample" "$PREMERGE" &&
+	setup_non_exec_hook "pre-merge" &&
 	git branch -f side side-orig &&
 	git checkout side &&
 	git merge -m "merge main" main &&
@@ -221,8 +203,7 @@ test_expect_success POSIXPERM 'with non-executable hook (merge)' '
 '
 
 test_expect_success POSIXPERM '--no-verify with non-executable hook (merge)' '
-	test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
-	cp "$HOOKDIR/non-exec.sample" "$PREMERGE" &&
+	setup_non_exec_hook "pre-merge" &&
 	git branch -f side side-orig &&
 	git checkout side &&
 	git merge --no-verify -m "merge main" main &&
@@ -230,10 +211,18 @@ test_expect_success POSIXPERM '--no-verify with non-executable hook (merge)' '
 	test_path_is_missing actual_hooks
 '
 
+setup_require_prefix_hook () {
+	test_when_finished "rm -f expected_hooks" &&
+	echo require-prefix >expected_hooks &&
+	test_hook pre-commit <<-\EOF
+	echo require-prefix >>actual_hooks
+	test $GIT_PREFIX = "success/"
+	EOF
+}
+
 test_expect_success 'with hook requiring GIT_PREFIX' '
-	test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks success" &&
-	cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
-	echo "$PRECOMMIT" >expected_hooks &&
+	test_when_finished "rm -rf actual_hooks success" &&
+	setup_require_prefix_hook &&
 	echo "more content" >>file &&
 	git add file &&
 	mkdir success &&
@@ -245,9 +234,8 @@ test_expect_success 'with hook requiring GIT_PREFIX' '
 '
 
 test_expect_success 'with failing hook requiring GIT_PREFIX' '
-	test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks fail" &&
-	cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
-	echo "$PRECOMMIT" >expected_hooks &&
+	test_when_finished "rm -rf actual_hooks fail" &&
+	setup_require_prefix_hook &&
 	echo "more content" >>file &&
 	git add file &&
 	mkdir fail &&
@@ -259,13 +247,23 @@ test_expect_success 'with failing hook requiring GIT_PREFIX' '
 	test_cmp expected_hooks actual_hooks
 '
 
+setup_require_author_hook () {
+	test_when_finished "rm -f expected_hooks actual_hooks" &&
+	echo check-author >expected_hooks &&
+	test_hook pre-commit <<-\EOF
+	echo check-author >>actual_hooks
+	test "$GIT_AUTHOR_NAME" = "New Author" &&
+	test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
+	EOF
+}
+
+
 test_expect_success 'check the author in hook' '
-	test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
-	cp "$HOOKDIR/check-author.sample" "$PRECOMMIT" &&
+	setup_require_author_hook &&
 	cat >expected_hooks <<-EOF &&
-	$PRECOMMIT
-	$PRECOMMIT
-	$PRECOMMIT
+	check-author
+	check-author
+	check-author
 	EOF
 	test_must_fail git commit --allow-empty -m "by a.u.thor" &&
 	(
diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh
index bba58f04806..a39de8c1126 100755
--- a/t/t7504-commit-msg-hook.sh
+++ b/t/t7504-commit-msg-hook.sh
@@ -54,15 +54,11 @@ test_expect_success '--no-verify with no hook (editor)' '
 
 '
 
-# now install hook that always succeeds
-HOOKDIR="$(git rev-parse --git-dir)/hooks"
-HOOK="$HOOKDIR/commit-msg"
-mkdir -p "$HOOKDIR"
-cat > "$HOOK" <<EOF
-#!/bin/sh
-exit 0
-EOF
-chmod +x "$HOOK"
+test_expect_success 'setup: commit-msg hook that always succeeds' '
+	test_hook --setup commit-msg <<-\EOF
+	exit 0
+	EOF
+'
 
 test_expect_success 'with succeeding hook' '
 
@@ -98,11 +94,11 @@ test_expect_success '--no-verify with succeeding hook (editor)' '
 
 '
 
-# now a hook that fails
-cat > "$HOOK" <<EOF
-#!/bin/sh
-exit 1
-EOF
+test_expect_success 'setup: commit-msg hook that always fails' '
+	test_hook --clobber commit-msg <<-\EOF
+	exit 1
+	EOF
+'
 
 commit_msg_is () {
 	test "$(git log --pretty=format:%s%b -1)" = "$1"
@@ -176,8 +172,12 @@ test_expect_success 'merge bypasses failing hook with --no-verify' '
 	commit_msg_is "Merge branch '\''main'\'' into newbranch"
 '
 
+test_expect_success 'setup: commit-msg hook made non-executable' '
+	git_dir="$(git rev-parse --git-dir)" &&
+	chmod -x "$git_dir/hooks/commit-msg"
+'
+
 
-chmod -x "$HOOK"
 test_expect_success POSIXPERM 'with non-executable hook' '
 
 	echo "content" >file &&
@@ -212,13 +212,12 @@ test_expect_success POSIXPERM '--no-verify with non-executable hook (editor)' '
 
 '
 
-# now a hook that edits the commit message
-cat > "$HOOK" <<'EOF'
-#!/bin/sh
-echo "new message" > "$1"
-exit 0
-EOF
-chmod +x "$HOOK"
+test_expect_success 'setup: commit-msg hook that edits the commit message' '
+	test_hook --clobber commit-msg <<-\EOF
+	echo "new message" >"$1"
+	exit 0
+	EOF
+'
 
 test_expect_success 'hook edits commit message' '
 
diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh
index e39c809ca42..2128142a61c 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -47,25 +47,19 @@ test_expect_success 'with no hook' '
 
 '
 
-# set up fake editor for interactive editing
-cat > fake-editor <<'EOF'
-#!/bin/sh
-exit 0
-EOF
-chmod +x fake-editor
-
-## Not using test_set_editor here so we can easily ensure the editor variable
-## is only set for the editor tests
-FAKE_EDITOR="$(pwd)/fake-editor"
-export FAKE_EDITOR
+test_expect_success 'setup fake editor for interactive editing' '
+	write_script fake-editor <<-\EOF &&
+	exit 0
+	EOF
 
-# now install hook that always succeeds and adds a message
-HOOKDIR="$(git rev-parse --git-dir)/hooks"
-HOOK="$HOOKDIR/prepare-commit-msg"
-mkdir -p "$HOOKDIR"
-echo "#!$SHELL_PATH" > "$HOOK"
-cat >> "$HOOK" <<'EOF'
+	## Not using test_set_editor here so we can easily ensure the editor variable
+	## is only set for the editor tests
+	FAKE_EDITOR="$(pwd)/fake-editor" &&
+	export FAKE_EDITOR
+'
 
+test_expect_success 'setup prepare-commit-msg hook' '
+	test_hook --setup prepare-commit-msg <<\EOF
 GIT_DIR=$(git rev-parse --git-dir)
 if test -d "$GIT_DIR/rebase-merge"
 then
@@ -103,7 +97,7 @@ else
 fi
 exit 0
 EOF
-chmod +x "$HOOK"
+'
 
 echo dummy template > "$(git rev-parse --git-dir)/template"
 
@@ -265,10 +259,11 @@ test_expect_success 'with hook and editor (cherry-pick)' '
 	test "$(git log -1 --pretty=format:%s)" = merge
 '
 
-cat > "$HOOK" <<'EOF'
-#!/bin/sh
-exit 1
-EOF
+test_expect_success 'setup: commit-msg hook that always fails' '
+	test_hook --setup --clobber prepare-commit-msg <<-\EOF
+	exit 1
+	EOF
+'
 
 test_expect_success 'with failing hook' '
 
@@ -296,9 +291,9 @@ test_expect_success 'with failing hook (merge)' '
 	git checkout -B other HEAD@{1} &&
 	echo "more" >> file &&
 	git add file &&
-	rm -f "$HOOK" &&
+	test_hook --remove prepare-commit-msg &&
 	git commit -m other &&
-	write_script "$HOOK" <<-EOF &&
+	test_hook --setup prepare-commit-msg <<-\EOF &&
 	exit 1
 	EOF
 	git checkout - &&
diff --git a/t/t7520-ignored-hook-warning.sh b/t/t7520-ignored-hook-warning.sh
index 634fb7f23a0..dc57526e6f1 100755
--- a/t/t7520-ignored-hook-warning.sh
+++ b/t/t7520-ignored-hook-warning.sh
@@ -5,10 +5,7 @@ test_description='ignored hook warning'
 . ./test-lib.sh
 
 test_expect_success setup '
-	hookdir="$(git rev-parse --git-dir)/hooks" &&
-	hook="$hookdir/pre-commit" &&
-	mkdir -p "$hookdir" &&
-	write_script "$hook" <<-\EOF
+	test_hook --setup pre-commit <<-\EOF
 	exit 0
 	EOF
 '
@@ -19,20 +16,20 @@ test_expect_success 'no warning if hook is not ignored' '
 '
 
 test_expect_success POSIXPERM 'warning if hook is ignored' '
-	chmod -x "$hook" &&
+	test_hook --disable pre-commit &&
 	git commit --allow-empty -m "even more" 2>message &&
 	test_i18ngrep -e "hook was ignored" message
 '
 
 test_expect_success POSIXPERM 'no warning if advice.ignoredHook set to false' '
 	test_config advice.ignoredHook false &&
-	chmod -x "$hook" &&
+	test_hook --disable pre-commit &&
 	git commit --allow-empty -m "even more" 2>message &&
 	test_i18ngrep ! -e "hook was ignored" message
 '
 
 test_expect_success 'no warning if unset advice.ignoredHook and hook removed' '
-	rm -f "$hook" &&
+	test_hook --remove pre-commit &&
 	test_unconfig advice.ignoredHook &&
 	git commit --allow-empty -m "even more" 2>message &&
 	test_i18ngrep ! -e "hook was ignored" message
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 6c9c61c79c2..a027f0c409e 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -562,9 +562,15 @@ write_script () {
 #	Overwrite an existing <hook-name>, if it exists. Implies
 #	--setup (i.e. the "test_when_finished" is assumed to have been
 #	set up already).
+#    --disable
+#	Disable (chmod -x) an existing <hook-name>, which must exist.
+#    --remove
+#	Remove (rm -f) an existing <hook-name>, which must exist.
 test_hook () {
 	setup= &&
 	clobber= &&
+	disable= &&
+	remove= &&
 	indir= &&
 	while test $# != 0
 	do
@@ -579,6 +585,12 @@ test_hook () {
 		--clobber)
 			clobber=t
 			;;
+		--disable)
+			disable=t
+			;;
+		--remove)
+			remove=t
+			;;
 		-*)
 			BUG "invalid argument: $1"
 			;;
@@ -592,6 +604,18 @@ test_hook () {
 	git_dir=$(git -C "$indir" rev-parse --absolute-git-dir) &&
 	hook_dir="$git_dir/hooks" &&
 	hook_file="$hook_dir/$1" &&
+	if test -n "$disable$remove"
+	then
+		test_path_is_file "$hook_file" &&
+		if test -n "$disable"
+		then
+			chmod -x "$hook_file"
+		elif test -n "$remove"
+		then
+			rm -f "$hook_file"
+		fi &&
+		return 0
+	fi &&
 	if test -z "$clobber"
 	then
 		test_path_is_missing "$hook_file"
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 12/13] proc-receive hook tests: use "test_hook" instead of "write_script"
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
                       ` (10 preceding siblings ...)
  2022-03-17 10:13     ` [PATCH v3 11/13] tests: extend "test_hook" for "rm" and "chmod -x", convert "$HOOK" Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 10:13     ` [PATCH v3 13/13] http tests: use "test_hook" for "smart" and "dumb" http tests Ævar Arnfjörð Bjarmason
  2022-03-17 16:31     ` [PATCH v3 00/13] tests: add and use a "test_hook" wrapper + hook fixes Junio C Hamano
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change the t5411/*.sh tests to use the test_hook helper instead of
"write_script". Unfortunately these tests do the setup and test across
different test_expect_success blocks, so we have to use
--clobber (implying --setup) for these.

Let's change those that can use a quoted here-doc to do so while we're
at it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5411/once-0010-report-status-v1.sh         |  2 +-
 t/t5411/test-0002-pre-receive-declined.sh     |  4 ++--
 ...st-0003-pre-receive-declined--porcelain.sh |  2 +-
 t/t5411/test-0013-bad-protocol.sh             | 20 +++++++++----------
 t/t5411/test-0014-bad-protocol--porcelain.sh  | 18 ++++++++---------
 t/t5411/test-0020-report-ng.sh                |  4 ++--
 t/t5411/test-0021-report-ng--porcelain.sh     |  4 ++--
 t/t5411/test-0022-report-unexpect-ref.sh      |  2 +-
 ...est-0023-report-unexpect-ref--porcelain.sh |  2 +-
 t/t5411/test-0024-report-unknown-ref.sh       |  2 +-
 ...test-0025-report-unknown-ref--porcelain.sh |  2 +-
 t/t5411/test-0026-push-options.sh             |  6 +++---
 t/t5411/test-0027-push-options--porcelain.sh  |  6 +++---
 t/t5411/test-0030-report-ok.sh                |  2 +-
 t/t5411/test-0031-report-ok--porcelain.sh     |  2 +-
 t/t5411/test-0032-report-with-options.sh      | 14 ++++++-------
 ...est-0033-report-with-options--porcelain.sh | 14 ++++++-------
 t/t5411/test-0034-report-ft.sh                |  2 +-
 t/t5411/test-0035-report-ft--porcelain.sh     |  2 +-
 ...t-0036-report-multi-rewrite-for-one-ref.sh |  6 +++---
 ...rt-multi-rewrite-for-one-ref--porcelain.sh |  6 +++---
 t/t5411/test-0038-report-mixed-refs.sh        |  2 +-
 .../test-0039-report-mixed-refs--porcelain.sh |  2 +-
 t/t5411/test-0040-process-all-refs.sh         |  2 +-
 .../test-0041-process-all-refs--porcelain.sh  |  2 +-
 ...t-0050-proc-receive-refs-with-modifiers.sh |  4 ++--
 26 files changed, 67 insertions(+), 67 deletions(-)

diff --git a/t/t5411/once-0010-report-status-v1.sh b/t/t5411/once-0010-report-status-v1.sh
index 297b10925d5..f9ffb01e509 100644
--- a/t/t5411/once-0010-report-status-v1.sh
+++ b/t/t5411/once-0010-report-status-v1.sh
@@ -3,7 +3,7 @@ test_expect_success "setup receive.procReceiveRefs" '
 '
 
 test_expect_success "setup proc-receive hook" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic1" \
diff --git a/t/t5411/test-0002-pre-receive-declined.sh b/t/t5411/test-0002-pre-receive-declined.sh
index 0c3490c9b1b..98a9d13041a 100644
--- a/t/t5411/test-0002-pre-receive-declined.sh
+++ b/t/t5411/test-0002-pre-receive-declined.sh
@@ -1,6 +1,6 @@
 test_expect_success "setup pre-receive hook ($PROTOCOL)" '
 	mv "$upstream/hooks/pre-receive" "$upstream/hooks/pre-receive.ok" &&
-	write_script "$upstream/hooks/pre-receive" <<-EOF
+	test_hook -C "$upstream" --clobber pre-receive <<-\EOF
 	exit 1
 	EOF
 '
@@ -21,7 +21,7 @@ test_expect_success "git-push is declined ($PROTOCOL)" '
 	EOF
 	test_cmp expect actual &&
 
-	test_cmp_refs -C "$upstream" <<-EOF
+	test_cmp_refs -C "$upstream" <<-\EOF
 	<COMMIT-A> refs/heads/main
 	EOF
 '
diff --git a/t/t5411/test-0003-pre-receive-declined--porcelain.sh b/t/t5411/test-0003-pre-receive-declined--porcelain.sh
index 2393b04ad95..67ca6dc4f8f 100644
--- a/t/t5411/test-0003-pre-receive-declined--porcelain.sh
+++ b/t/t5411/test-0003-pre-receive-declined--porcelain.sh
@@ -1,6 +1,6 @@
 test_expect_success "setup pre-receive hook ($PROTOCOL/porcelain)" '
 	mv "$upstream/hooks/pre-receive" "$upstream/hooks/pre-receive.ok" &&
-	write_script "$upstream/hooks/pre-receive" <<-EOF
+	test_hook -C "$upstream" --clobber pre-receive <<-\EOF
 	exit 1
 	EOF
 '
diff --git a/t/t5411/test-0013-bad-protocol.sh b/t/t5411/test-0013-bad-protocol.sh
index c08a00ded29..8d22e17aee3 100644
--- a/t/t5411/test-0013-bad-protocol.sh
+++ b/t/t5411/test-0013-bad-protocol.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (unknown version, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --version 2
 	EOF
@@ -40,7 +40,7 @@ test_expect_success "proc-receive: bad protocol (unknown version, $PROTOCOL)" '
 '
 
 test_expect_success "setup proc-receive hook (hook --die-read-version, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --die-read-version
 	EOF
@@ -65,13 +65,13 @@ test_expect_success "proc-receive: bad protocol (hook --die-read-version, $PROTO
 	grep "remote: fatal: die with the --die-read-version option" out-$test_count &&
 	grep "remote: error: fail to negotiate version with proc-receive hook" out-$test_count &&
 
-	test_cmp_refs -C "$upstream" <<-EOF
+	test_cmp_refs -C "$upstream" <<-\EOF
 	<COMMIT-A> refs/heads/main
 	EOF
 '
 
 test_expect_success "setup proc-receive hook (hook --die-write-version, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --die-write-version
 	EOF
@@ -102,7 +102,7 @@ test_expect_success "proc-receive: bad protocol (hook --die-write-version, $PROT
 '
 
 test_expect_success "setup proc-receive hook (hook --die-read-commands, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --die-read-commands
 	EOF
@@ -132,7 +132,7 @@ test_expect_success "proc-receive: bad protocol (hook --die-read-commands, $PROT
 '
 
 test_expect_success "setup proc-receive hook (hook --die-read-push-options, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --die-read-push-options
 	EOF
@@ -164,7 +164,7 @@ test_expect_success "proc-receive: bad protocol (hook --die-read-push-options, $
 '
 
 test_expect_success "setup proc-receive hook (hook --die-write-report, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --die-write-report
 	EOF
@@ -194,7 +194,7 @@ test_expect_success "proc-receive: bad protocol (hook --die-write-report, $PROTO
 '
 
 test_expect_success "setup proc-receive hook (no report, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v
 	EOF
@@ -236,7 +236,7 @@ test_expect_success "cleanup ($PROTOCOL)" '
 '
 
 test_expect_success "setup proc-receive hook (no ref, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok"
@@ -269,7 +269,7 @@ test_expect_success "proc-receive: bad protocol (no ref, $PROTOCOL)" '
 '
 
 test_expect_success "setup proc-receive hook (unknown status, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "xx refs/for/main/topic"
diff --git a/t/t5411/test-0014-bad-protocol--porcelain.sh b/t/t5411/test-0014-bad-protocol--porcelain.sh
index 3eaa597e0f7..298a3d1feca 100644
--- a/t/t5411/test-0014-bad-protocol--porcelain.sh
+++ b/t/t5411/test-0014-bad-protocol--porcelain.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (unknown version, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --version 2
 	EOF
@@ -40,7 +40,7 @@ test_expect_success "proc-receive: bad protocol (unknown version, $PROTOCOL/porc
 '
 
 test_expect_success "setup proc-receive hook (hook --die-read-version, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --die-read-version
 	EOF
@@ -71,7 +71,7 @@ test_expect_success "proc-receive: bad protocol (hook --die-read-version, $PROTO
 '
 
 test_expect_success "setup proc-receive hook (hook --die-write-version, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --die-write-version
 	EOF
@@ -102,7 +102,7 @@ test_expect_success "proc-receive: bad protocol (hook --die-write-version, $PROT
 '
 
 test_expect_success "setup proc-receive hook (hook --die-read-commands, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --die-read-commands
 	EOF
@@ -132,7 +132,7 @@ test_expect_success "proc-receive: bad protocol (hook --die-read-commands, $PROT
 '
 
 test_expect_success "setup proc-receive hook (hook --die-read-push-options, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --die-read-push-options
 	EOF
@@ -164,7 +164,7 @@ test_expect_success "proc-receive: bad protocol (hook --die-read-push-options, $
 '
 
 test_expect_success "setup proc-receive hook (hook --die-write-report, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v --die-write-report
 	EOF
@@ -194,7 +194,7 @@ test_expect_success "proc-receive: bad protocol (hook --die-write-report, $PROTO
 '
 
 test_expect_success "setup proc-receive hook (no report, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v
 	EOF
@@ -236,7 +236,7 @@ test_expect_success "cleanup ($PROTOCOL/porcelain)" '
 '
 
 test_expect_success "setup proc-receive hook (no ref, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok"
@@ -270,7 +270,7 @@ test_expect_success "proc-receive: bad protocol (no ref, $PROTOCOL/porcelain)" '
 '
 
 test_expect_success "setup proc-receive hook (unknown status, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "xx refs/for/main/topic"
diff --git a/t/t5411/test-0020-report-ng.sh b/t/t5411/test-0020-report-ng.sh
index e915dbc28df..6347c9629b3 100644
--- a/t/t5411/test-0020-report-ng.sh
+++ b/t/t5411/test-0020-report-ng.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (ng, no message, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ng refs/for/main/topic"
@@ -31,7 +31,7 @@ test_expect_success "proc-receive: fail to update (ng, no message, $PROTOCOL)" '
 '
 
 test_expect_success "setup proc-receive hook (ng message, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ng refs/for/main/topic error msg"
diff --git a/t/t5411/test-0021-report-ng--porcelain.sh b/t/t5411/test-0021-report-ng--porcelain.sh
index 2a392e099b9..502b34fe3dd 100644
--- a/t/t5411/test-0021-report-ng--porcelain.sh
+++ b/t/t5411/test-0021-report-ng--porcelain.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (ng, no message, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ng refs/for/main/topic"
@@ -32,7 +32,7 @@ test_expect_success "proc-receive: fail to update (ng, no message, $PROTOCOL/por
 '
 
 test_expect_success "setup proc-receive hook (ng message, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ng refs/for/main/topic error msg"
diff --git a/t/t5411/test-0022-report-unexpect-ref.sh b/t/t5411/test-0022-report-unexpect-ref.sh
index f7a494bdb9d..7744392a626 100644
--- a/t/t5411/test-0022-report-unexpect-ref.sh
+++ b/t/t5411/test-0022-report-unexpect-ref.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/heads/main"
diff --git a/t/t5411/test-0023-report-unexpect-ref--porcelain.sh b/t/t5411/test-0023-report-unexpect-ref--porcelain.sh
index 63c479e9759..6d116ef692c 100644
--- a/t/t5411/test-0023-report-unexpect-ref--porcelain.sh
+++ b/t/t5411/test-0023-report-unexpect-ref--porcelain.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/heads/main"
diff --git a/t/t5411/test-0024-report-unknown-ref.sh b/t/t5411/test-0024-report-unknown-ref.sh
index af055aa0864..619ca2f421a 100644
--- a/t/t5411/test-0024-report-unknown-ref.sh
+++ b/t/t5411/test-0024-report-unknown-ref.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic"
diff --git a/t/t5411/test-0025-report-unknown-ref--porcelain.sh b/t/t5411/test-0025-report-unknown-ref--porcelain.sh
index 99601ca321f..8b3f5d05a3f 100644
--- a/t/t5411/test-0025-report-unknown-ref--porcelain.sh
+++ b/t/t5411/test-0025-report-unknown-ref--porcelain.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic"
diff --git a/t/t5411/test-0026-push-options.sh b/t/t5411/test-0026-push-options.sh
index fec5f95793b..6dfc7b1c0da 100644
--- a/t/t5411/test-0026-push-options.sh
+++ b/t/t5411/test-0026-push-options.sh
@@ -1,6 +1,6 @@
 test_expect_success "setup proc-receive hook and disable push-options ($PROTOCOL)" '
 	git -C "$upstream" config receive.advertisePushOptions false &&
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic"
@@ -31,7 +31,7 @@ test_expect_success "enable push options ($PROTOCOL)" '
 '
 
 test_expect_success "setup version=0 for proc-receive hook ($PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		--version 0 \
@@ -75,7 +75,7 @@ test_expect_success "proc-receive: ignore push-options for version 0 ($PROTOCOL)
 '
 
 test_expect_success "restore proc-receive hook ($PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic"
diff --git a/t/t5411/test-0027-push-options--porcelain.sh b/t/t5411/test-0027-push-options--porcelain.sh
index 8fb75a8789d..768880b40fb 100644
--- a/t/t5411/test-0027-push-options--porcelain.sh
+++ b/t/t5411/test-0027-push-options--porcelain.sh
@@ -1,6 +1,6 @@
 test_expect_success "setup proc-receive hook and disable push-options ($PROTOCOL/porcelain)" '
 	git -C "$upstream" config receive.advertisePushOptions false &&
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic"
@@ -32,7 +32,7 @@ test_expect_success "enable push options ($PROTOCOL/porcelain)" '
 '
 
 test_expect_success "setup version=0 for proc-receive hook ($PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		--version 0 \
@@ -78,7 +78,7 @@ test_expect_success "proc-receive: ignore push-options for version 0 ($PROTOCOL/
 '
 
 test_expect_success "restore proc-receive hook ($PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic"
diff --git a/t/t5411/test-0030-report-ok.sh b/t/t5411/test-0030-report-ok.sh
index a3a6278213c..0f190a6e851 100644
--- a/t/t5411/test-0030-report-ok.sh
+++ b/t/t5411/test-0030-report-ok.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (ok, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic"
diff --git a/t/t5411/test-0031-report-ok--porcelain.sh b/t/t5411/test-0031-report-ok--porcelain.sh
index 0e175388b65..7ec39812638 100644
--- a/t/t5411/test-0031-report-ok--porcelain.sh
+++ b/t/t5411/test-0031-report-ok--porcelain.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (ok, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic"
diff --git a/t/t5411/test-0032-report-with-options.sh b/t/t5411/test-0032-report-with-options.sh
index 988a4302a67..07733b94b81 100644
--- a/t/t5411/test-0032-report-with-options.sh
+++ b/t/t5411/test-0032-report-with-options.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (option without matching ok, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "option refname refs/pull/123/head" \
@@ -30,7 +30,7 @@ test_expect_success "proc-receive: report option without matching ok ($PROTOCOL)
 '
 
 test_expect_success "setup proc-receive hook (option refname, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -62,7 +62,7 @@ test_expect_success "proc-receive: report option refname ($PROTOCOL)" '
 '
 
 test_expect_success "setup proc-receive hook (option refname and forced-update, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -95,7 +95,7 @@ test_expect_success "proc-receive: report option refname and forced-update ($PRO
 '
 
 test_expect_success "setup proc-receive hook (option refname and old-oid, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -129,7 +129,7 @@ test_expect_success "proc-receive: report option refname and old-oid ($PROTOCOL)
 '
 
 test_expect_success "setup proc-receive hook (option old-oid, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -161,7 +161,7 @@ test_expect_success "proc-receive: report option old-oid ($PROTOCOL)" '
 '
 
 test_expect_success "setup proc-receive hook (option old-oid and new-oid, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -195,7 +195,7 @@ test_expect_success "proc-receive: report option old-oid and new-oid ($PROTOCOL)
 '
 
 test_expect_success "setup proc-receive hook (report with multiple rewrites, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/a/b/c/topic" \
diff --git a/t/t5411/test-0033-report-with-options--porcelain.sh b/t/t5411/test-0033-report-with-options--porcelain.sh
index daacb3d69d4..2e1831b104e 100644
--- a/t/t5411/test-0033-report-with-options--porcelain.sh
+++ b/t/t5411/test-0033-report-with-options--porcelain.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (option without matching ok, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "option refname refs/pull/123/head" \
@@ -31,7 +31,7 @@ test_expect_success "proc-receive: report option without matching ok ($PROTOCOL/
 '
 
 test_expect_success "setup proc-receive hook (option refname, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -64,7 +64,7 @@ test_expect_success "proc-receive: report option refname ($PROTOCOL/porcelain)"
 '
 
 test_expect_success "setup proc-receive hook (option refname and forced-update, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -99,7 +99,7 @@ test_expect_success "proc-receive: report option refname and forced-update ($PRO
 '
 
 test_expect_success "setup proc-receive hook (option refname and old-oid, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -134,7 +134,7 @@ test_expect_success "proc-receive: report option refname and old-oid ($PROTOCOL/
 '
 
 test_expect_success "setup proc-receive hook (option old-oid, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -167,7 +167,7 @@ test_expect_success "proc-receive: report option old-oid ($PROTOCOL/porcelain)"
 '
 
 test_expect_success "setup proc-receive hook (option old-oid and new-oid, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -202,7 +202,7 @@ test_expect_success "proc-receive: report option old-oid and new-oid ($PROTOCOL/
 '
 
 test_expect_success "setup proc-receive hook (report with multiple rewrites, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/a/b/c/topic" \
diff --git a/t/t5411/test-0034-report-ft.sh b/t/t5411/test-0034-report-ft.sh
index 73a47d1ffdb..0e375350653 100644
--- a/t/t5411/test-0034-report-ft.sh
+++ b/t/t5411/test-0034-report-ft.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (ft, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
diff --git a/t/t5411/test-0035-report-ft--porcelain.sh b/t/t5411/test-0035-report-ft--porcelain.sh
index c3502011075..b9a05181f1a 100644
--- a/t/t5411/test-0035-report-ft--porcelain.sh
+++ b/t/t5411/test-0035-report-ft--porcelain.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (fall-through, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-\EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
diff --git a/t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh b/t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh
index 8c8a6c16e10..889e97057b8 100644
--- a/t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh
+++ b/t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh
@@ -14,7 +14,7 @@ test_expect_success "setup git config for remote-tracking of special refs" '
 '
 
 test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 1st rewrite, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -87,7 +87,7 @@ test_expect_success "proc-receive: check remote-tracking #1 ($PROTOCOL)" '
 '
 
 test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 2nd rewrite, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -162,7 +162,7 @@ test_expect_success "proc-receive: check remote-tracking #2 ($PROTOCOL)" '
 '
 
 test_expect_success "setup proc-receive hook (multiple rewrites for one ref, $PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
diff --git a/t/t5411/test-0037-report-multi-rewrite-for-one-ref--porcelain.sh b/t/t5411/test-0037-report-multi-rewrite-for-one-ref--porcelain.sh
index bc44810f33a..1e523b1c173 100644
--- a/t/t5411/test-0037-report-multi-rewrite-for-one-ref--porcelain.sh
+++ b/t/t5411/test-0037-report-multi-rewrite-for-one-ref--porcelain.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 1st rewrite, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -58,7 +58,7 @@ test_expect_success "proc-receive: multiple rewrite for one ref, no refname for
 '
 
 test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 2nd rewrite, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
@@ -119,7 +119,7 @@ test_expect_success "proc-receive: multiple rewrites for one ref, no refname for
 '
 
 test_expect_success "setup proc-receive hook (multiple rewrites for one ref, $PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/main/topic" \
diff --git a/t/t5411/test-0038-report-mixed-refs.sh b/t/t5411/test-0038-report-mixed-refs.sh
index e63fe7ba110..4c70e84e410 100644
--- a/t/t5411/test-0038-report-mixed-refs.sh
+++ b/t/t5411/test-0038-report-mixed-refs.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook ($PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/next/topic2" \
diff --git a/t/t5411/test-0039-report-mixed-refs--porcelain.sh b/t/t5411/test-0039-report-mixed-refs--porcelain.sh
index 99d17b73afd..40f4c5b1afb 100644
--- a/t/t5411/test-0039-report-mixed-refs--porcelain.sh
+++ b/t/t5411/test-0039-report-mixed-refs--porcelain.sh
@@ -1,5 +1,5 @@
 test_expect_success "setup proc-receive hook ($PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/for/next/topic2" \
diff --git a/t/t5411/test-0040-process-all-refs.sh b/t/t5411/test-0040-process-all-refs.sh
index 2f405adefa8..7ae3851efb9 100644
--- a/t/t5411/test-0040-process-all-refs.sh
+++ b/t/t5411/test-0040-process-all-refs.sh
@@ -17,7 +17,7 @@ test_expect_success "setup upstream branches ($PROTOCOL)" '
 '
 
 test_expect_success "setup proc-receive hook ($PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/heads/main" \
diff --git a/t/t5411/test-0041-process-all-refs--porcelain.sh b/t/t5411/test-0041-process-all-refs--porcelain.sh
index c88405792ef..02e1e084d6c 100644
--- a/t/t5411/test-0041-process-all-refs--porcelain.sh
+++ b/t/t5411/test-0041-process-all-refs--porcelain.sh
@@ -17,7 +17,7 @@ test_expect_success "setup upstream branches ($PROTOCOL/porcelain)" '
 '
 
 test_expect_success "setup proc-receive hook ($PROTOCOL/porcelain)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/heads/main" \
diff --git a/t/t5411/test-0050-proc-receive-refs-with-modifiers.sh b/t/t5411/test-0050-proc-receive-refs-with-modifiers.sh
index 31989f01850..7efdfe55987 100644
--- a/t/t5411/test-0050-proc-receive-refs-with-modifiers.sh
+++ b/t/t5411/test-0050-proc-receive-refs-with-modifiers.sh
@@ -9,7 +9,7 @@ test_expect_success "config receive.procReceiveRefs with modifiers ($PROTOCOL)"
 '
 
 test_expect_success "setup proc-receive hook ($PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/heads/main" \
@@ -70,7 +70,7 @@ test_expect_success "setup upstream: create tags/v123 ($PROTOCOL)" '
 '
 
 test_expect_success "setup proc-receive hook ($PROTOCOL)" '
-	write_script "$upstream/hooks/proc-receive" <<-EOF
+	test_hook -C "$upstream" --clobber proc-receive <<-EOF
 	printf >&2 "# proc-receive hook\n"
 	test-tool proc-receive -v \
 		-r "ok refs/heads/main" \
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v3 13/13] http tests: use "test_hook" for "smart" and "dumb" http tests
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
                       ` (11 preceding siblings ...)
  2022-03-17 10:13     ` [PATCH v3 12/13] proc-receive hook tests: use "test_hook" instead of "write_script" Ævar Arnfjörð Bjarmason
@ 2022-03-17 10:13     ` Ævar Arnfjörð Bjarmason
  2022-03-17 16:31     ` [PATCH v3 00/13] tests: add and use a "test_hook" wrapper + hook fixes Junio C Hamano
  13 siblings, 0 replies; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 10:13 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Emily Shaffer, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change the http tests to use "test_hook" insteadd of
"write_script". In both cases we can get rid of sub-shelling. For
"t/t5550-http-fetch-dumb.sh" add a trivial helper which sets up the
hook and calls "update-server-info".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5541-http-push-smart.sh | 10 ++++------
 t/t5550-http-fetch-dumb.sh | 25 ++++++++++---------------
 2 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index ab4b5cfcd11..2f09ff4fac6 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -419,10 +419,7 @@ test_expect_success CMDLINE_LIMIT 'push 2000 tags over http' '
 '
 
 test_expect_success GPG 'push with post-receive to inspect certificate' '
-	(
-		cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
-		mkdir -p hooks &&
-		write_script hooks/post-receive <<-\EOF &&
+	test_hook -C "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git post-receive <<-\EOF &&
 		# discard the update list
 		cat >/dev/null
 		# record the push certificate
@@ -437,8 +434,9 @@ test_expect_success GPG 'push with post-receive to inspect certificate' '
 		NONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}
 		NONCE=${GIT_PUSH_CERT_NONCE-nononce}
 		E_O_F
-		EOF
-
+	EOF
+	(
+		cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
 		git config receive.certnonceseed sekrit &&
 		git config receive.certnonceslop 30
 	) &&
diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh
index 259203926a9..f0d9cd584d3 100755
--- a/t/t5550-http-fetch-dumb.sh
+++ b/t/t5550-http-fetch-dumb.sh
@@ -25,16 +25,17 @@ test_expect_success 'setup repository' '
 	git commit -m two
 '
 
+setup_post_update_server_info_hook () {
+	test_hook --setup -C "$1" post-update <<-\EOF &&
+	exec git update-server-info
+	EOF
+	git -C "$1" update-server-info
+}
+
 test_expect_success 'create http-accessible bare repository with loose objects' '
 	cp -R .git "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
-	(cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
-	 git config core.bare true &&
-	 mkdir -p hooks &&
-	 write_script "hooks/post-update" <<-\EOF &&
-	 exec git update-server-info
-	EOF
-	 hooks/post-update
-	) &&
+	git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" config core.bare true &&
+	setup_post_update_server_info_hook "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
 	git remote add public "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
 	git push public main:main
 '
@@ -62,13 +63,7 @@ test_expect_success 'create password-protected repository' '
 
 test_expect_success 'create empty remote repository' '
 	git init --bare "$HTTPD_DOCUMENT_ROOT_PATH/empty.git" &&
-	(cd "$HTTPD_DOCUMENT_ROOT_PATH/empty.git" &&
-	 mkdir -p hooks &&
-	 write_script "hooks/post-update" <<-\EOF &&
-	 exec git update-server-info
-	EOF
-	 hooks/post-update
-	)
+	setup_post_update_server_info_hook "$HTTPD_DOCUMENT_ROOT_PATH/empty.git"
 '
 
 test_expect_success 'empty dumb HTTP repository has default hash algorithm' '
-- 
2.35.1.1384.g7d2906948a1


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v3 00/13] tests: add and use a "test_hook" wrapper + hook fixes
  2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
                       ` (12 preceding siblings ...)
  2022-03-17 10:13     ` [PATCH v3 13/13] http tests: use "test_hook" for "smart" and "dumb" http tests Ævar Arnfjörð Bjarmason
@ 2022-03-17 16:31     ` Junio C Hamano
  2022-03-17 21:04       ` Ævar Arnfjörð Bjarmason
  13 siblings, 1 reply; 51+ messages in thread
From: Junio C Hamano @ 2022-03-17 16:31 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Just a quick update before I finish my first integration cycle of
today.  t543 has a "test_hook" call inside a subshell, but because
the helper runs test_when_finished, a sanity check kicks in and
fails the test.

I'll continue the integration cycle with this topic kicked out of
'seen' for now.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v3 00/13] tests: add and use a "test_hook" wrapper + hook fixes
  2022-03-17 16:31     ` [PATCH v3 00/13] tests: add and use a "test_hook" wrapper + hook fixes Junio C Hamano
@ 2022-03-17 21:04       ` Ævar Arnfjörð Bjarmason
  2022-03-17 21:40         ` Junio C Hamano
  0 siblings, 1 reply; 51+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-03-17 21:04 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Emily Shaffer, Eric Sunshine


On Thu, Mar 17 2022, Junio C Hamano wrote:

> Just a quick update before I finish my first integration cycle of
> today.  t543 has a "test_hook" call inside a subshell, but because
> the helper runs test_when_finished, a sanity check kicks in and
> fails the test.
>
> I'll continue the integration cycle with this topic kicked out of
> 'seen' for now.

Pending a re-roll this fix-up for 11/13 should fix it.

I do test with /bin/bash before submitting to catch exactly this class
of issue, but for reasons I haven't looked into this one is odd in not
failing with --verbose-log, but I see the OSX CI (which I didn't wait
for) fails on the same issue. Sorry.

diff --git a/t/t5543-atomic-push.sh b/t/t5543-atomic-push.sh
index 90676365471..70431122a40 100755
--- a/t/t5543-atomic-push.sh
+++ b/t/t5543-atomic-push.sh
@@ -162,13 +162,10 @@ test_expect_success 'atomic push obeys update hook preventing a branch to be pus
 		test_commit two &&
 		git push --mirror up
 	) &&
-	(
-		cd upstream &&
-		test_hook update <<-\EOF
-			# only allow update to main from now on
-			test "$1" = "refs/heads/main"
-		EOF
-	) &&
+	test_hook -C upstream update <<-\EOF &&
+	# only allow update to main from now on
+	test "$1" = "refs/heads/main"
+	EOF
 	(
 		cd workbench &&
 		git checkout main &&

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v3 00/13] tests: add and use a "test_hook" wrapper + hook fixes
  2022-03-17 21:04       ` Ævar Arnfjörð Bjarmason
@ 2022-03-17 21:40         ` Junio C Hamano
  0 siblings, 0 replies; 51+ messages in thread
From: Junio C Hamano @ 2022-03-17 21:40 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Emily Shaffer, Eric Sunshine

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

> Pending a re-roll this fix-up for 11/13 should fix it.
>
> I do test with /bin/bash before submitting to catch exactly this class
> of issue, but for reasons I haven't looked into this one is odd in not
> failing with --verbose-log, but I see the OSX CI (which I didn't wait
> for) fails on the same issue. Sorry.

Hmph, my integration run failed right away.  I use bash and dash on
alternate days, and you got lucky today ;-)

> diff --git a/t/t5543-atomic-push.sh b/t/t5543-atomic-push.sh
> index 90676365471..70431122a40 100755
> --- a/t/t5543-atomic-push.sh
> +++ b/t/t5543-atomic-push.sh
> @@ -162,13 +162,10 @@ test_expect_success 'atomic push obeys update hook preventing a branch to be pus
>  		test_commit two &&
>  		git push --mirror up
>  	) &&
> -	(
> -		cd upstream &&
> -		test_hook update <<-\EOF
> -			# only allow update to main from now on
> -			test "$1" = "refs/heads/main"
> -		EOF
> -	) &&
> +	test_hook -C upstream update <<-\EOF &&
> +	# only allow update to main from now on
> +	test "$1" = "refs/heads/main"
> +	EOF

OK.

>  	(
>  		cd workbench &&
>  		git checkout main &&

^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2022-03-17 21:40 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-02 13:22 [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Ævar Arnfjörð Bjarmason
2022-03-02 13:22 ` [PATCH 01/10] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
2022-03-02 20:55   ` Junio C Hamano
2022-03-02 13:22 ` [PATCH 02/10] t5540: don't rely on "hook/post-update.sample" Ævar Arnfjörð Bjarmason
2022-03-02 21:06   ` Junio C Hamano
2022-03-02 13:22 ` [PATCH 03/10] tests: assume the hooks are disabled by default Ævar Arnfjörð Bjarmason
2022-03-02 21:13   ` Junio C Hamano
2022-03-02 13:22 ` [PATCH 04/10] bugreport tests: tighten up "git bugreport -s hooks" test Ævar Arnfjörð Bjarmason
2022-03-02 21:22   ` Junio C Hamano
2022-03-02 13:22 ` [PATCH 05/10] tests: indent and add hook setup to "test_expect_success" Ævar Arnfjörð Bjarmason
2022-03-02 21:27   ` Junio C Hamano
2022-03-02 13:22 ` [PATCH 06/10] hook tests: get rid of unnecessary sub-shells Ævar Arnfjörð Bjarmason
2022-03-02 21:31   ` Junio C Hamano
2022-03-02 13:22 ` [PATCH 07/10] fetch+push tests: have tests clean up their own mess Ævar Arnfjörð Bjarmason
2022-03-02 21:44   ` Junio C Hamano
2022-03-02 13:22 ` [PATCH 08/10] test-lib-functions: add and use a "test_hook" wrapper Ævar Arnfjörð Bjarmason
2022-03-02 21:59   ` Junio C Hamano
2022-03-02 13:22 ` [PATCH 09/10] tests: change "mkdir -p && write_script" to use "test_hook" Ævar Arnfjörð Bjarmason
2022-03-02 22:06   ` Junio C Hamano
2022-03-02 13:22 ` [PATCH 10/10] tests: change "cat && chmod +x" " Ævar Arnfjörð Bjarmason
2022-03-03  5:46   ` Eric Sunshine
2022-03-02 22:38 ` [PATCH 00/10] tests: add and use a "test_hook" wrapper + hook fixes Junio C Hamano
2022-03-07 12:43 ` [PATCH v2 " Ævar Arnfjörð Bjarmason
2022-03-07 12:43   ` [PATCH v2 01/10] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
2022-03-07 12:43   ` [PATCH v2 02/10] t5540: don't rely on "hook/post-update.sample" Ævar Arnfjörð Bjarmason
2022-03-07 12:43   ` [PATCH v2 03/10] tests: assume the hooks are disabled by default Ævar Arnfjörð Bjarmason
2022-03-07 12:43   ` [PATCH v2 04/10] bugreport tests: tighten up "git bugreport -s hooks" test Ævar Arnfjörð Bjarmason
2022-03-07 12:43   ` [PATCH v2 05/10] tests: indent and add hook setup to "test_expect_success" Ævar Arnfjörð Bjarmason
2022-03-07 12:43   ` [PATCH v2 06/10] hook tests: get rid of unnecessary sub-shells Ævar Arnfjörð Bjarmason
2022-03-07 12:43   ` [PATCH v2 07/10] fetch+push tests: have tests clean up their own mess Ævar Arnfjörð Bjarmason
2022-03-07 12:43   ` [PATCH v2 08/10] test-lib-functions: add and use a "test_hook" wrapper Ævar Arnfjörð Bjarmason
2022-03-07 12:43   ` [PATCH v2 09/10] tests: change "mkdir -p && write_script" to use "test_hook" Ævar Arnfjörð Bjarmason
2022-03-07 12:43   ` [PATCH v2 10/10] tests: change "cat && chmod +x" " Ævar Arnfjörð Bjarmason
2022-03-07 21:26   ` [PATCH v2 00/10] tests: add and use a "test_hook" wrapper + hook fixes Junio C Hamano
2022-03-17 10:13   ` [PATCH v3 00/13] " Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 01/13] test-lib-functions: add and use a "test_hook" wrapper Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 02/13] hook tests: turn exit code assertions into a loop Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 03/13] http tests: don't rely on "hook/post-update.sample" Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 04/13] tests: assume the hooks are disabled by default Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 05/13] bugreport tests: tighten up "git bugreport -s hooks" test Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 06/13] fetch+push tests: use "test_hook" and "test_when_finished" pattern Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 07/13] gc + p4 tests: use "test_hook", remove sub-shells Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 08/13] tests: change "cat && chmod +x" to use "test_hook" Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 09/13] tests: change "mkdir -p && write_script" " Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 10/13] tests: use "test_hook" for misc "mkdir -p" and "chmod" cases Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 11/13] tests: extend "test_hook" for "rm" and "chmod -x", convert "$HOOK" Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 12/13] proc-receive hook tests: use "test_hook" instead of "write_script" Ævar Arnfjörð Bjarmason
2022-03-17 10:13     ` [PATCH v3 13/13] http tests: use "test_hook" for "smart" and "dumb" http tests Ævar Arnfjörð Bjarmason
2022-03-17 16:31     ` [PATCH v3 00/13] tests: add and use a "test_hook" wrapper + hook fixes Junio C Hamano
2022-03-17 21:04       ` Ævar Arnfjörð Bjarmason
2022-03-17 21:40         ` Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).