Skip to content
zit Check-in [bb96853a0f]
Login

Check-in [bb96853a0f]

Overview
Comment:update: materialize symlink worktree entries

A check-in's F card can name a symlink (§4.7.6-m5), but update refused one outright with error.SymlinkUnsupported, so any history carrying such a card could not be checked out, reverted, or updated to. The refusal was cheap to write and wrong: the reader already represents the entry, and only the worktree side lacked a branch for it.

materializeEntry and writePayload now create the link from the card's target bytes instead of writing a regular file containing them, and isCurrentState compares against .sym_link and the recorded target rather than the size and mode of a file that is not there. The managed-set walks accept .sym_link beside .file, so a materialized link reads as a tracked entry instead of an intruder the admission check rejects.

`zit revert` on a symlink card previously exited 1 naming the refusal. It now restores the entry, and the test reads the link back with readLink, which distinguishes native materialization from a regular file that merely holds the target's bytes.

Timelines: family | ancestors | descendants | both | sub-manifest
Files: files | file ages | folders
SHA3-256: bb96853a0f638e33a412685628918cef35d90dd0685652ae445efd6967f6a4bc
User & Date: dmestas on 2026-07-31 01:26:49.925
Other Links: branch diff | manifest | tags
Context
2026-07-31
01:41
control_paths: one worktree-path admission policy

Two layers decided independently what a reserved path is. update carried its own validateWorktreePath — an absolute/backslash/dot-dot check plus a hand-rolled case-insensitive comparison against the .zit family — while extras carried isControlName, which tested only the first /-delimited component of a path. They agreed by coincidence rather than construction, and the extras form admitted `.zit-managed/entries` because it asked about the component instead of the root.

control_paths now owns both questions. validateWorktreePath and isReservedRoot are the single definitions; update delegates to the first and extras to the second. isControlName takes the full root-relative key that add and move already hand it, so a path rooted in a control entry is refused at any depth rather than only at depth zero. firstComponent goes with its last caller.

The update test that pinned the old list is now a case table naming what is reserved and what merely resembles it, including the case-insensitive spellings the previous ad-hoc comparison happened to get right. check-in: 581db6e5ba user: dmestas tags: sub-manifest

01:26
update: materialize symlink worktree entries

A check-in's F card can name a symlink (§4.7.6-m5), but update refused one outright with error.SymlinkUnsupported, so any history carrying such a card could not be checked out, reverted, or updated to. The refusal was cheap to write and wrong: the reader already represents the entry, and only the worktree side lacked a branch for it.

materializeEntry and writePayload now create the link from the card's target bytes instead of writing a regular file containing them, and isCurrentState compares against .sym_link and the recorded target rather than the size and mode of a file that is not there. The managed-set walks accept .sym_link beside .file, so a materialized link reads as a tracked entry instead of an intruder the admission check rejects.

`zit revert` on a symlink card previously exited 1 naming the refusal. It now restores the entry, and the test reads the link back with readLink, which distinguishes native materialization from a regular file that merely holds the target's bytes. check-in: bb96853a0f user: dmestas tags: sub-manifest

01:24
build: forward --test-filter to the e2e test root

The e2e root is one test binary holding every scenario, and its runner took no filter, so narrowing to a single scenario meant editing build.zig or paying for the whole root. `zig build e2e -- --test-filter NAME` now compiles the filter into the test artifact, accepting both the two-argument and the `--test-filter=NAME` spellings and passing nothing through when the arguments do not name a filter. check-in: cd70f19286 user: dmestas tags: sub-manifest

Changes