fix: UploadPackV2 always emits acks section when haves were sent #19

merged colechristensen cole.christensen@gmail.com wants to merge fix/upload-pack-v2-haves-always-emit-acks into main
No CI

Closes #28. Follow-up to #27 / PR #18.

Summary

The previous fix over-corrected: when the client sent haves but none matched + `done`, the server omitted the acks section entirely. Real clients reject this with

``` fatal: expected ‘acknowledgments’, received ‘packfile’ ```

This PR restores the invariant: if `haves` is non-empty, we emit the `acknowledgments` section. With `done` it ends in `ready` (zero or more ACKs + ready, which is spec-valid). Without `done` it ends in NAK / ACK + flush for multi-round.

Why the earlier tests missed it

The hephaestus-regression integration test had the client do `git init` + one commit + `git fetch`. In that setup the git client sent zero haves — my log traces confirm `1 wants, 0 haves`. So the broken branch (`done=true and acks==[]` with non-empty haves) never fired.

This PR forces haves via `–negotiation-tip=refs/heads/main` + `–depth=1` and adds explicit `refute`s for both regression error strings.

Test plan

  • `mix test –include integration` — 713 / 713 pass
  • `mix format –check-formatted`, `mix credo –strict` on touched files — no new issues
  • CI green
  • After deploy: `git pull` from `fangorn/anvil` / `fangorn/hephaestus` succeeds
Created Apr 18, 2026 at 23:24 UTC | Merged Apr 18, 2026 at 23:32 UTC by colechristensen cole.christensen@gmail.com