forked from mirrors/jj
cli: show hints for branches rejected to push
This commit is contained in:
parent
9e0b9e6dc8
commit
eb78ae9758
2 changed files with 51 additions and 13 deletions
|
@ -708,7 +708,7 @@ fn cmd_git_push(
|
||||||
match classify_branch_update(branch_name, &remote, targets) {
|
match classify_branch_update(branch_name, &remote, targets) {
|
||||||
Ok(Some(update)) => branch_updates.push((branch_name.to_owned(), update)),
|
Ok(Some(update)) => branch_updates.push((branch_name.to_owned(), update)),
|
||||||
Ok(None) => {}
|
Ok(None) => {}
|
||||||
Err(message) => writeln!(ui.warning(), "{message}")?,
|
Err(reason) => reason.print(ui)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tx_description = format!("push all branches to git remote {remote}");
|
tx_description = format!("push all branches to git remote {remote}");
|
||||||
|
@ -720,7 +720,7 @@ fn cmd_git_push(
|
||||||
match classify_branch_update(branch_name, &remote, targets) {
|
match classify_branch_update(branch_name, &remote, targets) {
|
||||||
Ok(Some(update)) => branch_updates.push((branch_name.to_owned(), update)),
|
Ok(Some(update)) => branch_updates.push((branch_name.to_owned(), update)),
|
||||||
Ok(None) => {}
|
Ok(None) => {}
|
||||||
Err(message) => writeln!(ui.warning(), "{message}")?,
|
Err(reason) => reason.print(ui)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tx_description = format!("push all deleted branches to git remote {remote}");
|
tx_description = format!("push all deleted branches to git remote {remote}");
|
||||||
|
@ -743,7 +743,7 @@ fn cmd_git_push(
|
||||||
ui.stderr(),
|
ui.stderr(),
|
||||||
"Branch {branch_name}@{remote} already matches {branch_name}",
|
"Branch {branch_name}@{remote} already matches {branch_name}",
|
||||||
)?,
|
)?,
|
||||||
Err(message) => return Err(user_error(message)),
|
Err(reason) => return Err(reason.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,7 +794,7 @@ fn cmd_git_push(
|
||||||
ui.stderr(),
|
ui.stderr(),
|
||||||
"Branch {branch_name}@{remote} already matches {branch_name}",
|
"Branch {branch_name}@{remote} already matches {branch_name}",
|
||||||
)?,
|
)?,
|
||||||
Err(message) => return Err(user_error(message)),
|
Err(reason) => return Err(reason.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,7 +837,7 @@ fn cmd_git_push(
|
||||||
match classify_branch_update(branch_name, &remote, targets) {
|
match classify_branch_update(branch_name, &remote, targets) {
|
||||||
Ok(Some(update)) => branch_updates.push((branch_name.to_owned(), update)),
|
Ok(Some(update)) => branch_updates.push((branch_name.to_owned(), update)),
|
||||||
Ok(None) => {}
|
Ok(None) => {}
|
||||||
Err(message) => writeln!(ui.warning(), "{message}")?,
|
Err(reason) => reason.print(ui)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!args.revisions.is_empty() || use_default_revset) && branches_targeted.is_empty() {
|
if (!args.revisions.is_empty() || use_default_revset) && branches_targeted.is_empty() {
|
||||||
|
@ -1006,21 +1006,53 @@ fn get_default_push_remote(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct RejectedBranchUpdateReason {
|
||||||
|
message: String,
|
||||||
|
hint: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RejectedBranchUpdateReason {
|
||||||
|
fn print(&self, ui: &Ui) -> io::Result<()> {
|
||||||
|
writeln!(ui.warning(), "{}", self.message)?;
|
||||||
|
if let Some(hint) = &self.hint {
|
||||||
|
writeln!(ui.hint(), "Hint: {hint}")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<RejectedBranchUpdateReason> for CommandError {
|
||||||
|
fn from(reason: RejectedBranchUpdateReason) -> Self {
|
||||||
|
let RejectedBranchUpdateReason { message, hint } = reason;
|
||||||
|
CommandError::UserError { message, hint }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn classify_branch_update(
|
fn classify_branch_update(
|
||||||
branch_name: &str,
|
branch_name: &str,
|
||||||
remote_name: &str,
|
remote_name: &str,
|
||||||
targets: TrackingRefPair,
|
targets: TrackingRefPair,
|
||||||
) -> Result<Option<BranchPushUpdate>, String> {
|
) -> Result<Option<BranchPushUpdate>, RejectedBranchUpdateReason> {
|
||||||
let push_action = classify_branch_push_action(targets);
|
let push_action = classify_branch_push_action(targets);
|
||||||
match push_action {
|
match push_action {
|
||||||
BranchPushAction::AlreadyMatches => Ok(None),
|
BranchPushAction::AlreadyMatches => Ok(None),
|
||||||
BranchPushAction::LocalConflicted => Err(format!("Branch {branch_name} is conflicted")),
|
BranchPushAction::LocalConflicted => Err(RejectedBranchUpdateReason {
|
||||||
BranchPushAction::RemoteConflicted => {
|
message: format!("Branch {branch_name} is conflicted"),
|
||||||
Err(format!("Branch {branch_name}@{remote_name} is conflicted"))
|
hint: Some(
|
||||||
}
|
"Run `jj branch list` to inspect, and use `jj branch set` to fix it up.".to_owned(),
|
||||||
BranchPushAction::RemoteUntracked => Err(format!(
|
),
|
||||||
"Non-tracking remote branch {branch_name}@{remote_name} exists"
|
}),
|
||||||
)),
|
BranchPushAction::RemoteConflicted => Err(RejectedBranchUpdateReason {
|
||||||
|
message: format!("Branch {branch_name}@{remote_name} is conflicted"),
|
||||||
|
hint: Some("Run `jj git fetch` to update the conflicted remote branch.".to_owned()),
|
||||||
|
}),
|
||||||
|
BranchPushAction::RemoteUntracked => Err(RejectedBranchUpdateReason {
|
||||||
|
message: format!("Non-tracking remote branch {branch_name}@{remote_name} exists"),
|
||||||
|
hint: Some(format!(
|
||||||
|
"Run `jj branch track {branch_name}@{remote_name}` to import the remote branch."
|
||||||
|
)),
|
||||||
|
}),
|
||||||
BranchPushAction::Update(update) => Ok(Some(update)),
|
BranchPushAction::Update(update) => Ok(Some(update)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -684,6 +684,7 @@ fn test_git_push_conflicting_branches() {
|
||||||
insta::assert_snapshot!(stdout, @"");
|
insta::assert_snapshot!(stdout, @"");
|
||||||
insta::assert_snapshot!(stderr, @r###"
|
insta::assert_snapshot!(stderr, @r###"
|
||||||
Branch branch2 is conflicted
|
Branch branch2 is conflicted
|
||||||
|
Hint: Run `jj branch list` to inspect, and use `jj branch set` to fix it up.
|
||||||
Nothing changed.
|
Nothing changed.
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
|
@ -691,6 +692,7 @@ fn test_git_push_conflicting_branches() {
|
||||||
let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch", "branch2"]);
|
let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch", "branch2"]);
|
||||||
insta::assert_snapshot!(stderr, @r###"
|
insta::assert_snapshot!(stderr, @r###"
|
||||||
Error: Branch branch2 is conflicted
|
Error: Branch branch2 is conflicted
|
||||||
|
Hint: Run `jj branch list` to inspect, and use `jj branch set` to fix it up.
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
// --all shouldn't be blocked by conflicting branch
|
// --all shouldn't be blocked by conflicting branch
|
||||||
|
@ -699,6 +701,7 @@ fn test_git_push_conflicting_branches() {
|
||||||
insta::assert_snapshot!(stdout, @"");
|
insta::assert_snapshot!(stdout, @"");
|
||||||
insta::assert_snapshot!(stderr, @r###"
|
insta::assert_snapshot!(stderr, @r###"
|
||||||
Branch branch2 is conflicted
|
Branch branch2 is conflicted
|
||||||
|
Hint: Run `jj branch list` to inspect, and use `jj branch set` to fix it up.
|
||||||
Branch changes to push to origin:
|
Branch changes to push to origin:
|
||||||
Move branch branch1 from 45a3aa29e907 to fd1d63e031ea
|
Move branch branch1 from 45a3aa29e907 to fd1d63e031ea
|
||||||
"###);
|
"###);
|
||||||
|
@ -709,6 +712,7 @@ fn test_git_push_conflicting_branches() {
|
||||||
insta::assert_snapshot!(stdout, @"");
|
insta::assert_snapshot!(stdout, @"");
|
||||||
insta::assert_snapshot!(stderr, @r###"
|
insta::assert_snapshot!(stderr, @r###"
|
||||||
Branch branch2 is conflicted
|
Branch branch2 is conflicted
|
||||||
|
Hint: Run `jj branch list` to inspect, and use `jj branch set` to fix it up.
|
||||||
Branch changes to push to origin:
|
Branch changes to push to origin:
|
||||||
Move branch branch1 from fd1d63e031ea to 8263cf992d33
|
Move branch branch1 from fd1d63e031ea to 8263cf992d33
|
||||||
"###);
|
"###);
|
||||||
|
@ -742,6 +746,7 @@ fn test_git_push_moved_forward_untracked() {
|
||||||
let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
||||||
insta::assert_snapshot!(stderr, @r###"
|
insta::assert_snapshot!(stderr, @r###"
|
||||||
Non-tracking remote branch branch1@origin exists
|
Non-tracking remote branch branch1@origin exists
|
||||||
|
Hint: Run `jj branch track branch1@origin` to import the remote branch.
|
||||||
Nothing changed.
|
Nothing changed.
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
@ -759,6 +764,7 @@ fn test_git_push_moved_sideways_untracked() {
|
||||||
let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
||||||
insta::assert_snapshot!(stderr, @r###"
|
insta::assert_snapshot!(stderr, @r###"
|
||||||
Non-tracking remote branch branch1@origin exists
|
Non-tracking remote branch branch1@origin exists
|
||||||
|
Hint: Run `jj branch track branch1@origin` to import the remote branch.
|
||||||
Nothing changed.
|
Nothing changed.
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue