t1800: add hook output stream tests
Lack of test coverage in this area led to some regressions while converting the remaining hooks to the newer hook.[ch] API. Add some tests to verify hooks write to the expected output streams. Suggested-by: Patrick Steinhardt <ps@pks.im> Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Adrian Ratiu committed
Jan 28, 2026 at 23:39 UTC
c9ef360403e0f64a5d4c70f66a9b25f02a98fda6
1 file changed
+137
t/t1800-hook.sh
+137
@@ -184,4 +184,141 @@ test_expect_success 'stdin to hooks' '
184
test_cmp expect actual
185
'
186
187
+check_stdout_separate_from_stderr () {
188
+ for hook in "$@"
189
+ do
190
+ # Ensure hook's stdout is only in stdout, not stderr
191
+ test_grep "Hook $hook stdout" stdout.actual || return 1
192
+ test_grep ! "Hook $hook stdout" stderr.actual || return 1
193
+
194
+ # Ensure hook's stderr is only in stderr, not stdout
195
+ test_grep "Hook $hook stderr" stderr.actual || return 1
196
+ test_grep ! "Hook $hook stderr" stdout.actual || return 1
197
+ done
198
+}
199
+
200
+check_stdout_merged_to_stderr () {
201
+ for hook in "$@"
202
+ do
203
+ # Ensure hook's stdout is only in stderr, not stdout
204
+ test_grep "Hook $hook stdout" stderr.actual || return 1
205
+ test_grep ! "Hook $hook stdout" stdout.actual || return 1
206
+
207
+ # Ensure hook's stderr is only in stderr, not stdout
208
+ test_grep "Hook $hook stderr" stderr.actual || return 1
209
+ test_grep ! "Hook $hook stderr" stdout.actual || return 1
210
+ done
211
+}
212
+
213
+setup_hooks () {
214
+ for hook in "$@"
215
+ do
216
+ test_hook $hook <<-EOF
217
+ echo >&1 Hook $hook stdout
218
+ echo >&2 Hook $hook stderr
219
+ EOF
220
+ done
221
+}
222
+
223
+test_expect_success 'client hooks: pre-push expects separate stdout and stderr' '
224
+ test_when_finished "rm -f stdout.actual stderr.actual" &&
225
+ git init --bare remote &&
226
+ git remote add origin remote &&
227
+ test_commit A &&
228
+ setup_hooks pre-push &&
229
+ git push origin HEAD:main >stdout.actual 2>stderr.actual &&
230
+ check_stdout_separate_from_stderr pre-push
231
+'
232
+
233
+test_expect_success 'client hooks: commit hooks expect stdout redirected to stderr' '
234
+ hooks="pre-commit prepare-commit-msg \
235
+ commit-msg post-commit \
236
+ reference-transaction" &&
237
+ setup_hooks $hooks &&
238
+ test_when_finished "rm -f stdout.actual stderr.actual" &&
239
+ git checkout -B main &&
240
+ git checkout -b branch-a &&
241
+ test_commit commit-on-branch-a &&
242
+ git commit --allow-empty -m "Test" >stdout.actual 2>stderr.actual &&
243
+ check_stdout_merged_to_stderr $hooks
244
+'
245
+
246
+test_expect_success 'client hooks: checkout hooks expect stdout redirected to stderr' '
247
+ setup_hooks post-checkout reference-transaction &&
248
+ test_when_finished "rm -f stdout.actual stderr.actual" &&
249
+ git checkout -b new-branch main >stdout.actual 2>stderr.actual &&
250
+ check_stdout_merged_to_stderr post-checkout reference-transaction
251
+'
252
+
253
+test_expect_success 'client hooks: merge hooks expect stdout redirected to stderr' '
254
+ setup_hooks pre-merge-commit post-merge reference-transaction &&
255
+ test_when_finished "rm -f stdout.actual stderr.actual" &&
256
+ test_commit new-branch-commit &&
257
+ git merge --no-ff branch-a >stdout.actual 2>stderr.actual &&
258
+ check_stdout_merged_to_stderr pre-merge-commit post-merge reference-transaction
259
+'
260
+
261
+test_expect_success 'client hooks: post-rewrite hooks expect stdout redirected to stderr' '
262
+ setup_hooks post-rewrite reference-transaction &&
263
+ test_when_finished "rm -f stdout.actual stderr.actual" &&
264
+ git commit --amend --allow-empty --no-edit >stdout.actual 2>stderr.actual &&
265
+ check_stdout_merged_to_stderr post-rewrite reference-transaction
266
+'
267
+
268
+test_expect_success 'client hooks: applypatch hooks expect stdout redirected to stderr' '
269
+ setup_hooks applypatch-msg pre-applypatch post-applypatch &&
270
+ test_when_finished "rm -f stdout.actual stderr.actual" &&
271
+ git checkout -b branch-b main &&
272
+ test_commit branch-b &&
273
+ git format-patch -1 --stdout >patch &&
274
+ git checkout -b branch-c main &&
275
+ git am patch >stdout.actual 2>stderr.actual &&
276
+ check_stdout_merged_to_stderr applypatch-msg pre-applypatch post-applypatch
277
+'
278
+
279
+test_expect_success 'client hooks: rebase hooks expect stdout redirected to stderr' '
280
+ setup_hooks pre-rebase &&
281
+ test_when_finished "rm -f stdout.actual stderr.actual" &&
282
+ git checkout -b branch-d main &&
283
+ test_commit branch-d &&
284
+ git checkout main &&
285
+ test_commit diverge-main &&
286
+ git checkout branch-d &&
287
+ git rebase main >stdout.actual 2>stderr.actual &&
288
+ check_stdout_merged_to_stderr pre-rebase
289
+'
290
+
291
+test_expect_success 'client hooks: post-index-change expects stdout redirected to stderr' '
292
+ setup_hooks post-index-change &&
293
+ test_when_finished "rm -f stdout.actual stderr.actual" &&
294
+ oid=$(git hash-object -w --stdin </dev/null) &&
295
+ git update-index --add --cacheinfo 100644 $oid new-file \
296
+ >stdout.actual 2>stderr.actual &&
297
+ check_stdout_merged_to_stderr post-index-change
298
+'
299
+
300
+test_expect_success 'server hooks expect stdout redirected to stderr' '
301
+ test_when_finished "rm -f stdout.actual stderr.actual" &&
302
+ git init --bare remote-server &&
303
+ git remote add origin-server remote-server &&
304
+ cd remote-server &&
305
+ setup_hooks pre-receive update post-receive post-update &&
306
+ cd .. &&
307
+ git push origin-server HEAD:new-branch >stdout.actual 2>stderr.actual &&
308
+ check_stdout_merged_to_stderr pre-receive update post-receive post-update
309
+'
310
+
311
+test_expect_success 'server push-to-checkout hook expects stdout redirected to stderr' '
312
+ test_when_finished "rm -f stdout.actual stderr.actual" &&
313
+ git init server &&
314
+ git -C server checkout -b main &&
315
+ test_config -C server receive.denyCurrentBranch updateInstead &&
316
+ git remote add origin-server-2 server &&
317
+ cd server &&
318
+ setup_hooks push-to-checkout &&
319
+ cd .. &&
320
+ git push origin-server-2 HEAD:main >stdout.actual 2>stderr.actual &&
321
+ check_stdout_merged_to_stderr push-to-checkout
322
+'
323
+
324
test_done