hook: one cat-file for the whole push, verified as it streams !234

merged merged by cmc on 2026-09-04 15:58 UTC · krz/gitbay:hook-batch into main

Discussion

cmc

Stacked on !233.

pre-receive on a require-signed repository forked a cat-file per incoming commit and built one JSON message holding every raw commit. A 50k-commit first push forked 50k processes and held the history in memory twice. One cat-file --batch now serves the push; each commit crosses the socket as its own value and the daemon verifies it as it arrives.

Two hazards the streaming shape introduces, both tested:

  • Object names are fed to git from their own goroutine. 4000 names is past a 64 KiB pipe, so writing them all before reading deadlocks.
  • The subprocess runs under a cancelled-on-return context. Without it, giving up part-way leaves git blocked on a pipe nobody reads and Wait blocked on git. TestStreamIncomingCommitsCallbackError hangs rather than fails without it — I confirmed that by reverting the guard.

The daemon drains the stream to its end before answering even once a commit has failed: answering early would leave the hook writing into a socket nobody reads.

Closes #100

retargeted from retention-sweep to main: !233 merged

2026-09-04 15:58 UTC