use crate::bare::GitBare; use crate::error::GitResult; use crate::paginate; use crate::pb::{Branch, ListBranchesRequest, ListBranchesResponse}; impl GitBare { pub fn list_branches(&self, request: ListBranchesRequest) -> GitResult { let repo = self.gix_repo()?; let merged_set = if request.merged_into_head || request.not_merged_into_head { let flag = if request.merged_into_head { "--merged" } else { "--no-merged" }; let check = duct::cmd( "git", [ "--git-dir", self.bare_dir.to_string_lossy().as_ref(), "branch", flag, "HEAD", ], ) .stdout_capture() .stderr_capture() .unchecked() .run(); match check { Ok(out) => String::from_utf8_lossy(&out.stdout) .lines() .map(|l| l.trim().trim_start_matches("* ").to_string()) .collect::>(), Err(_) => Vec::new(), } } else { Vec::new() }; let mut branches: Vec = Vec::new(); for r in repo.references()?.local_branches()? { let mut r = r.map_err(|e| crate::error::GitError::Gix(e.to_string()))?; let name = r.name().shorten().to_string(); if !request.pattern.is_empty() && !name.contains(&request.pattern) { continue; } if request.merged_into_head && !merged_set.contains(&name) { continue; } if request.not_merged_into_head && merged_set.contains(&name) { continue; } let hex = r .peel_to_id() .ok() .map(|id| id.to_string()) .unwrap_or_default(); branches.push(Branch { name, full_ref: r.name().to_string(), target_oid: Some(self.oid_to_pb(hex)), commit: None, upstream: None, is_default: false, is_head: false, is_merged: false, is_detached: false, }); } paginate::apply_sort(&mut branches, request.sort_direction); let (branches, page_info) = paginate::paginate(&branches, request.pagination.as_ref()); Ok(ListBranchesResponse { branches, page_info: Some(page_info), }) } }