Skip to content
zit zit 0.3.20
Login

zit 0.3.20

zit 0.3.20 fixes a server refusal that a stock fossil client could not read, and a remote verb that saved whatever it was handed.

No artifact, tag namespace, or on-disk repository format changed. Two error cards change their encoding on the wire, to the encoding the protocol already requires of them.

A refused push is now refused out loud

When a zit server rejects a request card, it resets its response and answers with one error card. The protocol writes those answers as prose, error bad command: LINE and error malformed CARD line, and zit emitted exactly that prose: the words separated by real spaces. The auth, sequence-number, sparse and content-policy refusals went through the encoder and arrived as one token; these two did not.

A fossil client reads an error card as exactly two tokens, the operator and one encoded text. Four tokens is not an error card to it: it parses error malformed, reports the trailing words as unknown commands, discards the lot, and prints its success summary. On a forge that ran for fifteen hours: every push said Artifacts sent: 94, every push sent the same 94 again, and a fresh clone had none of them. zit push against the same server said "the peer refused" in the same minute, because zit's own client tolerates the malformed card.

Every server error card is now assembled at one point, with its text encoded. The wire texts the protocol pins are unchanged; their spaces are \s, as fossil's own server writes them. A unit test drives every refusal variant through the emitter and fails if any card has a raw space after its operator, so a new fault cannot reintroduce this.

The sync draft's prose describes these texts unencoded, which is how they were transcribed here. That is an erratum against the draft's wording, not its meaning: the card grammar in the same document already says TEXT is encoded.

zit remote refuses what is not a URL

zit remote list saved the word list as the remote and reported success. The saved remote was gone, and the mistake surfaced at the next push, with an error that no longer looked related. Git trained everyone that remote has subcommands, so this was a natural thing to type.

The verb's help already defined its argument as an http:// or https:// address. The parser now holds it to that: any other positional is refused with a usage error, the saved remote is untouched, and the message says plainly that there are no subcommands and which form shows, sets, or clears the remote. Storing a valid URL verbatim is unchanged.

Compatibility

Qualification

zig build test, e2e, smoke (Fossil interop against a real fossil), muscle, git-import-e2e, git-export-e2e, dst, and cross, plus the three-runner CI battery.