Repository navigation
fix(cache): leave outputs that already match untouched when restoring a cache hit - #901
Open
jasonkuhrt wants to merge 3 commits into
Open
jasonkuhrt wants to merge 3 commits into
jasonkuhrt wants to merge 3 commits into
Conversation
jasonkuhrt
added a commit
to jasonkuhrt/vite-task
that referenced
this pull request
Oct 28, 2026
… a cache hit Restoring a cache hit unpacked every archived output over the workspace, so tar removed and recreated each file even when its content was unchanged. A file watcher saw every output change on every hit. Compare each regular-file entry with the file on disk first: a file with the same size, permissions and bytes is left as it is. A missing file, or one that differs in type, size or permissions, is unpacked right away, as before. One that matches in size but differs in content was found by reading the entry's data, so it is unpacked in a second pass over the archive. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
jasonkuhrt
force-pushed
the
fix/cache-restore-skip-unchanged
branch
from
October 28, 2026 20:42
a4d255a to
e9806c1
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #900
Motivation
A cache hit unpacked every archived output over the workspace, so each file was removed and created again even when its content hadn't changed, and a watcher on the outputs saw all of them change. In #900, a replay of a 1,000-file generated client made a Vite dev server send about 1,000 HMR updates and restarted an API running under
vite build --watch.Change
extract_output_archivecompares each regular-file entry with the file on disk before writing it:Entry::unpack_in, asArchive::unpackdid, so tar's path checks and the metadata it restores stay the same. The destination is canonicalized once, asArchive::unpackdoes.Only entries whose path is plain relative components are compared; anything else goes to
unpack_inas before. A match writes nothing, so tar's check that a write stays inside the workspace still guards every write.On the fixture in #900, a replay over unchanged outputs replaces none of the 1,000 files and fires no watcher events, against all 1,000 on
main. With one output edited and one deleted, it restores those 2. On Linux the same replay fired 3,000 inotify events onmainand none with the change.Release builds on GitHub's
macos-15andubuntu-24.04runners, each job building both revisions and alternating their runs, median of 40 (run):mainmainA restore into an empty directory is 5–7% slower, from looking up each missing file before unpacking it.
Two new tests fail on
main: matching files keep their modification time, and missing, resized and same-size-changed files are restored beside an untouched one. A third checks that a file whose permissions changed is restored.#866 (atomic writes) and #885 (symbolic links) also change this function. This change only decides which entries get written, so it combines with either.