From 5822b47b742b33f1afc9664127d2d882ed134752 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 14 Mar 2022 12:36:48 -0700 Subject: [PATCH] Ensure that worktrees' entry ids are unique across the project Fixes #512 --- crates/project/src/project.rs | 21 +++++++++++++++++---- crates/project/src/worktree.rs | 9 ++++++--- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index d8ae7f3de5..8fb59decf6 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -38,7 +38,10 @@ use std::{ ops::Range, path::{Component, Path, PathBuf}, rc::Rc, - sync::{atomic::AtomicBool, Arc}, + sync::{ + atomic::{AtomicBool, AtomicUsize}, + Arc, + }, time::Instant, }; use util::{post_inc, ResultExt, TryFutureExt as _}; @@ -56,6 +59,7 @@ pub struct Project { language_server_settings: Arc>, next_language_server_id: usize, client: Arc, + next_entry_id: Arc, user_store: ModelHandle, fs: Arc, client_state: ProjectClientState, @@ -331,6 +335,7 @@ impl Project { client, user_store, fs, + next_entry_id: Default::default(), language_servers_with_diagnostics_running: 0, language_servers: Default::default(), started_language_servers: Default::default(), @@ -381,6 +386,7 @@ impl Project { languages, user_store: user_store.clone(), fs, + next_entry_id: Default::default(), subscriptions: vec![client.add_model_for_remote_entity(remote_id, cx)], client: client.clone(), client_state: ProjectClientState::Remote { @@ -2979,6 +2985,7 @@ impl Project { ) -> Task>> { let fs = self.fs.clone(); let client = self.client.clone(); + let next_entry_id = self.next_entry_id.clone(); let path: Arc = abs_path.as_ref().into(); let task = self .loading_local_worktrees @@ -2986,9 +2993,15 @@ impl Project { .or_insert_with(|| { cx.spawn(|project, mut cx| { async move { - let worktree = - Worktree::local(client.clone(), path.clone(), visible, fs, &mut cx) - .await; + let worktree = Worktree::local( + client.clone(), + path.clone(), + visible, + fs, + next_entry_id, + &mut cx, + ) + .await; project.update(&mut cx, |project, _| { project.loading_local_worktrees.remove(&path); }); diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 1130063c98..1ef8dd34a0 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -172,10 +172,11 @@ impl Worktree { path: impl Into>, visible: bool, fs: Arc, + next_entry_id: Arc, cx: &mut AsyncAppContext, ) -> Result> { let (tree, scan_states_tx) = - LocalWorktree::new(client, path, visible, fs.clone(), cx).await?; + LocalWorktree::new(client, path, visible, fs.clone(), next_entry_id, cx).await?; tree.update(cx, |tree, cx| { let tree = tree.as_local_mut().unwrap(); let abs_path = tree.abs_path().clone(); @@ -425,11 +426,11 @@ impl LocalWorktree { path: impl Into>, visible: bool, fs: Arc, + next_entry_id: Arc, cx: &mut AsyncAppContext, ) -> Result<(ModelHandle, UnboundedSender)> { let abs_path = path.into(); let path: Arc = Arc::from(Path::new("")); - let next_entry_id = AtomicUsize::new(0); // After determining whether the root entry is a file or a directory, populate the // snapshot's "root name", which will be used for the purpose of fuzzy matching. @@ -457,7 +458,7 @@ impl LocalWorktree { scan_id: 0, ignores: Default::default(), removed_entry_ids: Default::default(), - next_entry_id: Arc::new(next_entry_id), + next_entry_id, snapshot: Snapshot { id: WorktreeId::from_usize(cx.model_id()), root_name: root_name.clone(), @@ -2425,6 +2426,7 @@ mod tests { Arc::from(Path::new("/root")), true, fs, + Default::default(), &mut cx.to_async(), ) .await @@ -2468,6 +2470,7 @@ mod tests { dir.path(), true, Arc::new(RealFs), + Default::default(), &mut cx.to_async(), ) .await