Skip to content
zit Timeline
Login

Timeline

10 most recent check-ins occurring on or after 2026-08-01 19:07:05.

More ↑
2026-08-02
19:52
repostate: note that control-carried tags make crosslink order observable

applyDirect's >= skip means a tag on a separate control artifact, rather than on the check-in manifest, depends on crosslink order; names emitBranchControls as the dependent. Also corrects branchValueOf's doc, left stale by c8c7c2696e. check-in: 941ddcb981 user: dmestas tags: sub-manifest

19:52
import-git: decide branch membership from the commit graph

fast-export emits each commit once, under whichever ref reached it first, so that header was provenance and not branch. A single-branch repository imported with ZERO branches; multi-head repositories were scrambled in proportion to merge activity, which at sqlite scale read as 7,421 leaves on master under repo-state §7.2's same-branch leaf test. Issue #26.

labelBranches claims the primary's first-parent chain, then each head shallowest tip first, then inherits; emitBranchControls writes one control per segment root. Two things the plan did not anticipate: objects are folded to check-ins by hash first, because two git commits can translate to one byte-identical check-in and §5.2 allows one branch tag per rid; and controls are emitted deepest-first, because §5.3's timestamp skip would otherwise let an ancestor's propagation win over a root whose commit shares its second.

source_ref is deleted rather than demoted -- after the change it had no readers. makeBranchControl now composes the §6.2 pair through artifact.composeCommitTags instead of a lone *branch card.

Content was never affected: artifacts, parent links and tip content were always correct. Only derived branch state was wrong, which is why a full benchmark ran clean through it. Repairing an existing imported store means re-importing; check-in hashes survive, since branch state lives in separate controls.

Two pre-existing expectations were rewritten, deliberately: both demanded two active branch tags on one rid, which §5.2 forbids, and were unsatisfiable rather than merely stale.

Verified: fmt, test 3281/3281, gate, e2e 716/716, git-import-e2e 11/11, dst 6x1000. Shapes A/B/C match git branch exactly, 11/11 tip parity. check-in: 4d7a22b93c user: dmestas tags: sub-manifest

14:29
repostate: branchValueOf reads the configured main branch, not "trunk"

repo-state §6.1 requires reading the configured value and falling back to trunk only when main-branch is unset -- "MUST NOT assume a fixed string in the presence of an explicit setting". branchValueOf, which backs the §7.2 same-branch leaf test, used the literal.

It hid because all three uses are comparisons: when both sides fall back identically the result is unchanged. It bites when one check-in is tagged and another is not, which is the imported-repository shape -- displayed as one branch by branchOf, leaf-tested as another by branchValueOf.

The name is now a field on RepoState, set through one RepoView setter so the two readers cannot drift, with branchOf asserting its argument agrees. That assert immediately found a second source: update.zig re-read the config itself and passed a value the state never saw. It also treats an empty stored name as unset, as the view already did. check-in: c8c7c2696e user: dmestas tags: sub-manifest

12:07
status/diff: resolve a tree check-in's file set before comparing

An S-bearing manifest carries its files in sub-manifests, not in its own F run, so reading bare .f found none of them and every tracked path was classified `added` -- identical output whether or not anything had changed. Issue #25.

CheckinBaseline and DiffBaselineResolver now flatten first, the same step commit already performs. §5.1's "downstream MUST NOT distinguish" is exactly this: a raw .f read is how a reader opts out of the derivation seam.

Submanifest-specific, confirmed both ways: a --no-submanifests import was already clean. Not import-specific though -- any tree-shaped checkout hits it, so a clone from a tree-emitting peer would too.

Regression test asserts clean status and empty diff after materializing a tree check-in, and that a real edit still reports `edited`. check-in: 1e8c8a198d user: dmestas tags: sub-manifest

07:14
commit: decode artifact names of either width, not just sha3-256

hexToDigest required exactly digest_len*2 hex characters. zit init writes the sha3-256 policy, so that looked like the only case -- but import-git opens its destination under git's sha1, naming every check-in in 40 hex. So commit rejected the parent of every imported repository and reported it corrupt on a store zit verify called clean. Issue #24.

Length now comes from the name, as artifact §7.2 allows both widths. pack.zig carried the same copy and would have dropped the primary-parent hint the same way; cmd/sync.zig's callers move to the slice form.

commitParentCorrupt now names which step failed. Collapsing an undecodable name, an absent parent and real damage into one sentence is why verify and commit could disagree with no way to tell which was right.

Reproduced on 12 commits and 40 files -- not scale-dependent, and not submanifest-specific: it fires before the S-card branch, so flat imports failed identically. Regression test commits over an imported sha1 history; mutation-proved by restoring the width check. check-in: ffea6238e6 user: dmestas tags: sub-manifest

01:29
import-git: differential test for flat vs tree imports

Same source, same path, two imports: check-in manifests byte-identical once F/S/Z/P are stripped, blob provenance identical, P topology re-derived through each import's own map. check-in: 81b01a1157 user: dmestas tags: sub-manifest

01:29
import-git: add --no-submanifests

Imports with sub-manifests off: flat manifests throughout and the spec-default config frame (k=0, enable off). Flat is §8.1's default shape; it is this verb's analyze-and-pin that is the deviation.

TreeFormat.Shape becomes flat | tree{k, height_max}, so flat-with-a-k and tree-without-one stop being representable and every tree-only site traps on the wrong tag. buildFlat drains the same MergedCursor, so ordering, dedup and rename/copy/delete stay single-sourced. SubmanifestChoice replaces submanifest_k from Request down to UserOptions.

Publication refuses if the store holds a SUBMANIFEST anyway, derived from work done rather than from the flag. Preflight analysis still runs under flat -- skipping it would put a second divergence inside the region the benchmark times.

Closes #23. check-in: 9b96469ae6 user: dmestas tags: sub-manifest

2026-08-01
19:26
import-git: set seen_submanifest when the import stores one

The latch is one-way and means 'an S reference is stored here', not 'trees are enabled'. The import set enable_submanifests and left it false, which stayed hidden only because the §7.2 gate is the disjunction of the two -- a later 'zit submanifest disable' would have left the repository advertising avoid-submanifests while holding S-bearing artifacts.

Derived from emitted_nodes, not from the k pin: an import whose sources all stay flat stores no S reference and must leave the latch false. check-in: 0b6e41e54f user: dmestas tags: sub-manifest

19:07
logstore: test the config shape tag round-trips

Additive; covers the tagged trailing block and the legacy widths. check-in: 3392ff5a3e user: dmestas tags: sub-manifest

19:07
update: use the repository's §5.2 tree resolver

Deletes the duplicate resolver in update.zig. The surviving path decodes S-card hashes case-insensitively per §3.5; the deleted one ran them through lowercase-only validateName and rejected a legal uppercase hash. TreeError codes mapped exhaustively rather than via else. check-in: 4a3061280e user: dmestas tags: sub-manifest

More ↓