From ff0864026ed9c981ed15252da4d4541e2190bfd9 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 21 Jul 2023 17:08:31 -0700 Subject: [PATCH] Only fetch statuses for changed paths --- crates/fs/src/repository.rs | 14 +++++++++----- crates/project/src/worktree.rs | 9 ++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/crates/fs/src/repository.rs b/crates/fs/src/repository.rs index 0a43c7ee26..851d495b01 100644 --- a/crates/fs/src/repository.rs +++ b/crates/fs/src/repository.rs @@ -27,7 +27,7 @@ pub trait GitRepository: Send { fn reload_index(&self); fn load_index_text(&self, relative_file_path: &Path) -> Option; fn branch_name(&self) -> Option; - fn statuses(&self) -> TreeMap; + fn statuses(&self, path_prefix: &Path) -> TreeMap; fn status(&self, path: &RepoPath) -> Result>; fn branches(&self) -> Result>; fn change_branch(&self, _: &str) -> Result<()>; @@ -78,9 +78,11 @@ impl GitRepository for LibGitRepository { Some(branch.to_string()) } - fn statuses(&self) -> TreeMap { + fn statuses(&self, path_prefix: &Path) -> TreeMap { let mut map = TreeMap::default(); - if let Some(statuses) = self.statuses(None).log_err() { + let mut options = git2::StatusOptions::new(); + options.pathspec(path_prefix); + if let Some(statuses) = self.statuses(Some(&mut options)).log_err() { for status in statuses .iter() .filter(|status| !status.status().contains(git2::Status::IGNORED)) @@ -201,11 +203,13 @@ impl GitRepository for FakeGitRepository { state.branch_name.clone() } - fn statuses(&self) -> TreeMap { + fn statuses(&self, path_prefix: &Path) -> TreeMap { let mut map = TreeMap::default(); let state = self.state.lock(); for (repo_path, status) in state.worktree_statuses.iter() { - map.insert(repo_path.to_owned(), status.to_owned()); + if repo_path.0.starts_with(path_prefix) { + map.insert(repo_path.to_owned(), status.to_owned()); + } } map } diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 880313b6b1..85cf032464 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -2165,7 +2165,10 @@ impl BackgroundScannerState { let mut containing_repository = None; if !ignore_stack.is_all() { if let Some((workdir_path, repo)) = self.snapshot.local_repo_for_path(&path) { - containing_repository = Some((workdir_path, repo.repo_ptr.lock().statuses())); + if let Ok(repo_path) = path.strip_prefix(&workdir_path.0) { + containing_repository = + Some((workdir_path, repo.repo_ptr.lock().statuses(repo_path))); + } } } if !ancestor_inodes.contains(&entry.inode) { @@ -2357,7 +2360,7 @@ impl BackgroundScannerState { .repository_entries .update(&work_dir, |entry| entry.branch = branch.map(Into::into)); - let statuses = repository.statuses(); + let statuses = repository.statuses(Path::new("")); self.update_git_statuses(&work_dir, &statuses); } } @@ -2415,7 +2418,7 @@ impl BackgroundScannerState { }, ); - let statuses = repo_lock.statuses(); + let statuses = repo_lock.statuses(Path::new("")); self.update_git_statuses(&work_directory, &statuses); drop(repo_lock);