Skip to content

Reload cached files for Created watch events - #64909

Merged
John Favret (johnfav03) merged 5 commits into
microsoft:mainfrom
johnfav03:fix/64195
Oct 22, 2026
Merged

John Favret (johnfav03) merged 5 commits into
microsoft:mainfrom
johnfav03:fix/64195

Conversation

@johnfav03

Copy link
Copy Markdown
Contributor

Fixes #64195

Atomic saves replace an existing file by renaming a temporary file over it; file watchers can report that replacement as Created rather than Changed. We previously only invalidated the cache on Changed events; when a file that already exists in the program received a Created event, its cached contents remained stale, causing diagnostics to reflect outdated info.

Copilot AI balanced review requested due to automatic review settings October 21, 2026 18:14
@github-project-automation github-project-automation Bot moved this to Not started in PR Backlog Oct 21, 2026
@typescript-automation typescript-automation Bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Oct 21, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Directory deletions can leave symlink caches stale, and ordinary atomic saves unnecessarily traverse every cached alias.

2 open issues
What changed in this PR

Fixes #64195 by refreshing language-server file caches when atomic saves produce Created watch events.

Changes:

  • Reloads cached files for created paths, directories, and symlink aliases.
  • Compares open-file overlays with disk contents after save and watch events.
  • Adds regression coverage for atomic saves and bulk notifications.
File Description
tsc/​internal/​project/​snapshotfs.go Expands created events and reloads cached contents.
tsc/​internal/​project/​snapshotfs_test.go Tests created events and symlink cache handling.
tsc/​internal/​project/​snapshot.go Expands events before bulk invalidation.
tsc/​internal/​project/​session_test.go Tests atomic saves and overlay consistency.
tsc/​internal/​project/​overlayfs.go Updates overlay-to-disk comparisons.
tsc/​internal/​project/​overlayfs_test.go Tests save/watch ordering.
tsc/​internal/​project/​bulkcache_test.go Tests created-event batches and directory notifications.

Review effort: Balanced

Comment thread tsc/internal/project/snapshot.go Outdated
Comment thread tsc/internal/project/snapshotfs.go

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unrelated directory-creation events introduce avoidable workspace-wide cache scans.

1 open issue
2 resolved since last review

Review effort: Balanced

Comment thread tsc/internal/project/snapshotfs.go Outdated

@jakebailey Jake Bailey (jakebailey) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had copilot look at this locally and it noticed a few things


I think the fix itself is right: treating a Created event on a cached file as a possible content change fixes the atomic-save case, and the tests cover it well. My main concern is the disk checks added before the large-batch check (see the comments on snapshot.go and the two DirectoryExists calls), and I think they can be removed entirely.

Comment thread tsc/internal/project/snapshot.go Outdated
Comment thread tsc/internal/project/snapshot.go Outdated
Comment thread tsc/internal/project/snapshot.go Outdated
Comment thread tsc/internal/project/snapshotfs.go Outdated
Comment thread tsc/internal/project/snapshotfs.go
Comment thread tsc/internal/project/snapshotfs.go Outdated

if events.saved {
if o != nil {
if o != nil && (events.watchObserved || events.saved) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: with this change, every didSave reads the file from disk while holding fs.mu. Before, an open file was simply assumed to match the disk after a save. Comparing against the disk is more accurate, so this is probably fine, but I wanted to point out the extra read on every save.

@jakebailey Jake Bailey (jakebailey) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor follow-up idea: the post-expansion Created set can still look excessive to configFileRegistryBuilder.DidChangeFiles, which may clear the config cache.

@github-project-automation github-project-automation Bot moved this from Not started to Needs merge in PR Backlog Oct 22, 2026
@johnfav03
John Favret (johnfav03) added this pull request to the merge queue Oct 22, 2026
Merged via the queue into microsoft:main with commit a91e938 Oct 22, 2026
29 checks passed
@johnfav03
John Favret (johnfav03) deleted the fix/64195 branch October 22, 2026 19:20
@github-project-automation github-project-automation Bot moved this from Needs merge to Done in PR Backlog Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

LSP: file contents are not re-read when didChangeWatchedFiles reports Created (type 1) for a file already in the program

3 participants