]> git.ipfire.org Git - thirdparty/git.git/blob - t/t7503-pre-commit-and-pre-merge-commit-hooks.sh
bisect--helper: plug strvec leak
[thirdparty/git.git] / t / t7503-pre-commit-and-pre-merge-commit-hooks.sh
1 #!/bin/sh
2
3 test_description='pre-commit and pre-merge-commit hooks'
4
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8 . ./test-lib.sh
9
10 test_expect_success 'root commit' '
11 echo "root" >file &&
12 git add file &&
13 git commit -m "zeroth" &&
14 git checkout -b side &&
15 echo "foo" >foo &&
16 git add foo &&
17 git commit -m "make it non-ff" &&
18 git branch side-orig side &&
19 git checkout main
20 '
21
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
32 '
33
34 test_expect_success 'with no hook' '
35 test_when_finished "rm -f actual_hooks" &&
36 echo "foo" >file &&
37 git add file &&
38 git commit -m "first" &&
39 test_path_is_missing actual_hooks
40 '
41
42 test_expect_success 'with no hook (merge)' '
43 test_when_finished "rm -f actual_hooks" &&
44 git branch -f side side-orig &&
45 git checkout side &&
46 git merge -m "merge main" main &&
47 git checkout main &&
48 test_path_is_missing actual_hooks
49 '
50
51 test_expect_success '--no-verify with no hook' '
52 test_when_finished "rm -f actual_hooks" &&
53 echo "bar" >file &&
54 git add file &&
55 git commit --no-verify -m "bar" &&
56 test_path_is_missing actual_hooks
57 '
58
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 &&
62 git checkout side &&
63 git merge --no-verify -m "merge main" main &&
64 git checkout main &&
65 test_path_is_missing actual_hooks
66 '
67
68 setup_success_hook () {
69 test_when_finished "rm -f actual_hooks expected_hooks" &&
70 echo "$1" >expected_hooks &&
71 test_hook "$1" <<-EOF
72 echo $1 >>actual_hooks
73 EOF
74 }
75
76 test_expect_success 'with succeeding hook' '
77 setup_success_hook "pre-commit" &&
78 echo "more" >>file &&
79 git add file &&
80 git commit -m "more" &&
81 test_cmp expected_hooks actual_hooks
82 '
83
84 test_expect_success 'with succeeding hook (merge)' '
85 setup_success_hook "pre-merge-commit" &&
86 git checkout side &&
87 git merge -m "merge main" main &&
88 git checkout main &&
89 test_cmp expected_hooks actual_hooks
90 '
91
92 test_expect_success 'automatic merge fails; both hooks are available' '
93 setup_success_hook "pre-commit" &&
94 setup_success_hook "pre-merge-commit" &&
95
96 git checkout conflicting-a &&
97 test_must_fail git merge -m "merge conflicting-b" conflicting-b &&
98 test_path_is_missing actual_hooks &&
99
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
105 '
106
107 test_expect_success '--no-verify with succeeding hook' '
108 setup_success_hook "pre-commit" &&
109 echo "even more" >>file &&
110 git add file &&
111 git commit --no-verify -m "even more" &&
112 test_path_is_missing actual_hooks
113 '
114
115 test_expect_success '--no-verify with succeeding hook (merge)' '
116 setup_success_hook "pre-merge-commit" &&
117 git branch -f side side-orig &&
118 git checkout side &&
119 git merge --no-verify -m "merge main" main &&
120 git checkout main &&
121 test_path_is_missing actual_hooks
122 '
123
124 setup_failing_hook () {
125 test_when_finished "rm -f actual_hooks" &&
126 test_hook "$1" <<-EOF
127 echo $1-failing-hook >>actual_hooks
128 exit 1
129 EOF
130 }
131
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 &&
136
137 echo "another" >>file &&
138 git add file &&
139 test_must_fail git commit -m "another" &&
140 test_cmp expected_hooks actual_hooks
141 '
142
143 test_expect_success '--no-verify with failing hook' '
144 setup_failing_hook "pre-commit" &&
145 echo "stuff" >>file &&
146 git add file &&
147 git commit --no-verify -m "stuff" &&
148 test_path_is_missing actual_hooks
149 '
150
151 test_expect_success 'with failing hook (merge)' '
152 setup_failing_hook "pre-merge-commit" &&
153 echo "pre-merge-commit-failing-hook" >expected_hooks &&
154 git checkout side &&
155 test_must_fail git merge -m "merge main" main &&
156 git checkout main &&
157 test_cmp expected_hooks actual_hooks
158 '
159
160 test_expect_success '--no-verify with failing hook (merge)' '
161 setup_failing_hook "pre-merge-commit" &&
162
163 git branch -f side side-orig &&
164 git checkout side &&
165 git merge --no-verify -m "merge main" main &&
166 git checkout main &&
167 test_path_is_missing actual_hooks
168 '
169
170 setup_non_exec_hook () {
171 test_when_finished "rm -f actual_hooks" &&
172 test_hook "$1" <<-\EOF &&
173 echo non-exec >>actual_hooks
174 exit 1
175 EOF
176 test_hook --disable "$1"
177 }
178
179
180 test_expect_success POSIXPERM 'with non-executable hook' '
181 setup_non_exec_hook "pre-commit" &&
182 echo "content" >>file &&
183 git add file &&
184 git commit -m "content" &&
185 test_path_is_missing actual_hooks
186 '
187
188 test_expect_success POSIXPERM '--no-verify with non-executable hook' '
189 setup_non_exec_hook "pre-commit" &&
190 echo "more content" >>file &&
191 git add file &&
192 git commit --no-verify -m "more content" &&
193 test_path_is_missing actual_hooks
194 '
195
196 test_expect_success POSIXPERM 'with non-executable hook (merge)' '
197 setup_non_exec_hook "pre-merge" &&
198 git branch -f side side-orig &&
199 git checkout side &&
200 git merge -m "merge main" main &&
201 git checkout main &&
202 test_path_is_missing actual_hooks
203 '
204
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 &&
208 git checkout side &&
209 git merge --no-verify -m "merge main" main &&
210 git checkout main &&
211 test_path_is_missing actual_hooks
212 '
213
214 setup_require_prefix_hook () {
215 test_when_finished "rm -f expected_hooks" &&
216 echo require-prefix >expected_hooks &&
217 test_hook pre-commit <<-\EOF
218 echo require-prefix >>actual_hooks
219 test $GIT_PREFIX = "success/"
220 EOF
221 }
222
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 &&
227 git add file &&
228 mkdir success &&
229 (
230 cd success &&
231 git commit -m "hook requires GIT_PREFIX = success/"
232 ) &&
233 test_cmp expected_hooks actual_hooks
234 '
235
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 &&
240 git add file &&
241 mkdir fail &&
242 (
243 cd fail &&
244 test_must_fail git commit -m "hook must fail"
245 ) &&
246 git checkout -- file &&
247 test_cmp expected_hooks actual_hooks
248 '
249
250 setup_require_author_hook () {
251 test_when_finished "rm -f expected_hooks actual_hooks" &&
252 echo check-author >expected_hooks &&
253 test_hook pre-commit <<-\EOF
254 echo check-author >>actual_hooks
255 test "$GIT_AUTHOR_NAME" = "New Author" &&
256 test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
257 EOF
258 }
259
260
261 test_expect_success 'check the author in hook' '
262 setup_require_author_hook &&
263 cat >expected_hooks <<-EOF &&
264 check-author
265 check-author
266 check-author
267 EOF
268 test_must_fail git commit --allow-empty -m "by a.u.thor" &&
269 (
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" &&
274 git show -s
275 ) &&
276 git commit --author="New Author <newauthor@example.com>" \
277 --allow-empty -m "by new.author via command line" &&
278 git show -s &&
279 test_cmp expected_hooks actual_hooks
280 '
281
282 test_done