diff --git a/cli/src/commands/git/push.rs b/cli/src/commands/git/push.rs index d3608bf86f8..527f0db2a7e 100644 --- a/cli/src/commands/git/push.rs +++ b/cli/src/commands/git/push.rs @@ -402,15 +402,35 @@ fn validate_commits_ready_to_push( if commit.has_conflict()? { reasons.push("it has conflicts"); } - if !args.allow_private && is_private(commit.id())? { + let is_private = is_private(commit.id())?; + if !args.allow_private && is_private { reasons.push("it is private"); } if !reasons.is_empty() { - return Err(user_error(format!( + let short = short_commit_hash(commit.id()); + let mut error = user_error(format!( "Won't push commit {} since {}", - short_commit_hash(commit.id()), + short, reasons.join(" and ") - ))); + )); + if !args.allow_private && is_private { + error.add_formatted_hint_with(|formatter| { + write!(formatter, "Private commit {short}: ")?; + workspace_helper.write_commit_summary(formatter, &commit)?; + Ok(()) + }); + error.add_formatted_hint_with(|formatter| { + write!( + formatter, + "Configured git.private-commits: '{}'", + settings + .get_string("git.private-commits") + .expect("should have private-commits setting") + )?; + Ok(()) + }); + } + return Err(error); } } Ok(()) diff --git a/cli/tests/test_git_private_commits.rs b/cli/tests/test_git_private_commits.rs index fadd5ca05b5..44657d8e206 100644 --- a/cli/tests/test_git_private_commits.rs +++ b/cli/tests/test_git_private_commits.rs @@ -88,9 +88,11 @@ fn test_git_private_commits_block_pushing() { // Will not push when a pushed commit is contained in git.private-commits test_env.add_config(r#"git.private-commits = "description(glob:'private*')""#); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--all"]); - insta::assert_snapshot!(stderr, @r###" + insta::assert_snapshot!(stderr, @r" Error: Won't push commit aa3058ff8663 since it is private - "###); + Hint: Private commit aa3058ff8663: yqosqzyt aa3058ff main* | (empty) private 1 + Hint: Configured git.private-commits: 'description(glob:'private*')' + "); // May push when the commit is removed from git.private-commits test_env.add_config(r#"git.private-commits = "none()""#); @@ -114,9 +116,11 @@ fn test_git_private_commits_can_be_overridden() { // Will not push when a pushed commit is contained in git.private-commits test_env.add_config(r#"git.private-commits = "description(glob:'private*')""#); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--all"]); - insta::assert_snapshot!(stderr, @r###" + insta::assert_snapshot!(stderr, @r" Error: Won't push commit aa3058ff8663 since it is private - "###); + Hint: Private commit aa3058ff8663: yqosqzyt aa3058ff main* | (empty) private 1 + Hint: Configured git.private-commits: 'description(glob:'private*')' + "); // May push when the commit is removed from git.private-commits let (_, stderr) = test_env.jj_cmd_ok( @@ -166,9 +170,11 @@ fn test_git_private_commits_not_directly_in_line_block_pushing() { &workspace_root, &["git", "push", "--allow-new", "-b=bookmark1"], ); - insta::assert_snapshot!(stderr, @r###" + insta::assert_snapshot!(stderr, @r" Error: Won't push commit f1253a9b1ea9 since it is private - "###); + Hint: Private commit f1253a9b1ea9: yqosqzyt f1253a9b (empty) private 1 + Hint: Configured git.private-commits: 'description(glob:'private*')' + "); } #[test] @@ -270,7 +276,9 @@ fn test_git_private_commits_are_evaluated_separately_for_each_remote() { &workspace_root, &["git", "push", "--remote=other", "-b=main"], ); - insta::assert_snapshot!(stderr, @r###" + insta::assert_snapshot!(stderr, @r" Error: Won't push commit 36b7ecd11ad9 since it is private - "###); + Hint: Private commit 36b7ecd11ad9: znkkpsqq 36b7ecd1 (empty) private 1 + Hint: Configured git.private-commits: 'description(glob:'private*')' + "); }