git_backend: classify "merge with root" as user error

Perhaps, there will be more error types that hold BackendError internally, but
this change is good enough to handle a merge error.
This commit is contained in:
Yuya Nishihara 2024-03-29 19:54:21 +09:00
parent 91ff1fdd1e
commit f20004fffe
4 changed files with 18 additions and 7 deletions

View file

@ -238,7 +238,10 @@ impl From<CheckOutCommitError> for CommandError {
impl From<BackendError> for CommandError {
fn from(err: BackendError) -> Self {
internal_error_with_message("Unexpected error from backend", err)
match &err {
BackendError::Unsupported(_) => user_error(err),
_ => internal_error_with_message("Unexpected error from backend", err),
}
}
}
@ -305,7 +308,11 @@ want this file to be snapshotted. Otherwise add it to your `.gitignore` file."#,
impl From<TreeMergeError> for CommandError {
fn from(err: TreeMergeError) -> Self {
internal_error_with_message("Merge failed", err)
let kind = match &err {
TreeMergeError::BackendError(BackendError::Unsupported(_)) => CommandErrorKind::User,
_ => CommandErrorKind::Internal,
};
CommandError::with_message(kind, "Merge failed", err)
}
}

View file

@ -314,9 +314,9 @@ fn test_bug_2600_rootcommit_special_case() {
"###);
// Now, the test
let stderr = test_env.jj_cmd_internal_error(&repo_path, &["abandon", "base"]);
let stderr = test_env.jj_cmd_failure(&repo_path, &["abandon", "base"]);
insta::assert_snapshot!(stderr, @r###"
Internal error: Merge failed
Error: Merge failed
Caused by: The Git backend does not support creating merge commits with the root commit as one of the parents.
"###);
}

View file

@ -200,6 +200,10 @@ pub enum BackendError {
},
#[error(transparent)]
Other(Box<dyn std::error::Error + Send + Sync>),
/// A valid operation attempted, but failed because it isn't supported by
/// the particular backend.
#[error("{0}")]
Unsupported(String),
}
pub type BackendResult<T> = Result<T, BackendError>;

View file

@ -1121,10 +1121,10 @@ impl Backend for GitBackend {
// there are no other parents since Git cannot represent a merge between a root
// commit and another commit.
if contents.parents.len() > 1 {
return Err(BackendError::Other(
return Err(BackendError::Unsupported(
"The Git backend does not support creating merge commits with the root \
commit as one of the parents."
.into(),
.to_owned(),
));
}
} else {
@ -1702,7 +1702,7 @@ mod tests {
commit.parents = vec![first_id, backend.root_commit_id().clone()];
assert_matches!(
backend.write_commit(commit, None),
Err(BackendError::Other(err)) if err.to_string().contains("root commit")
Err(BackendError::Unsupported(message)) if message.contains("root commit")
);
}