From 071d5c5d088670c445d7df1875ff7d0084bfca32 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Sat, 9 Dec 2023 10:23:13 +0900 Subject: [PATCH] cli: print failed git export reason for each ref Not all reasons are actionable, but we print hint in common cryptic cases. --- cli/src/cli_util.rs | 6 +++--- cli/tests/test_branch_command.rs | 2 +- cli/tests/test_git_colocated.rs | 2 +- cli/tests/test_git_import_export.rs | 2 +- lib/src/git.rs | 14 +++++++++++--- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index 2f7c192146..5c95fb78b0 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -1843,10 +1843,10 @@ pub fn print_failed_git_export( if !failed_branches.is_empty() { writeln!(ui.warning(), "Failed to export some branches:")?; let mut formatter = ui.stderr_formatter(); - for failed_ref_export in failed_branches { + for FailedRefExport { name, reason } in failed_branches { formatter.write_str(" ")?; - write!(formatter.labeled("branch"), "{}", failed_ref_export.name)?; - formatter.write_str("\n")?; + write!(formatter.labeled("branch"), "{name}")?; + writeln!(formatter, ": {reason}")?; } drop(formatter); if failed_branches diff --git a/cli/tests/test_branch_command.rs b/cli/tests/test_branch_command.rs index 60d9b4e3ec..16c78892c5 100644 --- a/cli/tests/test_branch_command.rs +++ b/cli/tests/test_branch_command.rs @@ -74,7 +74,7 @@ fn test_branch_at_root() { insta::assert_snapshot!(stderr, @r###" Nothing changed. Failed to export some branches: - fred + fred: Ref cannot point to the root commit in Git "###); } diff --git a/cli/tests/test_git_colocated.rs b/cli/tests/test_git_colocated.rs index 6d7244ad9e..f92228f00a 100644 --- a/cli/tests/test_git_colocated.rs +++ b/cli/tests/test_git_colocated.rs @@ -403,7 +403,7 @@ fn test_git_colocated_conflicting_git_refs() { insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Failed to export some branches: - main/sub + main/sub: Failed to set: A lock could not be obtained for reference "refs/heads/main/sub" Hint: Git doesn't allow a branch name that looks like a parent directory of another (e.g. `foo` and `foo/bar`). Try to rename the branches that failed to export or their "parent" branches. diff --git a/cli/tests/test_git_import_export.rs b/cli/tests/test_git_import_export.rs index c17de22a93..e5dd0dc633 100644 --- a/cli/tests/test_git_import_export.rs +++ b/cli/tests/test_git_import_export.rs @@ -69,7 +69,7 @@ fn test_git_export_conflicting_git_refs() { insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Failed to export some branches: - main/sub + main/sub: Failed to set: A lock could not be obtained for reference "refs/heads/main/sub" Hint: Git doesn't allow a branch name that looks like a parent directory of another (e.g. `foo` and `foo/bar`). Try to rename the branches that failed to export or their "parent" branches. diff --git a/lib/src/git.rs b/lib/src/git.rs index 48e0e65f19..b0d2966959 100644 --- a/lib/src/git.rs +++ b/lib/src/git.rs @@ -543,25 +543,33 @@ pub struct FailedRefExport { } /// The reason we failed to export a ref to Git. -#[derive(Debug)] +#[derive(Debug, Error)] pub enum FailedRefExportReason { /// The name is not allowed in Git. + #[error("Name is not allowed in Git")] InvalidGitName, /// The ref was in a conflicted state from the last import. A re-import /// should fix it. + #[error("Ref was in a conflicted state from the last import")] ConflictedOldState, /// The branch points to the root commit, which Git doesn't have + #[error("Ref cannot point to the root commit in Git")] OnRootCommit, /// We wanted to delete it, but it had been modified in Git. + #[error("Deleted ref had been modified in Git")] DeletedInJjModifiedInGit, /// We wanted to add it, but Git had added it with a different target + #[error("Added ref had been added with a different target in Git")] AddedInJjAddedInGit, /// We wanted to modify it, but Git had deleted it + #[error("Modified ref had been deleted in Git")] ModifiedInJjDeletedInGit, /// Failed to delete the ref from the Git repo - FailedToDelete(Box), + #[error("Failed to delete: {0}")] + FailedToDelete(#[source] Box), /// Failed to set the ref in the Git repo - FailedToSet(Box), + #[error("Failed to set: {0}")] + FailedToSet(#[source] Box), } #[derive(Debug)]