50 descendants of 3c3f9366323ab7a8
|
2026-08-29
| ||
| 20:11 | Fossil's words by default: status rows, ADDED/DELETED/RENAME/REVERT/UNDO lines, blame's user column, a no-op update's checkout line, singular counts (zit#170) check-in: 201202f4c8 user: dmestas tags: trunk | |
| 19:39 | muscle: fourteen more session steps (stash, branch cycle, conflicting merge, undo, help); zig build ux keeps every step's bytes under zig-out/ux (zit#170) check-in: 11b68d9d99 user: dmestas tags: trunk | |
| 19:21 | Prefixes resolve through aliases and name the shortest spelling that works; verb help lists its aliases (zit#170) check-in: bb2f45e4ff user: dmestas tags: trunk | |
| 18:27 | Receipts: commit summary and content notes, undo per-file rows, stash file names, revert undo hint, short hashes in update (zit#170) check-in: 69f708db73 user: dmestas tags: trunk | |
| 17:46 |
listings take Fossil's shape: ls names, leaves lines, day-grouped timeline, annotate line numbers; branch -v (zit#170)
Twelve-character hashes and the weekday in day headers and leaf lines are the departures; -F oneline keeps the one-line timeline for scripts. check-in: 16c197b4dc user: dmestas tags: trunk | |
| 16:57 |
status leads with Fossil's checkout block; changes drops it; bare info adds the count (zit#170)
Twelve-character names and the weekday in the times are the only departures from Fossil's shape. cli.shortHash and cli.humanTime are the primitives the rest of the terminal-speech work builds on. check-in: d72b6372ab user: dmestas tags: trunk | |
| 15:33 |
info with no NAME describes the current check-in; revert names only the files it changes
Both found by running one session through fossil and zit side by side. check-in: a0690841c1 user: dmestas tags: trunk | |
| 14:40 |
update: with no CHECKIN move to the branch's newest check-in, as Fossil does
A bare 'zit update' was a usage error; Fossil's means --latest. check-in: b618fc675d user: dmestas tags: trunk | |
| 12:44 |
logstore: putArtifactPreferring takes a known base before searching (zit#169)
The converter's hints are the source's own chains and each manifest's parent, so one delta usually settles it; the best-of-N window is the fallback. Conversion is now faster than the old convert-then-pack. check-in: 598d040de5 user: dmestas tags: trunk | |
| 12:04 |
import-fossil --submanifest: delta-encode the converted store as it is written (zit#169)
Blobs take the flat source's own delta base as the hint, manifests their parent, carried artifacts the recent window. A 28x full-form gap on a toy corpus became 1.3x of packed, with no second pass and no double-disk peak. check-in: 38b9743ff8 user: dmestas tags: trunk | |
| 10:18 |
release: prepare zit 0.3.0
Fossil parity on the everyday verbs, landings and strata, protected branches behind a trusted front, Fossil's user table, and the read paths that now scale with the change rather than the store. check-in: 1e2a7bbc0d user: dmestas tags: trunk, version-0.3.0 | |
| 09:26 |
ui launches quarry's local mode (zit#165, quarry RFC 0010)
Runs quarry ui on the checkout root with the terminal inherited; the binary comes from ZIT_QUARRY or PATH, and an absent one is a three-line pointer, exit 1. check-in: 95553946e3 user: dmestas tags: trunk | |
| 09:07 |
diff --by, timeline -F html, and a reserved ui verb (zit#165)
--by writes a side-by-side page under $TMPDIR and opens it from a terminal; -F html renders the timeline as a table; ui names quarry's local mode and exits 1 until it exists. check-in: 87f4be2914 user: dmestas tags: trunk | |
| 08:46 |
settings editor and autosync pullonly, --changed/--value; grep -i -c -l -v --once; annotate -n -l (zit#164)
The two new settings ride the keyed config block; a configured editor makes commit editor-capable without a terminal. check-in: 7d9dcb2de1 user: dmestas tags: trunk | |
| 07:53 |
stash: snapshot, diff, goto, and apply --merge (zit#164)
--merge three-way merges a stashed change into a dirty file; conflicts get markers, are listed, and exit 5 with the entry kept. check-in: 21ce2c785d user: dmestas tags: trunk | |
| 07:35 |
merge: --integrate, --baseline, -n, and a bare merge onto the one other leaf (zit#164)
The checkout record carries the integrated leaf's hash as an optional sixth field; commit closes it with the same control artifact branch close mints. check-in: 2a522aab40 user: dmestas tags: trunk | |
| 07:01 |
diff: PATH operands, --numstat, --invert, --checkin, --branch (zit#164)
-Z is -w; -N is accepted (an added file's hunks already carry it all). check-in: 39c88046ab user: dmestas tags: trunk | |
| 06:35 |
mv takes many operands and directories; revert -r/-n, undo -n (zit#164)
The managed set records one pending rename per moved file. mv moves files into a directory or a tracked directory as a unit, --soft records without moving, -n previews. revert -r VERSION restores another check-in's content; revert/undo/redo -n name what they would touch. add -f takes ignored files; clean gains -n/-f and --emptydirs. check-in: ece16d74a9 user: dmestas tags: trunk | |
| 05:30 |
branch sub-verbs; clone opens its tree, open URL clones (zit#164)
branch new/close/reopen/hide/unhide/current/info. clone DIR defaults from the URL and is followed by open (--no-open keeps the bare store); open URL delegates to clone. check-in: 5d2f9a7e6e user: dmestas tags: trunk | |
| 03:36 |
timeline filters and formats, status classification, -R for the sync family
timeline gains -b/-c/-p/-u filters, -r and --offset, -F medium|full (a date header per day, *CURRENT* on the checkout's check-in, user and tags) and -v for changed files; the default line is unchanged. status gains --classify (Fossil's words, aligned), --added/--edited/--missing/--conflict/--extra/ --differ filters, -v's header block, CONFLICT for an edited file still carrying markers under a pending merge, and MERGED_WITH. pull, push, sync and remote accept -R, so a bare mirror needs no working tree. current/ ckout/prev/next take effect in these verbs through the same hint. Refs zit#163. check-in: 6c84f304f4 user: dmestas tags: trunk | |
| 02:33 |
Everyday verbs: update receipt, network narration, commit editor, checkout-relative names
update prints Fossil's receipt on stderr (per-file UPDATE/ADD/REMOVE/MERGE/ CONFLICT, the from/to block, the undo hint) and gains -n, --latest and -v. Every sync-family line names the peer, a no-op is always 'already in sync', clone prints the project code, an unreachable peer is named, and pull/push/ sync show per-round progress on a terminal. commit takes -M FILE, composes the comment in $VISUAL/$EDITOR/--editor over a template of the change set (kept in .zit-ci-comment when the commit then fails), and gains -n and --allow-empty; --no-warnings is accepted as Fossil's spelling of --no-checks — the content gate stays opt-in by design. The names current/ ckout, prev/previous and next resolve against the checkout. The muscle harness now enforces all of it. Closes zit#157, zit#158, zit#159, zit#160, zit#161. check-in: e5beabd7c0 user: dmestas tags: trunk | |
| 00:59 |
fossil-muscle-memory: a differential transcript through fossil and zit
zig build muscle runs one scripted session — 27 lines a Fossil user types most — through the real fossil and the real zit against local servers, and compares each step's exit-status class and whether the verb spoke at all. Deliberate divergences carry their reason, known gaps carry their issue; anything else fails the run. CI runs it beside smoke. Closes zit#162. check-in: 741f6d428b user: dmestas tags: trunk | |
| 00:59 |
Verb prefixes, Fossil aliases, and a suggester that never says 'rm'
Any unambiguous prefix of a command dispatches (zit up, zit tim); an ambiguous one names its candidates; an exact verb always wins, so stat stays the store census. Aliases: ci/checkin, co/checkout, changes, delete/forget/ remove, rename, blame/praise, new. A token of three letters or fewer is only suggested at edit distance 1, and an unknown verb prints two lines, never the command list. Closes zit#156. check-in: e114f7a174 user: dmestas tags: trunk | |
|
2026-08-28
| ||
| 21:29 |
import-fossil --submanifest: read and parse each baseline manifest once
repo.files re-read and re-parsed the B-card baseline for every delta check-in — 79% of the mint phase on pkgsrc. Repository.filesMemo takes a caller-owned BaselineMemo keyed by artifact name; consecutive deltas over one baseline borrow the parsed manifest and read nothing. On a 30k-file history of 300 deltas, source enumeration went from 10s to 0.3s and the conversion from 13.5s to 3.7s, every check-in hash identical. The memo holds a heap entry with a stable address; the optional-by-value form did not persist under ReleaseFast. Closes zit#167. check-in: c80728261e user: dmestas tags: trunk | |
| 16:04 |
submanifest convert, and import-fossil --submanifest straight from a fossil URL
The rebirth arm of import-fossil required a zit store, so the verb that says 'import a fossil' could not take one. It now accepts the fossil's sync URL like --compatible does, cloning a transient flat store beside DIR and removing it after; a local store stays accepted. The zit->zit conversion gets its proper home as 'zit submanifest convert SRC DEST', beside 'enable', which now says what it does not do: existing check-ins stay flat, and fossil peers receive nothing new from the next commit. Diagnostics carry the verb the operator typed. Closes zit#168. check-in: abd850dc4c user: dmestas tags: trunk | |
| 03:59 |
import-fossil --submanifest: drop the whole-history replay gate and --force
The gate replayed every commit through the from-scratch tree builder three times to predict what the conversion itself measures, and on pkgsrc that was 14 of 26 hours before a byte was written. The conversion writes a new project beside an untouched source, so the honest evidence is the converted store: the summary now reports its bytes against the flat source's. The partition parameter comes from --k or the tip sweep; a history no k partitions is refused, as 'submanifest enable' refuses it. 'zit submanifest analyze --replay-all' keeps the model for anyone who wants it first. Closes zit#129. check-in: 04d944c1dd user: dmestas tags: trunk | |
| 01:56 |
import-fossil --submanifest: build each check-in's tree from its parent's with the sub-manifest editor
Every check-in went through artifact.buildTree from scratch, so a wide tree cost its whole file set per commit against a few changed slices actually written. The converter now applies each check-in's change set over its primary parent's root with TreeEditor — the commit verb's builder — keeps a parent cache released as children consume it, interns the retained cards, runs the pair proof through the run-scoped flatten memo, and parses each source manifest once. The Git importer's LogTreeStore moves to a shared module. Output is unchanged: every check-in hash matches the from-scratch build on libfossil and on a 30k-file synthetic history. Refs zit#167. check-in: 5e0155427e user: dmestas tags: trunk | |
| 01:00 |
import-fossil --submanifest: strip SSH signatures, verify per pair in the mint loop, fold the census into pass 1, skip the replay under --k --force
The converter only stripped PGP armor, so an SSH-signed check-in re-minted with its envelope inside and failed its own verify silently. Verification now runs as each pair is minted, the census counts come from the first pass instead of a second corpus read, and --k narrows the gate's replay to one arm (skipped with --force). Each phase reports its wall time on stderr; the summary points at 'zit pack'. Closes zit#155. check-in: 75c8669553 user: dmestas tags: trunk | |
|
2026-08-27
| ||
| 20:02 | merge settings-config-repo-flag-153: accept -R on a bare store for settings and config (#153) check-in: 26ed9cbc86 user: dmestas tags: trunk | |
| 19:00 |
settings, config: accept -R on a bare store
Their repository and global tiers, and config's user/shun areas, all live in the store, not the working tree -- fossil serves them under -R too. Move both out of the -R blanket refusal, resolve the override, and name a bad -R path with the #97 diagnostic rather than the discovery message that advises the flag already given. Issue #153. closed check-in: b342686fd9 user: dmestas tags: settings-config-repo-flag-153 | |
| 11:04 |
landing: update -- bring the target into the proposed branch on the store
The reverse of accept, through the same ephemeral-checkout merge, now one function that does not know which direction it runs. Always merges in a working area of its own, checkout or not, so a tree is never left half-merged. Up to date is exit 0 with nothing written; a conflict is refused with its paths; a settled record is refused; a stacked landing is not, since refreshing a rung is what the rungs above it need. The refresh is a reply in the record's thread. Issue #152. check-in: c4b949ebbf user: dmestas tags: trunk | |
|
2026-08-26
| ||
| 19:43 | merge serve-protected-branches: per-request branch protection behind a trusted front (#151) check-in: d46cb9a855 user: dmestas tags: trunk | |
| 16:57 |
serve: refuse a check-in's own singleton claim on a protected name; warm the image only after a push
A self-targeted +sym-B is not how a branch is joined, but nothing legitimate mints one on a protected name. maintain now derives the fast-read image only when the log grew, so a pull-heavy fronted server does not pay an image load per connection. Pins that a merge with a protected secondary parent stays on its primary's branch. Issue #151. closed check-in: 13760d0c92 user: dmestas tags: serve-protected-branches | |
| 16:14 |
serve: refuse membership changes to protected branches, per request, from a trusted front
A front that authenticates every push knows who is pushing; the store knows which branch a pushed check-in resolves to. The front sends only the rule -- X-Zit-Protect, a glob list -- and zit serve --fronted refuses the whole round when a check-in would join one of those branches or a tag would move a held check-in in or out of one. Same error card as a content-policy refusal, so a stock fossil client reads it. Without --fronted the header is ignored and the server is unchanged. Nothing new on the wire or in the repository. Resolution is crosslink's own, through the fast-read image, which maintain keeps warm between connections. A parent not yet held is admitted: it is judged on arrival. Resolver faults fail closed. Issue #151. check-in: 63ec7d6dc8 user: dmestas tags: serve-protected-branches | |
| 14:35 | merge landing-reply-to-149: --reply-to aims a landing comment's I-card (#149) check-in: 2892f40e8b user: dmestas tags: trunk | |
| 14:05 |
landing: --reply-to aims a comment's I-card at a post, not just the root
comment collapsed the G and I cards onto the record root, so a landing thread could not branch. Split mintForum's root and reply-to; landing comment takes --reply-to POST, resolving the thread root with the same helper forum uses and refusing a target outside the record's own thread. closed check-in: fed51b20cb user: dmestas tags: landing-reply-to-149 | |
|
2026-08-25
| ||
| 21:19 | merge rfc-vector-guard: vectors inert on disk check-in: ca7453995e user: dmestas tags: trunk | |
| 21:09 |
rfc vectors: keep them inert on disk
An unguarded vector parses as a real artifact, so Fossil crosslinks it into every clone -- two check-ins, a technote, twelve sub-manifest slices and a phantom pair that sync chases forever. Each vector now carries a leading # block; rfc_vectors.zig strips it at comptime so callers still see the exact RFC bytes. Background and the cleanup that follows: see wiki page 'rfc-vector-ledger'. closed check-in: 32ef56aaf4 user: dmestas tags: rfc-vector-guard | |
| 18:50 | merge fix-148-prefix-lookup: byte-aligned name lookup (#148) check-in: 3f8aa36a1d user: dmestas tags: trunk | |
| 18:30 |
logstore: answer a byte-aligned name prefix from the sorted directory
A complete SHA-1 name is shorter than max_hash_len, so it missed the full-width fast path and fell to the O(store) hex scan -- once per file under `ls --size` and `ls --long`. On tcl's tip the 545 SHA-1 named files cost ~54ms each against ~0.2ms for the 1,653 SHA3 ones. The directory is ordered by raw digest, so a prefix's matches form one contiguous run. A binary search for the run plus a walk of it proves uniqueness rather than assuming it, which is what the SHA-1 case was surrendered to the scan for. Odd-length prefixes end mid-byte and keep the scan. ls --size on tcl: 1.98s -> 0.03s. Issue #148. closed check-in: 4829f043b1 user: dmestas tags: fix-148-prefix-lookup | |
|
2026-08-24
| ||
| 21:41 | merge strata: stacked landings (#144) check-in: 2e060aa7c0 user: dmestas tags: trunk | |
| 20:23 |
landing: pin the stack-depth bound the indent trusts
The cycle panic was in the indent computation, and rewriting it made the panic go away without my being able to explain the arithmetic -- 32*2 into a 64-byte buffer should not overflow. This asserts the bound directly, so the renderer's assumption is checked rather than believed. closed check-in: 5a35874240 user: dmestas tags: strata | |
| 20:10 |
landing: cycles, unresolvable targets, and already-contained branches
Three holes found by walking the scenario space rather than the happy path. A retarget could make a cycle. Every segment in one then refuses forever, each waiting on the next, and 'ls' panicked outright computing an indent for a chain with no bottom. Cycles are now refused, direct and indirect. A retarget accepted a branch name that does not resolve, minting a permanent record aimed at nothing -- the check 'open' has always made before minting one. A branch already contained in its target reported 'did not merge cleanly; resolve and commit'. There was nothing to resolve: 'merge' had said 'already up to date'. The record could then only be closed by rejecting it, recording the opposite of what happened. It now settles as accepted with no merge, which is what is true. Reachable from a stack by landing the top segment first -- it carries the ones below it in. check-in: b450374bce user: dmestas tags: strata | |
| 19:17 |
landing: refuse a landing whose base was rejected or already landed
The ordering guard only looked for an OPEN base, so a rejected one slipped through and the accept SUCCEEDED -- 'accepted seg2 -> seg1', filing the work on a branch nobody would land. Nothing failed and nothing warned; the merge is fine, which is why only a rule catches it. Same hole for a base that already landed, reachable when the auto-retarget after that accept did not run. All three cases now refuse and name the retarget that fixes them. Documented the half of this that surprises: rejecting a landing rejects the proposal, not the code beneath a segment stacked on it. That branch descends from the rejected one and still carries its check-ins, so landing it on trunk lands them too. check-in: f91105346b user: dmestas tags: strata | |
| 18:52 |
landing: close the landed leaf without propagating
The propagating form marked every segment ABOVE a landed one closed too: in a stack those check-ins descend from the landed tip, so propagation followed the DAG straight into work that was still open. The landing records stayed open and correct; only 'branch' and 'leaves' lied, which is exactly where you look for what still needs doing. Fossil's own propagating close is safe because it closes a check-in with no descendants. A landed segment is a leaf by the same-branch rule while still having children on the branch above it. check-in: d97b39b272 user: dmestas tags: strata | |
| 18:46 | merge: hardware crc32 and index v3 sorted directory (#143, #145) check-in: 2a676a5df1 user: dmestas tags: trunk | |
| 18:33 |
logstore: index v3 carries a sorted directory, so opening builds no hash map
Adopting an index inserted every entry into a StringHashMap before answering anything: 255,167 keys on a 302MB store, to serve the one or two lookups a tree listing makes. Measured at 5.5ms of a 24ms open by building the map twice and taking the delta. v3 appends entry_count little-endian u32 rids ordered by digest, and lookup binary-searches it -- ~18 comparisons against a quarter-million insertions. Opening tcl drops 24.0ms to 20.0ms; with the hardware crc32 change before it, 38.5ms to 20.0ms. Output byte-identical. The directory carries RIDS and the entry records stay in scan order. Sorting the entries themselves would renumber every rid, and ancestry, phantom snapshots and the sync walk all read that numbering. lookup consults the map first, then the directory: entries appended after adoption -- a tail resume past the index boundary, and every write on a scan-path store -- are only in the map. Every held-check that was reading index.get directly now goes through lookup, because intern runs during a tail resume and a miss there mints a duplicate entry for a digest already held. A v2 sidecar is refused and rewritten rather than adopted, as v1 was: adopting one would leave lookup with neither a map nor a directory and answer null for held artifacts. Pinned by a test that downgrades a v3 blob and re-checksums it. The tests pin what equality cannot: that the map is EMPTY after adoption and every digest still resolves, that a digest which is not held returns null rather than a neighbour -- the failure a binary search has and a map does not -- and that digests written out of sort order still resolve, so a directory that merely mirrored insertion order would fail. Closes #145 closed check-in: 0d16bc966d user: dmestas tags: index-v3-145 | |
| 18:16 |
landing: close the branch an accepted landing lands
Every landed branch stayed an open leaf, which was survivable one landing at a time and is not with stacks: a six-deep stack left seven leaves, and 'leaves' is how you find work that still needs doing. accept now writes fossil's propagating 'closed' tag on the branch it merged. reject does not -- a rejected branch is one the author may revise and propose again, and closing it would decide that for them. Best-effort and last, like the retargets: a leaf that stayed open is untidy, never incorrect, and the diagnostic names the command that fixes it. check-in: c9b0147381 user: dmestas tags: strata | |
| 17:53 |
crc32: fold with ARMv8's crc32 instruction where the target has it
Checksumming was half the cost of opening a repository: 18.8ms of a 37ms `ls` on a 302MB store, across the two sidecars (26.3MB derived-state image at 13.5ms, 9.7MB log index at 5.3ms). Both measured by doubling the work and taking the delta, so the number is the checksum and not its neighbours. ARMv8's crc32b/crc32x implement CRC-32/ISO-HDLC -- the same generator this file is already defined in terms of, in the same reflected convention -- so this is an instruction-count change and never a value change, which is what the module doc says every edit here must be. tcl opens in 24.5ms against 38.5ms, output byte-identical. aarch64 only, deliberately. x86_64's SSE4.2 crc32 instruction is CRC-32C/Castagnoli, a DIFFERENT generator; taking it because the mnemonic matches would orphan every store already written. x86_64 keeps the table path, which stays load-bearing rather than becoming a fallback nobody runs. The new test recomputes CRC-32 as a plain bit-at-a-time recurrence, independent of update and its tables, and holds both paths to it at every length 0..1024 -- all eight residues mod 8, including the lengths below the fold width. The two paths differ only in where the fold stops and the tail begins, so a divergence would appear at particular residues and nowhere else, which is the shape a spot check misses. Chunked updates are pinned too: the store checksums payloads in 4 KiB pieces, so a path correct only for single-shot input would corrupt exactly the largest artifacts. Refs #143 closed check-in: b82aacc805 user: dmestas tags: crc-hardware-143 | |
| 17:40 |
landing: stacked landings (strata)
A landing may target another branch that has its own open landing; that pair is a stack, read from the targets rather than recorded anywhere. No new card, no dependency field -- the edge is already implied. Stacks land bottom-up. accept refuses a landing whose target has its own open landing, and accepting one retargets whatever was stacked on it onto the branch it just landed on. That is the whole restack: a metadata write per child, because a segment's branch already descends from the one below it, so after that lands the merge sees only the segment's own change. Adds 'landing retarget', a target reply resolved by the same latest-wins rule as a state transition. ls indents a stack by depth; show names what a segment sits on, what sits on it, and when its base was rejected. Verified six deep on a shared file, which is the depth the design claim was previously only reasoned about. check-in: 3767f1eafc user: dmestas tags: strata | |
| 16:50 | merge index-borrow-143: adopted index entries slice the blob (#143) check-in: 3c3f936632 user: dmestas tags: trunk | |