Repository navigation
v0.9.2 - Times Survive a Restore, `--force-with-lease` Works, and a Directory the Tool Cannot Read No Longer Vanishes From the Snapshot
What's Changed in v0.9.2
Two more rounds of independent review went over the snapshot tool: Opus twice on the code (the second
time on code written for this release), and GLM-5.3 and Gemini on the specification. Every finding that
reproduced is fixed with a test that fails without the fix. The suite is 1049 tests; the tool and helper
changes were also run on Linux (Debian under WSL) and against a real Seafile server (CE 13.0.28) in a
scratch library.
The one that mattered most
- A directory the tool could not read was silently missing from the snapshot.
git addprints a
warning for a directory it cannot open and exits 0, so everything under it was absent and the run
reported success. The run now stops and names the directory;--excludeleaves it out on purpose.
Added
- Modification times of git-stored files are restored. A snapshot that pushes to a
seafile://remote
records them in.seafile-payload/mtimes.jsonand--restoreputs them back (payload files already
carried theirs).--record-mtimes/--no-record-mtimes; an explicit choice is remembered; a run with
nothing typed follows the last snapshot. Touching a file without changing it still makes no new snapshot. git push --force-with-leaseis supported: a push may rewrite history over exactly the value you
saw, and is refused asstale infoif the remote moved. Updates, deletions and--dry-run.- A fetch no longer advertises half a repository. A refs directory that its parent listed and that then
answers 404 is retried once and then an error. - macOS network mounts are recognised by the clock probe.
Fixed in the snapshot tool
- A restore overwrote and then removed a real git file named
<payload file>.part, and certified the tree. - A manifest path through a link to
.git(tool/hooks/pre-commit) passed the "inside the destination"
check; a hostile manifest could fill the disk before its sizes were compared. - A share whose clock ran 2 to 5 s behind kept a stale hash (the noise floor was wider than the racy
window); a share that could not be probed fell back to the machine's clock; a same-size edit that put the
old mtime back was trusted. The cache key now holds the device and the inode change time, unprobed
shares and other devices get a one-hour margin, and whole-second mtimes are trusted (twice the margin)
instead of being re-read on every run of a FAT or HFS+ volume. --no-embedded-reposafter a capturing run wrote a gitlink naming the vault's own commit; a repository
inside a repository crashed the run; one with no commit failed every run; a junction that is itself a
repository was followed out of the tree.--payload-gcdecided from a listing that could have skipped a branch (so its objects looked unused),
and from a decision minutes old. The listing is strict and the refs are read again before the first
deletion.- A pid recycled by an unrelated process blocked every later snapshot on Windows.
- The weekly report copied the whole vault into the temporary directory and ran on a vault's first run.
- A manifest path using a code point HFS+ ignores was accepted; flags that would be ignored are refused.
Documentation
- Corrected: the source is "never written to" (a probe file on a network share), objects are "never
overwritten", a payload vault can snapshot offline (it cannot),--payload-verifycovers every snapshot
(the newest only), and 0.9.1's claim that the conflict-copy warning missed dotted refs (measured on a
real server: it did not). - Stated: tags must be pushed to be seen by retention; the manifest is one line; a 0.8.8 machine restores a
payload vault's git tree only, without a warning.
Upgrading from 0.9.1
- A directory that cannot be read now stops the run: a scheduled job that had been skipping one will fail
until it is made readable or excluded. --payload-gcstops, deleting nothing, if a ref cannot be read or a push landed while it decided.- A vault gets
.seafile-payload/mtimes.jsonon its next pushing run (about 60 bytes a file; about 1.5 MB
compressed at 100,000 files, uploaded whole each time anything changes).--no-record-mtimesopts out. - No file format changed; 0.9.1 vaults and remotes are read as before.
Known gaps
- The times record is one blob, rewritten whole when any file changes (sharding it is a format change).
- A nested repository's history, and directory times, are not captured.
- macOS (NFD names, HFS+,
utimeon symlinks) is covered by reasoning and CI, not by a Mac here.
The full list, with measurements, is in CHANGELOG.md.
Full Changelog: v0.9.1...v0.9.2