Hooks now run synchronously and stream stdout/stderr to the pushing client
as "remote: ..." lines over the git sideband progress channel (band 2).
Previously they ran asynchronously after the push response, and output was
captured to slog only — the client never saw it.
To support streaming, fork go-git's transport.ReceivePack (v6) into
cmd/objgitd/receivepack.go as receivePackStreaming(). go-git keeps the
sideband Muxer internal and sends the closing flush-pkt before returning,
so there's no public seam to inject progress. The fork adds one callback
onUpdated(progress io.Writer), invoked after report-status but before the
final flush. When sideband is negotiated, progress writes to band 2
(ProgressMessage); otherwise it's nil and hooks fall back to logging.
HTTP adds a flush-on-write wrapper (flushWriter) to the receive-pack
response so net/http buffering doesn't hold the "remote:" lines back.
git:// and SSH write through live sockets and need no such wrapper.
Remove the now-dead async machinery: hookWG field and its shutdown drain.
Hooks complete before receivePackStreaming returns, so the connection
already holds them until completion.
Update tests to assert hook output appears in the push output (as "remote:"
lines) rather than in logs. Add TestSmartHTTPHookStreams to cover the HTTP
flush path. All three transports (git://, HTTP, SSH) verified.
Note: Clients now wait for hooks to finish (bounded by -hook-timeout,
default 60s) before the push completes, rather than push completing while
hooks run in the background. This is inherent to streaming output live.
Assisted-by: Claude Opus 4.8 via Claude Code
Signed-off-by: Xe Iaso <me@xeiaso.net>
Address code-review feedback:
- Stat the absolute "/test.git/config" path (memfs can resolve
relative vs absolute lookups differently); matches the rest of
the package.
- Close the listener in startSSHServer cleanup as well as the
server, avoiding a listener leak if Cleanup fires before the
concurrent Serve registers the listener.
- Quote the key path in GIT_SSH_COMMAND so paths with spaces are
not mis-split when git execs ssh.
- Rename the TestGitServiceFor loop variable tc -> tt for
package-wide consistency.
Assisted-by: Claude Opus 4.8 via Claude Code