From c80d21322712a9a0b79c8bd91f6c41b97e5de2b9 Mon Sep 17 00:00:00 2001 From: Andrew Farkas <6060305+HactarCE@users.noreply.github.com> Date: Mon, 6 Oct 2025 15:20:01 -0400 Subject: [PATCH] Fix infinite loop when worktree is deleted (#39637) Closes #39442 Release Notes: - Fixed infinite loop when worktree is deleted Co-authored-by: Conrad Irwin --- crates/project/src/worktree_store.rs | 2 +- crates/worktree/src/worktree.rs | 36 +++++++++++++--------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/crates/project/src/worktree_store.rs b/crates/project/src/worktree_store.rs index 37bad3387a3c101f67eb721dded477ba538ae933..8e18a8085dd311d8e5c34da783dc720570553bc5 100644 --- a/crates/project/src/worktree_store.rs +++ b/crates/project/src/worktree_store.rs @@ -395,7 +395,7 @@ impl WorktreeStore { // Otherwise, the FS watcher would do it on the `RootUpdated` event, // but with a noticeable delay, so we handle it proactively. local.update_abs_path_and_refresh( - Some(SanitizedPath::new_arc(&abs_new_path)), + SanitizedPath::new_arc(&abs_new_path), cx, ); Task::ready(Ok(this.root_entry().cloned())) diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index 4e476c3f07c1d74a29bbb0d6e211a6a529028528..d1f8901f8833191ead7d29d94db7e28e9567fa8e 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -331,7 +331,7 @@ enum ScanState { scanning: bool, }, RootUpdated { - new_path: Option>, + new_path: Arc, }, } @@ -1769,21 +1769,19 @@ impl LocalWorktree { pub fn update_abs_path_and_refresh( &mut self, - new_path: Option>, + new_path: Arc, cx: &Context, ) { - if let Some(new_path) = new_path { - self.snapshot.git_repositories = Default::default(); - self.snapshot.ignores_by_parent_abs_path = Default::default(); - let root_name = new_path - .as_path() - .file_name() - .and_then(|f| f.to_str()) - .map_or(RelPath::empty().into(), |f| { - RelPath::unix(f).unwrap().into() - }); - self.snapshot.update_abs_path(new_path, root_name); - } + self.snapshot.git_repositories = Default::default(); + self.snapshot.ignores_by_parent_abs_path = Default::default(); + let root_name = new_path + .as_path() + .file_name() + .and_then(|f| f.to_str()) + .map_or(RelPath::empty().into(), |f| { + RelPath::unix(f).unwrap().into() + }); + self.snapshot.update_abs_path(new_path, root_name); self.restart_background_scanners(cx); } } @@ -3775,18 +3773,18 @@ impl BackgroundScanner { .map(|path| SanitizedPath::new_arc(&path)) .filter(|new_path| *new_path != root_path); - if let Some(new_path) = new_path.as_ref() { + if let Some(new_path) = new_path { log::info!( "root renamed from {} to {}", root_path.as_path().display(), new_path.as_path().display() - ) + ); + self.status_updates_tx + .unbounded_send(ScanState::RootUpdated { new_path }) + .ok(); } else { log::warn!("root path could not be canonicalized: {}", err); } - self.status_updates_tx - .unbounded_send(ScanState::RootUpdated { new_path }) - .ok(); return; } };