Artifact de309bf8d9257d090ef8909fee221fe3f79032a43c46bba18ffa5928b838fa48:
- File docs/RELEASE-NOTES-0.13.0.md — part of check-in [77edd09407] at 2026-11-08 16:57:58 on branch trunk — 0.13.0 notes: upgrade costs measured on a forge's stores (user: dmestas, size: 5685) [annotate] [blame] [check-ins using]
zit 0.13.0
zit 0.13.0 aligns its line diff and three-way merge with Fossil's, and makes the reads a forge pages through cheap on large stores: annotate, the history of one file, and the daemon's start and feed.
This release is from trunk. Stores and the wire are unchanged from 0.12.1. Two caches beside each store are rebuilt once; see Compatibility.
Diff and merge follow Fossil
- Line diff. Every line diff in zit, from
diffand its line counts toannotateandmerge, is a port of the line diff in Fossil's diff.c (D. Richard Hipp). It replaces the patience and Myers engines, so zit aligns repeated lines as Fossil does, andannotatecredits a check-in only with the lines its diff adds. - Three-way merge.
mergewalks the two edit scripts as Fossil's merge3.c does. An edit beside the other side's change now merges cleanly. Where both sides add lines at the same point, the merge now stops with a conflict, as Fossil's does, instead of taking both. Every merge decision and merged text matchesfossil 3-way-merge, except where zit keeps a final newline or a byte-order mark on purpose.
annotate
-n Nis Fossil's version limit.annotate -n Nwalks at most N versions of the file, newest first. A line the oldest walked version already carried is printed with blank check-in and date columns, asfossil annotateprints it. Before,-ncounted check-ins and credited older lines to the oldest check-in shown. A script that read those columns from every line must now allow blank ones, or pass-n none.- Versions come from the file-history index, and the walk stops as
soon as
-nor the nearest cached version allows.annotate -n 50of the most-edited file in a 644 MB store went from 38 s to 50 ms. - A blame cache.
annotatekeeps the answers for a file's recently annotated versions in.zit-cacheand starts from the nearest one, so annotating a tip after a new commit costs tens of milliseconds instead of seconds. An answer that depended on a missing parent, a gap, a limit or content removed by policy is never cached.
log for a path
zit log PATHreads content only for the rows it prints and decides the rest from the file index. A 200-row page of a 2,000-version history costs tens of milliseconds.--offset Nskips N rows, as Fossil'sfinfospells it.--cursor Cstarts after the row a cursor names, and-F jsonreturns the next cursor. A cursor page costs the same at any depth; an offset page still costs the rows it skips. Page by cursor where you can.
Daemon
- Start.
zit daemonanswers its first request in about 0.3 s on a 68,000-file store, where it took 8 to 10 s. It opens what a commit needs on the first commit, from the saved log index, and that commit costs about a second more than later ones. - After a commit the daemon reads only the frames the commit added instead of reopening the store.
- Feed pages. A
feedrequest may carrylimit, the most check-ins to return; the reply'smoresays whether more follow. A page of 500 costs about 0.2 s. A request withoutlimitis answered as before, and every feed reply now carriesmore.morecan be true when only tag or other control artifacts follow, in which case the next page is empty. A daemon older than 0.13.0 refuses a request carryinglimit. - A session that reads the whole bootstrap feed peaks at 1.0 to 1.1 GB on a 68,000-file store, paged or not.
Compatibility
Stores, check-ins, the sync protocol and the daemon protocol version are unchanged.
Two caches in .zit-cache are rebuilt from the store, because the line
diff behind them changed: the blame cache, by the first annotate of each
file, and the line counts, by the first crosslink --lines. The line counts
are the whole upgrade cost, and they grow with a store's history, not its
size: stores with long histories take longest. Measured on a forge's stores
(8 cores, zit at low CPU priority beside the live forge), first command
after upgrading from caches 0.12.1 built:
| store | size | crosslink --lines |
peak memory | info |
ls --long tip |
annotate -n 50 |
|---|---|---|---|---|---|---|
| tcl | 420 MB | 717 s | 218 MB | 0.01 s | 0.11 s | 0.54 s |
| sqlite | 331 MB | 366 s | 220 MB | 0.02 s | 0.04 s | 0.28 s |
| pkgsrc (sub-manifests) | 632 MB | 299 s | 781 MB | 0.13 s | 0.94 s | 0.16 s |
Later crosslink --lines calls take under a second. A store with no
.zit-cache at all builds every cache on its first commands; on the same
forge, from an empty cache, crosslink --lines took 1,524 s on netbsd-src
(3.8 GB, 928 MB peak), 681 s on tcl, 353 s on sqlite, 341 s on fossil and
275 s on pkgsrc, and under 50 s on every smaller store.
A server can build the new caches ahead of time on a copy of each store,
taken with its .zit-cache (crosslink --lines, then ls --long tip),
then move the copy's .zit-cache into place at the switch, as for 0.12.0.
Do not let an older zit open a store whose caches are in the new format: it
rebuilds its own over them.
Merges that both add lines at the same point now conflict where 0.12.1 took both sides; see above.
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.