zit 0.4.0 targets revision -01 of the Fossil drafts, which fold every erratum into the text, and brings its behaviour into line with them where Fossil and the -00 text disagreed. It closes a weakness in the sync server's handling of authentication, and it is the first release built with Zig 0.17.
zit version now reports targets Fossil RFC rev 01. The -01 drafts ship
in docs/rfcs/ beside the -00 texts they replace.
No artifact, tag namespace, wire, or on-disk repository format changed. The repository cache's layout version changed, so the first command after upgrading rebuilds derived state once.
Security: cards before a valid login no longer borrow its rights
The sync server used to grant a request's rights once, after verifying its
login card, to every card in the request, including cards placed before the
login. A captured signed request could be extended with cards ahead of the
login card, and those cards ran with the signer's rights. Each card is now
judged by the rights in force where it appears, as the draft requires and
as Fossil does. Hosts that serve a repository over zit serve should
upgrade.
Check-in times follow a date tag
A check-in amended with a date tag is ordered by the tag's value, not by
its original D card, as Fossil orders it. The newest date tag wins, a
cancelled one restores the original time, and a value that does not parse
is ignored. Tips, leaves, tip, plain-name resolution, info, timeline and
log --long all follow the retimed check-in. log --long now prints the
event time in whole seconds, as info and timeline do, rather than the D
card's milliseconds. Dates before 1970 are outside zit's time range, for D
cards and date tags alike, as before.
A reply cut short no longer aborts the sync
A sync reply whose body ends inside a file, cfile or uvfile payload used to
abort the exchange. pull, push, sync, config and uv now keep
everything they processed before the cut, print one warning naming the
count, and continue as after any other handler error, exiting 0 as Fossil's
do. clone prints the warning, says the clone is incomplete, leaves the
directory for you to remove, and exits non-zero, as Fossil's clone fails.
The server's answer to a short payload is unchanged: malformed file line.
import-fossil re-converts a sub-manifest source
zit import-fossil --submanifest used to refuse a source that already
carried sub-manifests: it kept the source's S cards beside the run it
minted, so every minted check-in failed verification. It now replaces the
source's file run whatever letter it used, and the conversion succeeds. The
refusal path also freed a remap key twice; on a strict allocator that was a
crash that left the staging directory behind.
Artifact format
- An F card naming a reserved filename is dropped before it can set the artifact's type, as Fossil drops it; a manifest whose only F cards are reserved resolves to a control artifact and is rejected.
- A delta manifest whose baseline is itself a delta is read as Fossil reads it: one level, from the baseline's own F cards. zit used to reject it. A commit atop such a baseline writes a full manifest.
- An F card without a hash in a manifest that is not a delta is rejected.
Repository state
- A singleton tag applied by a T card now walks the check-in's descendants as a cancel, removing the same-named inherited tag, as Fossil's crosslink does.
- A tag operation that is skipped as older than the row it would replace no longer starts a propagation walk.
- Trailing punctuation in a symbolic name is retried exactly as Fossil
retries it: one or two of
. _ ) > ! ? ,are stripped from a name long enough to carry them.trunk^,rel.andrelease;no longer resolve; 0.3.0's notes advertisedtrunk^, and that form is gone.
Sync protocol
- Artifact names on file and cfile cards are validated as 40 or 64 lowercase
hex characters; anything else is
malformed file line. - A second login card is
multiple login cards. - A duplicate delta card is ignored, and an absent delta source becomes a phantom that a later gimme requests, as in Fossil.
- A failed login's reply carries the timestamp line, and a push refused after
an accepted pull is answered with
message pull only - not authorized to pushrather than an error. - A redirect target has one trailing
/xferstripped, not every one.
Built with Zig 0.17.0
The toolchain moves from Zig 0.16.0 to 0.17.0, pinned in CI with the
published checksums for all three targets. Building from source needs
0.17.0. The sources changed where the language and standard library did:
array multiplication became @splat or a comptime repeat helper, type
reflection reads the struct-of-arrays shape, and the build script uses the
reworked build API. zig build e2e takes its filter as -De2e-filter=NAME
now, because a build script can no longer see pass-through arguments.
Compatibility
- The release ships
docs/rfcs/draft-fossil-{artifact-format,repo-state, sync-protocol}-01.txt; section numbers are unchanged from -00, and each -01 ends with an appendix listing its changes. trunk^and other non-Fossil trailing punctuation no longer resolve.- No other command's output changed.
Qualification
Qualified on macos-aarch64 with Zig 0.17.0 and the full local battery:
format check, --release=fast build, unit tests, e2e, deterministic simulation (seed 1,
1000 steps), all 32 fuzz targets at 100 rounds, and the smoke suite three
times against fossil 2.28 [52445a27f1]. Linux targets are qualified when
the release is cut.