Skip to content
zit Timeline
Login

Timeline

10 most recent check-ins occurring on or after 2026-08-18 20:37:02.

More ↑
2026-08-21
02:31
crosslink: stream derived per-check-in records (#109)

The record body now captures the U-card user and the changed-file set, diffed against the primary parent at derive time where the parsed manifest is already in hand (layout 5, checkpoint 4; one-time rebuild per store). 'zit crosslink' replays it: identity, comment, tags, and file changes as a versioned text stream, cache-served under the same key discipline as every read verb, byte-identical to --no-cache.

sqlite dumps 36,797 check-ins in 0.11s / 14.9MB against the 3.87GB structural stream. A parent the store does not hold reads as 'files unknown', never as an empty change set -- sqlite's corpus carries exactly one, a 2009 check-in with a genuinely absent parent.

Mixed binary versions thrash across the layout bump: each side rejects the other's cache and re-derives. Update every binary that shares a store. check-in: 2a68d2fc79 user: dmestas tags: trunk

01:00
frames: --structural emits only what the crosslink links (#108)

Content blobs dominate a full stream (13.2GB on sqlite) and indexing consumers discard them. The gate is artifact.parseForImport on the reconstructed bytes -- never a cache -- behind an O(1) reject-fast screen that admits card shapes and signature wrappers; skipped frames are not hashed or emitted, and the cursor advances over them, so filtered and unfiltered polls compose against one cursor. sqlite 13.2GB -> 3.9GB, tcl -> 682MB. check-in: a2fb222e32 user: dmestas tags: trunk

2026-08-20
19:17
repostate: index the two tag lookups the cache serializer loops over

serialize called tagsOf per rid and resolveName per symbol, each a full tagxref scan -- O(rids x rows) and O(symbols x rows). A one-check-in append cost the next reader 42s on a 42K-check-in store (#107); now 0.8s, and a full derive drops 74s to 21s.

tagsOf routes through the existing rid_tags index; resolveName gets the inverse tag_rids index, maintained by the same helper pair so the two stay precise together. Selection semantics unchanged. check-in: 0aa75ac13d user: dmestas tags: trunk

2026-08-19
17:45
release: put the manifest assembler in the tree

release-manifest.json is the authoritative record of a release -- checksums, targets, qualification -- and nothing that produced it was in the repository. Its source_tree_sha256 had to be reverse-engineered from published output to cut 0.2.0: sha256 over 'sha256 path' lines sorted BY LINE, so by hash, which is the sha256sum | sort | sha256sum idiom.

The release whose manifest nobody could check is the one carrying false fields. 0.1.3 labelled a native build x86_64-linux-musl and claims 104 source files against a tarball holding 93.

The script re-verifies every archive against its own metadata fragment before describing it as qualified, and reproduces the published 0.2.0 manifest exactly. check-in: 520e388d6a user: dmestas tags: trunk

16:58
release: prepare zit 0.2.0

The 0.1.x line grew from 38 dispatched verbs to 61, gained the sub-manifest dialect, and grew a layered derived-state cache. 0.1.4's notes mention sub-manifests once and never say cache, so the notes here cover that machinery rather than only what changed since 0.1.4. check-in: 09e80bc9ef user: dmestas tags: trunk, version-0.2.0

02:50
reference: pin the flags, not just the verbs

An audit of all 57 verbs against their own --help found two gaps the existing pins could not see, because reference_test.zig checks that a verb HAS a section and #68 checks options-table flags against the usage block.

pack --drop-elided was in neither. The flag is real -- it is the sparse spec's narrow-then-compact deletion, destructive and irreversible -- and it appeared in no help output at all, so nothing compared it to anything. Now documented, including that unlike shun it leaves no tombstone, so a later widening re-fetches from a peer.

settings --global was accepted but missing from the reference.

The new e2e pin holds every verb's real --help against its reference section both ways: a flag the verb accepts that the section never names, and a flag the section documents that --help never mentions. The second direction matters more than it looks -- an omission is discoverable from --help, a promise sends someone hunting for something that is not there.

It lives in the e2e lane because it needs the help TEXT, and the help constants are in main.zig, outside the library test module. Conventions flags (-R, --no-cache) count as covered wherever they are documented once; matching is whole-token so --cone cannot satisfy --cone-not.

Both directions were verified by breaking them deliberately. check-in: 03e606ea49 user: dmestas tags: trunk

2026-08-18
23:30
merge -X ours|theirs: resolve content conflicts wholesale (#91)

merge3 already resolved every region except one -- the case where both sides changed it differently. That branch now takes a side instead of always writing an envelope; the clean cases above it are untouched, which is the whole point. A region only one side changed is still that side's under either strategy, so -X is not 'discard their work', it is 'stop asking me'. The mechanical cases are what it is for: a regenerated lockfile, a vendored tree taken whole from upstream.

Applies to content disagreements -- conflicting hunks, add-vs-add, and both-modified binaries. It deliberately does NOT resolve modify-vs-delete: that is a disagreement about whether the file should exist, not about its contents, and either reading silently destroys work. git declines it too.

-X ours is not --backout, and the help says so outright: --backout reverses NAME's change, -X ours keeps your side where the two collide and reverses nothing. They read alike and do different things.

Composes with precedent (#103) without either knowing about the other: precedent is a pass over the outcome set, so a strategy that leaves no conflict leaves it nothing to replay or record. Verified both ways -- -X records no precedent, and a plain merge still conflicts and records.

A bad or missing -X value is a usage error rather than a silent fall back to markers, which would look exactly like a strategy that ran and found nothing. check-in: 52b8c57f4c user: dmestas tags: trunk

22:40
export-git: drop a verb-list line pasted into its usage block

'zit export-git --help' printed " \ import-fossil bring a fossil repository's history into zit" as its second line, backslash included. The verbatim help pins cover merge and stash only.

The new pin checks shape instead: no rendered help line may start with a backslash, which catches the paste for every verb. The reference gains merge --no-precedent, which was documented under the wrong verb. check-in: 5fe0d9eafe user: dmestas tags: trunk

21:28
stash: reserve .zit-stash so it cannot be tracked

The sidecar was absent from the control-path registry, so extras listed it and add accepted it: an ordinary add put the contents of stashed work into a check-in and synced it to every peer, recoverable only by shunning. The stash help already promised "never an artifact"; nothing enforced it.

Authoritative tier, matching what losing the file costs. check-in: 503637a369 user: dmestas tags: trunk

20:37
precedent: remember conflict resolutions and replay them

A merge records each conflict in the local .zit-precedent sidecar; commit attaches the resolution the operator settled on; a later merge whose conflicted bytes match replays it instead of writing markers. Keyed by path and conflicted bytes, exact because the diff3 envelope carries all three sides. Whole-file, so a file whose other conflict moved will not replay.

Replay is named per file, never silent. --no-precedent declines for one merge without forgetting. 'zit precedent list|show|forget', alias rerere. The sidecar is a reserved advisory name, so it can never become an artifact. check-in: a9a24a857c user: dmestas tags: trunk

More ↓