From 022540d75f6f80c154d429ad5d47fc66f5089a56 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 12 Jan 2025 19:49:50 +0100 Subject: [PATCH] feat: add `Repository::upstream_branch_and_remote_name_for_tracking_branch()` It's a way to learn about the Remote and upstream branch which would match the given local tracking branch. --- gix/src/repository/config/branch.rs | 37 ++++++++++++++++++++++------- gix/src/repository/mod.rs | 11 +++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/gix/src/repository/config/branch.rs b/gix/src/repository/config/branch.rs index 661dbb264d0..e24a15ed54f 100644 --- a/gix/src/repository/config/branch.rs +++ b/gix/src/repository/config/branch.rs @@ -5,7 +5,9 @@ use gix_ref::{FullName, FullNameRef}; use crate::bstr::BStr; use crate::config::cache::util::ApplyLeniencyDefault; use crate::config::tree::{Branch, Push}; -use crate::repository::{branch_remote_ref_name, branch_remote_tracking_ref_name}; +use crate::repository::{ + branch_remote_ref_name, branch_remote_tracking_ref_name, upstream_branch_and_remote_name_for_tracking_branch, +}; use crate::{push, remote}; /// Query configuration related to branches. @@ -20,19 +22,18 @@ impl crate::Repository { self.subsection_str_names_of("branch") } - /// Returns the validated reference on the remote associated with the given `name`, + /// Returns the validated reference name of the upstream branch on the remote associated with the given `name`, /// which will be used when *merging*. - /// The returned value corresponds to the `branch..merge` configuration key. + /// The returned value corresponds to the `branch..merge` configuration key for [`remote::Direction::Fetch`]. + /// For the [push direction](`remote::Direction::Push`) the Git configuration is used for a variety of different outcomes, + /// similar to what would happen when running `git push `. /// - /// Returns `None` if there is no value at the given key, or if no remote or remote ref is configured. - /// May return an error if the reference name to be returned is invalid. + /// Returns `None` if there is nothing configured, or if no remote or remote ref is configured. /// /// ### Note /// - /// This name refers to what Git calls upstream branch (as opposed to upstream *tracking* branch). + /// The returned name refers to what Git calls upstream branch (as opposed to upstream *tracking* branch). /// The value is also fast to retrieve compared to its tracking branch. - /// Also note that a [remote::Direction] isn't used here as Git only supports (and requires) configuring - /// the remote to fetch from, not the one to push to. /// /// See also [`Reference::remote_ref_name()`](crate::Reference::remote_ref_name()). #[doc(alias = "branch_upstream_name", alias = "git2")] @@ -125,6 +126,26 @@ impl crate::Repository { .map(|res| res.map_err(Into::into)) } + /// Given a local `tracking_branch` name, find the remote that maps to it along with the name of the branch on + /// the side of the remote, also called upstream branch. + /// + /// Return `Ok(None)` if there is no remote with fetch-refspecs that would match `tracking_branch` on the right-hand side, + /// or `Err` if the matches were ambiguous. + /// + /// ### Limitations + /// + /// A single valid mapping is required as fine-grained matching isn't implemented yet. This means that + pub fn upstream_branch_and_remote_name_for_tracking_branch( + &self, + tracking_branch: &FullNameRef, + ) -> Result< + Option<(Cow<'_, FullNameRef>, remote::Name<'_>)>, + upstream_branch_and_remote_name_for_tracking_branch::Error, + > { + for remote_name in self.remote_names() {} + todo!() + } + /// Returns the unvalidated name of the remote associated with the given `short_branch_name`, /// typically `main` instead of `refs/heads/main`. /// In some cases, the returned name will be an URL. diff --git a/gix/src/repository/mod.rs b/gix/src/repository/mod.rs index 4d5ca4093fa..eabf8588968 100644 --- a/gix/src/repository/mod.rs +++ b/gix/src/repository/mod.rs @@ -360,6 +360,17 @@ pub mod branch_remote_tracking_ref_name { } } +/// +pub mod upstream_branch_and_remote_name_for_tracking_branch { + /// The error returned by [Repository::upstream_branch_and_remote_name_for_tracking_branch()](crate::Repository::upstream_branch_and_remote_name_for_tracking_branch()). + #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] + pub enum Error { + #[error("The name of the tracking reference was invalid")] + ValidateTrackingRef(#[from] gix_validate::reference::name::Error), + } +} + /// #[cfg(feature = "attributes")] pub mod pathspec_defaults_ignore_case {