microsoft / microsoft/TypeScript
FSEvents watcher drops events when requested casing differs from disk casing
- 主要语言
- Go
- 星标
- 111k
- 派生
- 14.3k
- 平均合并
- 2 天 4 小时
- 30 天内合并 PR
- 132
描述
After https://github.com/microsoft/typescript-go/pull/4867, realpath on macOS now preserves the caller casing when the input isn't a symlink. That exposes a watch bug. `WatchManager`'s `DirWatchSet` contains lowercased paths (even though they're typed as `string`, not `tspath.Path`). Those lowercased paths are given to `fswatch`, which works, but FSEvents then reports back events using actual disk casing. `fsevents` uses case-insensitive comparison to determine whether to call its callback, so the events get dropped.
I handed this to Copilot and it immediately jumped to bringing back the pre-https://github.com/microsoft/typescript-go/pull/4867 `realpath` behavior for directories specifically, since directories can't be hardlinks. I thought that was a really weird place to start, but technically it seems to fix the bug.
I think the more likely correct fix is either:
- `WatchManager` should hold both the original file casing for passing to `fswatch` and lowercased casing for deduplication/comparison
- `fswatch` should be doing case-insensitive matching on case-insensitive file systems
The latter seems like the most robust (I'm not sure if we can guarantee that the original file casing we see in `tsc` actually matches the disk in all cases; it seems possible that the casing of `"include": ["SRC"]` from a tsconfig will get preserved and we'll never be aware of the disk casing). But it also seems the most expensive and invasive, which is a bummer.
cc @jakebailey @johnfav03
贡献指南
评估
这个 Issue 还没有评估数据。