Skip to content
zit Artifact [1bfd8f153b]
Login

Artifact [1bfd8f153b]

Artifact 1bfd8f153b211d190af21e8911a9c1318a0a2992755e45142261586f40f76315:


# zit

A [Fossil](https://fossil-scm.org) version-control system in
[Zig](https://ziglang.org).

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/`](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](https://fossil.craftdesign.group/zit/uv/download.html)
and mirrored to [GitHub releases](https://github.com/danmestas/zit/releases).
Each release has notes under [`docs/`](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-git` and `export-git`, each checked
  against a real `git` in 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-git` picks 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** — `frames` and `crosslink` stream raw artifacts and
  derived per-check-in records from a cursor, for a forge or a search index;
  `info` answers many names in one call, as text or JSON.
- **Store care** — `verify` (fsck), `pack`, `purge`, `shun`, and a local,
  disposable rebuild `checkpoint` that keeps cache-cold opens fast on large
  histories. Never stored in the repository, never synced.
- **Review records** — `landing` proposes a branch to land on trunk as a
  reviewable record; `precedent` reuses 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 ui` hands the checkout to a
  forge that serves it.
- **Unversioned files.** No `uv` verb 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 init` writes 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/`](docs/rfcs/erratum/).

| Module | Draft | What it specifies |
|--------|-------|-------------------|
| `delta` | `draft-fossil-delta-format-00` | byte-level delta encoding |
| `artifact` | `draft-fossil-artifact-format-00` | manifest / control-artifact card format, naming, checksums |
| `repostate` | `draft-fossil-repo-state-00` | 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-00` | 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.

```sh
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](https://github.com/danmestas/zit), where issues and CI
live.