Artifact 824e26f2cb5b8d426f10304ac9fe14b8571c7b83b18f6bb937cbc7f7a657d4ac:
- File docs/RELEASE-NOTES-0.3.14.md — part of check-in [37a5af6b08] at 2026-09-14 13:43:34 on branch trunk — 0.3.14: version bump and release notes (user: dmestas, size: 4027) [annotate] [blame] [check-ins using]
zit 0.3.14
zit 0.3.14 makes a file's history cheap to ask for. zit log CHECKIN PATH
reconstructed a check-in manifest for every check-in it walked, so one file's
history on a mirror of SQLite took over two minutes and the cost grew with how
much unrelated history sat behind it. It now answers from an index the derive
was already computing and discarding.
No artifact, tag namespace, sync message, or on-disk format changed. The index
is a .zit-cache member: advisory, rebuilt from the log if deleted, and
answering nothing the log cannot.
log PATH and timeline -p (zit#188)
Two defects, fixed in that order.
The predicate asked twice. It computed a check-in's effective content for
PATH once as the check-in and once as the primary parent of the check-in below
it, and each call re-read, re-verified and re-parsed the manifest because
fileAt took neither the walk's plaintext memo nor a baseline memo. Threading
both — and the answer itself, memoised by rid — took reconstructions per walk
from 2N-1 to exactly N. timeline -p PATH shared the defect and is fixed
with it.
The predicate should not have been reconstructing at all. zit already
computes each check-in's change set against its primary parent during the
derive (ChangedFile is Fossil's mlink row) and streams it to the
crosslink feed without keeping it. That fact, inverted by path, is now
persisted as .zit-cache/finfo, keyed to the log tail and the shun
fingerprint exactly like the cluster and disposition maps. The PATH walk
traverses the derived adjacency — as the unfiltered walk has since #98 — and
the index narrows it.
log --long -n 50, SQLite mirror (131,558 artifacts) |
before | after |
|---|---|---|
| README.md | 72.20s | 1.58s |
| src/btree.c | 24.88s | 1.11s |
| manifest reconstructions (README.md) | 25,106 | 141 |
Output is byte-identical, checked per path rather than inferred.
The index narrows; it does not decide. captureFileFacts diffs at F-card
level, so a delta manifest that restates a path with the hash it already had
reads as a change there while the path's effective content did not move — one
check-in in 2,113 on btree.c's full history, an over-report and never an
omission. Every candidate the index names is therefore still confirmed by the
change predicate, which is what keeps the answer exact. ZIT_NO_FILE_INDEX=1
answers by reconstruction alone; an end-to-end test compares the two for every
tracked path so a regression cannot silently drop a file's history.
Building the index is a one-time pass over the check-ins (about 164s and 882 KB on the SQLite mirror) and happens on the first PATH query.
What this does not fix. About 0.7s of each figure above is opening the repository, which is unchanged here and is now tracked on its own. A warm process pays it once; a single CLI invocation pays it every time.
zig build cross
A new gate step compiles the CLI for x86_64-linux and aarch64-linux and
runs nothing. This project links no libc and macOS links libc unconditionally,
so a call that demands libc builds on a developer's mac, passes every local
lane, and refuses on both Linux runners. That happened during this release's
development. gate depends on the new step; CI does not run it, because CI
compiles the real thing on all three targets it ships for.
Compatibility
- No on-disk or wire format changed; Fossil RFC revision 00 remains the target.
.zit-cache/finfois a new cache member. Older zit ignores it, and deleting it costs one rebuild.- No command or flag changed.
ZIT_NO_FILE_INDEXis a diagnostic seam, not a supported interface.
Qualification
zig build test, e2e, smoke (Fossil interop against a real fossil),
muscle (41 differential steps), git-import-e2e, git-export-e2e, dst,
and cross, plus the three-runner CI battery. The timings above are release
builds against the flat SQLite mirror; the before figures come from the
preceding binary run on the same store.