git error

This commit is contained in:
Nikita Galaiko 2023-08-31 12:53:57 +02:00 committed by GitButler
parent fef92705bc
commit 7860dd3c97
12 changed files with 185 additions and 118 deletions

View File

@ -36,7 +36,7 @@ pub enum Error {
#[error("path not found: {0}")]
ProjectPathNotFound(path::PathBuf),
#[error(transparent)]
Git(#[from] git2::Error),
Git(#[from] git::Error),
#[error(transparent)]
Other(#[from] anyhow::Error),
}
@ -581,17 +581,15 @@ impl Repository {
let repo = git::Repository::open(&project.path).context("failed to open repository")?;
let reference = repo.find_reference(&refname);
match reference {
Err(e) => {
if e.code() == git2::ErrorCode::NotFound {
tracing::warn!(
"{}: reference {} not found, no migration",
project.id,
refname
);
return Ok(false);
}
Err(e.into())
Err(git::Error::NotFound(_)) => {
tracing::warn!(
"{}: reference {} not found, no migration",
project.id,
refname
);
Ok(false)
}
Err(e) => Err(e.into()),
Result::Ok(reference) => {
let mut walker = repo.revwalk()?;
walker.push(reference.target().unwrap().into())?;
@ -723,12 +721,10 @@ fn build_wd_tree(
.context("failed to write wd tree")?;
Ok(wd_tree_oid.into())
}
Err(git::Error::NotFound(_)) => build_wd_tree_from_repo(gb_repository, project_repository)
.context("failed to build wd index"),
Err(e) => {
if e.code() != git2::ErrorCode::NotFound {
return Err(e.into());
}
build_wd_tree_from_repo(gb_repository, project_repository)
.context("failed to build wd index")
return Err(e.into());
}
}
}
@ -1106,20 +1102,17 @@ fn write_gb_commit(
)?;
Ok(new_commit)
}
Err(e) => {
if e.code() == git2::ErrorCode::NotFound {
let new_commit = gb_repository.git_repository.commit(
Some("refs/heads/current"),
&author, // author
&comitter, // committer
"gitbutler check", // commit message
&gb_repository.git_repository.find_tree(tree_id).unwrap(), // tree
&[], // parents
)?;
Ok(new_commit)
} else {
Err(e.into())
}
Err(git::Error::NotFound(_)) => {
let new_commit = gb_repository.git_repository.commit(
Some("refs/heads/current"),
&author, // author
&comitter, // committer
"gitbutler check", // commit message
&gb_repository.git_repository.find_tree(tree_id).unwrap(), // tree
&[], // parents
)?;
Ok(new_commit)
}
Err(e) => Err(e.into()),
}
}

View File

@ -24,7 +24,7 @@ impl<'repo> Branch<'repo> {
}
pub fn upstream(&self) -> Result<Branch<'repo>> {
self.branch.upstream().map(Into::into)
self.branch.upstream().map(Into::into).map_err(Into::into)
}
pub fn refname_bytes(&self) -> &[u8] {
@ -32,7 +32,11 @@ impl<'repo> Branch<'repo> {
}
pub fn peel_to_commit(&self) -> Result<Commit<'repo>> {
self.branch.get().peel_to_commit().map(Into::into)
self.branch
.get()
.peel_to_commit()
.map(Into::into)
.map_err(Into::into)
}
pub fn is_remote(&self) -> bool {

View File

@ -34,7 +34,7 @@ impl<'repo> Commit<'repo> {
}
pub fn tree(&self) -> Result<Tree<'repo>> {
self.commit.tree().map(Into::into)
self.commit.tree().map(Into::into).map_err(Into::into)
}
pub fn tree_id(&self) -> Oid {
@ -42,7 +42,7 @@ impl<'repo> Commit<'repo> {
}
pub fn parent(&self, n: usize) -> Result<Commit<'repo>> {
self.commit.parent(n).map(Into::into)
self.commit.parent(n).map(Into::into).map_err(Into::into)
}
pub fn time(&self) -> git2::Time {

View File

@ -1 +1,21 @@
pub type Result<T> = std::result::Result<T, git2::Error>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("not found: {0}")]
NotFound(Box<dyn std::error::Error + Send + Sync>),
#[error("authentication failed")]
Auth(Box<dyn std::error::Error + Send + Sync>),
#[error(transparent)]
Other(Box<dyn std::error::Error + Send + Sync>),
}
impl From<git2::Error> for Error {
fn from(err: git2::Error) -> Self {
match err.code() {
git2::ErrorCode::NotFound => Error::NotFound(err.into()),
git2::ErrorCode::Auth => Error::Auth(err.into()),
_ => Error::Other(err.into()),
}
}
}
pub type Result<T> = std::result::Result<T, Error>;

View File

@ -37,19 +37,22 @@ impl Index {
T: git2::IntoCString,
I: IntoIterator<Item = T>,
{
self.index.add_all(pathspecs, flag, cb)
self.index.add_all(pathspecs, flag, cb).map_err(Into::into)
}
pub fn conflicts(&self) -> Result<git2::IndexConflicts> {
self.index.conflicts()
self.index.conflicts().map_err(Into::into)
}
pub fn read_tree(&mut self, tree: &Tree) -> Result<()> {
self.index.read_tree(tree.into())
self.index.read_tree(tree.into()).map_err(Into::into)
}
pub fn write_tree_to(&mut self, repo: &Repository) -> Result<Oid> {
self.index.write_tree_to(repo.into()).map(Into::into)
self.index
.write_tree_to(repo.into())
.map(Into::into)
.map_err(Into::into)
}
pub fn has_conflicts(&self) -> bool {
@ -57,23 +60,23 @@ impl Index {
}
pub fn write_tree(&mut self) -> Result<Oid> {
self.index.write_tree().map(Into::into)
self.index.write_tree().map(Into::into).map_err(Into::into)
}
pub fn add(&mut self, entry: &IndexEntry) -> Result<()> {
self.index.add(&entry.clone().into())
self.index.add(&entry.clone().into()).map_err(Into::into)
}
pub fn write(&mut self) -> Result<()> {
self.index.write()
self.index.write().map_err(Into::into)
}
pub fn add_path(&mut self, path: &path::Path) -> Result<()> {
self.index.add_path(path)
self.index.add_path(path).map_err(Into::into)
}
pub fn remove_path(&mut self, path: &path::Path) -> Result<()> {
self.index.remove_path(path)
self.index.remove_path(path).map_err(Into::into)
}
pub fn get_path(&self, path: &path::Path, stage: i32) -> Option<IndexEntry> {

View File

@ -24,11 +24,17 @@ impl<'repo> Reference<'repo> {
}
pub fn peel_to_commit(&self) -> Result<Commit<'repo>> {
self.reference.peel_to_commit().map(Into::into)
self.reference
.peel_to_commit()
.map(Into::into)
.map_err(Into::into)
}
pub fn peel_to_tree(&self) -> Result<Tree<'repo>> {
self.reference.peel_to_tree().map(Into::into)
self.reference
.peel_to_tree()
.map(Into::into)
.map_err(Into::into)
}
pub fn rename(
@ -40,10 +46,11 @@ impl<'repo> Reference<'repo> {
self.reference
.rename(new_name, force, log_message)
.map(Into::into)
.map_err(Into::into)
}
pub fn delete(&mut self) -> Result<()> {
self.reference.delete()
self.reference.delete().map_err(Into::into)
}
pub fn is_remote(&self) -> bool {

View File

@ -24,7 +24,7 @@ impl<'repo> Remote<'repo> {
refspec: &[&str],
opts: Option<&mut git2::PushOptions<'_>>,
) -> Result<()> {
self.inner.push(refspec, opts)
self.inner.push(refspec, opts).map_err(Into::into)
}
pub fn fetch(
@ -32,6 +32,6 @@ impl<'repo> Remote<'repo> {
refspec: &[&str],
opts: Option<&mut git2::FetchOptions<'_>>,
) -> Result<()> {
self.inner.fetch(refspec, opts, None)
self.inner.fetch(refspec, opts, None).map_err(Into::into)
}
}

View File

@ -32,13 +32,17 @@ impl Repository {
}
pub fn add_disk_alternate(&self, path: &str) -> Result<()> {
self.0.odb().and_then(|odb| odb.add_disk_alternate(path))
self.0
.odb()
.and_then(|odb| odb.add_disk_alternate(path))
.map_err(Into::into)
}
pub fn find_annotated_commit(&self, id: Oid) -> Result<AnnotatedCommit<'_>> {
self.0
.find_annotated_commit(id.into())
.map(AnnotatedCommit::from)
.map_err(Into::into)
}
pub fn rebase(
@ -48,16 +52,21 @@ impl Repository {
onto: Option<&AnnotatedCommit<'_>>,
opts: Option<&mut git2::RebaseOptions<'_>>,
) -> Result<git2::Rebase<'_>> {
self.0.rebase(
branch.map(|commit| commit.into()),
upstream.map(|commit| commit.into()),
onto.map(|commit| commit.into()),
opts,
)
self.0
.rebase(
branch.map(|commit| commit.into()),
upstream.map(|commit| commit.into()),
onto.map(|commit| commit.into()),
opts,
)
.map_err(Into::into)
}
pub fn merge_base(&self, one: Oid, two: Oid) -> Result<Oid> {
self.0.merge_base(one.into(), two.into()).map(Oid::from)
self.0
.merge_base(one.into(), two.into())
.map(Oid::from)
.map_err(Into::into)
}
pub fn merge_trees(
@ -74,6 +83,7 @@ impl Repository {
None,
)
.map(Index::from)
.map_err(Into::into)
}
pub fn diff_tree_to_tree(
@ -82,11 +92,13 @@ impl Repository {
new_tree: Option<&Tree<'_>>,
opts: Option<&mut git2::DiffOptions>,
) -> Result<git2::Diff<'_>> {
self.0.diff_tree_to_tree(
old_tree.map(|tree| tree.into()),
new_tree.map(|tree| tree.into()),
opts,
)
self.0
.diff_tree_to_tree(
old_tree.map(|tree| tree.into()),
new_tree.map(|tree| tree.into()),
opts,
)
.map_err(Into::into)
}
pub fn diff_tree_to_workdir(
@ -96,6 +108,7 @@ impl Repository {
) -> Result<git2::Diff<'_>> {
self.0
.diff_tree_to_workdir(old_tree.map(|tree| tree.into()), opts)
.map_err(Into::into)
}
pub fn reset(
@ -105,58 +118,74 @@ impl Repository {
checkout: Option<&mut git2::build::CheckoutBuilder<'_>>,
) -> Result<()> {
let commit: &git2::Commit = commit.into();
self.0.reset(commit.as_object(), kind, checkout)
self.0
.reset(commit.as_object(), kind, checkout)
.map_err(Into::into)
}
pub fn find_reference(&self, name: &str) -> Result<Reference> {
self.0.find_reference(name).map(Reference::from)
self.0
.find_reference(name)
.map(Reference::from)
.map_err(Into::into)
}
pub fn head(&self) -> Result<Reference> {
self.0.head().map(Reference::from)
self.0.head().map(Reference::from).map_err(Into::into)
}
pub fn find_tree(&self, id: Oid) -> Result<Tree> {
self.0.find_tree(id.into()).map(Tree::from)
self.0
.find_tree(id.into())
.map(Tree::from)
.map_err(Into::into)
}
pub fn find_commit(&self, id: Oid) -> Result<Commit> {
self.0.find_commit(id.into()).map(Commit::from)
self.0
.find_commit(id.into())
.map(Commit::from)
.map_err(Into::into)
}
pub fn find_blob(&self, id: Oid) -> Result<git2::Blob> {
self.0.find_blob(id.into())
self.0.find_blob(id.into()).map_err(Into::into)
}
pub fn revwalk(&self) -> Result<git2::Revwalk> {
self.0.revwalk()
self.0.revwalk().map_err(Into::into)
}
pub fn is_path_ignored<P: AsRef<path::Path>>(&self, path: P) -> Result<bool> {
self.0.is_path_ignored(path)
self.0.is_path_ignored(path).map_err(Into::into)
}
pub fn branches(
&self,
filter: Option<git2::BranchType>,
) -> Result<impl Iterator<Item = Result<(Branch, git2::BranchType)>>> {
self.0.branches(filter).map(|branches| {
branches.map(|branch| {
branch.map(|(branch, branch_type)| (Branch::from(branch), branch_type))
self.0
.branches(filter)
.map(|branches| {
branches.map(|branch| {
branch
.map(|(branch, branch_type)| (Branch::from(branch), branch_type))
.map_err(Into::into)
})
})
})
.map_err(Into::into)
}
pub fn index(&self) -> Result<Index> {
self.0.index().map(Into::into)
self.0.index().map(Into::into).map_err(Into::into)
}
pub fn blob_path(&self, path: &path::Path) -> Result<Oid> {
self.0.blob_path(path).map(Into::into)
self.0.blob_path(path).map(Into::into).map_err(Into::into)
}
pub fn blob(&self, data: &[u8]) -> Result<Oid> {
self.0.blob(data).map(Into::into)
self.0.blob(data).map(Into::into).map_err(Into::into)
}
pub fn commit(
@ -182,10 +211,11 @@ impl Repository {
&parents,
)
.map(Into::into)
.map_err(Into::into)
}
pub fn config(&self) -> Result<git2::Config> {
self.0.config()
self.0.config().map_err(Into::into)
}
pub fn treebuilder<'repo>(&'repo self, tree: Option<&'repo Tree>) -> TreeBuilder<'repo> {
@ -204,45 +234,57 @@ impl Repository {
self.0
.branch_upstream_name(branch_name)
.map(|s| s.as_str().unwrap().to_string())
.map_err(Into::into)
}
pub fn branch_remote_name(&self, refname: &str) -> Result<String> {
self.0
.branch_remote_name(refname)
.map(|s| s.as_str().unwrap().to_string())
.map_err(Into::into)
}
pub fn branch_upstream_remote(&self, branch_name: &str) -> Result<String> {
self.0
.branch_upstream_remote(branch_name)
.map(|s| s.as_str().unwrap().to_string())
.map_err(Into::into)
}
pub fn statuses(
&self,
options: Option<&mut git2::StatusOptions>,
) -> Result<git2::Statuses<'_>> {
self.0.statuses(options)
self.0.statuses(options).map_err(Into::into)
}
pub fn remote_anonymous(&self, url: &str) -> Result<Remote> {
self.0.remote_anonymous(url).map(Into::into)
self.0
.remote_anonymous(url)
.map(Into::into)
.map_err(Into::into)
}
pub fn find_remote(&self, name: &str) -> Result<Remote> {
self.0.find_remote(name).map(Into::into)
self.0.find_remote(name).map(Into::into).map_err(Into::into)
}
pub fn find_branch(&self, name: &str, branch_type: git2::BranchType) -> Result<Branch> {
self.0.find_branch(name, branch_type).map(Into::into)
self.0
.find_branch(name, branch_type)
.map(Into::into)
.map_err(Into::into)
}
pub fn refname_to_id(&self, name: &str) -> Result<Oid> {
self.0.refname_to_id(name).map(Into::into)
self.0
.refname_to_id(name)
.map(Into::into)
.map_err(Into::into)
}
pub fn checkout_head(&self, opts: Option<&mut git2::build::CheckoutBuilder>) -> Result<()> {
self.0.checkout_head(opts)
self.0.checkout_head(opts).map_err(Into::into)
}
pub fn checkout_index(
@ -250,7 +292,9 @@ impl Repository {
index: Option<&mut Index>,
opts: Option<&mut git2::build::CheckoutBuilder<'_>>,
) -> Result<()> {
self.0.checkout_index(index.map(Into::into), opts)
self.0
.checkout_index(index.map(Into::into), opts)
.map_err(Into::into)
}
pub fn checkout_tree(
@ -259,11 +303,13 @@ impl Repository {
opts: Option<&mut git2::build::CheckoutBuilder<'_>>,
) -> Result<()> {
let tree: &git2::Tree = tree.into();
self.0.checkout_tree(tree.as_object(), opts)
self.0
.checkout_tree(tree.as_object(), opts)
.map_err(Into::into)
}
pub fn set_head(&self, refname: &str) -> Result<()> {
self.0.set_head(refname)
self.0.set_head(refname).map_err(Into::into)
}
pub fn reference(
@ -276,17 +322,19 @@ impl Repository {
self.0
.reference(name, id.into(), force, log_message)
.map(Into::into)
.map_err(Into::into)
}
#[cfg(test)]
pub fn remote(&self, name: &str, url: &str) -> Result<Remote> {
self.0.remote(name, url).map(Into::into)
self.0.remote(name, url).map(Into::into).map_err(Into::into)
}
#[cfg(test)]
pub fn references(&self) -> Result<impl Iterator<Item = Result<Reference>>> {
self.0
.references()
.map(|iter| iter.map(|reference| reference.map(Into::into)))
.map(|iter| iter.map(|reference| reference.map(Into::into).map_err(Into::into)))
.map_err(Into::into)
}
}

View File

@ -24,7 +24,7 @@ impl<'repo> Tree<'repo> {
}
pub fn get_path(&self, path: &path::Path) -> Result<TreeEntry<'repo>> {
self.tree.get_path(path).map(Into::into)
self.tree.get_path(path).map(Into::into).map_err(Into::into)
}
pub fn walk<C, T>(&self, mode: git2::TreeWalkMode, mut callback: C) -> Result<()>
@ -34,6 +34,7 @@ impl<'repo> Tree<'repo> {
{
self.tree
.walk(mode, |root, entry| callback(root, &entry.clone().into()))
.map_err(Into::into)
}
pub fn get_name(&self, filename: &str) -> Option<TreeEntry> {
@ -57,7 +58,7 @@ impl<'repo> TreeEntry<'repo> {
}
pub fn to_object(&self, repo: &'repo Repository) -> Result<git2::Object> {
self.entry.to_object(repo.into())
self.entry.to_object(repo.into()).map_err(Into::into)
}
pub fn kind(&self) -> Option<git2::ObjectType> {

View File

@ -1,3 +1,5 @@
use crate::git;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("branch name is invalid: {0}")]
@ -7,7 +9,7 @@ pub enum Error {
#[error("branch is not remote: {0}")]
NotRemote(String),
#[error(transparent)]
GitError(#[from] git2::Error),
GitError(#[from] git::Error),
#[error(transparent)]
Utf8Error(#[from] std::string::FromUtf8Error),
}

View File

@ -75,16 +75,11 @@ impl TryFrom<&git::Branch<'_>> for Name {
branch,
remote: Some(RemoteName::try_from(&upstream)?),
}),
Err(error) => {
if error.code() == git2::ErrorCode::NotFound {
Ok(Self {
branch,
remote: None,
})
} else {
Err(error.into())
}
}
Err(git::Error::NotFound(_)) => Ok(Self {
branch,
remote: None,
}),
Err(error) => Err(error.into()),
}
}
}

View File

@ -14,7 +14,7 @@ pub struct Repository<'repository> {
}
impl<'project> TryFrom<&'project projects::Project> for Repository<'project> {
type Error = git2::Error;
type Error = git::Error;
fn try_from(project: &'project projects::Project) -> std::result::Result<Self, Self::Error> {
let git_repository = git::Repository::open(&project.path)?;
@ -39,7 +39,7 @@ impl<'repository> Repository<'repository> {
})
}
pub fn get_head(&self) -> Result<git::Reference, git2::Error> {
pub fn get_head(&self) -> Result<git::Reference, git::Error> {
let head = self.git_repository.head()?;
Ok(head)
}
@ -439,14 +439,11 @@ impl<'repository> Repository<'repository> {
tracing::info!("{}: git push succeeded", self.project.id);
return Ok(());
}
Err(e) => {
if e.code() == git2::ErrorCode::Auth {
tracing::info!("{}: git push failed: {:#}", self.project.id, e);
continue;
} else {
return Err(Error::Other(e.into()));
}
Err(git::Error::Auth(e)) => {
tracing::info!("{}: git push failed: {:#}", self.project.id, e);
continue;
}
Err(e) => return Err(Error::Other(e.into())),
}
}
@ -511,14 +508,11 @@ impl<'repository> Repository<'repository> {
tracing::info!("{}: fetched {}", self.project.id, remote_name);
return Ok(());
}
Err(e) => {
if e.code() == git2::ErrorCode::Auth {
tracing::warn!("{}: auth error", self.project.id);
continue;
} else {
return Err(Error::Other(e.into()));
}
Err(git::Error::Auth(e)) => {
tracing::info!("{}: fetch failed: {:#}", self.project.id, e);
continue;
}
Err(e) => return Err(Error::Other(e.into())),
}
}