handle the case when a branch is only a virtual branch and a remote is not yet set

This commit is contained in:
Kiril Videlov 2024-07-25 13:53:02 +02:00
parent 5147638d74
commit a0c724077a
No known key found for this signature in database
GPG Key ID: A4C733025427C471

View File

@ -1,4 +1,3 @@
use std::any::TypeId;
use std::cmp::max; use std::cmp::max;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
@ -12,6 +11,7 @@ use gitbutler_branch::BranchId;
use gitbutler_branch::VirtualBranchesHandle; use gitbutler_branch::VirtualBranchesHandle;
use gitbutler_command_context::ProjectRepository; use gitbutler_command_context::ProjectRepository;
use gitbutler_reference::normalize_branch_name;
use serde::Serialize; use serde::Serialize;
use crate::{VirtualBranch, VirtualBranchesExt}; use crate::{VirtualBranch, VirtualBranchesExt};
@ -54,7 +54,7 @@ fn combine_branches<'a>(
group_branches.push(GroupBranch::Git(branch)); group_branches.push(GroupBranch::Git(branch));
} }
// Group branches by identity // Group branches by identity
let mut groups: HashMap<BString, Vec<&GroupBranch>> = HashMap::new(); let mut groups: HashMap<Option<BString>, Vec<&GroupBranch>> = HashMap::new();
for branch in group_branches.iter() { for branch in group_branches.iter() {
let identity = branch.identity(); let identity = branch.identity();
if let Some(group) = groups.get_mut(&identity) { if let Some(group) = groups.get_mut(&identity) {
@ -94,7 +94,7 @@ fn combine_branches<'a>(
/// Converts a group of branches with the same identity into a single branch entry /// Converts a group of branches with the same identity into a single branch entry
fn branch_group_to_branch( fn branch_group_to_branch(
identity: BString, identity: Option<BString>,
group_branches: Vec<&GroupBranch>, group_branches: Vec<&GroupBranch>,
repo: &git2::Repository, repo: &git2::Repository,
local_author: &Author, local_author: &Author,
@ -192,8 +192,15 @@ fn branch_group_to_branch(
virtual_branch.map_or(0, |x| x.updated_timestamp_ms), virtual_branch.map_or(0, |x| x.updated_timestamp_ms),
); );
// If this was a virtual branch and there was never any remote set, use the virtual branch name as the identity
let identity = identity.unwrap_or(BString::from(
virtual_branch
.map(|vb| normalize_branch_name(&vb.name))
.unwrap_or_default(),
));
let branch = BranchListing { let branch = BranchListing {
name: identity.to_string(), name: identity,
remotes, remotes,
virtual_branch: virtual_branch_reference, virtual_branch: virtual_branch_reference,
lines_added: diff_stats.insertions(), lines_added: diff_stats.insertions(),
@ -217,15 +224,12 @@ enum GroupBranch<'a> {
impl GroupBranch<'_> { impl GroupBranch<'_> {
/// A name identifier for the branch. When multiple branches (e.g. virtual, local, reomte) have the same identity, /// A name identifier for the branch. When multiple branches (e.g. virtual, local, reomte) have the same identity,
/// they are grouped together under the same `Branch` entry. /// they are grouped together under the same `Branch` entry.
fn identity(&self) -> BString { fn identity(&self) -> Option<BString> {
match self { match self {
GroupBranch::Git(branch) => branch.name().shorten().into(), GroupBranch::Git(branch) => Some(branch.name().shorten().into()),
// When a user changes the remote name via the "set remote branch name" in the UI, // When a user changes the remote name via the "set remote branch name" in the UI,
// the virtual branch will be in a different group. This is probably the desired behavior. // the virtual branch will be in a different group. This is probably the desired behavior.
GroupBranch::Virtual(branch) => branch GroupBranch::Virtual(branch) => branch.upstream.clone().map(|x| x.branch().into()),
.upstream
.clone()
.map_or(BString::default(), |x| x.branch().into()),
} }
} }
} }
@ -256,7 +260,8 @@ fn should_list_git_branch(branch: &gix::Reference, vb_handle: &VirtualBranchesHa
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct BranchListing { pub struct BranchListing {
/// The name of the branch (e.g. `main`, `feature/branch`), excluding the remote name /// The name of the branch (e.g. `main`, `feature/branch`), excluding the remote name
pub name: String, #[serde(serialize_with = "gitbutler_serde::serde::as_string_lossy")]
pub name: BString,
/// This is a list of remote that this branch can be found on (e.g. `origin`, `upstream` etc.). /// This is a list of remote that this branch can be found on (e.g. `origin`, `upstream` etc.).
/// If this branch is a local branch, this list will be empty. /// If this branch is a local branch, this list will be empty.
#[serde(serialize_with = "gitbutler_serde::serde::as_string_lossy_vec")] #[serde(serialize_with = "gitbutler_serde::serde::as_string_lossy_vec")]