fix(git): make unsetting upstream idempotent
Saving sync settings with no upstream could cause a fatal Git error when unsetting upstream on a branch that never had tracking information. This change guards the operation by checking for an existing merge configuration before unsetting, making it idempotent. A test was added to verify that clearing an unconfigured upstream is a no-op. - Add test ensuring clearing an unconfigured upstream is a no-op
This commit is contained in:
+26
-1
@@ -836,7 +836,13 @@ pub fn set_branch_upstream(
|
||||
)?;
|
||||
}
|
||||
None => {
|
||||
run_git(&repo, ["branch", "--unset-upstream", branch.as_str()])?;
|
||||
// Saving sync settings with "No upstream" must be idempotent. Git
|
||||
// exits with a fatal error when --unset-upstream is used on a
|
||||
// branch that never had tracking information, which is the normal
|
||||
// state immediately after adding the first remote.
|
||||
if git_config_value(&repo, &format!("branch.{branch}.merge")).is_some() {
|
||||
run_git(&repo, ["branch", "--unset-upstream", branch.as_str()])?;
|
||||
}
|
||||
}
|
||||
}
|
||||
status_for_repo(&repo)
|
||||
@@ -7661,6 +7667,25 @@ mod tests {
|
||||
assert_eq!(remote.upstream, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clearing_an_unconfigured_upstream_is_a_noop() {
|
||||
let repo = init_temp_repo("unset_missing_upstream");
|
||||
commit_initial_file(&repo.path);
|
||||
let branch = git_output_test(&repo.path, ["branch", "--show-current"]);
|
||||
run_git_test(&repo.path, ["remote", "add", "origin", "."]);
|
||||
|
||||
let status = set_branch_upstream(
|
||||
repo.path.to_string_lossy().to_string(),
|
||||
branch.clone(),
|
||||
None,
|
||||
)
|
||||
.expect("saving an empty upstream should not fail");
|
||||
|
||||
assert_eq!(status.current_branch.as_deref(), Some(branch.as_str()));
|
||||
assert_eq!(status.upstream, None);
|
||||
assert!(git_config_value(&repo.path, &format!("branch.{branch}.merge")).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn commit_notes_can_be_created_updated_and_deleted_without_changing_commit() {
|
||||
let repo = init_temp_repo("commit_notes_crud");
|
||||
|
||||
Reference in New Issue
Block a user