You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#65 added git restore-mtime static so the deploy's --link-dest could hard-link the static tree. It has never worked in CI, and the step exits 0.
The VPS agent measured the result and asked us to find out why before the next deploy. They were right to.
The measurement, from the host
20260808-154717 : 3275 files
20260809-030521 : 3275 files
SHARED inodes : 0 (0.0%)
site/media in the new release: 778 files, 1 distinct mtime day -> 2026-08-09
site/external in the new release: 270 files, 1 distinct mtime day -> 2026-08-09
Not "fewer than expected" — none. The static trees arrive with build-time mtimes, exactly as before the change.
Root cause, from the production run's log
1,052 files to be processed in work dir
'git whatchanged' is nominated for removal.
...
fatal: refusing to run without --i-still-use-this
1,052 files not found in log, trying merge commits
git-restore-mtime 2022.12, the Ubuntu package, shells out to git whatchanged. Recent git refuses to run it without --i-still-use-this. The tool got no log output, found no commit to date any file from, restored nothing, and exited 0. Git refused 12 times in that one step and the job reported success.
Local git still permits it, so the two-clone test genuinely restored 1052 files. The runner's git does not. The measurement was real; it just did not measure the runner.
What this is an instance of
Two rules already in TODO.md, both of which this walked into:
"A query that matches nothing reads as a clean result." The tool reported 1,052 files to be processed, which reads like success, and then processed none of them.
The VPS agent's three candidates were all reasonable and none was it: the assembly uses rsync -a and does preserve timestamps, and Hugo does preserve static mtimes into public/.
Fix
Two parts, and the second matters more than the first.
Make it work. Options, roughly in order of preference:
Replace the dependency with git log --pretty=%at --name-only --no-merges -- static and set mtimes directly. No deprecated command, nothing to install, and the logic is the few lines that actually matter here.
A newer upstream git-restore-mtime if it has dropped whatchanged, pinned by checksum rather than taken from apt.
Aliasing whatchanged does not work: git resolves builtins ahead of aliases.
Make it fail loudly. Whatever restores the mtimes, assert afterwards that static/ actually carries more than one distinct mtime day, or that its oldest file predates the checkout. A restore that silently does nothing must red the deploy rather than ship a full copy and report success. Without this, the next tool deprecation reproduces the same silence.
Blocked behind nothing. Until it lands, every release is a full ~586 MB copy, which is the pre-#65 behaviour and is not itself broken — the cost is bandwidth and disk, reclaimed by the host's prune timer.
#65addedgit restore-mtime staticso the deploy's--link-destcould hard-link the static tree. It has never worked in CI, and the step exits 0.The VPS agent measured the result and asked us to find out why before the next deploy. They were right to.
The measurement, from the host
Not "fewer than expected" — none. The static trees arrive with build-time mtimes, exactly as before the change.
Root cause, from the production run's log
git-restore-mtime2022.12, the Ubuntu package, shells out togit whatchanged. Recent git refuses to run it without--i-still-use-this. The tool got no log output, found no commit to date any file from, restored nothing, and exited 0. Git refused 12 times in that one step and the job reported success.Why the local measurement in #65 was still honest
Local git still permits it, so the two-clone test genuinely restored 1052 files. The runner's git does not. The measurement was real; it just did not measure the runner.
What this is an instance of
Two rules already in
TODO.md, both of which this walked into:1,052 files to be processed, which reads like success, and then processed none of them.The VPS agent's three candidates were all reasonable and none was it: the assembly uses
rsync -aand does preserve timestamps, and Hugo does preserve static mtimes intopublic/.Fix
Two parts, and the second matters more than the first.
git log --pretty=%at --name-only --no-merges -- staticand set mtimes directly. No deprecated command, nothing to install, and the logic is the few lines that actually matter here.git-restore-mtimeif it has droppedwhatchanged, pinned by checksum rather than taken fromapt.whatchangeddoes not work: git resolves builtins ahead of aliases.static/actually carries more than one distinct mtime day, or that its oldest file predates the checkout. A restore that silently does nothing must red the deploy rather than ship a full copy and report success. Without this, the next tool deprecation reproduces the same silence.Blocked behind nothing. Until it lands, every release is a full ~586 MB copy, which is the pre-#65 behaviour and is not itself broken — the cost is bandwidth and disk, reclaimed by the host's prune timer.