mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-20 17:41:37 +00:00
Keep watching directories recreated at a removed path (AI-assisted)
This commit is contained in:
parent
a36a199835
commit
f54ade744d
4 changed files with 50 additions and 5 deletions
1
AI-canary.txt
Normal file
1
AI-canary.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
This pull request is AI generated
|
||||
|
|
@ -32,8 +32,10 @@ Making a new release? Simply add the new header with the version and date undern
|
|||
## Unreleased
|
||||
|
||||
* LocalizationTables no longer report as changed when nothing changes. [(#1333)]
|
||||
* Fixed live sync on Linux (`rojo serve` and the `--watch` modes) missing every change inside a directory that was removed or moved aside and then recreated at the same path within another synced directory. ([#1341])
|
||||
|
||||
[#1333]: https://github.com/rojo-rbx/rojo/pull/1333
|
||||
[#1341]: https://github.com/rojo-rbx/rojo/pull/1341
|
||||
|
||||
## [7.7.1] (October 1st, 2026)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
# memofs Changelog
|
||||
|
||||
## Unreleased Changes
|
||||
* Fixed `StdBackend` on Linux dropping the watches on a directory recreated at a path whose removal was committed afterwards, which stopped events for everything inside it. [#1341]
|
||||
|
||||
[#1341]: https://github.com/rojo-rbx/rojo/pull/1341
|
||||
|
||||
# 0.4.0 (2026-07-01)
|
||||
* Added `Vfs::canonicalize`. [#1201]
|
||||
|
|
|
|||
|
|
@ -122,15 +122,54 @@ impl VfsBackend for StdBackend {
|
|||
{
|
||||
Ok(())
|
||||
} else {
|
||||
// This recursive watch covers any watch we already hold below
|
||||
// `path`. Release those, so that every path in `watches` is the
|
||||
// only watch covering it and `unwatch` can trust that. Release them
|
||||
// first: on inotify this watch shares their per-directory entries,
|
||||
// and unwatching them afterwards would delete its coverage too.
|
||||
let covered: Vec<PathBuf> = self
|
||||
.watches
|
||||
.iter()
|
||||
.filter(|watched| watched.starts_with(path))
|
||||
.cloned()
|
||||
.collect();
|
||||
for watched in &covered {
|
||||
self.watches.remove(watched);
|
||||
let _ = self.watcher.unwatch(watched);
|
||||
}
|
||||
|
||||
if let Err(err) = self.watcher.watch(path, RecursiveMode::Recursive) {
|
||||
// Put back what we released, so a failed watch loses nothing.
|
||||
// inotify keeps whatever part of the walk succeeded, so drop
|
||||
// that first to free its watches.
|
||||
let _ = self.watcher.unwatch(path);
|
||||
for watched in covered {
|
||||
if self
|
||||
.watcher
|
||||
.watch(&watched, RecursiveMode::Recursive)
|
||||
.is_ok()
|
||||
{
|
||||
self.watches.insert(watched);
|
||||
}
|
||||
}
|
||||
return Err(io::Error::other(err));
|
||||
}
|
||||
self.watches.insert(path.to_path_buf());
|
||||
self.watcher
|
||||
.watch(path, RecursiveMode::Recursive)
|
||||
.map_err(io::Error::other)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn unwatch(&mut self, path: &Path) -> io::Result<()> {
|
||||
self.watches.remove(path);
|
||||
// Only stop a watch we started. Any other path is covered by an
|
||||
// ancestor's recursive watch, for which inotify keeps an entry per
|
||||
// directory, keyed by path. By the time a removal is committed, that
|
||||
// entry may belong to a new directory created at the same path, and
|
||||
// unwatching it would stop events for that directory and everything
|
||||
// under it.
|
||||
if self.watches.remove(path) {
|
||||
self.watcher.unwatch(path).map_err(io::Error::other)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue