From 18c585e6a667c0442e94ffb370cd34f8e1d9c347 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Sun, 1 Mar 2026 22:12:57 -0800 Subject: [PATCH] Buffer request body to fix large push deadlock --- apps/git/index.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/git/index.tsx b/apps/git/index.tsx index 5868d3e..7c40042 100644 --- a/apps/git/index.tsx +++ b/apps/git/index.tsx @@ -252,7 +252,7 @@ async function getDefaultBranch(bare: string): Promise { async function gitRpc( repo: string, service: string, - body: ReadableStream | null, + body: Uint8Array | ReadableStream | null, ): Promise { const bare = repoPath(repo) @@ -594,7 +594,12 @@ app.on('POST', ['/:repo{.+\\.git}/git-receive-pack', '/:repo/git-receive-pack'], await ensureBareRepo(repoParam) - const response = await gitRpc(repoParam, 'git-receive-pack', c.req.raw.body) + // Buffer the request body before passing to git-receive-pack. Piping a live + // HTTP ReadableStream directly to subprocess stdin deadlocks on large pushes: + // the pipe buffer fills, stalling the stream reader, while git-receive-pack + // can't finish reading stdin to produce stdout — both sides block. + const body = new Uint8Array(await c.req.raw.arrayBuffer()) + const response = await gitRpc(repoParam, 'git-receive-pack', body) // Buffer the full response so we can inject sideband error messages before the // final flush-pkt on deploy failure. The receive-pack response is just ref status // lines (not pack data), so the buffer is small regardless of push size.