git: Don't rebuild the project diff when the active repository changes (#47718)

Cole Miller created

Release Notes:

- N/A

Change summary

crates/project/src/git_store/branch_diff.rs | 46 +++++++++++++++-------
1 file changed, 31 insertions(+), 15 deletions(-)

Detailed changes

crates/project/src/git_store/branch_diff.rs 🔗

@@ -59,17 +59,31 @@ impl BranchDiff {
         cx: &mut Context<Self>,
     ) -> Self {
         let git_store = project.read(cx).git_store().clone();
+        let repo = git_store.read(cx).active_repository();
         let git_store_subscription = cx.subscribe_in(
             &git_store,
             window,
-            move |this, _git_store, event, _window, cx| match event {
-                GitStoreEvent::ActiveRepositoryChanged(_)
-                | GitStoreEvent::RepositoryUpdated(_, RepositoryEvent::StatusesChanged, true)
-                | GitStoreEvent::ConflictsUpdated => {
+            move |this, _git_store, event, _window, cx| {
+                let should_update = match event {
+                    GitStoreEvent::ActiveRepositoryChanged(new_repo_id) => {
+                        this.repo.is_none() && new_repo_id.is_some()
+                    }
+                    GitStoreEvent::RepositoryUpdated(
+                        event_repo_id,
+                        RepositoryEvent::StatusesChanged,
+                        _,
+                    ) => this
+                        .repo
+                        .as_ref()
+                        .is_some_and(|r| r.read(cx).snapshot().id == *event_repo_id),
+                    GitStoreEvent::ConflictsUpdated => this.repo.is_some(),
+                    _ => false,
+                };
+
+                if should_update {
                     cx.emit(BranchDiffEvent::FileListChanged);
                     *this.update_needed.borrow_mut() = ();
                 }
-                _ => {}
             },
         );
 
@@ -78,7 +92,6 @@ impl BranchDiff {
             let this = cx.weak_entity();
             async |cx| Self::handle_status_updates(this, recv, cx).await
         });
-        let repo = git_store.read(cx).active_repository();
 
         Self {
             diff_base: source,
@@ -106,15 +119,18 @@ impl BranchDiff {
         while recv.next().await.is_some() {
             let Ok(needs_update) = this.update(cx, |this, cx| {
                 let mut needs_update = false;
-                let active_repo = this
-                    .project
-                    .read(cx)
-                    .git_store()
-                    .read(cx)
-                    .active_repository();
-                if active_repo != this.repo {
-                    needs_update = true;
-                    this.repo = active_repo;
+
+                if this.repo.is_none() {
+                    let active_repo = this
+                        .project
+                        .read(cx)
+                        .git_store()
+                        .read(cx)
+                        .active_repository();
+                    if active_repo.is_some() {
+                        this.repo = active_repo;
+                        needs_update = true;
+                    }
                 } else if let Some(repo) = this.repo.as_ref() {
                     repo.update(cx, |repo, _| {
                         if let Some(branch) = &repo.branch