# zit 0.12.0
zit 0.12.0 makes one-shot calls cheaper on large stores: a diff reads only
the parts of two trees that differ, `log` for a path reads one line per tree
node, and an open no longer checksums whole cache files.
This release is from trunk. Stores and the wire are unchanged from 0.11.0.
Two caches beside each store change format and are rebuilt once; see
Compatibility before deploying on a large store.
## Faster
- **Diff between two check-ins.** `diff` walks both check-ins' trees together
and skips every sub-manifest the two share by hash, reading only the parts
that differ. On a 42,000-file store a one-file diff took 83 ms in-process
and now takes about 3 ms. Wide changes, which touch most of the tree, gain
less. The daemon's `diff` and `timeline -v` use the same walk.
- **`log` for a path.** Each tree node is read through one cache per call and
only the line that leads to the file is parsed. Twenty versions on a
42,000-file store took 11 ms in-process and now take about 3 ms; output is
byte for byte the same.
- **Opening a store.** The log index and the file-history index carry a
header and a table of checksums for 4 KiB blocks, and a call checks only the
blocks it reads. A file lookup in the file-history index now bisects instead
of sweeping. `info` costs about 0.75 ms in-process on a 42,000-file store.
## Fixed
- A diff between two check-ins whose shared part of the tree is missing from
the store, for example in a clone without older history, now answers instead
of failing, because it no longer needs to read that part.
## Compatibility
Stores, check-ins and the sync protocol are unchanged.
The log index and the file-history index in `.zit-cache` change format and
are rebuilt from the store once, by the first command after the upgrade,
whichever it is. On small stores this takes moments. Measured on a forge's
stores, first command after upgrading:
| store | size | first command | peak memory |
|---|---|---|---|
| netbsd-src | 3.8 GB | 1,200 s | 1.05 GB |
| pkgsrc (sub-manifests) | 663 MB | 182 s | 775 MB |
| SquirrelJME | 215 MB | 136 s | 547 MB |
| sqlite | 347 MB | 86 s | 263 MB |
| tcl | 441 MB | 57 s | 251 MB |
| fossil | 142 MB | 35 s | 244 MB |
Later calls run at normal speed. The cost grows with the store's history and
file count far more than with its size in bytes.
A server can build the new caches ahead of time on a copy of each store with
the new binary (`info`, `cat` and `log` for any path), then move the copy's
`.zit-cache` into place at the switch, as for 0.9.0. Do not let an older zit
open a store whose caches are in the new format: it rebuilds its own over
them.
A damaged block in either cache is detected when it is read; the cache is
rebuilt from the store and the call still gives the right answer. A store
whose log cannot be read fails as before, with "repository is corrupt".
## Qualification
The release manifest records native qualification against the exact tagged
source archive on macOS ARM64, Linux x86-64 and Linux ARM64, using the pinned
Zig 0.17.0 toolchain. Publication is gated on unit and end-to-end tests, Git
differentials, deterministic simulation, seeded fuzzing, and Fossil
interoperability checks on every distributed target.
For the basis of the conformance claim, see
[the 0.1.0 release notes](RELEASE-NOTES-0.1.0.md).