diff --git a/asyncgit/src/sync/branch/mod.rs b/asyncgit/src/sync/branch/mod.rs index a6f019b9..9d50d457 100644 --- a/asyncgit/src/sync/branch/mod.rs +++ b/asyncgit/src/sync/branch/mod.rs @@ -55,9 +55,18 @@ pub struct LocalBranch { /// pub has_upstream: bool, /// + pub upstream: Option, + /// pub remote: Option, } +/// +#[derive(Clone, Debug)] +pub struct UpstreamBranch { + /// + pub reference: String, +} + /// #[derive(Clone, Debug)] pub struct RemoteBranch { @@ -154,10 +163,18 @@ pub fn get_branches_info( let name_bytes = branch.name_bytes()?; + let upstream_branch = + upstream.ok().and_then(|upstream| { + bytes2string(upstream.get().name_bytes()) + .ok() + .map(|reference| UpstreamBranch { reference }) + }); + let details = if local { BranchDetails::Local(LocalBranch { is_head: branch.is_head(), - has_upstream: upstream.is_ok(), + has_upstream: upstream_branch.is_some(), + upstream: upstream_branch, remote, }) } else { diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index 5bd4b0b7..a7bf7d64 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -41,7 +41,7 @@ pub use branch::{ merge_commit::merge_upstream_commit, merge_ff::branch_merge_upstream_fastforward, merge_rebase::merge_upstream_rebase, rename::rename_branch, - validate_branch_name, BranchCompare, BranchInfo, + validate_branch_name, BranchCompare, BranchDetails, BranchInfo, }; pub use commit::{amend, commit, tag_commit}; pub use commit_details::{ diff --git a/src/components/commitlist.rs b/src/components/commitlist.rs index bdf67ea8..48cccc1a 100644 --- a/src/components/commitlist.rs +++ b/src/components/commitlist.rs @@ -13,7 +13,8 @@ use crate::{ }; use anyhow::Result; use asyncgit::sync::{ - checkout_commit, BranchInfo, CommitId, RepoPathRef, Tags, + checkout_commit, BranchDetails, BranchInfo, CommitId, + RepoPathRef, Tags, }; use chrono::{DateTime, Local}; use crossterm::event::Event; @@ -430,13 +431,40 @@ impl CommitList { let remote_branches = self .remote_branches .get(&e.id) - .map(|remote_branches| { - remote_branches + .and_then(|remote_branches| { + let filtered_branches: Vec<_> = remote_branches .iter() + .filter(|remote_branch| { + self.local_branches + .get(&e.id) + .map_or(true, |local_branch| { + local_branch.iter().any( + |local_branch| { + let has_corresponding_local_branch = match &local_branch.details { + BranchDetails::Local(details) => + details + .upstream + .as_ref() + .map_or(false, |upstream| upstream.reference == remote_branch.reference), + BranchDetails::Remote(_) => + false, + }; + + !has_corresponding_local_branch + }, + ) + }) + }) .map(|remote_branch| { format!("[{0}]", remote_branch.name) }) - .join(" ") + .collect(); + + if filtered_branches.is_empty() { + None + } else { + Some(filtered_branches.join(" ")) + } }); let marked = if any_marked {