fix: stop the pre-push tracker-leak check hanging on stdin
Issue for this PR
Closes #1574
Type of change
- Bug fix
- New feature
- Refactor / code improvement
- Documentation
What does this PR do?
git push sometimes hung forever in the pre-push hook's tracker-leak check, so people had to bypass it with SKIP_TRACKER_CHECK=1.
What we know: one push stayed stuck for eight days (macOS, git 2.42, over ssh). In that push:
- git was in
wait4, waiting for the hook. bun script/check-tracker-leaks.tssat idle in its event loop (kevent) with no child process.- Its stdin pipe's writer was already closed:
lsofshowed no peer.
The script was awaiting something that had already finished: either the stdin stream (Bun.stdin.stream()) or a Bun.$ git call. The stuck process can't tell us which.
The fix: remove both waits.
- stdin is read with a blocking
readFileSync(0, "utf-8"). git()runs withBun.spawnSync, with no stdin.
The script no longer waits on the event loop at all. Behaviour is otherwise unchanged: the TTY guard, the HEAD fallback when there is no input, deletion-only handling, and the fail-loud exit on unexpected git errors.
The hang never reproduced on demand, so there is no before/after reproduction.
How did you verify your code works?
- New test in
tracker-leak-check.test.ts: a realgit pushthrough a pre-push hook to a local bare repo. A clean ref pushes, and a leaky ref that isn'tHEADis rejected. This guards the stdin contract end to end. It passes on the old code too, so it is not a reproduction of the hang. - Tests:
bun test test/skill/tracker-leak-check.test.tsgives 35 pass. - Same results as before: old and new scripts give byte-identical output on a 3,174-file, 596k-line diff (0.8 s).
- Hook order: the hook's earlier steps (
bun -e,bun typecheck) leave git's stdin unread. - Real pushes: both commits went to GitHub over ssh through the real husky hook, without the skip flag. Each took 12 s.
- Reviews: Codex (gpt-6.1-sol) reviewed
0d0df4dc74and found nothing. A second independent review pointed out that the root cause was unproven and that the test doesn't reproduce the hang; both are addressed in4cd57d0c2f.
Cost side effects
None.
Screenshots / recordings
Not a UI change.
Checklist
- I have tested my changes locally
- I have not included unrelated changes in this PR
- I checked for cost side effects (model calls, queries or cloud resources that grow with user data) and described them, or wrote "none"
🤖 Generated with Claude Code
Summary by CodeRabbit
- Bug Fixes
- The pre-push scan checks the refs being pushed, so branches containing tracker references are rejected even when the current checkout is clean. Clean pushes continue to succeed, and rejected pushes report the detected reference.
- Tests
- Added coverage for clean and tracker-containing pushes using a local Git repository, including the case where the pushed branch differs from the current checkout.