forked from mirrors/jj
refs: error out push if non-tracking remote branches exist
We can provide more actionable error message than "not fast-forwardable". If the push was fast-forwardable, "jj branch track" should be able to merge the remote branch without conflicts, so the added step would be minimal.
This commit is contained in:
parent
089503abfb
commit
9e0b9e6dc8
4 changed files with 17 additions and 11 deletions
|
@ -38,6 +38,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
See [automatic local branch creation](docs/config.md#automatic-local-branch-creation)
|
See [automatic local branch creation](docs/config.md#automatic-local-branch-creation)
|
||||||
for details.
|
for details.
|
||||||
|
|
||||||
|
* It's not allowed to push branches if non-tracking remote branches of the same
|
||||||
|
name exist.
|
||||||
|
|
||||||
* Pushing deleted/moved branches no longer abandons the local commits referenced
|
* Pushing deleted/moved branches no longer abandons the local commits referenced
|
||||||
by the remote branches.
|
by the remote branches.
|
||||||
|
|
||||||
|
|
|
@ -1018,6 +1018,9 @@ fn classify_branch_update(
|
||||||
BranchPushAction::RemoteConflicted => {
|
BranchPushAction::RemoteConflicted => {
|
||||||
Err(format!("Branch {branch_name}@{remote_name} is conflicted"))
|
Err(format!("Branch {branch_name}@{remote_name} is conflicted"))
|
||||||
}
|
}
|
||||||
|
BranchPushAction::RemoteUntracked => Err(format!(
|
||||||
|
"Non-tracking remote branch {branch_name}@{remote_name} exists"
|
||||||
|
)),
|
||||||
BranchPushAction::Update(update) => Ok(Some(update)),
|
BranchPushAction::Update(update) => Ok(Some(update)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -741,8 +741,8 @@ fn test_git_push_moved_forward_untracked() {
|
||||||
test_env.jj_cmd_ok(&workspace_root, &["branch", "untrack", "branch1@origin"]);
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "untrack", "branch1@origin"]);
|
||||||
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###"
|
||||||
Branch changes to push to origin:
|
Non-tracking remote branch branch1@origin exists
|
||||||
Add branch branch1 to a25f24af0d0e
|
Nothing changed.
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,12 +756,10 @@ fn test_git_push_moved_sideways_untracked() {
|
||||||
&["branch", "set", "--allow-backwards", "branch1"],
|
&["branch", "set", "--allow-backwards", "branch1"],
|
||||||
);
|
);
|
||||||
test_env.jj_cmd_ok(&workspace_root, &["branch", "untrack", "branch1@origin"]);
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "untrack", "branch1@origin"]);
|
||||||
let stderr = test_env.jj_cmd_failure(&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###"
|
||||||
Branch changes to push to origin:
|
Non-tracking remote branch branch1@origin exists
|
||||||
Add branch branch1 to cfbae7608334
|
Nothing changed.
|
||||||
Error: The push conflicts with changes made on the remote (it is not fast-forwardable).
|
|
||||||
Hint: Try fetching from the remote, then make the branch point to where you want it to be, and push again.
|
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,7 @@ pub enum BranchPushAction {
|
||||||
AlreadyMatches,
|
AlreadyMatches,
|
||||||
LocalConflicted,
|
LocalConflicted,
|
||||||
RemoteConflicted,
|
RemoteConflicted,
|
||||||
|
RemoteUntracked,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Figure out what changes (if any) need to be made to the remote when pushing
|
/// Figure out what changes (if any) need to be made to the remote when pushing
|
||||||
|
@ -145,6 +146,8 @@ pub fn classify_branch_push_action(targets: TrackingRefPair) -> BranchPushAction
|
||||||
BranchPushAction::LocalConflicted
|
BranchPushAction::LocalConflicted
|
||||||
} else if remote_target.has_conflict() {
|
} else if remote_target.has_conflict() {
|
||||||
BranchPushAction::RemoteConflicted
|
BranchPushAction::RemoteConflicted
|
||||||
|
} else if targets.remote_ref.is_present() && !targets.remote_ref.is_tracking() {
|
||||||
|
BranchPushAction::RemoteUntracked
|
||||||
} else {
|
} else {
|
||||||
BranchPushAction::Update(BranchPushUpdate {
|
BranchPushAction::Update(BranchPushUpdate {
|
||||||
old_target: remote_target.as_normal().cloned(),
|
old_target: remote_target.as_normal().cloned(),
|
||||||
|
@ -237,6 +240,8 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_classify_branch_push_action_removed_untracked() {
|
fn test_classify_branch_push_action_removed_untracked() {
|
||||||
|
// This is not RemoteUntracked error since non-tracking remote branches
|
||||||
|
// have no relation to local branches, and there's nothing to push.
|
||||||
let commit_id1 = CommitId::from_hex("11");
|
let commit_id1 = CommitId::from_hex("11");
|
||||||
let targets = TrackingRefPair {
|
let targets = TrackingRefPair {
|
||||||
local_target: RefTarget::absent_ref(),
|
local_target: RefTarget::absent_ref(),
|
||||||
|
@ -258,10 +263,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
classify_branch_push_action(targets),
|
classify_branch_push_action(targets),
|
||||||
BranchPushAction::Update(BranchPushUpdate {
|
BranchPushAction::RemoteUntracked
|
||||||
old_target: None,
|
|
||||||
new_target: Some(commit_id2),
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue