Skip to content

git-remote-gitlawb deadlocks on incremental (multi-round) fetch #117

Description

@beardthelion

Summary

The git-remote-gitlawb helper bridges git's stateful upload-pack connect stream onto a single stateless HTTP POST, so it deadlocks on an incremental (multi-round) fetch. read_upload_pack_request treats a flush pkt (0000) as "keep reading" and only breaks on the done\n pkt-line, and handle_connect issues exactly one POST after done. In an incremental fetch git sends wants, then a have-batch terminated by a flush, and blocks waiting for the server's ACK/NAK before sending done. The helper is blocked reading stdin for a done that never comes; git is blocked reading the helper's stdout for a response that is never sent. The fetch hangs until the request timeout.

A fresh clone (the client sends wants + done in one shot) works, which is why this was not caught earlier.

Where

  • crates/gitlawb-node/../git-remote-gitlawb/src/main.rsread_upload_pack_request (breaks only on done\n or EOF; continues past a flush) and the single-POST flow in handle_connect.

Reproduced by execution

Live repro against a local node: built a ~50-commit shared history, cloned via gitlawb://, advanced the server by a few commits, then git fetch origin.

  • Fresh clone (control): exit 0, ~1s.
  • Incremental fetch, few haves (git short-circuits, sends want + haves + done in one shot): exit 0, ~0s.
  • Incremental fetch, >32 haves (forces multi-round): hung the full 40s, killed by timeout (exit 124).

GIT_TRACE_PACKET confirmed git sent 1 want, 32 have lines, a flush 0000, and zero done, then blocked. Only the initial ref advertisement ever came back.

Impact

Any fetch where the client has more than ~32 commits of overlapping history with the server (the common "pull updates into an existing clone") hangs indefinitely. Not a security issue; a functional break in the helper's fetch path.

Options

  1. Implement git's stateless-RPC multi-round negotiation (a POST per have-batch, streaming ACK/NAK back), or
  2. advertise/implement the stateless-connect capability instead of connect.

Pre-existing; surfaced while verifying the receive-pack advertisement fix end to end.

Metadata

Metadata

Assignees

No one assigned

    Labels

    crate:git-remotegit-remote-gitlawb — the git remote helperkind:bugDefect fix — wrong or unsafe behaviorsev:mediumDegraded but workaround existssubsystem:apiNode REST API request/response surface

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions