3 test_description
='pre-commit and pre-merge-commit hooks'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10 test_expect_success
'root commit' '
13 git commit -m "zeroth" &&
14 git checkout -b side &&
17 git commit -m "make it non-ff" &&
18 git branch side-orig side &&
22 test_expect_success
'setup conflicting branches' '
23 test_when_finished "git checkout main" &&
24 git checkout -b conflicting-a main &&
25 echo a >conflicting &&
26 git add conflicting &&
27 git commit -m conflicting-a &&
28 git checkout -b conflicting-b main &&
29 echo b >conflicting &&
30 git add conflicting &&
31 git commit -m conflicting-b
34 test_expect_success
'with no hook' '
35 test_when_finished "rm -f actual_hooks" &&
38 git commit -m "first" &&
39 test_path_is_missing actual_hooks
42 test_expect_success
'with no hook (merge)' '
43 test_when_finished "rm -f actual_hooks" &&
44 git branch -f side side-orig &&
46 git merge -m "merge main" main &&
48 test_path_is_missing actual_hooks
51 test_expect_success
'--no-verify with no hook' '
52 test_when_finished "rm -f actual_hooks" &&
55 git commit --no-verify -m "bar" &&
56 test_path_is_missing actual_hooks
59 test_expect_success
'--no-verify with no hook (merge)' '
60 test_when_finished "rm -f actual_hooks" &&
61 git branch -f side side-orig &&
63 git merge --no-verify -m "merge main" main &&
65 test_path_is_missing actual_hooks
68 setup_success_hook
() {
69 test_when_finished
"rm -f actual_hooks expected_hooks" &&
70 echo "$1" >expected_hooks
&&
72 echo $1 >>actual_hooks
76 test_expect_success
'with succeeding hook' '
77 setup_success_hook "pre-commit" &&
80 git commit -m "more" &&
81 test_cmp expected_hooks actual_hooks
84 test_expect_success
'with succeeding hook (merge)' '
85 setup_success_hook "pre-merge-commit" &&
87 git merge -m "merge main" main &&
89 test_cmp expected_hooks actual_hooks
92 test_expect_success
'automatic merge fails; both hooks are available' '
93 setup_success_hook "pre-commit" &&
94 setup_success_hook "pre-merge-commit" &&
96 git checkout conflicting-a &&
97 test_must_fail git merge -m "merge conflicting-b" conflicting-b &&
98 test_path_is_missing actual_hooks &&
100 echo "pre-commit" >expected_hooks &&
101 echo a+b >conflicting &&
102 git add conflicting &&
103 git commit -m "resolve conflict" &&
104 test_cmp expected_hooks actual_hooks
107 test_expect_success
'--no-verify with succeeding hook' '
108 setup_success_hook "pre-commit" &&
109 echo "even more" >>file &&
111 git commit --no-verify -m "even more" &&
112 test_path_is_missing actual_hooks
115 test_expect_success
'--no-verify with succeeding hook (merge)' '
116 setup_success_hook "pre-merge-commit" &&
117 git branch -f side side-orig &&
119 git merge --no-verify -m "merge main" main &&
121 test_path_is_missing actual_hooks
124 setup_failing_hook
() {
125 test_when_finished
"rm -f actual_hooks" &&
126 test_hook
"$1" <<-EOF
127 echo $1-failing-hook >>actual_hooks
132 test_expect_success
'with failing hook' '
133 setup_failing_hook "pre-commit" &&
134 test_when_finished "rm -f expected_hooks" &&
135 echo "pre-commit-failing-hook" >expected_hooks &&
137 echo "another" >>file &&
139 test_must_fail git commit -m "another" &&
140 test_cmp expected_hooks actual_hooks
143 test_expect_success
'--no-verify with failing hook' '
144 setup_failing_hook "pre-commit" &&
145 echo "stuff" >>file &&
147 git commit --no-verify -m "stuff" &&
148 test_path_is_missing actual_hooks
151 test_expect_success
'with failing hook (merge)' '
152 setup_failing_hook "pre-merge-commit" &&
153 echo "pre-merge-commit-failing-hook" >expected_hooks &&
155 test_must_fail git merge -m "merge main" main &&
157 test_cmp expected_hooks actual_hooks
160 test_expect_success
'--no-verify with failing hook (merge)' '
161 setup_failing_hook "pre-merge-commit" &&
163 git branch -f side side-orig &&
165 git merge --no-verify -m "merge main" main &&
167 test_path_is_missing actual_hooks
170 setup_non_exec_hook
() {
171 test_when_finished
"rm -f actual_hooks" &&
172 test_hook
"$1" <<-\EOF &&
173 echo non-exec >>actual_hooks
176 test_hook --disable "$1"
180 test_expect_success POSIXPERM 'with non-executable hook' '
181 setup_non_exec_hook "pre-commit" &&
182 echo "content" >>file &&
184 git commit -m "content" &&
185 test_path_is_missing actual_hooks
188 test_expect_success POSIXPERM '--no-verify with non-executable hook' '
189 setup_non_exec_hook "pre-commit" &&
190 echo "more content" >>file &&
192 git commit --no-verify -m "more content" &&
193 test_path_is_missing actual_hooks
196 test_expect_success POSIXPERM 'with non-executable hook (merge)' '
197 setup_non_exec_hook "pre-merge" &&
198 git branch -f side side-orig &&
200 git merge -m "merge main" main &&
202 test_path_is_missing actual_hooks
205 test_expect_success POSIXPERM '--no-verify with non-executable hook (merge)' '
206 setup_non_exec_hook "pre-merge" &&
207 git branch -f side side-orig &&
209 git merge --no-verify -m "merge main" main &&
211 test_path_is_missing actual_hooks
214 setup_require_prefix_hook () {
215 test_when_finished "rm -f expected_hooks" &&
216 echo require-prefix >expected_hooks &&
217 test_hook pre-commit <<-\
EOF
218 echo require-prefix >>actual_hooks
219 test $GIT_PREFIX = "success/"
223 test_expect_success 'with hook requiring GIT_PREFIX' '
224 test_when_finished "rm -rf actual_hooks success" &&
225 setup_require_prefix_hook &&
226 echo "more content" >>file &&
231 git commit -m "hook requires GIT_PREFIX = success/"
233 test_cmp expected_hooks actual_hooks
236 test_expect_success 'with failing hook requiring GIT_PREFIX' '
237 test_when_finished "rm -rf actual_hooks fail" &&
238 setup_require_prefix_hook &&
239 echo "more content" >>file &&
244 test_must_fail git commit -m "hook must fail"
246 git checkout -- file &&
247 test_cmp expected_hooks actual_hooks
250 setup_require_author_hook () {
251 test_when_finished "rm -f expected_hooks actual_hooks" &&
252 echo check-author >expected_hooks &&
253 test_hook pre-commit <<-\EOF
254 echo check-author >>actual_hooks
255 test "$GIT_AUTHOR_NAME" = "New Author" &&
256 test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
261 test_expect_success 'check the author in hook' '
262 setup_require_author_hook &&
263 cat >expected_hooks <<-EOF &&
268 test_must_fail git commit --allow-empty -m "by a.u.thor" &&
270 GIT_AUTHOR_NAME="New Author" &&
271 GIT_AUTHOR_EMAIL="newauthor@example.com" &&
272 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
273 git commit --allow-empty -m "by new.author via env" &&
276 git commit --author="New Author <newauthor@example.com>" \
277 --allow-empty -m "by new.author via command line" &&
279 test_cmp expected_hooks actual_hooks