3 test_description='pre-commit and pre-merge-commit hooks'
7 HOOKDIR="$(git rev-parse --git-dir)/hooks"
8 PRECOMMIT="$HOOKDIR/pre-commit"
9 PREMERGE="$HOOKDIR/pre-merge-commit"
11 # Prepare sample scripts that write their $0 to actual_hooks
12 test_expect_success 'sample script setup' '
13 mkdir -p "$HOOKDIR" &&
14 write_script "$HOOKDIR/success.sample" <<-\EOF &&
15 echo $0 >>actual_hooks
18 write_script "$HOOKDIR/fail.sample" <<-\EOF &&
19 echo $0 >>actual_hooks
22 write_script "$HOOKDIR/non-exec.sample" <<-\EOF &&
23 echo $0 >>actual_hooks
26 chmod -x "$HOOKDIR/non-exec.sample" &&
27 write_script "$HOOKDIR/require-prefix.sample" <<-\EOF &&
28 echo $0 >>actual_hooks
29 test $GIT_PREFIX = "success/"
31 write_script "$HOOKDIR/check-author.sample" <<-\EOF
32 echo $0 >>actual_hooks
33 test "$GIT_AUTHOR_NAME" = "New Author" &&
34 test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
38 test_expect_success 'root commit' '
41 git commit -m "zeroth" &&
42 git checkout -b side &&
45 git commit -m "make it non-ff" &&
46 git branch side-orig side &&
50 test_expect_success 'setup conflicting branches' '
51 test_when_finished "git checkout master" &&
52 git checkout -b conflicting-a master &&
53 echo a >conflicting &&
54 git add conflicting &&
55 git commit -m conflicting-a &&
56 git checkout -b conflicting-b master &&
57 echo b >conflicting &&
58 git add conflicting &&
59 git commit -m conflicting-b
62 test_expect_success 'with no hook' '
63 test_when_finished "rm -f actual_hooks" &&
66 git commit -m "first" &&
67 test_path_is_missing actual_hooks
70 test_expect_success 'with no hook (merge)' '
71 test_when_finished "rm -f actual_hooks" &&
72 git branch -f side side-orig &&
74 git merge -m "merge master" master &&
75 git checkout master &&
76 test_path_is_missing actual_hooks
79 test_expect_success '--no-verify with no hook' '
80 test_when_finished "rm -f actual_hooks" &&
83 git commit --no-verify -m "bar" &&
84 test_path_is_missing actual_hooks
87 test_expect_success '--no-verify with no hook (merge)' '
88 test_when_finished "rm -f actual_hooks" &&
89 git branch -f side side-orig &&
91 git merge --no-verify -m "merge master" master &&
92 git checkout master &&
93 test_path_is_missing actual_hooks
96 test_expect_success 'with succeeding hook' '
97 test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
98 cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
99 echo "$PRECOMMIT" >expected_hooks &&
100 echo "more" >>file &&
102 git commit -m "more" &&
103 test_cmp expected_hooks actual_hooks
106 test_expect_success 'with succeeding hook (merge)' '
107 test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
108 cp "$HOOKDIR/success.sample" "$PREMERGE" &&
109 echo "$PREMERGE" >expected_hooks &&
111 git merge -m "merge master" master &&
112 git checkout master &&
113 test_cmp expected_hooks actual_hooks
116 test_expect_success 'automatic merge fails; both hooks are available' '
117 test_when_finished "rm -f \"$PREMERGE\" \"$PRECOMMIT\"" &&
118 test_when_finished "rm -f expected_hooks actual_hooks" &&
119 test_when_finished "git checkout master" &&
120 cp "$HOOKDIR/success.sample" "$PREMERGE" &&
121 cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
123 git checkout conflicting-a &&
124 test_must_fail git merge -m "merge conflicting-b" conflicting-b &&
125 test_path_is_missing actual_hooks &&
127 echo "$PRECOMMIT" >expected_hooks &&
128 echo a+b >conflicting &&
129 git add conflicting &&
130 git commit -m "resolve conflict" &&
131 test_cmp expected_hooks actual_hooks
134 test_expect_success '--no-verify with succeeding hook' '
135 test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
136 cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
137 echo "even more" >>file &&
139 git commit --no-verify -m "even more" &&
140 test_path_is_missing actual_hooks
143 test_expect_success '--no-verify with succeeding hook (merge)' '
144 test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
145 cp "$HOOKDIR/success.sample" "$PREMERGE" &&
146 git branch -f side side-orig &&
148 git merge --no-verify -m "merge master" master &&
149 git checkout master &&
150 test_path_is_missing actual_hooks
153 test_expect_success 'with failing hook' '
154 test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
155 cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
156 echo "$PRECOMMIT" >expected_hooks &&
157 echo "another" >>file &&
159 test_must_fail git commit -m "another" &&
160 test_cmp expected_hooks actual_hooks
163 test_expect_success '--no-verify with failing hook' '
164 test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
165 cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
166 echo "stuff" >>file &&
168 git commit --no-verify -m "stuff" &&
169 test_path_is_missing actual_hooks
172 test_expect_success 'with failing hook (merge)' '
173 test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
174 cp "$HOOKDIR/fail.sample" "$PREMERGE" &&
175 echo "$PREMERGE" >expected_hooks &&
177 test_must_fail git merge -m "merge master" master &&
178 git checkout master &&
179 test_cmp expected_hooks actual_hooks
182 test_expect_success '--no-verify with failing hook (merge)' '
183 test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
184 cp "$HOOKDIR/fail.sample" "$PREMERGE" &&
185 git branch -f side side-orig &&
187 git merge --no-verify -m "merge master" master &&
188 git checkout master &&
189 test_path_is_missing actual_hooks
192 test_expect_success POSIXPERM 'with non-executable hook' '
193 test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
194 cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
195 echo "content" >>file &&
197 git commit -m "content" &&
198 test_path_is_missing actual_hooks
201 test_expect_success POSIXPERM '--no-verify with non-executable hook' '
202 test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
203 cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
204 echo "more content" >>file &&
206 git commit --no-verify -m "more content" &&
207 test_path_is_missing actual_hooks
210 test_expect_success POSIXPERM 'with non-executable hook (merge)' '
211 test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
212 cp "$HOOKDIR/non-exec.sample" "$PREMERGE" &&
213 git branch -f side side-orig &&
215 git merge -m "merge master" master &&
216 git checkout master &&
217 test_path_is_missing actual_hooks
220 test_expect_success POSIXPERM '--no-verify with non-executable hook (merge)' '
221 test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
222 cp "$HOOKDIR/non-exec.sample" "$PREMERGE" &&
223 git branch -f side side-orig &&
225 git merge --no-verify -m "merge master" master &&
226 git checkout master &&
227 test_path_is_missing actual_hooks
230 test_expect_success 'with hook requiring GIT_PREFIX' '
231 test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks success" &&
232 cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
233 echo "$PRECOMMIT" >expected_hooks &&
234 echo "more content" >>file &&
239 git commit -m "hook requires GIT_PREFIX = success/"
241 test_cmp expected_hooks actual_hooks
244 test_expect_success 'with failing hook requiring GIT_PREFIX' '
245 test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks fail" &&
246 cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
247 echo "$PRECOMMIT" >expected_hooks &&
248 echo "more content" >>file &&
253 test_must_fail git commit -m "hook must fail"
255 git checkout -- file &&
256 test_cmp expected_hooks actual_hooks
259 test_expect_success 'check the author in hook' '
260 test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
261 cp "$HOOKDIR/check-author.sample" "$PRECOMMIT" &&
262 cat >expected_hooks <<-EOF &&
267 test_must_fail git commit --allow-empty -m "by a.u.thor" &&
269 GIT_AUTHOR_NAME="New Author" &&
270 GIT_AUTHOR_EMAIL="newauthor@example.com" &&
271 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
272 git commit --allow-empty -m "by new.author via env" &&
275 git commit --author="New Author <newauthor@example.com>" \
276 --allow-empty -m "by new.author via command line" &&
278 test_cmp expected_hooks actual_hooks