diff --git a/src-tauri/src/gb_repository/repository.rs b/src-tauri/src/gb_repository/repository.rs index b89e894d0..80ff5b38d 100644 --- a/src-tauri/src/gb_repository/repository.rs +++ b/src-tauri/src/gb_repository/repository.rs @@ -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()), } } diff --git a/src-tauri/src/git/branch.rs b/src-tauri/src/git/branch.rs index 4fe8899dc..1c11646c2 100644 --- a/src-tauri/src/git/branch.rs +++ b/src-tauri/src/git/branch.rs @@ -24,7 +24,7 @@ impl<'repo> Branch<'repo> { } pub fn upstream(&self) -> Result> { - 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> { - 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 { diff --git a/src-tauri/src/git/commit.rs b/src-tauri/src/git/commit.rs index 637e5988b..0720a63d5 100644 --- a/src-tauri/src/git/commit.rs +++ b/src-tauri/src/git/commit.rs @@ -34,7 +34,7 @@ impl<'repo> Commit<'repo> { } pub fn tree(&self) -> Result> { - 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> { - self.commit.parent(n).map(Into::into) + self.commit.parent(n).map(Into::into).map_err(Into::into) } pub fn time(&self) -> git2::Time { diff --git a/src-tauri/src/git/error.rs b/src-tauri/src/git/error.rs index 35bff1727..6c4085171 100644 --- a/src-tauri/src/git/error.rs +++ b/src-tauri/src/git/error.rs @@ -1 +1,21 @@ -pub type Result = std::result::Result; +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("not found: {0}")] + NotFound(Box), + #[error("authentication failed")] + Auth(Box), + #[error(transparent)] + Other(Box), +} + +impl From 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 = std::result::Result; diff --git a/src-tauri/src/git/index.rs b/src-tauri/src/git/index.rs index 7c9cc3022..b577478f6 100644 --- a/src-tauri/src/git/index.rs +++ b/src-tauri/src/git/index.rs @@ -37,19 +37,22 @@ impl Index { T: git2::IntoCString, I: IntoIterator, { - self.index.add_all(pathspecs, flag, cb) + self.index.add_all(pathspecs, flag, cb).map_err(Into::into) } pub fn conflicts(&self) -> Result { - 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 { - 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 { - 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 { diff --git a/src-tauri/src/git/reference.rs b/src-tauri/src/git/reference.rs index 11241f841..aefe64944 100644 --- a/src-tauri/src/git/reference.rs +++ b/src-tauri/src/git/reference.rs @@ -24,11 +24,17 @@ impl<'repo> Reference<'repo> { } pub fn peel_to_commit(&self) -> Result> { - 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> { - 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 { diff --git a/src-tauri/src/git/remote.rs b/src-tauri/src/git/remote.rs index e391ab237..1616b867b 100644 --- a/src-tauri/src/git/remote.rs +++ b/src-tauri/src/git/remote.rs @@ -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) } } diff --git a/src-tauri/src/git/repository.rs b/src-tauri/src/git/repository.rs index 3fade39f3..80850d20e 100644 --- a/src-tauri/src/git/repository.rs +++ b/src-tauri/src/git/repository.rs @@ -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> { 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> { - 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 { - 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> { - 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> { 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 { - 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 { - self.0.head().map(Reference::from) + self.0.head().map(Reference::from).map_err(Into::into) } pub fn find_tree(&self, id: Oid) -> Result { - 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 { - 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 { - self.0.find_blob(id.into()) + self.0.find_blob(id.into()).map_err(Into::into) } pub fn revwalk(&self) -> Result { - self.0.revwalk() + self.0.revwalk().map_err(Into::into) } pub fn is_path_ignored>(&self, path: P) -> Result { - self.0.is_path_ignored(path) + self.0.is_path_ignored(path).map_err(Into::into) } pub fn branches( &self, filter: Option, ) -> Result>> { - 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 { - 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 { - 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 { - 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 { - 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 { 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 { 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> { - self.0.statuses(options) + self.0.statuses(options).map_err(Into::into) } pub fn remote_anonymous(&self, url: &str) -> Result { - 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 { - 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 { - 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 { - 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 { - 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>> { 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) } } diff --git a/src-tauri/src/git/tree.rs b/src-tauri/src/git/tree.rs index da4a48143..2ec8b52c9 100644 --- a/src-tauri/src/git/tree.rs +++ b/src-tauri/src/git/tree.rs @@ -24,7 +24,7 @@ impl<'repo> Tree<'repo> { } pub fn get_path(&self, path: &path::Path) -> Result> { - self.tree.get_path(path).map(Into::into) + self.tree.get_path(path).map(Into::into).map_err(Into::into) } pub fn walk(&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 { @@ -57,7 +58,7 @@ impl<'repo> TreeEntry<'repo> { } pub fn to_object(&self, repo: &'repo Repository) -> Result { - self.entry.to_object(repo.into()) + self.entry.to_object(repo.into()).map_err(Into::into) } pub fn kind(&self) -> Option { diff --git a/src-tauri/src/project_repository/branch/names/error.rs b/src-tauri/src/project_repository/branch/names/error.rs index 6318bab83..c777bb909 100644 --- a/src-tauri/src/project_repository/branch/names/error.rs +++ b/src-tauri/src/project_repository/branch/names/error.rs @@ -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), } diff --git a/src-tauri/src/project_repository/branch/names/local.rs b/src-tauri/src/project_repository/branch/names/local.rs index 8e0a4a5e7..0dd6833ea 100644 --- a/src-tauri/src/project_repository/branch/names/local.rs +++ b/src-tauri/src/project_repository/branch/names/local.rs @@ -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()), } } } diff --git a/src-tauri/src/project_repository/repository.rs b/src-tauri/src/project_repository/repository.rs index 59fbdc068..da5bf6f64 100644 --- a/src-tauri/src/project_repository/repository.rs +++ b/src-tauri/src/project_repository/repository.rs @@ -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 { let git_repository = git::Repository::open(&project.path)?; @@ -39,7 +39,7 @@ impl<'repository> Repository<'repository> { }) } - pub fn get_head(&self) -> Result { + pub fn get_head(&self) -> Result { 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())), } }