git: Always reload current branch after pushing (cherry-pick #28327) (#28394)

Cole Miller created

Closes #ISSUE

Release Notes:

- Fixed the git panel sometimes failing to update after pushing to a
remote.

Change summary

crates/project/src/git_store.rs | 37 ++++++++++++++++++++++++++++++----
1 file changed, 32 insertions(+), 5 deletions(-)

Detailed changes

crates/project/src/git_store.rs 🔗

@@ -3174,29 +3174,56 @@ impl Repository {
         remote: SharedString,
         options: Option<PushOptions>,
         askpass: AskPassDelegate,
-        _cx: &mut App,
+        cx: &mut Context<Self>,
     ) -> oneshot::Receiver<Result<RemoteCommandOutput>> {
         let askpass_delegates = self.askpass_delegates.clone();
         let askpass_id = util::post_inc(&mut self.latest_askpass_id);
         let id = self.id;
 
-        self.send_job(move |git_repo, cx| async move {
+        let updates_tx = self
+            .git_store()
+            .and_then(|git_store| match &git_store.read(cx).state {
+                GitStoreState::Local { downstream, .. } => downstream
+                    .as_ref()
+                    .map(|downstream| downstream.updates_tx.clone()),
+                _ => None,
+            });
+        let this = cx.weak_entity();
+
+        self.send_job(move |git_repo, mut cx| async move {
             match git_repo {
                 RepositoryState::Local {
                     backend,
                     environment,
                     ..
                 } => {
-                    backend
+                    let result = backend
                         .push(
                             branch.to_string(),
                             remote.to_string(),
                             options,
                             askpass,
                             environment.clone(),
-                            cx,
+                            cx.clone(),
                         )
-                        .await
+                        .await;
+                    if result.is_ok() {
+                        let branches = backend.branches().await?;
+                        let branch = branches.into_iter().find(|branch| branch.is_head);
+                        log::info!("head branch after scan is {branch:?}");
+                        let snapshot = this.update(&mut cx, |this, cx| {
+                            this.snapshot.branch = branch;
+                            let snapshot = this.snapshot.clone();
+                            cx.emit(RepositoryEvent::Updated { full_scan: false });
+                            snapshot
+                        })?;
+                        if let Some(updates_tx) = updates_tx {
+                            updates_tx
+                                .unbounded_send(DownstreamUpdate::UpdateRepository(snapshot))
+                                .ok();
+                        }
+                    }
+                    result
                 }
                 RepositoryState::Remote { project_id, client } => {
                     askpass_delegates.lock().insert(askpass_id, askpass);