From 0b1d3d78a49ef4be76f8edafe1d5d799092928d9 Mon Sep 17 00:00:00 2001 From: Mayank Verma Date: Thu, 6 Nov 2025 10:48:08 +0530 Subject: [PATCH] git: Fix pull failing when tracking remote with different branch name (#41768) Closes #31430 Release Notes: - Fixed git pull failing when tracking remote with different branch name Here's a before/after comparison when `dev` branch has upstream set to `origin/main`: https://github.com/user-attachments/assets/3a47e736-c7b7-4634-8cd1-aca7300c3a73 --- crates/fs/src/fake_git_repo.rs | 2 +- crates/git/src/repository.rs | 6 +++--- crates/git_ui/src/git_panel.rs | 13 ++++++------- crates/project/src/git_store.rs | 23 +++++++++++++---------- crates/proto/proto/git.proto | 2 +- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/crates/fs/src/fake_git_repo.rs b/crates/fs/src/fake_git_repo.rs index a6e9bcdac67db7564b5b6c62323e2c7b209651cb..4652e0fdb098a8b7ee6bfdb5ac9f3215831afb97 100644 --- a/crates/fs/src/fake_git_repo.rs +++ b/crates/fs/src/fake_git_repo.rs @@ -541,7 +541,7 @@ impl GitRepository for FakeGitRepository { fn pull( &self, - _branch: String, + _branch: Option, _remote: String, _rebase: bool, _askpass: AskPassDelegate, diff --git a/crates/git/src/repository.rs b/crates/git/src/repository.rs index 6fcbbb919ca6970cd56cdc9fe6f6be3a745842fa..225ab81abdb3e5299880731951832eee000d8e5c 100644 --- a/crates/git/src/repository.rs +++ b/crates/git/src/repository.rs @@ -531,7 +531,7 @@ pub trait GitRepository: Send + Sync { fn pull( &self, - branch_name: String, + branch_name: Option, upstream_name: String, rebase: bool, askpass: AskPassDelegate, @@ -1689,7 +1689,7 @@ impl GitRepository for RealGitRepository { fn pull( &self, - branch_name: String, + branch_name: Option, remote_name: String, rebase: bool, ask_pass: AskPassDelegate, @@ -1713,7 +1713,7 @@ impl GitRepository for RealGitRepository { command .arg(remote_name) - .arg(branch_name) + .args(branch_name) .stdout(smol::process::Stdio::piped()) .stderr(smol::process::Stdio::piped()); diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index e233edcbbffd4402b0bcf4f18539dfda00759c59..7cbcef3dce0433ef3b14e4f60bf0e191c72bd2cb 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -2250,14 +2250,13 @@ impl GitPanel { this.askpass_delegate(format!("git pull {}", remote.name), window, cx) })?; + let branch_name = branch + .upstream + .is_none() + .then(|| branch.name().to_owned().into()); + let pull = repo.update(cx, |repo, cx| { - repo.pull( - branch.name().to_owned().into(), - remote.name.clone(), - rebase, - askpass, - cx, - ) + repo.pull(branch_name, remote.name.clone(), rebase, askpass, cx) })?; let remote_message = pull.await?; diff --git a/crates/project/src/git_store.rs b/crates/project/src/git_store.rs index 486d51fef88b6b8d3cb507efa7c97af2c424f776..f44a3cb570109651b9231f73b9e25c450b78dacc 100644 --- a/crates/project/src/git_store.rs +++ b/crates/project/src/git_store.rs @@ -1723,7 +1723,7 @@ impl GitStore { &mut cx, ); - let branch_name = envelope.payload.branch_name.into(); + let branch_name = envelope.payload.branch_name.map(|name| name.into()); let remote_name = envelope.payload.remote_name.into(); let rebase = envelope.payload.rebase; @@ -4293,7 +4293,7 @@ impl Repository { pub fn pull( &mut self, - branch: SharedString, + branch: Option, remote: SharedString, rebase: bool, askpass: AskPassDelegate, @@ -4303,13 +4303,16 @@ impl Repository { let askpass_id = util::post_inc(&mut self.latest_askpass_id); let id = self.id; - let status = if rebase { - Some(format!("git pull --rebase {} {}", remote, branch).into()) - } else { - Some(format!("git pull {} {}", remote, branch).into()) - }; + let mut status = "git pull".to_string(); + if rebase { + status.push_str(" --rebase"); + } + status.push_str(&format!(" {}", remote)); + if let Some(b) = &branch { + status.push_str(&format!(" {}", b)); + } - self.send_job(status, move |git_repo, cx| async move { + self.send_job(Some(status.into()), move |git_repo, cx| async move { match git_repo { RepositoryState::Local { backend, @@ -4318,7 +4321,7 @@ impl Repository { } => { backend .pull( - branch.to_string(), + branch.as_ref().map(|b| b.to_string()), remote.to_string(), rebase, askpass, @@ -4339,7 +4342,7 @@ impl Repository { repository_id: id.to_proto(), askpass_id, rebase, - branch_name: branch.to_string(), + branch_name: branch.as_ref().map(|b| b.to_string()), remote_name: remote.to_string(), }) .await diff --git a/crates/proto/proto/git.proto b/crates/proto/proto/git.proto index a25934467a4a4f5685b168efcc20734254a7dd19..d8ce1d2a75633eb4f31378ee574ffe043f956e05 100644 --- a/crates/proto/proto/git.proto +++ b/crates/proto/proto/git.proto @@ -403,7 +403,7 @@ message Pull { reserved 2; uint64 repository_id = 3; string remote_name = 4; - string branch_name = 5; + optional string branch_name = 5; uint64 askpass_id = 6; bool rebase = 7; }