fix a bug in handling the case of remote refname being none

This commit is contained in:
Kiril Videlov 2024-06-05 14:31:26 +02:00
parent 9760cee950
commit f4ec31f81b
4 changed files with 57 additions and 43 deletions

View File

@ -19,7 +19,7 @@ pub trait RepositoryExt {
fn checkout_index_builder<'a>(&'a self, index: &'a mut git2::Index) -> CheckoutIndexBuilder; fn checkout_index_builder<'a>(&'a self, index: &'a mut git2::Index) -> CheckoutIndexBuilder;
fn checkout_index_path_builder<P: AsRef<Path>>(&self, path: P) -> Result<()>; fn checkout_index_path_builder<P: AsRef<Path>>(&self, path: P) -> Result<()>;
fn checkout_tree_builder<'a>(&'a self, tree: &'a git2::Tree<'a>) -> CheckoutTreeBuidler; fn checkout_tree_builder<'a>(&'a self, tree: &'a git2::Tree<'a>) -> CheckoutTreeBuidler;
fn find_branch_by_refname(&self, name: &Refname) -> Result<git2::Branch, git2::Error>; fn find_branch_by_refname(&self, name: &Refname) -> Result<Option<git2::Branch>>;
/// Based on the index, add all data similar to `git add .` and create a tree from it, which is returned. /// Based on the index, add all data similar to `git add .` and create a tree from it, which is returned.
fn get_wd_tree(&self) -> Result<Tree>; fn get_wd_tree(&self) -> Result<Tree>;
@ -79,8 +79,8 @@ impl RepositoryExt for Repository {
} }
} }
fn find_branch_by_refname(&self, name: &Refname) -> Result<git2::Branch, git2::Error> { fn find_branch_by_refname(&self, name: &Refname) -> Result<Option<git2::Branch>> {
self.find_branch( let branch = self.find_branch(
&name.simple_name(), &name.simple_name(),
match name { match name {
Refname::Virtual(_) | Refname::Local(_) | Refname::Other(_) => { Refname::Virtual(_) | Refname::Local(_) | Refname::Other(_) => {
@ -88,8 +88,12 @@ impl RepositoryExt for Repository {
} }
Refname::Remote(_) => git2::BranchType::Remote, Refname::Remote(_) => git2::BranchType::Remote,
}, },
) );
// .map_err(Into::into) match branch {
Ok(branch) => Ok(Some(branch)),
Err(e) if e.code() == git2::ErrorCode::NotFound => Ok(None),
Err(e) => Err(e.into()),
}
} }
#[instrument(level = tracing::Level::DEBUG, skip(self), err(Debug))] #[instrument(level = tracing::Level::DEBUG, skip(self), err(Debug))]

View File

@ -1,6 +1,6 @@
use std::{path::Path, time}; use std::{path::Path, time};
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, Context, Result};
use git2::Index; use git2::Index;
use serde::Serialize; use serde::Serialize;
@ -131,11 +131,9 @@ pub fn set_base_branch(
// lookup a branch by name // lookup a branch by name
let target_branch = match repo.find_branch_by_refname(&target_branch_ref.clone().into()) { let target_branch = match repo.find_branch_by_refname(&target_branch_ref.clone().into()) {
Ok(branch) => branch, Ok(branch) => branch,
Err(err) if err.code() == git2::ErrorCode::NotFound => { Err(err) => return Err(err),
bail!("remote branch '{}' not found", target_branch_ref)
} }
Err(err) => return Err(err.into()), .ok_or(anyhow!("remote branch '{}' not found", target_branch_ref))?;
};
let remote = repo let remote = repo
.find_remote(target_branch_ref.remote()) .find_remote(target_branch_ref.remote())
@ -340,6 +338,7 @@ pub fn update_base_branch(
.context(format!("failed to find branch {}", target.branch))?; .context(format!("failed to find branch {}", target.branch))?;
let new_target_commit = target_branch let new_target_commit = target_branch
.ok_or(anyhow!("failed to get branch"))?
.get() .get()
.peel_to_commit() .peel_to_commit()
.context(format!("failed to peel branch {} to commit", target.branch))?; .context(format!("failed to peel branch {} to commit", target.branch))?;
@ -577,7 +576,9 @@ pub fn target_to_base_branch(
target: &target::Target, target: &target::Target,
) -> Result<super::BaseBranch> { ) -> Result<super::BaseBranch> {
let repo = project_repository.repo(); let repo = project_repository.repo();
let branch = repo.find_branch_by_refname(&target.branch.clone().into())?; let branch = repo
.find_branch_by_refname(&target.branch.clone().into())?
.ok_or(anyhow!("failed to get branch"))?;
let commit = branch.get().peel_to_commit()?; let commit = branch.get().peel_to_commit()?;
let oid = commit.id(); let oid = commit.id();

View File

@ -732,19 +732,10 @@ pub fn list_virtual_branches(
let repo = project_repository.repo(); let repo = project_repository.repo();
update_conflict_markers(project_repository, &files)?; update_conflict_markers(project_repository, &files)?;
let upstream_branch = match branch let upstream_branch = match branch.clone().upstream {
.upstream Some(upstream) => repo.find_branch_by_refname(&git::Refname::from(upstream))?,
.as_ref() None => None,
.map(|name| repo.find_branch_by_refname(&git::Refname::from(name))) };
.transpose()
{
Ok(branch) => Ok(branch),
Err(error) => Err(error),
}
.context(format!(
"failed to find upstream branch for {}",
branch.name
))?;
let upstram_branch_commit = upstream_branch let upstram_branch_commit = upstream_branch
.as_ref() .as_ref()
@ -2398,7 +2389,8 @@ fn is_commit_integrated(
) -> Result<bool> { ) -> Result<bool> {
let remote_branch = project_repository let remote_branch = project_repository
.repo() .repo()
.find_branch_by_refname(&target.branch.clone().into())?; .find_branch_by_refname(&target.branch.clone().into())?
.ok_or(anyhow!("failed to get branch"))?;
let remote_head = remote_branch.get().peel_to_commit()?; let remote_head = remote_branch.get().peel_to_commit()?;
let upstream_commits = project_repository.l( let upstream_commits = project_repository.l(
remote_head.id().into(), remote_head.id().into(),
@ -2471,7 +2463,8 @@ pub fn is_remote_branch_mergeable(
let branch = project_repository let branch = project_repository
.repo() .repo()
.find_branch_by_refname(&branch_name.into())?; .find_branch_by_refname(&branch_name.into())?
.ok_or(anyhow!("branch not found"))?;
let branch_oid = branch.get().target().context("detatched head")?; let branch_oid = branch.get().target().context("detatched head")?;
let branch_commit = project_repository let branch_commit = project_repository
.repo() .repo()

View File

@ -149,7 +149,7 @@ impl TestProject {
.remote_repository .remote_repository
.find_branch_by_refname(&branch_name) .find_branch_by_refname(&branch_name)
.unwrap(); .unwrap();
let branch_commit = branch.get().peel_to_commit().unwrap(); let branch_commit = branch.unwrap().get().peel_to_commit().unwrap();
let master_branch = { let master_branch = {
let name: git::Refname = "refs/heads/master".parse().unwrap(); let name: git::Refname = "refs/heads/master".parse().unwrap();
@ -157,7 +157,7 @@ impl TestProject {
.find_branch_by_refname(&name) .find_branch_by_refname(&name)
.unwrap() .unwrap()
}; };
let master_branch_commit = master_branch.get().peel_to_commit().unwrap(); let master_branch_commit = master_branch.unwrap().get().peel_to_commit().unwrap();
let mut rebase_options = git2::RebaseOptions::new(); let mut rebase_options = git2::RebaseOptions::new();
rebase_options.quiet(true); rebase_options.quiet(true);
@ -228,7 +228,7 @@ impl TestProject {
.remote_repository .remote_repository
.find_branch_by_refname(&branch_name) .find_branch_by_refname(&branch_name)
.unwrap(); .unwrap();
let branch_commit = branch.get().peel_to_commit().unwrap(); let branch_commit = branch.as_ref().unwrap().get().peel_to_commit().unwrap();
let master_branch = { let master_branch = {
let name: git::Refname = "refs/heads/master".parse().unwrap(); let name: git::Refname = "refs/heads/master".parse().unwrap();
@ -236,7 +236,12 @@ impl TestProject {
.find_branch_by_refname(&name) .find_branch_by_refname(&name)
.unwrap() .unwrap()
}; };
let master_branch_commit = master_branch.get().peel_to_commit().unwrap(); let master_branch_commit = master_branch
.as_ref()
.unwrap()
.get()
.peel_to_commit()
.unwrap();
let merge_base = { let merge_base = {
let oid = self let oid = self
@ -250,8 +255,8 @@ impl TestProject {
.remote_repository .remote_repository
.merge_trees( .merge_trees(
&merge_base.tree().unwrap(), &merge_base.tree().unwrap(),
&master_branch.get().peel_to_tree().unwrap(), &master_branch.unwrap().get().peel_to_tree().unwrap(),
&branch.get().peel_to_tree().unwrap(), &branch.unwrap().get().peel_to_tree().unwrap(),
None, None,
) )
.unwrap(); .unwrap();
@ -295,24 +300,35 @@ impl TestProject {
} }
pub fn checkout(&self, branch: &git::LocalRefname) { pub fn checkout(&self, branch: &git::LocalRefname) {
let branch: git::Refname = branch.into(); let refname: git::Refname = branch.into();
let head_commit = self let head_commit = self
.local_repository .local_repository
.head() .head()
.unwrap() .unwrap()
.peel_to_commit() .peel_to_commit()
.unwrap(); .unwrap();
let tree = match self.local_repository.find_branch_by_refname(&branch) { let tree = match self.local_repository.find_branch_by_refname(&refname) {
Ok(branch) => branch.get().peel_to_tree().unwrap(), Ok(branch) => match branch {
Err(err) if err.code() == git2::ErrorCode::NotFound => { Some(branch) => branch.get().peel_to_tree().unwrap(),
None => {
self.local_repository self.local_repository
.reference(&branch.to_string(), head_commit.id(), false, "new branch") .reference(&refname.to_string(), head_commit.id(), false, "new branch")
.unwrap(); .unwrap();
head_commit.tree().unwrap() head_commit.tree().unwrap()
} }
},
// Ok(branch) => branch.get().peel_to_tree().unwrap(),
// Err(err) if err.code() == git2::ErrorCode::NotFound => {
// self.local_repository
// .reference(&branch.to_string(), head_commit.id(), false, "new branch")
// .unwrap();
// head_commit.tree().unwrap()
// }
Err(error) => panic!("{:?}", error), Err(error) => panic!("{:?}", error),
}; };
self.local_repository.set_head(&branch.to_string()).unwrap(); self.local_repository
.set_head(&refname.to_string())
.unwrap();
self.local_repository self.local_repository
.checkout_tree_builder(&tree) .checkout_tree_builder(&tree)
.force() .force()