Replace 500ms sleep with deterministic project worktree scan

Richard Feldman created

Change summary

crates/sidebar/src/sidebar.rs       | 37 +++++++++++++++++++++++++++---
crates/sidebar/src/sidebar_tests.rs |  7 -----
2 files changed, 34 insertions(+), 10 deletions(-)

Detailed changes

crates/sidebar/src/sidebar.rs 🔗

@@ -2370,10 +2370,39 @@ impl Sidebar {
                 }
             }
 
-            // Wait for the worktree to be recognized by the project.
-            cx.background_executor()
-                .timer(std::time::Duration::from_millis(500))
-                .await;
+            // Tell the project about the new worktree and wait for it
+            // to finish scanning so the GitStore creates a Repository.
+            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)
+                })
+            })?;
+
+            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| {

crates/sidebar/src/sidebar_tests.rs 🔗

@@ -5015,12 +5015,7 @@ async fn test_archive_and_restore_single_worktree(cx: &mut TestAppContext) {
         sidebar.activate_archived_thread(metadata, window, cx);
     });
     // The restore flow involves multiple async steps: worktree creation,
-    // a 500ms timer, reset, branch switch, DB cleanup. We need to park
-    // (to let the spawn reach the timer), advance the clock past the
-    // timer, then park again to let the rest complete.
-    cx.run_until_parked();
-    cx.executor()
-        .advance_clock(std::time::Duration::from_secs(1));
+    // project scan, reset, branch switch, DB cleanup.
     cx.run_until_parked();
 
     // 1. The thread should no longer be archived.