zit 0.3.21 accepts a stock fossil push that carries more than one check-in,
and accepts the request type fossil sends under --httptrace.
No artifact, tag namespace, or on-disk repository format changed. One server error card is new, and one request media type is no longer refused.
A multi-check-in push lands
fossil sends a batch of check-ins as one round, with each manifest a delta against the previous one. The server scans the round before it stores anything, so a rejected request leaves no trace, and the scan reconstructed each pushed delta against the committed store. A manifest delivered earlier in the same round is not committed yet. The lookup failed, and the failure was reported as a malformed file card.
The consequence was that any push of two or more check-ins from a stock fossil client was refused, and the only workaround was pushing one check-in at a time, which nobody would guess. Single-check-in rounds, including ones with several file cards, were unaffected, which is why every existing interop test passed. It cost a tester two days, most of them spent on card syntax because the refusal said "malformed".
The scan now parks a delta whose basis is not held and settles it once the whole round has been seen. A basis is either committed or was delivered by this round, possibly as another parked delta, so resolution runs to a fixpoint and the sender's order within the round does not matter. Whatever is still unresolved names a basis the round never carried and the store never held, and that refusal now says so:
error delta basis not held: TARGET against BASIS
Two unit tests push a delta against a basis delivered earlier and later in the same round, the second through a chain of two deltas. A new fossil interop smoke scenario clones a served zit repository with stock fossil, commits three times offline, pushes once, and checks all three check-ins are in the served store. It fails against 0.3.20.
--httptrace reaches a zit server
fossil's --httptrace sends its request uncompressed under the media type
application/x-fossil-debug. The server refused that type with a bare 415,
on the stated premise that the reference client never sends it. It does,
and it is the first thing anyone reaches for when a sync misbehaves, so the
diagnostic was refused in the one situation it exists for.
The type is accepted. The exchange tells the request handler whether the
body is a zlib container or plain cards, and the handler decodes or copies
accordingly. The reply is framed as before; fossil picks the reply's framing
off the reply's own content type. application/x-fossil-uncompressed
remains reply-only and is still refused on a request.
Compatibility
- No on-disk repository or wire format changed; Fossil RFC revision 00 remains the target.
- A pushed delta with no basis anywhere is refused with a new named error card in place of "malformed file line". The draft's own rule for this case is to park the delta and create a phantom; a stateless server cannot park it across requests, so the refusal stays, and now says why.
- Any client's
application/x-fossil-debugrequest is answered rather than refused.
Qualification
zig fmt --check, zig build test, e2e, smoke (Fossil interop against
a real fossil, now sixteen scenarios), muscle, git-import-e2e,
git-export-e2e, dst, and cross, plus the three-runner CI battery.