Skip to content
zit Check-in [3b7fe2fbe1]
Login

Check-in [3b7fe2fbe1]

Overview
Comment:Merge release-0.1: status: report edited files by hashing tracked files against the current check-in

Lands release step P3-F5-status on trunk, completing the B-status-16 deferral.

The increment: `status` previously classified only `added` and `missing`, so a tracked file that was present but modified produced no line at all — the gap was documented in a comment, in `--help`, and in an e2e test that pinned the silence. Documenting a hole is not the same as not having one, and "your working copy looks clean" is the wrong thing for a version control system to say about an edited file. `status` now resolves the current check-in and compares every tracked file against it, emitting an `edited` row when the bytes or the file mode differ; a file whose contents match is still not listed.

The comparison is not a second implementation. The check-in resolution, the legacy trailing-separator F-card tolerance, the delta-manifest walk, and the merge against the sorted managed set were all machinery `diff` already had; that machinery is extracted into `CheckinBaseline` and `walkWorkingTree`, and both verbs now run through it, with each verb supplying only a sink. `diff` is a pure refactor here — same output, less code. Dirtiness remains a non-failure: every `added`/`edited`/ `missing` row exits 0 (B-status-15); only a genuine comparison failure exits 1. `--help` no longer defers edited-file detection and now narrows the deferral text to the two cases that genuinely remain out of scope.

This lands the full detection called for by P3-F5, not the fallback. The plan's fallback of record required an explicit operator decision; none was taken and none was needed.

Merge evidence: `fossil merge release-0.1` reported no conflicts, updating only src/e2e.zig and src/main.zig. The tree carries no conflict markers — the three open-marker occurrences a grep turns up in src/e2e.zig are string literals inside assertions pinning zit's own merge3 conflict sentinel, not merge residue.

Verification evidence: the merged tree — not merely the branch — was re-verified on trunk after the merge. `zig fmt --check .`, `zig build`, and `zig build test` each exit 0. Behavioral evidence rides in the branch commit's new e2e coverage, which pins each acceptance criterion: an edited tracked file is reported as edited; a rewrite with identical bytes (mtime bump, same content) is not reported; an executable-bit-only change is reported; a file deleted from the check-in but no longer tracked is still not reported; and a delta checkout with an absent B-card baseline fails cleanly rather than reporting a false clean tree. The e2e that pinned the old deferral is replaced by those tests, and the help-text e2es compare against a hand-written expected string, so the `--help` change is pinned too.

`fossil extras` is empty, so the merge adds no file it fails to track.

No performance claim is made here. No borrowed techniques in this change, so no attribution is owed.

Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 3b7fe2fbe19529b6157e8fdcbe5246da7823e697b904d4e9947b06460aa81a01
User & Date: dmestas on 2026-07-18 23:14:29.351
Other Links: manifest | tags
Context
2026-07-18
23:19
Merge release-0.1: zit open — the clone-to-working-tree path (P3-F3)

Lands the last of the three P3 CLI cliffs. A clone previously produced only an artifact log: there was no verb that turned one into a working tree, so clone-to-usable-checkout was unreachable and unproven by any test. `zit open` closes that path, resolving the trunk tip and materializing the check-in into the target directory.

The merged tree — not merely the branch — was re-verified on trunk after the merge: zig fmt --check ., zig build, and zig build test all exit 0. The merge reported no conflicts and touched six already-tracked files; fossil extras is empty, so nothing referenced went unadded. The conflict-marker byte sequences that a repo-wide grep reports in src/merge3.zig and src/e2e.zig are that module's own conflict sentinel and the tests asserting on it, not merge residue.

Landed separately from the sibling status increment (3b7fe2fbe1) rather than folded into one commit: the two are independent release steps and each keeps its own subject and evidence. check-in: 91c682fd06 user: dmestas tags: trunk

23:14
Merge release-0.1: status: report edited files by hashing tracked files against the current check-in

Lands release step P3-F5-status on trunk, completing the B-status-16 deferral.

The increment: `status` previously classified only `added` and `missing`, so a tracked file that was present but modified produced no line at all — the gap was documented in a comment, in `--help`, and in an e2e test that pinned the silence. Documenting a hole is not the same as not having one, and "your working copy looks clean" is the wrong thing for a version control system to say about an edited file. `status` now resolves the current check-in and compares every tracked file against it, emitting an `edited` row when the bytes or the file mode differ; a file whose contents match is still not listed.

The comparison is not a second implementation. The check-in resolution, the legacy trailing-separator F-card tolerance, the delta-manifest walk, and the merge against the sorted managed set were all machinery `diff` already had; that machinery is extracted into `CheckinBaseline` and `walkWorkingTree`, and both verbs now run through it, with each verb supplying only a sink. `diff` is a pure refactor here — same output, less code. Dirtiness remains a non-failure: every `added`/`edited`/ `missing` row exits 0 (B-status-15); only a genuine comparison failure exits 1. `--help` no longer defers edited-file detection and now narrows the deferral text to the two cases that genuinely remain out of scope.

This lands the full detection called for by P3-F5, not the fallback. The plan's fallback of record required an explicit operator decision; none was taken and none was needed.

Merge evidence: `fossil merge release-0.1` reported no conflicts, updating only src/e2e.zig and src/main.zig. The tree carries no conflict markers — the three open-marker occurrences a grep turns up in src/e2e.zig are string literals inside assertions pinning zit's own merge3 conflict sentinel, not merge residue.

Verification evidence: the merged tree — not merely the branch — was re-verified on trunk after the merge. `zig fmt --check .`, `zig build`, and `zig build test` each exit 0. Behavioral evidence rides in the branch commit's new e2e coverage, which pins each acceptance criterion: an edited tracked file is reported as edited; a rewrite with identical bytes (mtime bump, same content) is not reported; an executable-bit-only change is reported; a file deleted from the check-in but no longer tracked is still not reported; and a delta checkout with an absent B-card baseline fails cleanly rather than reporting a false clean tree. The e2e that pinned the old deferral is replaced by those tests, and the help-text e2es compare against a hand-written expected string, so the `--help` change is pinned too.

`fossil extras` is empty, so the merge adds no file it fails to track.

No performance claim is made here. No borrowed techniques in this change, so no attribution is owed. check-in: 3b7fe2fbe1 user: dmestas tags: trunk

23:08
status: report edited files by hashing tracked files against the current check-in

Completes the B-status-16 deferral. `status` previously classified only `added` and `missing`: a tracked file that was present but modified produced no line at all, and the gap was documented in a comment, in `--help`, and in an e2e test that pinned the silence. Documenting a hole is not the same as not having one, and "your working copy looks clean" is the wrong thing for a version control system to say about an edited file.

What changed:

- `status` now resolves the current check-in and compares every tracked file against it, emitting an `edited` row naming the path when the bytes or the file mode differ. A file whose contents match is still not listed.

- The comparison is not a second implementation. `diff` already resolved the current check-in, tolerated the legacy trailing-separator F-card, walked the delta manifest, and merged that effective file set against the sorted managed set. That machinery is extracted into `CheckinBaseline` (open/resolve) and `walkWorkingTree` (the merge), and both verbs now run through it. `diff` is a pure refactor here -- same output, less code. The `diff*Fail` diagnostic mappers become `compare*Fail` and take the verb as a parameter, the shape `checkoutFail` and `managedFail` already used.

- A verb supplies only a sink with `emit(entry)`. `DiffSink` renders diff records; `StatusSink` renders human rows and drops the deleted-from-check-in class, which `status` still defers because it iterates the managed set. The sink is comptime-generic rather than an erased pointer pair: both sinks are known at compile time, so the call stays direct and type-checked.

- The whole report is buffered and written once, as `diff` already did. A comparison failure part-way through the walk now leaves stdout empty rather than a header above a truncated report. Dirtiness is still never a failure: every `added`/`edited`/`missing` row exits 0 (B-status-15). Only a genuine comparison failure -- unreadable tracked file, corrupt or unresolvable check-in -- exits 1.

- `CheckinBaseline` is self-referential (the walk borrows the resolver, which borrows the log, which reads through the file storage), so it is initialized in place and must not be moved. The open/deinit contract used to rest purely on each call site placing its `defer` correctly; an `opened` flag now makes that invariant assertable, and both `deinit` and the failure path assert it.

- `walkWorkingTree` carries a termination guard against the exact bound (one step per managed path, one per effective file), plus a per-iteration progress assertion, because correctness of the merge rests on every switch arm advancing exactly one cursor. Debug-only, alongside the existing debug-only assertion that the managed set is sorted.

- `--help` no longer defers edited-file detection. It documents the three row classes and narrows the deferral text to the two cases that genuinely remain out of scope: a file deleted from the check-in but no longer tracked, and untracked "extra" files -- pointing at `zit diff` and `zit extras`.

Test evidence: new e2e coverage pins each acceptance criterion -- an edited tracked file is reported as edited in the born state; a rewrite with identical bytes (mtime bump, same content) is not reported; an executable-bit-only change is reported as edited; a file deleted from the check-in but untracked is still not reported; and a current delta checkout with an absent B-card baseline fails cleanly rather than reporting a false clean tree. The pre-existing e2e that pinned the deferral is replaced by the tests above. The help-text e2es compare against a hand-written expected string, so the `--help` change is pinned too. `zig build` and `zig build test` pass in this worktree after absorbing the sibling add/rm recursion commit (281c0ed815), and the commit is proved against a clean `fossil open` checkout running `zig build` then `zig build test`. check-in: 02d993f860 user: dmestas tags: release-0.1

22:52
Merge release-0.1: Implement add/rm directory recursion through the shipped extras.sweep walk

Lands release step P3-F4-addrm on trunk. `zit add DIR` and `zit rm DIR` were hard errors directing the user to name individual files, which made `zit add .` and adding a source subtree dead ends. The increment makes both verbs recurse: `add DIR` expands over the already-shipped `extras.sweep` of the checkout root rather than introducing a second walker, so the exclusions, the no-follow symlink posture, and the tracked-set subtraction are the ones `addremove` and `clean` already use, with the sweep lazy and memoized so multiple directory arguments still perform one enumeration. `rm DIR` expands over the tracked keys via `ManagedSet.iterate` rather than over the disk, so an already-deleted directory remains forgettable. A single containment predicate, `pathUnderDir`, serves both verbs so the prefix-boundary case cannot diverge between them. Help text and exit-status wording now describe recursion instead of the removed directory error.

Merge evidence: `fossil merge release-0.1` reported no conflicts, updating only src/e2e.zig and src/main.zig; the tree carries no conflict markers (the open-marker occurrences that a grep turns up in src/merge3.zig and src/e2e.zig are that module's own conflict sentinel constant and the tests asserting on it, not merge residue). The merged tree — not merely the branch — was re-verified green on trunk after the merge: `zig fmt --check .`, `zig build`, and `zig build test` all exit 0. `fossil extras` is empty, so the merge adds no file it fails to track.

No borrowed techniques in this change, so no attribution is owed. check-in: fca1e073c2 user: dmestas tags: trunk

Changes