Files in the top-level directory from the latest check-in of branch trunk
zit
A Fossil version-control system in Zig.
zit reads and writes Fossil's artifacts and speaks Fossil's sync protocol, so
it clones from, pushes to, pulls from, and serves stock fossil, and a
checkout means the same thing to both tools. It is written from the
specifications, not ported from C: six Internet-Drafts frozen in
docs/rfcs/ are the authority, and Fossil itself appears only
in the differential tests that hold the two implementations to the same
answer.
The zit binary is a thin command over a library — a Zig counterpart to
libfossil. No module touches ambient time, randomness, filesystem, or network;
effects arrive through injected interfaces, the sync client is a pure state
machine, and the whole stack runs under seeded deterministic simulation where
any failure replays exactly from its seed.
Download
Release binaries for macOS ARM64 and Linux x86-64/ARM64, with checksums and a
source archive, are at
fossil.craftdesign.group/zit
and mirrored to GitHub releases.
Each release has notes under docs/.
What it does
The everyday verbs — init, add, commit, update, merge, diff,
status, timeline, branch, tag, annotate, grep, bisect, stash,
undo/redo, clone, push, pull, sync, serve — with Fossil's output
shapes and Fossil's settings: .fossil-settings/ is read at every tier, and
ignore-glob, clean-glob, manifest, and the rest mean what they mean in
Fossil. zit help lists everything; any unambiguous prefix of a verb works.
Beyond that:
- Git in both directions —
import-gitandexport-git, each checked against a realgitin the differential suites. - Sub-manifests (
draft-fossil-submanifests-00) — S-card tree manifests bound per-commit manifest size on wide repositories, with adoption tooling that replays the repository's own history to measure whether enabling pays (submanifest analyze/enable;import-gitpicks a k the same way). This is the one compatibility break. A repository that emits S-bearing artifacts is permanently unreadable by stock Fossil, and sync's peer-version gate refuses to send trees to a pre-S peer rather than hand it artifacts it would misread. Emission is off by default; enabling it states the spend. - Sparse cones (
draft-fossil-sparse-cone-00) — partial worktrees (open --cone,cone). - Indexer feeds —
framesandcrosslinkstream raw artifacts and derived per-check-in records from a cursor, for a forge or a search index;infoanswers many names in one call, as text or JSON. - Store care —
verify(fsck),pack,purge,shun, and a local, disposable rebuildcheckpointthat keeps cache-cold opens fast on large histories. Never stored in the repository, never synced. - Review records —
landingproposes a branch to land on trunk as a reviewable record;precedentreuses a remembered conflict resolution.
What it leaves to Fossil
By decision, not omission — zit is a version-control system, not a forge.
- The collaboration layer. Wiki, tickets, forum, technotes, and
attachments are carried opaquely — stored and synced by hash, never
interpreted. The web UI goes with them:
zit uihands the checkout to a forge that serves it. - Unversioned files. No
uvverb and no unversioned store. The uvfile sync vocabulary is fully parsed and content-verified on the wire, and a peer's unversioned files are declined visibly — the session completes and reports how many were not transferred. - Manifest signing. Signature wrappers are recognized and stripped on read; zit never signs what it commits.
- SHA-1 repository creation. SHA-1 history clones and reads fine;
zit initwrites the sha3-256 naming policy only. - Delta-manifest authoring on fresh repositories. A repository whose history carries delta manifests keeps its dialect; a flat repository stays flat.
The specifications
The drafts are the authority, not Fossil's source. Test expectations come
from the spec text and its worked examples — every normative clause a module
implements gets a test citing its section. Where the code deliberately
follows Fossil's implemented behaviour against the published draft text, the
divergence is recorded in docs/rfcs/erratum/.
| Module | Draft | What it specifies |
|---|---|---|
delta |
draft-fossil-delta-format-00 |
byte-level delta encoding |
artifact |
draft-fossil-artifact-format-01 |
manifest / control-artifact card format, naming, checksums |
repostate |
draft-fossil-repo-state-01 |
derived branch / tag / leaf / current-trunk views |
submanifest |
draft-fossil-submanifests-00 |
S-card tree manifests: bounded per-commit manifest size for wide repositories |
sync |
draft-fossil-sync-protocol-01 |
HTTP sync / clone protocol |
cone |
draft-fossil-sparse-cone-00 |
sparse cones: partial worktrees, the sparse-store path for monorepos |
Build
Requires Zig 0.16 or later.
zig build --release=fast # the shipped binary, at zig-out/bin/zit
zig-out/bin/zit version
zig build test # unit tests, one cited test per RFC clause
--release=fast is what the release builds use; a plain zig build is a
Debug binary, many times slower on a real history.
Further steps: zig build e2e (spawns the real binary), smoke (interop
against a fossil on PATH), muscle (differential transcript against
fossil), git-import-e2e / git-export-e2e (against a real git), dst
(deterministic simulation; -- --seed N replays), fuzz -- <target> --seed N,
bench, and cov (kcov line coverage). zig build --help lists them all.
Source control
This project is itself under Fossil. The repository lives in .zit.fossil
(ignored); open a checkout with fossil open --keep .zit.fossil. Trunk is
mirrored to GitHub, where issues and CI
live.