diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index b720c7f3cfc739c7f429ec60b69a6596af46b3c0..69c23652c28971f1cde8a2d97f12335560d143db 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -46,9 +46,9 @@ use ui::{ use util::ResultExt as _; use util::path_list::{PathList, SerializedPathList}; use workspace::{ - AddFolderToProject, AppState, CloseWindow, FocusWorkspaceSidebar, MultiWorkspace, - MultiWorkspaceEvent, Open, OpenOptions, Sidebar as WorkspaceSidebar, SidebarSide, - ToggleWorkspaceSidebar, Workspace, WorkspaceId, sidebar_side_context_menu, + AddFolderToProject, CloseWindow, FocusWorkspaceSidebar, MultiWorkspace, MultiWorkspaceEvent, + Open, Sidebar as WorkspaceSidebar, SidebarSide, ToggleWorkspaceSidebar, Workspace, WorkspaceId, + sidebar_side_context_menu, }; use zed_actions::OpenRecent; @@ -2302,7 +2302,7 @@ impl Sidebar { } Some(row) => { let fs = cx.update(|_window, cx| ::global(cx))?; - match Self::restore_archived_worktree(row, fs, cx).await { + match Self::restore_archived_worktree(row, &workspaces, fs, cx).await { Ok(restored_path) => { final_paths.push(restored_path); Self::maybe_cleanup_archived_worktree(row, &store, &workspaces, cx) @@ -2334,58 +2334,19 @@ impl Sidebar { async fn restore_archived_worktree( row: &ArchivedGitWorktree, + workspaces: &[Entity], fs: Arc, cx: &mut AsyncWindowContext, ) -> anyhow::Result { let commit_hash = row.commit_hash.clone(); - let main_repo_path = row.main_repo_path.clone(); - - // Ensure the main repo's workspace is open (finds existing or opens new). - let open_task = cx.update(|_window, cx| { - let app_state = AppState::global(cx); - workspace::open_paths( - std::slice::from_ref(&main_repo_path), - app_state, - OpenOptions::default(), - cx, - ) - })?; - let open_result = open_task.await?; - let project = open_result - .workspace - .update(cx, |workspace, _cx| workspace.project().clone()); - - // Wait for worktree scans to complete so the Repository entities are available. - let scan_futures = cx.update(|_window, cx| { - project - .read(cx) - .worktrees(cx) - .filter_map(|worktree| { - worktree - .read(cx) - .as_local() - .map(|local| local.scan_complete()) - }) - .collect::>() - })?; - for scan_future in scan_futures { - scan_future.await; - } - // Find the main repo entity in the project. + // Find the main repo entity. let main_repo = cx.update(|_window, cx| { - project - .read(cx) - .repositories(cx) - .values() - .find_map(|repo_entity| { - let repo = repo_entity.read(cx); - (repo.is_main_worktree() && *repo.work_directory_abs_path == *main_repo_path) - .then(|| repo_entity.clone()) - }) + find_main_repo_in_workspaces(workspaces, &row.main_repo_path, cx) })?; let Some(main_repo) = main_repo else { + // Main repo not found — fall back to fresh worktree. return Self::create_fresh_worktree(row, &fs, cx).await; }; @@ -2396,13 +2357,17 @@ impl Sidebar { let is_restored_and_valid = already_exists && row.restored && cx.update(|_window, cx| { - project - .read(cx) - .repositories(cx) - .values() - .any(|repo_entity| { - *repo_entity.read(cx).snapshot().work_directory_abs_path == *worktree_path - }) + workspaces.iter().any(|workspace| { + let project = workspace.read(cx).project().clone(); + project + .read(cx) + .repositories(cx) + .values() + .any(|repo_entity| { + *repo_entity.read(cx).snapshot().work_directory_abs_path + == *worktree_path + }) + }) })?; let final_worktree_path = if !already_exists { @@ -2466,35 +2431,52 @@ impl Sidebar { // Tell the project about the new worktree and wait for it // to finish scanning so the GitStore creates a Repository. - let path_for_register = final_worktree_path.clone(); - let worktree_result = project - .update(cx, |project, cx| { - project.find_or_create_worktree(path_for_register, true, cx) + let project = cx.update(|_window, cx| { + workspaces.iter().find_map(|workspace| { + let project = workspace.read(cx).project().clone(); + let has_main_repo = project.read(cx).repositories(cx).values().any(|repo| { + let repo = repo.read(cx); + repo.is_main_worktree() + && *repo.work_directory_abs_path == *row.main_repo_path + }); + has_main_repo.then_some(project) }) - .await; - if let Ok((worktree, _)) = worktree_result { - let scan_complete = cx.update(|_window, cx| { - worktree - .read(cx) - .as_local() - .map(project::LocalWorktree::scan_complete) - })?; - if let Some(future) = scan_complete { - future.await; + })?; + + if let Some(project) = project { + let path_for_register = final_worktree_path.clone(); + let worktree_result = project + .update(cx, |project, cx| { + project.find_or_create_worktree(path_for_register, true, cx) + }) + .await; + if let Ok((worktree, _)) = worktree_result { + let scan_complete = cx.update(|_window, cx| { + worktree + .read(cx) + .as_local() + .map(project::LocalWorktree::scan_complete) + })?; + if let Some(future) = scan_complete { + future.await; + } } } // Find the new worktree's repo entity. let worktree_repo = cx.update(|_window, cx| { - project - .read(cx) - .repositories(cx) - .values() - .find_map(|repo_entity| { - let snapshot = repo_entity.read(cx).snapshot(); - (*snapshot.work_directory_abs_path == *final_worktree_path) - .then(|| repo_entity.clone()) - }) + workspaces.iter().find_map(|workspace| { + let project = workspace.read(cx).project().clone(); + project + .read(cx) + .repositories(cx) + .values() + .find_map(|repo_entity| { + let snapshot = repo_entity.read(cx).snapshot(); + (*snapshot.work_directory_abs_path == *final_worktree_path) + .then(|| repo_entity.clone()) + }) + }) })?; if let Some(worktree_repo) = worktree_repo {