Skip to content

Commit

Permalink
cli: git push: optionally describe commits that would fail push
Browse files Browse the repository at this point in the history
  • Loading branch information
shanesveller committed Nov 29, 2024
1 parent d76bcd9 commit 6259a0b
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
25 changes: 23 additions & 2 deletions cli/src/commands/git/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ pub struct GitPushArgs {
/// Only display what will change on the remote
#[arg(long)]
dry_run: bool,
/// Display per-commit reasons for failed pushes
#[arg(long)]
explain_denied: bool,
}

fn make_bookmark_term(bookmark_names: &[impl fmt::Display]) -> String {
Expand Down Expand Up @@ -402,15 +405,33 @@ fn validate_commits_ready_to_push(
if commit.has_conflict()? {
reasons.push("it has conflicts");
}
let mut exposition = vec![];
if !args.allow_private && is_private(commit.id())? {
reasons.push("it is private");

if args.explain_denied {
exposition.push(format!(
"commit {}, description: '{}'",
short_commit_hash(commit.id()),
commit
.description()
.lines()
.next()
.expect("commit should have at least one line with private description")
));
}
}
if !reasons.is_empty() {
return Err(user_error(format!(
let mut message = format!(
"Won't push commit {} since {}",
short_commit_hash(commit.id()),
reasons.join(" and ")
)));
);
if args.explain_denied {
message.push('\n');
message.push_str(&exposition.join("\n"));
}
return Err(user_error(message));
}
}
Ok(())
Expand Down
19 changes: 19 additions & 0 deletions cli/tests/test_git_private_commits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,25 @@ fn test_git_private_commits_block_pushing() {
"#);
}

#[test]
fn test_git_private_commits_block_pushing_with_explanation() {
let (test_env, workspace_root) = set_up();

test_env.jj_cmd_ok(&workspace_root, &["new", "main", "-m=private 1"]);
test_env.jj_cmd_ok(&workspace_root, &["bookmark", "set", "main"]);

// 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", "--explain-failed"],
);
insta::assert_snapshot!(stderr, @r###"
Error: Won't push commit aa3058ff8663 since it is private
commit aa3058ff8663, description: 'private 1'
"###);
}

#[test]
fn test_git_private_commits_can_be_overridden() {
let (test_env, workspace_root) = set_up();
Expand Down

0 comments on commit 6259a0b

Please sign in to comment.