.
D 2026-10-13T03:08:19.728
L Home
N text/x-markdown
P 4e9c857510dba6853f339221c69fd201c59a007c96c7b3ec867611a1be96a9fa
U dmestas
W 5905
# 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 this
repository 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 — whose modules take no ambient time, randomness, filesystem, or
network, so the whole stack runs under seeded deterministic simulation.
## Download
[Download Zit 0.4.0 for macOS ARM64 or Linux x86-64/ARM64, or get the source archive](uv/download.html?v=0.4.0), or read the [release notes](doc/version-0.4.0/docs/RELEASE-NOTES-0.4.0.md).
Releases are also mirrored to [GitHub](https://github.com/danmestas/zit/releases).
## 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, `ignore-glob`, `clean-glob`, `manifest`, and the rest mean
what they mean in Fossil.
Beyond that:
* **Git in both directions** — `import-git` and `export-git`.
* **Sub-manifests** — bounded per-commit manifest size for wide
repositories (`submanifest analyze` / `enable`). Off by default; a
repository that turns them on is no longer readable by stock Fossil, and
sync refuses to hand such artifacts to a peer that would misread them.
* **Sparse cones** — partial worktrees (`open --cone`, `cone`).
* **Indexer feeds** — `frames` and `crosslink` stream raw artifacts and
derived per-check-in records from a cursor, for a forge or search index.
* **Store care** — `verify`, `pack`, `purge`, `shun`, and a local rebuild
`checkpoint` that keeps cache-cold opens fast on large histories.
* **Sync at Fossil's scale** — clusters are indexed, announced bounded,
and minted at Fossil's own thresholds, so a no-op pull of a
million-artifact repository sends kilobytes, not the whole inventory;
clone streams to disk as it arrives.
* **A write plane for forges** — the machine verbs `wiki`, `ticket`,
`forum`, `technote`, and `attach` author Fossil's collaboration
artifacts, `landing` proposes and lands a branch as an ordinary forum
thread, and `attach list` reads attachments back. Each is one line of
stdout, exact exit codes, and works against a bare store with `-R` —
the seam [quarry](https://zeitforge.app/r/dmestas/quarry) writes through.
* **Signed check-ins** — `commit --sign` clearsigns the manifest through
Fossil's own `pgp-command` contract, and the signature survives pack,
verify, and sync byte-exact.
## What it leaves to Fossil
By decision, not omission. zit authors and syncs the collaboration
artifacts but renders none of them: the web UI belongs to a forge
(`zit ui` hands off to one that serves the repository), and wiki, tickets,
forum threads, and technotes are read there rather than here. There is no
unversioned-file store; a peer's unversioned files are declined visibly.
zit never creates a SHA-1 repository, though it reads one.
## The specifications
The drafts under [docs/rfcs](dir?ci=trunk&name=docs/rfcs) are the sole
authority. Expected values in tests come from the spec text and its worked
examples, never from observing another implementation; where the code
follows Fossil's implemented behaviour against the published text, the
divergence is recorded in [docs/rfcs/erratum](dir?ci=trunk&name=docs/rfcs/erratum).
| Layer | Draft | Specifies |
|-------|-------|-----------|
| `delta` | [draft-fossil-delta-format-00](doc/trunk/docs/rfcs/draft-fossil-delta-format-00.txt) | byte-level delta encoding: copy/literal segments, base-64 integers, mod-2³² checksum |
| `artifact` | [draft-fossil-artifact-format-00](doc/trunk/docs/rfcs/draft-fossil-artifact-format-00.txt) | card-structured manifests and control artifacts, content addressing (SHA-1 / SHA3-256), checksums |
| `repostate` | [draft-fossil-repo-state-00](doc/trunk/docs/rfcs/draft-fossil-repo-state-00.txt) | branch, tag, and leaf state derived from the append-only artifact set |
| `submanifest` | [draft-fossil-submanifests-00](doc/trunk/docs/rfcs/draft-fossil-submanifests-00.txt) | S-card tree manifests: bounded per-commit manifest size for wide repositories |
| `sync` | [draft-fossil-sync-protocol-00](doc/trunk/docs/rfcs/draft-fossil-sync-protocol-00.txt) | HTTP replication of the artifact set between repositories |
| `cone` | [draft-fossil-sparse-cone-00](doc/trunk/docs/rfcs/draft-fossil-sparse-cone-00.txt) | sparse cones: partial worktrees and the sparse-store path for monorepos |
## Building
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
zig build smoke # interop check against a fossil binary on PATH
`--release=fast` is what the release builds use; a plain `zig build` is a
Debug binary, many times slower on a real history.
## Finding your way
* [Timeline](timeline) — current activity and history
* [Source tree](dir?ci=trunk) — browse the code at trunk
* [README](doc/trunk/README.md) — design notes, scope, and build steps
* [Release notes](dir?ci=trunk&name=docs&re=RELEASE-NOTES) — every release, oldest to newest
* [Technotes](timeline?y=e) — engineering notes on how and why things changed
* [docs/rfcs](dir?ci=trunk&name=docs/rfcs) — the six frozen drafts
* [GitHub mirror](https://github.com/danmestas/zit) — issues and CI
Z 1adb2d6b5254bf0eb29ed1ee8dc49b30