Artifact 2f9f587dba3a716f4270a83037def2cc5b965bf5a384b7cc73470cbedd7c6b83:
- File
src/root.zig
— part of check-in
[5c445bb3f3]
at
2026-09-28 02:39:03
on branch trunk
— Take the writer lock inside LogStore.open and test the lock class
LogStore.open now takes the exclusive lock before it reads the file's length and scans for the end, and a read-only handle refuses to append. purge undo opens the store through the shared writer path.
A new DST sweep runs two to four writers interleaved against one log through a file that models the lock. It flags unlocked or misplaced appends as they happen, checks each writer sees everything committed before it locked and reads back its own writes, including deltas. A source check fails on any write-mode open of the store outside openStoreAppend. An e2e test races commits, tags and user-table writes on one store and counts what landed. (user: dmestas, size: 11484) [annotate] [blame] [check-ins using]
//! zit — a Fossil version-control system implemented in Zig. //! //! zit is a direct port of the Fossil formats and protocol as specified by //! four companion Internet-Drafts, kept in `docs/rfcs/`: //! //! * delta — draft-fossil-delta-format-00 (byte-level delta encoding) //! * artifact— draft-fossil-artifact-format-00 (manifest/control-artifact cards) //! * reposta.— draft-fossil-repo-state-00 (derived branch/tag/leaf/trunk views) //! * sync — draft-fossil-sync-protocol-00 (HTTP sync/clone protocol) //! //! Implementation order follows the RFC dependency layering: //! delta -> artifact -> repostate -> sync //! //! Each module cites the section of its RFC that governs a given rule. const std = @import("std"); /// The §4.1 zlib container codec — a leaf below delta/artifact/repostate/sync, /// the single home for the container framing those layers store and transmit. pub const container = @import("container.zig"); pub const delta = @import("delta.zig"); pub const artifact = @import("artifact.zig"); pub const rfc_vectors = @import("rfc_vectors.zig"); pub const repostate = @import("repostate.zig"); pub const sync = @import("sync.zig"); pub const control_paths = @import("control_paths.zig"); pub const cone = @import("cone.zig"); pub const repocache = @import("repocache.zig"); pub const clusterindex = @import("clusterindex.zig"); pub const attachstub = @import("attachstub.zig"); pub const fileindex = @import("fileindex.zig"); pub const sparse = @import("sparse.zig"); pub const managed = @import("managed.zig"); pub const ignore = @import("ignore.zig"); /// Content classification (fossil's `lookslike.c`), shared by the /// commit gate and the push gate so the two cannot disagree about a file. pub const lookslike = @import("lookslike.zig"); pub const graveyard = @import("graveyard.zig"); pub const purge = @import("purge.zig"); pub const settings = @import("settings.zig"); /// The fully populated `.fossil-settings/` fixture the e2e /// and fossil-interop smoke lanes both build, kept in one place so the two /// cannot drift apart. pub const settings_fixture = @import("settings_fixture.zig"); pub const archive = @import("archive.zig"); /// The persistence layers, folded into the one embeddable `zit` module so a /// library consumer wires a single dependency instead of five peers: the /// content-addressed on-disk file (`storage`), the framed append-only log over /// it (`logstore`), the `.zit-checkout` working-state record (`checkout`), and /// the working-tree materializer (`update`). Circular file-level imports among /// these and the per-RFC modules are legal within one module; only cross-module /// edges may not cycle. pub const storage = @import("storage.zig"); pub const logstore = @import("logstore.zig"); pub const publication = @import("publication.zig"); /// Importer modules cross the executable/library module boundary. Zig module /// privacy requires exporting them here so the CLI and embedders share one set /// of type identities instead of compiling duplicate file modules. pub const git_fast_export = @import("git/git_fast_export.zig"); pub const git_import = @import("git/git_import.zig"); pub const git_export = @import("git/git_export.zig"); /// The import benchmark's compile-time specialization seam, exported so the /// benchmark root (src/git/, cannot import above its module root) reaches it /// through the module without double-claiming the implementation files. pub const git_import_benchmark_support = @import("git/git_import_benchmark_support.zig"); pub const submanifest_editor = @import("submanifest_editor.zig"); pub const log_tree_store = @import("log_tree_store.zig"); /// The CLI parser surface, exported so the git-interop test roots — which /// live in src/git/ and therefore cannot import above their module root — /// reach it through the module like every other parent-level dependency. pub const cli = @import("cli.zig"); /// The vendored CRC-32/ISO-HDLC every on-disk checksum in the store is defined /// in terms of. Exported for the same reason `storestat` is: the benchmark that /// measures the checksum must measure the one the product actually runs, and a /// file can belong to only one module — so `warmread_benchmark.zig` cannot /// import it by path. Not a promise about the algorithm; the guarantee is only /// that it is bit-identical to `std.hash.Crc32`, which the formats already fix. /// /// NOT a precedent for exporting other leaf modules — the default stays the one /// `repocache.zig` sets, which is no export. This line is forced rather than /// chosen: `crc32.zig` is a `zit` member (`logstore`, `repocache`, `bisect` and /// `undo` all import it by path), and its two out-of-module consumers — the /// benchmark's `phaseCrc` and `crc32_fuzz.zig`'s differential-against-std lane, /// both of which live in their own root modules — have no other way to reach /// it. `@import("crc32.zig")` from either is `error: file exists in modules /// 'zit' and 'root'`. Reverting this export does not close the surface; it /// deletes the only benchmark of the hot checksum and the only test in the tree /// that diffs against an outside oracle. Add an export here only when a leaf /// module acquires an out-of-module consumer with the same no-alternative /// shape. pub const crc32 = @import("crc32.zig"); /// The `.zit-stash` sidecar — `zit stash`'s durable local storage. pub const stash = @import("stash.zig"); /// The `.zit-precedent` sidecar — remembered conflict resolutions. pub const precedent = @import("precedent.zig"); /// Line-oriented unified diff (patience alignment) — `zit diff`'s textual /// hunks. A leaf: no RFC anchors it, nothing below `std` feeds it. pub const textdiff = @import("textdiff.zig"); /// The store's own byte accounting — the single physical frame walk behind /// both `zit stat` and the storage benchmark, so the two can never drift into /// reporting different totals for the same file. pub const storestat = @import("storestat.zig"); pub const checkout = @import("checkout.zig"); pub const update = @import("update.zig"); pub const bisect = @import("bisect.zig"); /// The `zit pack` re-deltification pass (storage-delta-base-selection.md §6): /// the pure store-to-store generational rewrite that re-bases every artifact /// through `logstore`'s `pickBase` policy. In the module so the CLI wiring /// (main.zig) and the DST/fuzz harnesses drive the identical transform. pub const pack = @import("pack.zig"); /// The repository facade — the deep module the north star names as the public /// repo surface: open a repository, resolve a name, read the derived view, list /// and cat content. `repoview` (the derived-view loader) is re-exported as its /// public collaborator; `repocache` stays library-internal, reached only /// through `Repository`. pub const Repository = @import("repository.zig").Repository; /// The §9.3 seam adapter: a manifest's file surface for `artifact.enumerate`. pub const manifestFilesOf = @import("repository.zig").manifestFilesOf; pub const repoview = @import("repoview.zig"); /// The durable rebuild checkpoint's operator surface (`zit checkpoint`): /// `build`/`verify`/`drop`/`tryLoad` and their report types. The container /// format itself stays module-internal. pub const checkpoint = @import("checkpoint.zig"); /// The zero-parse read image — the materialized hot query answers a warm read /// reloads without re-deriving. Re-exported for the simulation harness, which /// pins the round-trip property (a materialized image is query-equivalent to /// the derived state it was made from). pub const repoimage = @import("repoimage.zig"); pub const repo_filename = @import("repository.zig").repo_filename; /// draft-fossil-submanifests-00 §6.3/§8.1 — the writer-side sub-manifest /// settings, the emission decision they determine, and the §6.3 analysis pass /// that measures k. Beside the repository facade, not inside `RepoView`: see /// the namespace's own doc comment for why the derived view is the wrong home. pub const submanifest = @import("repository.zig").submanifest; /// Suite version of the specifications this implementation targets. pub const rfc_revision = "00"; test { _ = cli; // the parser lives in this module now; its inline tests ride along _ = @import("settings.zig"); _ = @import("lookslike.zig"); _ = @import("archive.zig"); // Aggregate every module's tests into the library test binary. _ = @import("container.zig"); _ = @import("clusterindex.zig"); _ = @import("attachstub.zig"); _ = @import("fileindex.zig"); _ = @import("textdiff.zig"); _ = @import("stash.zig"); _ = @import("precedent.zig"); _ = @import("container_test.zig"); _ = @import("delta.zig"); _ = @import("delta_test.zig"); _ = @import("artifact.zig"); _ = @import("artifact_test.zig"); // Importer foundation tests remain test-only; none of their private // implementation modules enter the shipped `zit` API. _ = @import("submanifest_editor_test.zig"); _ = @import("git/git_fast_export_test.zig"); _ = @import("git/git_fast_import_test.zig"); _ = @import("git/git_export_state_test.zig"); _ = @import("git/git_export_test.zig"); _ = @import("repostate.zig"); _ = @import("repostate_test.zig"); _ = @import("sync.zig"); _ = @import("sync_test.zig"); _ = @import("managed.zig"); // The folded store layers and their sibling public-surface test files. _ = @import("storage.zig"); _ = @import("logstore.zig"); _ = @import("logstore_test.zig"); _ = @import("storestat.zig"); _ = @import("pack.zig"); _ = @import("checkout.zig"); _ = @import("update.zig"); _ = @import("update_test.zig"); // The repository facade and its derived-view collaborators. _ = @import("repoview.zig"); _ = @import("repoimage.zig"); _ = @import("repocache.zig"); // The vendored CRC-32/ISO-HDLC the storage formats are checksummed with. _ = @import("crc32.zig"); _ = @import("repository.zig"); _ = @import("repository_test.zig"); // The durable prefix checkpoint (`.zit-cache/checkpoint`) and its suite. _ = @import("checkpoint.zig"); _ = @import("checkpoint_test.zig"); // The checkout-local bisection state module (`.zit-bisect`). _ = @import("bisect.zig"); // The purge graveyard (`.zit-graveyard`) and the drop-set plan that // decides what a purge removes. _ = @import("graveyard.zig"); _ = @import("purge.zig"); // Structural pins over the shipped source distribution (LICENSE, the // package manifest's `.paths`, the versioned ignore-glob). _ = @import("packaging_test.zig"); // Structural pins over the CI workflow (the battery it runs, the pinned // toolchain, and the build steps it deliberately skips). _ = @import("ci_test.zig"); // Structural pins over the embedded command reference (www/reference.html). _ = @import("reference_test.zig"); _ = @import("readpath_test.zig"); // The dead-file guard: every src/**/*.zig must be reachable from a test root, // so a moved file cannot silently stop running its tests. _ = @import("tidy.zig"); // The release-assert guard: no NEW `std.debug.assert` may stand in for // validation of untrusted input in a `pub fn` that returns an error union. _ = @import("release_assert_test.zig"); _ = @import("store_write_guard_test.zig"); }