Skip to content
zit Artifact [bd97af5fcc]
Login

Artifact [bd97af5fcc]

Artifact bd97af5fcc53a62604bf0e96b3dcf2f5249fefbd9e67f85bd34b96fad9fd0a11:


zit 0.7.3

zit 0.7.3 makes import-git take the history Git itself stores, where 0.7.2 stopped on the Linux kernel's with a bare Malformed. Git tags import under their own names, and a store imported by an earlier release is renamed on its next --into. A shunned tag can no longer push a seed's date backwards and hold horizon clones at the content horizon. A push no longer asks the origin for content, as Fossil's never does, and the deterministic simulation passes its whole sweep again.

This release is from trunk. Stores are unchanged from 0.7.2.

import-git takes what Git stores

Old histories hold commits that today's Git would not write, but Git stores, fetches and exports every one of them. 0.7.2 refused the first one it met, after doing all the work before it, and said only Malformed. The Linux kernel's history stopped it twice: 261 identities with an empty name, and 212 commits that declare a Latin-1 encoding.

The parser's rule is now Git's. An identity in the form NAME <EMAIL> SECONDS ZONE reads exactly as before, so every check-in an earlier import wrote keeps its hash. One that is not reads the way Git reads it:

Git converts a commit that declares another encoding to UTF-8 as it exports it. Names and messages that are not UTF-8 and declare nothing are kept as their bytes, and the provenance map records them as hex. 0.7.2 refused them as it wrote the map.

A file whose path no checkout can hold is left out of the imported tree. That covers .. or ., an empty part, a backslash, or a name zit keeps at the root, such as .zit. 0.7.2 refused the whole history for one.

The import report counts the identities read as Git reads them, and the file entries left out, and names the first of each, so it can be found in Git. An empty name is not counted: it is valid.

A refusal names its record

When the export stream is refused, the report now names the record and the rule, for example commit febf7ea4bedc: its from is not a mark or a hex object name. When git fast-export itself fails, the report points to Git's own message, printed above it, instead of naming a parse error in the stream Git cut short.

Git tags keep their names

0.7.2 imported a Git tag v1.0 as tags/v1.0 and repeated every branch as a heads/NAME tag, so zit update v1.0 and a forge's ?t=v1.0 found nothing. Remote-tracking refs became tags that never moved.

Now a Git tag X is the tag X, as fossil import --git names it. A branch is named by its branch alone, with the name added directly on its head only when the head sits on another branch's check-in. Refs outside refs/heads/ and refs/tags/ become no tag. A tag that shares a branch's name keeps tags/X, so it never stops that branch's name from propagating.

A store imported by an earlier release is renamed by its next --into, even when nothing changed upstream. The old names are cancelled where they stand and the plain ones published, once. The import map records that, so later runs write nothing.

A shun no longer moves a seed's date back

A seed is dated at the latest tag event in the repository. Shunning a tag removes its events, so a seed minted after a shun could be dated earlier than the one a clone held. The clone refused it as a replay and fell back to the content horizon. A tag pushed with a far-future date and then shunned did this to every horizon clone.

An origin now dates a seed no earlier than the latest date it has minted. It records that date in .zit-cache/seed-floor. Losing the record dates the next seed from tag state alone, as 0.7.2 did. The horizon draft states the rule in Section 5.2.2, and Appendix C records the change.

A push asks for nothing

Since 0.7.0 an origin has answered a gimme only in a request that carries a pull card, as Fossil's does. A zit client still sent its phantoms as gimme cards in a push: names an earlier pull had left unfilled. Nothing answered them. The client now requests content only in a pull, a sync or a clone, as Fossil's requests it only when pulling.

The deterministic simulation passes again

The daily soak of the deterministic simulation had failed since 0.7.0, at its 21st seed, on the push above. It stopped there, so the seeds after it went unrun. They now pass in both build modes. The next failure they found was in the horizon sweep's own setup. It chose the file a crashed clone commits by listing the whole tree, so only its fault-free twin fetched the tree nodes the origin withholds. Every seed the soak runs now passes.

Known limits

import-git holds state for every commit it imports, so its memory grows with the length of the history. The Linux kernel imports past its first 340,000 commits, the stretch that stopped 0.7.2, with nothing refused. Its whole history of 1.5 million commits needs more than 10 GB. Import a history that long on a machine that has the memory, and leave sub-manifests on: with flat manifests every check-in writes its whole file list.

Under a structural horizon with the leaves rule, zit leaves can list a check-in held below the horizon as a leaf. Only the listing is affected; nothing held is lost or wrong. The simulation reaches this case past the seeds the soak runs.

Compatibility

Stores are unchanged from 0.7.2. A store imported by 0.7.2 or earlier keeps every check-in hash. Its tag names change on the next --into. That writes the renaming controls and an import map at a new version. An earlier release refuses that map, so a destination renamed by 0.7.3 is added to only by 0.7.3 or later.

On the wire nothing changes.

Qualification

The release manifest records native qualification against the exact tagged source archive on macOS ARM64, Linux x86-64 and Linux ARM64, using the pinned Zig 0.17.0 toolchain. Publication is gated on unit and end-to-end tests, Git differentials, deterministic simulation, seeded fuzzing, and Fossil interoperability checks on every distributed target.

For the basis of the conformance claim, see the 0.1.0 release notes.