From c2e826f12abbb35ba4eca8afbe3a928b11b3e045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20R=C3=BC=C3=9Fler?= Date: Fri, 29 Aug 2025 09:19:47 +0200 Subject: [PATCH 1/2] Use git_repo() in get_tags() --- asyncgit/src/sync/tags.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/asyncgit/src/sync/tags.rs b/asyncgit/src/sync/tags.rs index f2193b2193..b30f0aaf5a 100644 --- a/asyncgit/src/sync/tags.rs +++ b/asyncgit/src/sync/tags.rs @@ -1,5 +1,8 @@ use super::{get_commits_info, CommitId, RepoPath}; -use crate::{error::Result, sync::repository::repo}; +use crate::{ + error::Result, + sync::{gix_repo, repository::repo}, +}; use scopetime::scope_time; use std::collections::{BTreeMap, HashMap, HashSet}; @@ -58,9 +61,7 @@ pub fn get_tags(repo_path: &RepoPath) -> Result { } }; - let gix_repo: gix::Repository = - gix::ThreadSafeRepository::discover_with_environment_overrides(repo_path.gitpath()) - .map(Into::into)?; + let gix_repo = gix_repo(repo_path)?; let platform = gix_repo.references()?; for mut reference in (platform.tags()?).flatten() { let commit = reference.peel_to_commit(); From 654e43e9696ef5a2859382db9208d7af932170f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20R=C3=BC=C3=9Fler?= Date: Fri, 29 Aug 2025 09:22:55 +0200 Subject: [PATCH 2/2] Use gitoxide in get_branches_info --- asyncgit/src/sync/branch/mod.rs | 158 ++++++++++++++++++++------------ 1 file changed, 97 insertions(+), 61 deletions(-) diff --git a/asyncgit/src/sync/branch/mod.rs b/asyncgit/src/sync/branch/mod.rs index 9b613897fa..b0f034a258 100644 --- a/asyncgit/src/sync/branch/mod.rs +++ b/asyncgit/src/sync/branch/mod.rs @@ -9,11 +9,12 @@ use super::{utils::bytes2string, RepoPath}; use crate::{ error::{Error, Result}, sync::{ - remotes::get_default_remote_for_push_in_repo, + gix_repo, remotes::get_default_remote_for_push_in_repo, repository::repo, utils::get_head_repo, CommitId, }, }; use git2::{Branch, BranchType, Repository}; +use gix::remote::Direction; use scopetime::scope_time; use std::collections::HashSet; @@ -123,76 +124,111 @@ pub fn get_branches_info( ) -> Result> { scope_time!("get_branches_info"); - let repo = repo(repo_path)?; + let gix_repo = gix_repo(repo_path)?; + let platform = gix_repo.references()?; + let head_name = gix_repo.head_name().ok().flatten(); + + let mut branches_for_display: Vec<_> = if local { + platform + .local_branches()? + .flatten() + .filter_map(|mut branch| { + let branch_name = branch.name(); + let name = branch_name.shorten().to_string(); + let reference = branch_name.to_owned().to_string(); + // TODO: + // Verify that this is sufficiently similar to `git2`’s `is_head` by looking at the + // implementation of `git_branch_is_head`. + let is_head = + head_name.as_ref().is_some_and(|head_name| { + head_name.as_ref() == branch_name + }); + + let top_commit = branch.peel_to_commit().ok()?; + let upstream = branch.remote_tracking_ref_name( + // TODO: + // Is that correct? + Direction::Fetch, + ); + + let upstream_branch = match upstream { + Some(Ok(reference)) => Some(UpstreamBranch { + reference: reference.into_owned().to_string(), + }), + _ => None, + }; + + let remote = branch + .remote_name( + // TODO: + // Is that correct? + Direction::Fetch, + ) + .map(|name| name.as_bstr().to_string()); + + let details = BranchDetails::Local(LocalBranch { + is_head, + has_upstream: upstream_branch.is_some(), + upstream: upstream_branch, + remote, + }); - let (filter, remotes_with_tracking) = if local { - (BranchType::Local, HashSet::default()) + Some(BranchInfo { + name, + reference, + top_commit_message: top_commit + .message() + .ok()? + .title + .to_string(), + top_commit: top_commit.into(), + details, + }) + }) + .collect() } else { - let remotes: HashSet<_> = repo - .branches(Some(BranchType::Local))? - .filter_map(|b| { - let branch = b.ok()?.0; - let upstream = branch.upstream(); - upstream - .ok()? - .name_bytes() - .ok() - .map(ToOwned::to_owned) + let remotes_with_tracking: HashSet<_> = platform + .local_branches()? + .flatten() + .filter_map(|branch| { + let upstream = branch.remote_tracking_ref_name( + // TODO: + // Is that correct? + Direction::Fetch, + )?; + Some(upstream.ok()?.into_owned()) }) .collect(); - (BranchType::Remote, remotes) - }; - - let mut branches_for_display: Vec = repo - .branches(Some(filter))? - .map(|b| { - let branch = b?.0; - let top_commit = branch.get().peel_to_commit()?; - let reference = bytes2string(branch.get().name_bytes())?; - let upstream = branch.upstream(); - - let remote = repo - .branch_upstream_remote(&reference) - .ok() - .as_ref() - .and_then(git2::Buf::as_str) - .map(String::from); - let name_bytes = branch.name_bytes()?; + platform + .remote_branches()? + .flatten() + .filter_map(|mut branch| { + let branch_name = branch.name(); + let name = branch_name.shorten().to_string(); + let reference = branch_name.to_owned().to_string(); - let upstream_branch = - upstream.ok().and_then(|upstream| { - bytes2string(upstream.get().name_bytes()) - .ok() - .map(|reference| UpstreamBranch { reference }) + let details = BranchDetails::Remote(RemoteBranch { + has_tracking: remotes_with_tracking + .contains(branch_name), }); - let details = if local { - BranchDetails::Local(LocalBranch { - is_head: branch.is_head(), - has_upstream: upstream_branch.is_some(), - upstream: upstream_branch, - remote, + let top_commit = branch.peel_to_commit().ok()?; + + Some(BranchInfo { + name, + reference, + top_commit_message: top_commit + .message() + .ok()? + .title + .to_string(), + top_commit: top_commit.into(), + details, }) - } else { - BranchDetails::Remote(RemoteBranch { - has_tracking: remotes_with_tracking - .contains(name_bytes), - }) - }; - - Ok(BranchInfo { - name: bytes2string(name_bytes)?, - reference, - top_commit_message: bytes2string( - top_commit.summary_bytes().unwrap_or_default(), - )?, - top_commit: top_commit.id().into(), - details, }) - }) - .filter_map(Result::ok) - .collect(); + .collect() + }; branches_for_display.sort_by(|a, b| a.name.cmp(&b.name));