feat(git): support credentials for remote branch rename

Allow remote branch renames to be performed with optional credentials so
operations against protected remotes succeed when authentication is needed.
The backend accepts username/password and uses an authenticated push path
when provided, while the frontend prompts for and reuses stored credentials.

- Add optional username/password to rename RPC and use authenticated push
- Wire UI to queue rename, open credential dialog, and execute rename
- Extend credential dialog and handling to include the rename action
This commit is contained in:
2026-08-15 17:23:40 +02:00
parent 37d2152fcd
commit 32832f5db7
4 changed files with 87 additions and 29 deletions
+28 -13
View File
@@ -683,9 +683,17 @@ pub async fn rename_remote_branch(
remote: String,
old_branch: String,
new_branch: String,
username: Option<String>,
password: Option<String>,
) -> Result<GitStatus, String> {
run_git_task("Could not rename remote branch", move || {
rename_remote_branch_core(path, remote, old_branch, new_branch)
rename_remote_branch_core(
path,
remote,
old_branch,
new_branch,
username.as_deref().zip(password.as_deref()),
)
})
.await
}
@@ -695,6 +703,7 @@ fn rename_remote_branch_core(
remote: String,
old_branch: String,
new_branch: String,
credentials: Option<(&str, &str)>,
) -> Result<GitStatus, String> {
let repo = resolve_repo(&path)?;
let remote = validate_remote_name(&repo, &remote, true)?;
@@ -730,18 +739,23 @@ fn rename_remote_branch_core(
// Git has no standalone remote-rename command. Create the new ref and delete
// the old one in a single atomic push so a rejected update leaves both untouched.
run_git(
&repo,
[
"push",
"--atomic",
source_lease.as_str(),
destination_lease.as_str(),
remote.as_str(),
create_refspec.as_str(),
delete_refspec.as_str(),
],
)?;
let push_args = [
"push",
"--atomic",
source_lease.as_str(),
destination_lease.as_str(),
remote.as_str(),
create_refspec.as_str(),
delete_refspec.as_str(),
];
match credentials {
Some((username, password)) if !username.is_empty() || !password.is_empty() => {
run_git_authenticated(&repo, push_args, username, password)?;
}
_ => {
run_git(&repo, push_args)?;
}
}
// Git normally updates remote-tracking refs after a successful push. Keep the
// local view consistent as a fallback for unusual remote/refspec setups.
@@ -7662,6 +7676,7 @@ mod tests {
"origin".to_string(),
"feature/old-name".to_string(),
"feature/new-name".to_string(),
None,
)
.unwrap();