[BUG] push: pre-push hook that waits for stdin is slow
- From
- Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com>
- Date
- Jan 13, 2026, 20:26 UTC
- Message-ID
- <249f08d1-4457-4a41-8dbe-9725c0c392de@app.fastmail.com>
Thank you for filling out a Git bug report! Please answer the following questions to help us understand your issue.
What did you do before the bug happened? (Steps to reproduce your issue)
Used `git push` with a pre-push hook which included a loop over standard input (stdin):
``` #!/usr/bin/env bash
while read -r -a array
do
# what the loop body does is not important
:
done
```At first I tested with a loop body. But I got the same behavior with `:`.
It’s just the usual: check if what we are about to push is to some blessed branch. If it is it says that the push failed and tells the user to use `--no-verify` if they are sure.
What did you expect to happen? (Expected behavior)
For the hook to finish quickly and the push to finish within a few seconds at most.
What happened instead? (Actual behavior)
The push to the remote (Bitbucket cloud) takes over a minute. But not with `git push --no-verify`. Then it takes a few seconds.
What's different between what you expected and what actually happened?
Time.
Anything else you want to add:
I bisected using `timeout 3 git push ...` with a local remote to 857f047e (hook: allow overriding the ungroup option, 2025-12-26). I used a script on my own $dayjob repository. But I also tested the following script on commit f0f19d01 (fails) and the commit right before it (does not fail).
It uses a pre-push hook which is just `cat`. Apparently it has to do with how stdin is handled. An empty script does not have this problem. And neither does a script that just uses `echo` (example).
``` #!/bin/sh
uuid=d0befd7e-efe4-11f0-b6e1-8b95c76aee96 repo="$HOME"/"$uuid"
# Destroy test stuff
cleanup () {
rm -rf "$repo"
}setup () {
# I seem to need a realistic/meaty repo
git clone . "$repo" &&
(
cd "$repo" &&
git tag test-tag &&
remote=b896ac6c-efe7-11f0-bebc-3bf1b96c1ded
git clone . "$remote" &&
git remote add local "$remote" &&
# hook setup
mkdir hooks &&
cat <<-\EOF >hooks/pre-push &&
#!/bin/sh
cat
EOF
chmod +x hooks/pre-push
)
}if test "$1" = cleanup
then
cleanup
echo >&2 "bisect: cleaned up test data"
exit 128
fi &&if ! test -e "$repo"
then
setup
fi &&make || exit 125
timeout 3 \
./bin-wrappers/git -C "$repo" -c core.hookspath=hooks \
push local test-tag# exit code 124: timeout(1) timed out
if test "$?" = 124
then
exit 1
else
exit 0
fi
```I tested and reproduced the issue on `master`, `next`, and `seen`:
• master: on 8745eae5 (The 17th batch, 2026-01-11) • next: 054afa95 (Sync with 'master', 2026-01-12) • seen: b351b516 (Merge branch 'bc/sha1-256-interop-02' into seen, 2026-01-12)
Please review the rest of the bug report below. You can delete any lines you don't wish to share.
[System Info] git version: git version 2.52.0.421.gc32ead4fc78 cpu: x86_64 built from commit: c32ead4fc78dfd0327f6b2599e4fdca8166afa18 sizeof-long: 8 sizeof-size_t: 8 shell-path: /bin/sh rust: disabled libcurl: 7.81.0 OpenSSL: OpenSSL 3.0.2 15 Mar 2022 zlib: 1.2.11 SHA-1: SHA1_DC SHA-256: SHA256_BLK default-ref-format: files default-hash: sha1 uname: Linux 6.8.0-90-generic #91~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Nov 20 15:20:45 UTC 2 x86_64 compiler info: gnuc: 11.4 libc info: glibc: 2.35 $SHELL (typically, interactive shell): /bin/bash
[Enabled Hooks] commit-msg post-applypatch post-checkout post-commit post-merge post-rewrite pre-auto-gc pre-push reference-transaction
-- Kristoffer