# zit 0.5.0

zit 0.5.0 lets a repository imported from Git be kept current: `zit
import-git SOURCE DEST --into` adds the upstream commits DEST does not yet
hold to the ones it has, so a Git upstream can be followed the way a Fossil
one is followed with `pull`. The release also brings the leaf table into
line with Fossil's, ships the Fossil drafts as one file per draft with the
errata folded in as history, and records six more errata found against
Fossil 2.28.

No artifact, tag namespace, wire, or on-disk repository format changed. A
Git import now publishes one more file in its destination, `.zit-import-map`
(see below).

## import-git --into

`zit import-git SOURCE DEST --into` reads which upstream commits DEST
already holds, exports only the rest, and writes their check-ins on top of
the existing ones. The check-ins written are the ones a full import would
write, so a repository kept current this way has the same check-in names
as one imported in a single pass at the same sub-manifest k. Check-ins
already in DEST are never changed: they keep the branch they were given,
and the branch rule is applied to the new commits only. Tags and heads are
reconciled by name against what the source publishes: a head that moved
away from its old tip is reported and the check-ins it left behind stay; a
head or tag deleted upstream loses its name and nothing else.

A fresh import now writes the commit map that makes this possible,
`.zit-import-map` in DEST: the source's identity, the settings the import
ran under, every commit's check-in and branch label, and every ref's tip.
It is a reserved name at the checkout root, like `.zit-checkout`, and
losing it costs a full re-import. The sub-manifest k, `--attribution`,
`--refuse-signed` and `--default-branch` of the first import are reused;
a flag that contradicts them is refused rather than applied.

The import is transactional: it appends to DEST's store under the writer
lock, and any failure before the map is written truncates the store back
to its previous length, so DEST is left as it was. It refuses a destination
with no map, one imported from a different repository, one committed to
with zit since its import, and one whose first import met a Fossil mirror's
own metadata. A tag on a commit DEST already holds is imported as its name
alone; a tag's message is not carried. `--provenance` applies to a fresh
import only.

## Leaf table

The leaf table is now kept as Fossil keeps it: a check-in is rechecked only
when a branch tag is applied to it or propagated to it, never merely
because it was crosslinked or linked to a parent. A hand-built history
whose check-ins carry no branch tag therefore shows no leaves, as it does
in Fossil; every check-in zit or Fossil writes carries one. `ckout` is no
longer a name on its own: it is a keyword only for the `ci+` request form,
and `current` names the checkout everywhere else.

## Drafts

The Fossil drafts ship as one file per draft, `docs/rfcs/draft-fossil-*-00.txt`,
each carrying its current revision inside the text and its errata as
check-in history: one check-in per erratum, so `zit log` on a draft shows
exactly what each erratum changed. The separate `-01` files are gone. Every
erratum under `docs/rfcs/erratum/` is applied to its draft and listed in
that draft's change appendix. Six were recorded since 0.4.0, each from
reading and running Fossil 2.28:

- repo-state §5.3: the skip test for a tag operation compares the existing
  row whether it was applied directly or inherited, so the result depends
  on arrival order when an ancestor's propagating tag is newer.
- repo-state §7.3: the leaf table is rechecked only on branch-tag events;
  the full rebuild is the table that one batch crosslink produces.
- repo-state §8.3: `ckout` is a keyword only under the `ci+` request type,
  and only for the whole name.
- sync-protocol §9.4: the ci-lock reply carries `avoid-delta-manifests`
  when the server's `forbid-delta-manifests` setting is on; Fossil 2.29
  turns that setting on by default, 2.28 leaves it off.
- sync-protocol §10.1: a received file whose content does not match its
  hash fails the round, prefix included, and starts no further round.
- sync-protocol §5.1 and §6.6, §5.3: the earlier -01 errata on truncated
  payloads, a file card after a refused push, and the error count in the
  closing timestamp comment, now carried as history of the one file.

zit's behaviour changed for the §7.3 and §8.3 errata (see above); the
others record what Fossil does where the draft was silent or wrong. The
citation re-keying tool `scripts/rekey-citations.py` moves `§X.Y Lnnn`
citations in the sources across a re-rendered draft; all 958 citations
resolve.

## Compatibility

- A Git import's destination holds `.zit-import-map` beside `.zit` and
  `.zit-checkout`. It is reserved: `zit add` refuses it and `zit extras`
  does not list it. Destinations imported by 0.4.0 or earlier have no map
  and cannot be added to; re-import them once to get one.
- `ckout` resolves only under `ci+`; use `current` elsewhere.
- A history whose root check-in has no branch tag shows no leaves.
- No other command's output changed.

## Qualification

Qualified natively on macos-aarch64, linux-x86_64 and linux-aarch64 from
the release tarball with Zig 0.17.0 and the full battery: format check,
`--release=fast` build, unit tests, e2e, deterministic simulation (seed 1,
1000 steps), all 32 fuzz targets at 100 rounds, and the smoke suite
against fossil 2.28 [52445a27f1] (three passes on macOS, ten on each Linux
host).
