Semantic Diff

#8839 Fix rewatch losing watches when an overlapping source folder is removed

1 commit, rendered from its record.

Summary

RangeCommitsChangelogAreasJS output changesFormatsFailed checks
735a485fae1a3dc04b016bbc23cc62f72a226051..pr-88391๐Ÿ› Bug fixrewatchtests0none0

Changelog draft

๐Ÿ› Bug fix
  • Rewatch: keep watching a source folder on Linux when an overlapping recursive source folder is removed from rescript.json. #8839

735a485fae1a3dc04b016bbc23cc62f72a226051..pr-8839

d3591fd08 ยท Christoph Knittel ยท Oct 16, 2026 ยท #8839 discussion โ†—

Keep watching a source folder when an overlapping one is removed

๐Ÿ› Bug fixrewatchtests

Rust rewatch (rescript-rust) watches each source folder separately, and source folders may overlap. On a full rebuild it unwatched the paths that went away and registered only the new ones. With inotify on Linux, notify keeps one watch per directory, shared by every registered path that reaches it, so unwatching a removed recursive folder also dropped a folder that is still configured, and edits there were no longer compiled. Outside macOS, every configured path is now registered again after the stale ones are unwatched; registering an already watched directory only updates its watch, so unchanged watches have no gap. macOS keeps registering only the new paths, because FSEvents restarts its event stream on every watch change and its watches don't depend on each other.

Watches are also registered non-recursive first. notify keeps one recursive flag per directory, set by the last registration that reaches it, so a non-recursive source folder inside a recursive one could clear the flag, and folders created there later weren't watched.

Example output

rescript.json of a package, while `rescript-rust watch` runs:
  "sources": [{"dir": "src", "subdirs": true}, "src/retained"]
changed to
  "sources": ["src", "src/retained"]
then src/retained/Retained.res is edited. Before the change, a file is
also created in a new folder src/retained/nested.
Before output
The edit isn't compiled (Linux). The new folder's file is missed in mostruns.
After output
Both are compiled.

Source rewatch/tests/watch/08-watch-overlapping-source-removed.sh, run against master's rescript-rust (the edit fails 2 of 2), this branch without the registration order (the new folder fails 7 of 8) and this branch (passes 8 of 8).

๐Ÿ› Bug fix- Rewatch: keep watching a source folder on Linux when an overlapping recursive source folder is removed from rescript.json. #8839

Review

No effect
Output: unchanged
Tests
rewatch integration rewatch/tests/+ watch/08-watch-overlapping-source-removed.sh~ suite.sh
4 files ยท +173 โˆ’6 ยท changelog 1 ยท rewatch 1 ยท tests 2
Achanges/rewatch-overlapping-unwatch.fix.md+1โˆ’0
Mrewatch/src/watcher.rs+36โˆ’6
Mrewatch/tests/suite.sh+1โˆ’0
Arewatch/tests/watch/08-watch-overlapping-source-removed.sh+135โˆ’0
with Claude Opus 5.5