From a2ca58a3f6b1a5eff0c650d60b9f50928e946e6f Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Sat, 20 Mar 2021 18:47:53 +0100 Subject: [PATCH] use branches upstream remote if it is already tracked (#598) closes #597 --- CHANGELOG.md | 3 ++ asyncgit/src/sync/branch/mod.rs | 51 +++++++++++++++++++++++++++++++++ asyncgit/src/sync/mod.rs | 4 +-- src/components/push.rs | 21 ++++++++++++-- 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca666127..1ff35032 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Fixed +- push branch to its tracking remote ([#597](https://github.com/extrawurst/gitui/issues/597)) + ## [0.13.0] - 2020-03-15 - Happy Birthday GitUI 🥳 Thanks for your interest and support over this year! Read more about the 1 year anniversary reflections of this project on my [blog](https://blog.extrawurst.org/general/programming/rust/2021/03/15/gitui-a-year-in-opensource.html). diff --git a/asyncgit/src/sync/branch/mod.rs b/asyncgit/src/sync/branch/mod.rs index 3abe6a3d..7c55e5bd 100644 --- a/asyncgit/src/sync/branch/mod.rs +++ b/asyncgit/src/sync/branch/mod.rs @@ -128,6 +128,22 @@ pub(crate) fn branch_set_upstream( Ok(()) } +/// returns remote of the upstream tracking branch for `branch` +pub fn get_branch_remote( + repo_path: &str, + branch: &str, +) -> Result> { + let repo = utils::repo(repo_path)?; + let branch = repo.find_branch(branch, BranchType::Local)?; + let reference = bytes2string(branch.get().name_bytes())?; + let remote_name = repo.branch_upstream_remote(&reference).ok(); + if let Some(remote_name) = remote_name { + Ok(Some(bytes2string(remote_name.as_ref())?)) + } else { + Ok(None) + } +} + /// returns whether the pull merge strategy is set to rebase pub fn config_is_pull_rebase(repo_path: &str) -> Result { let repo = utils::repo(repo_path)?; @@ -411,6 +427,41 @@ mod tests_branches { assert_eq!(branches.len(), 3); assert_eq!(branches[1].remote.as_ref().unwrap(), "r1"); assert_eq!(branches[2].remote.as_ref().unwrap(), "r2"); + + assert_eq!( + get_branch_remote(repo_path, "r1branch") + .unwrap() + .unwrap(), + String::from("r1") + ); + + assert_eq!( + get_branch_remote(repo_path, "r2branch") + .unwrap() + .unwrap(), + String::from("r2") + ); + } + + #[test] + fn test_branch_remote_no_upstream() { + let (_r, repo) = repo_init().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); + + assert_eq!( + get_branch_remote(repo_path, "master").unwrap(), + None + ); + } + + #[test] + fn test_branch_remote_no_branch() { + let (_r, repo) = repo_init().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); + + assert!(get_branch_remote(repo_path, "foo").is_err()); } } diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index 71977edd..c31048fe 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -26,8 +26,8 @@ pub mod utils; pub use branch::{ branch_compare_upstream, checkout_branch, config_is_pull_rebase, - create_branch, delete_branch, get_branches_info, - merge_commit::merge_upstream_commit, + create_branch, delete_branch, get_branch_remote, + get_branches_info, merge_commit::merge_upstream_commit, merge_ff::branch_merge_upstream_fastforward, merge_rebase::merge_upstream_rebase, rename::rename_branch, BranchCompare, BranchInfo, diff --git a/src/components/push.rs b/src/components/push.rs index 266ac76a..7755bb05 100644 --- a/src/components/push.rs +++ b/src/components/push.rs @@ -15,7 +15,7 @@ use asyncgit::{ extract_username_password, need_username_password, BasicAuthCredential, }, - get_default_remote, + get_branch_remote, get_default_remote, }, AsyncNotification, AsyncPush, PushRequest, RemoteProgress, RemoteProgressState, CWD, @@ -78,6 +78,7 @@ impl PushComponent { self.branch = branch; self.force = force; self.show()?; + if need_username_password()? { let cred = extract_username_password().unwrap_or_else(|_| { @@ -99,10 +100,26 @@ impl PushComponent { cred: Option, force: bool, ) -> Result<()> { + let remote = if let Some(remote) = + get_branch_remote(CWD, &self.branch)? + { + log::info!("push: branch '{}' has upstream for remote '{}' - using that",self.branch,remote); + remote + } else { + log::info!("push: branch '{}' has no upstream - looking up default remote",self.branch); + let remote = get_default_remote(CWD)?; + log::info!( + "push: branch '{}' to remote '{}'", + self.branch, + remote + ); + remote + }; + self.pending = true; self.progress = None; self.git_push.request(PushRequest { - remote: get_default_remote(CWD)?, + remote, branch: self.branch.clone(), force, basic_credential: cred,