Skip to content
zit Artifact [bf662eac57]
Login

Artifact [bf662eac57]

Artifact bf662eac57f0c9b958ff5c7cd002e2b9db6faf3dac5b74445f8678fdf1185ad3:


zit 0.3.33

zit 0.3.33 changes how a repository is locked for writing: the lock is now a file created with O_CREAT|O_EXCL, the way git and most Unix programs lock, instead of flock. A writer that has to wait now says what it is waiting for, and gives up with a message instead of waiting forever. It also gives repositories made by zit import-git the project code every sync peer requires.

No artifact, tag namespace, sync message, or on-disk repository format changed.

The write lock is a lock file

Every command that writes a repository first creates .zit.lock beside the store's .zit file, exclusively, and deletes it when the write has committed. Only one process can create the file, which the filesystem guarantees. The file records the holder's process id and host.

The old lock was flock on .zit itself. flock is not part of POSIX, and on network filesystems it ranges from correct to silently locking nothing. Exclusive create is defined by POSIX and is atomic on NFSv3 and later. A blocked flock also waited without a word and without end, which is how a hung writer could stall every other writer to a repository with no sign of why.

Now a writer that finds the lock held waits for it, and after a second says:

zit: waiting for the repository lock, held by process 4242 on build-host

If the holder keeps it for a minute, the writer gives up, names the holder, and names the file to delete if no zit process is really using it.

A lock file outlives a crashed holder, which flock did not. A lock that names a process on this machine that no longer exists is stale, and the next writer breaks it without asking. Breaking is serialised by a second lock and removes the file only if it still names the dead process, so a writer can never remove a lock a live process has just taken. A lock held from another machine cannot be checked from here, so it is only ever waited for.

A process that already holds the lock and asks for it again is refused at once instead of waiting for itself forever.

zit pack and zit shun --force exclude each other with the same kind of lock, .zit-tmp-pack.lock. They now also hold the writer lock across their final check and the rename that installs the new store. Before, a commit that landed between the check and the rename went into the store the rename replaced, and was lost.

Keep a repository on a network filesystem only if one process at a time writes it. Lock files are sound there, but network filesystems cache aggressively, and zit makes no attempt to work around that.

import-git records a project code

Every sync peer checks the repository's project code in its handshake and refuses a repository without one. zit import-git wrote none, so the store it made verified cleanly and could not be served, cloned by fossil, or adopted by a forge. It now records a code derived from the new repository's path, exactly as zit init does.

A store imported by an earlier release still has no code. Import it again to give it one. zit verify now says when a repository has no project code, without counting it as damage.

Tests

Compatibility

Qualification

zig fmt --check, zig build test, e2e, smoke, git-import-e2e, git-export-e2e, and dst, plus the three-runner CI battery.