Skip to content
zit Timeline
Login

Timeline

10 most recent check-ins occurring on or after 2026-08-17 19:42:59.

More ↑
2026-08-18
13:07
info reads the warm image too: §5.2 overrides, resolved (#98)

info was the last of the three verbs held on the record-body rung, and it was held by one thing: amend --comment stores its override as a tag, and tagxref is empty on an image backing, so the fast path printed the manifest's original comment. On tcl that cost 58s to print one check-in.

The image carries the three display overrides now -- comment, user, date -- RESOLVED. The derive has already applied the cancel rule and mtime precedence by the time they are written, so the image stores the answer and never re-judges it, the same trade branch_id already makes with the §6.1 fallback. That is also what fossil does: tagxref holds one row per (rid, tag) with propagation flattened in by tag_propagate at write time, so its readers do group-bys rather than precedence.

activeTagValue now asserts derived backing instead of answering null there. It returned null for a caller that had a tag, which is the silent shape of wrong this whole issue is about; displayOverride is the image-safe door for the subset the image actually carries. check-in: 8c3abc36c7 user: dmestas tags: trunk

02:18
ls, cat and bisect read the warm image instead of re-deriving (#98)

On tcl's tip zit ls drops from 58.3s to 0.31s: the derived state it needed was already in the cache, in the zero-parse image, and the verb asked for the record-body replay anyway.

Adjacency arrived in the image last change; what remained was every read that went around the accessors. events, its count, and store.count are all empty on an image backing, so a bound taken from them read zero and a branch value read from tagxref fell back to main_branch for every rid -- the section 8.4 walk then never left the branch and answered start:/root: with a check-in from somewhere else, exit 0 and no diagnostic. Those reads route through hasEvent, mtimeOf, hashOf, ridCount and eventsIter now, which name one enumeration order for both backings rather than inheriting insertion order from one of them.

info stays on the full derive: amend --comment stores its override as a tag, and the image carries no tag tables, so on the fast path info printed the manifest's original comment. An existing test caught that the moment the verb moved; branch and tag stay behind for the same reason. check-in: 2772dd3942 user: dmestas tags: trunk

02:10
log: memoize the delta bases the walk re-resolves

walkLog reconstructed every manifest with log.content, which walks the delta chain from scratch. Check-in manifests are routinely stored as deltas against their neighbours, so the same base chain was re-resolved once per check-in -- work that grows with the history behind a node rather than with the node. Per-check-in cost climbed with repository size (0.5ms on libfossil against 2.2ms on sqlite) instead of staying flat.

Every other read path in this file already took #84's PlaintextCache; this one did not. Output is byte-identical -- contentCached is the same bytes, only less work.

log tip, min of repeated runs, warm, ReleaseFast:

pikchr 0.14s -> 0.04s wapp 0.05s -> 0.01s libfossil 1.26s -> 0.34s libspatialite 4.69s -> 2.28s fossil 19.36s -> 7.24s sqlite 59.70s -> 23.81s tcl 38.29s -> 5.99s
check-in: 55b176c8dd user: dmestas tags: trunk
00:02
repoimage: carry adjacency, and read it through one door (#98)

The image held mtimes, hashes, branch ids and the symbol table but not the parent/child relation, which is why every verb needing ancestry re-derived the whole log on open. Six CSR columns carry it now, both directions with the primary flag -- primary-parent selection and merge-edge skipping both read it, so an image without it answers wrongly rather than refusing.

The two backings hold the same relation in different shapes, so edgesOf hides which one a caller got, and the equivalence test compares them in order with a guard that fails when the corpus has no edges to compare.

Behaviour-neutral: no assert relaxed, no verb moved. Freeing those needs an events equivalent as well -- resolve reads self.events directly, and that table is empty on an image backing. check-in: 82de6f83d0 user: dmestas tags: trunk

2026-08-17
22:54
build: the ~25x pack figure does not reproduce; record what does

Measured on wapp warm, modes interleaved and repeated: pack is ~8.5s fast, ~9.5s safe, ~10.7s small, and the read path is 0.31/0.33/0.36 with leaves at 0.01s in all three. So fast buys ~12% on writes and nothing measurable on reads.

The '599ms fast against 15.2s safe, ~25x' this file carried reproduces in neither the ratio nor the absolutes; the delta encoder's search was reworked since it was taken. Left uncorrected it would have justified almost any correctness cost, which is the expensive kind of stale number to leave in a comment that decides the shipped build. check-in: 6181a57e0c user: dmestas tags: trunk

22:37
build: ship ReleaseFast

zit ships ReleaseFast, so --release names it. This reverses the ReleaseSafe pin; pack runs ~25x faster and read verbs are indistinguishable between the modes (ls over tcl's 300MB store is 0.31s fast against 0.33s safe, leaves 0.01s in both).

The cost is real: over a thousand std.debug.assert calls compile to nothing, so release_assert_test.zig stops being belt-and-braces and becomes the thing keeping an assert from standing in for validation of untrusted input. Its rationale is rewritten around that.

Stating a preference makes it the ONLY reachable release mode, which the old comment got wrong: it documented --release=fast as an escape hatch from the ReleaseSafe pin, and that flag produced a ReleaseSafe binary anyway -- safety strings present to prove it. Anything benchmarked through it before now measured the checked build. The ci pin moves from 'keeps assertions alive' to 'the mode is stated, not left to whoever packages', which is the part that survives the reversal. check-in: da904fbe1c user: dmestas tags: trunk

21:30
CI: assert fossil's version, do not only print it (#100)

smoke is the only lane that runs a real fossil against zit, so runners on different fossils make the conformance claim mean a different thing on each -- a regression against the newer can pass on the older, and newer-only behaviour reddens the older for something that is not a defect. Both are silent, because the version is printed hundreds of log lines before the failure it explains. fossil sqlite3 quoting its output on 2.26 but not 2.28 cost three round trips that way. The printed line stays; the release notes still need it. check-in: ab3a1983cb user: dmestas tags: trunk

20:25
grep -S and -G: the pickaxe over history (#92)

-S reports the check-ins where the occurrence count of PATTERN changed, -G those where a changed line mentions it. A string added once and deleted later is two lines, where plain grep reports every version that held it in between.

The issue expected this to need a diff per revision. It does not: a path whose blob hash matches its parent's cannot have moved either answer, so the walk compares F-card hashes and reads only the blobs that changed. Deletions are picked up from the parent side, which a walk over the child's files alone would miss.

Merges compare against the primary parent, as git log -S does; counting against every parent reports one appearance twice. check-in: 28c48bb3f7 user: dmestas tags: trunk

20:00
archive differential: fossil sqlite3 quotes its output on 2.26 (#95)

The runner on 2.26 returns the check-in uuid wrapped in single quotes where 2.28 returns it bare, so the name handed to fossil tarball could not resolve -- and the failure named the hash, which reads like a missing check-in rather than a quoting difference. The harness strips to hex and then insists on a 40- or 64-character hash, so a future output change is refused by name here instead of failing two commands later. The CI step no longer runs its own copy of the query; one place for this to go wrong is enough. check-in: f37a155d45 user: dmestas tags: trunk

19:42
archive differential: fossil's documented argument order, and print its errors (#95)

One runner carries fossil 2.26 where the others carry 2.28, and 2.26 refuses options before the positionals -- fossil documents 'tarball VERSION OUTPUTFILE [OPTIONS]' and 2.28 merely tolerated the other order.

The reason that took a full CI round trip to find is the second change: a failure said 'see $WORK/x.log' on a machine nobody can log into. It now prints the log, so fossil's own sentence reaches the build output. check-in: e492130985 user: dmestas tags: trunk

More ↓