# zit 0.3.8
zit 0.3.8 gives `annotate` a real diff core, lets `info` answer many
check-ins in one call, and closes the last corners where `fossil` and `zit`
could read the same checkout differently.
No artifact, tag namespace, or sync message changed.
## `annotate` on a diff core (zit#176)
`annotate` compared versions with an O(n×m) LCS and re-derived a manifest
at every step of the walk. The crosslink record now carries each changed
file's artifact hash — fossil's `mlink` shape — so annotate reads blobs by
hash, and `merge3` moves to a linear-space Myers LCS. Plaintext and
baselines are cached across versions. On the sqlite corpus
`annotate src/shell.c.in` went from 57 s to 3.1 s; fossil takes 2.3 s at
its default version limit and 4.4 s with `--limit none`.
Output is byte-identical to the previous build. Attribution still differs
from fossil's on merged lines, by design: zit credits a line to the oldest
check-in that carries it and merged lines to their origin branch, where
fossil credits along primary parents. Help now states the 12-character
prefix annotate actually prints.
## `info` takes many names (zit#177)
`zit info A B C` answers every name in one process, and `-` reads the names
from stdin. `-F json` emits one object per line. A name that fails to
resolve goes to stderr and the run continues, exiting 1 at the end. A forge
rendering a page from hundreds of `info` calls does one spawn instead of
hundreds.
## One checkout, two tools, the last corners (zit#175)
- **Glob classes.** In `.fossil-settings` and `.zit-settings` globs, `!`
is a class member and only `^` negates, as in sqlite's GLOB. The
`.zitignore` (gitignore) dialect keeps `!`.
- **A versioned-only `manifest` setting** is read out of the check-in at
`open`, the way fossil's `db_get_versioned` does, so the stamps appear on
the first checkout rather than the first `update`.
- **`open --manifest=off` is remembered.** A project setting cannot
re-enable stamps at the next `update`. `--manifest=on`, `yes`, `true`,
and `1` mean `ru`.
- **`add --force`** means what it means in fossil: a file named directly is
added even when `ignore-glob` matches it. A directory expansion always
honours `ignore-glob` and `clean-glob`; a named `ignore-glob` match
without `--force` is skipped with a note, a named `clean-glob` match is
added silently. `changes` after either step is byte-identical to
fossil's, and the differential smoke now checks it.
- **`.fslckout`, `_FOSSIL_`, and `.fos`** at the root match
case-insensitively on macOS and Windows only; Linux compares exactly, as
fossil does.
## Behaviour changes
- `[!abc]` in a fossil-dialect glob no longer negates the class. Rewrite
as `[^abc]`.
- `zit add FILE` where `ignore-glob` matches FILE now skips it and says so;
`--force` adds it. `zit add DIR` no longer adds `clean-glob` matches.
- `zit open` without `--manifest` follows the project's versioned setting
from the first checkout.
## Compatibility
- Artifacts, tags, and the sync protocol are unchanged; Fossil RFC
revision 00 remains the target.
- The cache format changed: the crosslink record is at format 5 and the
checkpoint at format 5. A cache written by 0.3.7 is re-derived once on
the first open; nothing needs to be run by hand.
- Flags added: `-F json` and `-` (stdin) on `info`; `--manifest=on|off`
on `open`. Output changes only where the section above says so.
## Qualification
`zig build test`, `e2e`, `smoke` (Fossil interop against a real `fossil`,
now with the `add --force` scenario), `muscle` (41 differential steps),
`git-import-e2e`, `git-export-e2e`, and `dst`, plus the three-runner CI
battery (macOS ARM64, Linux x86-64, Linux ARM64). `annotate` timings were
taken on the sqlite corpus with release builds; attribution and `changes`
output were diffed against fossil 2.28.