git_store: Avoid redundant work in worktree git repository update (#60205)
## Objective While profiling https://github.com/zed-industries/zed/issues/60102 I noticed `GitStore::update_repositories_from_worktree` does unneeded work. It fires on every `WorktreeUpdatedGitRepositories` event, which under filesystem pressure (`rescan: user dropped`) repeats roughly once per second and can fire more frequently in a large monorepo with many repositories, since the redundant work scales with the number of repositories. ## Solution In `crates/project/src/git_store.rs`: - Drop the per-iteration `Arc<Path>` clone in the repo lookup; compare the borrowed reference instead. - Hoist the `is_trusted` (`can_trust`) computation out of the loop since it only depends on `worktree_id`. No behavior change is intended; this is purely reducing redundant work per event. ## Notes The *frequency* of these events originates upstream in `LocalWorktree::changed_repos` (`crates/worktree/src/worktree.rs`), which re-emits an `UpdatedGitRepository` whenever `git_dir_scan_id` changes on a full rescan. That path is intentionally left untouched here since it involves scan semantics; this PR only addresses the redundant work on the consumer side. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - N/A
This commit is contained in:
1 parent
e2deea1d5b
commit
cf7248308b
1 file changed
+12
-24
@@ -1817,13 +1817,21 @@ impl GitStore {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let mut removed_ids = Vec::new();
|
||||
|
||||
let is_trusted = TrustedWorktrees::try_get_global(cx)
|
||||
.map(|trusted_worktrees| {
|
||||
trusted_worktrees.update(cx, |trusted_worktrees, cx| {
|
||||
trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
|
||||
})
|
||||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
for update in updated_git_repositories.iter() {
|
||||
if let Some((id, existing)) = self.repositories.iter().find(|(_, repo)| {
|
||||
let existing_work_directory_abs_path =
|
||||
repo.read(cx).work_directory_abs_path.clone();
|
||||
Some(&existing_work_directory_abs_path)
|
||||
let existing_work_directory_abs_path = &repo.read(cx).work_directory_abs_path;
|
||||
Some(existing_work_directory_abs_path)
|
||||
== update.old_work_directory_abs_path.as_ref()
|
||||
|| Some(&existing_work_directory_abs_path)
|
||||
|| Some(existing_work_directory_abs_path)
|
||||
== update.new_work_directory_abs_path.as_ref()
|
||||
}) {
|
||||
let repo_id = *id;
|
||||
@@ -1842,17 +1850,6 @@ impl GitStore {
|
||||
update.repository_dir_abs_path.clone()
|
||||
&& let Some(common_dir_abs_path) = update.common_dir_abs_path.clone()
|
||||
{
|
||||
let is_trusted = TrustedWorktrees::try_get_global(cx)
|
||||
.map(|trusted_worktrees| {
|
||||
trusted_worktrees.update(cx, |trusted_worktrees, cx| {
|
||||
trusted_worktrees.can_trust(
|
||||
&self.worktree_store,
|
||||
worktree_id,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
})
|
||||
.unwrap_or(false);
|
||||
existing.update(cx, |existing, cx| {
|
||||
existing.reinitialize_local_backend(
|
||||
new_work_directory_abs_path,
|
||||
@@ -1888,16 +1885,7 @@ impl GitStore {
|
||||
..
|
||||
} = update
|
||||
{
|
||||
let repository_dir_abs_path = repository_dir_abs_path.clone();
|
||||
let common_dir_abs_path = common_dir_abs_path.clone();
|
||||
let id = RepositoryId(next_repository_id.fetch_add(1, atomic::Ordering::Release));
|
||||
let is_trusted = TrustedWorktrees::try_get_global(cx)
|
||||
.map(|trusted_worktrees| {
|
||||
trusted_worktrees.update(cx, |trusted_worktrees, cx| {
|
||||
trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
|
||||
})
|
||||
})
|
||||
.unwrap_or(false);
|
||||
let git_store = cx.weak_entity();
|
||||
let repo = cx.new(|cx| {
|
||||
let mut repo = Repository::local(
|
||||
|
||||
Reference in new issue
Block a user