дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 03:05:40 +02:00
fix(vcs): push to an upstream with another name
A plain git push refuses under push.default=simple when the tracked branch is named differently from the local one. Push now names the tracked ref explicitly in that case, which covers the Push dialog and Commit and Push.
Цей коміт міститься в:
1 джерело
df6ed5ccba
коміт
79e4233c56
2 files changed
+45
No files matched your search
@@ -723,6 +723,8 @@ pub(crate) fn push(
|
||||
})
|
||||
.ok_or_else(|| IdeError::invalid("no remote configured"))?;
|
||||
args.extend(["--set-upstream".into(), remote, short]);
|
||||
} else if let Some((remote, target)) = renamed_upstream(r)? {
|
||||
args.extend([remote, format!("HEAD:{target}")]);
|
||||
}
|
||||
let argv: Vec<&str> = args.iter().map(String::as_str).collect();
|
||||
cli::run_streaming(r.root(), &argv, cancel, on_output)?;
|
||||
@@ -814,6 +816,23 @@ pub(crate) fn update_branch(
|
||||
}
|
||||
|
||||
/// The remote the current branch pushes to (`origin`, or the only remote, by default).
|
||||
/// The remote and ref HEAD's branch tracks when the ref has another name: a plain
|
||||
/// `git push` refuses that under the default `push.default=simple`.
|
||||
fn renamed_upstream(r: &Repo) -> IdeResult<Option<(String, String)>> {
|
||||
let repo = r.gix()?;
|
||||
let Some(head) = repo.head_name().map_err(gx)? else { return Ok(None) };
|
||||
let direction = gix::remote::Direction::Fetch;
|
||||
let Some(Ok(merge)) = repo.branch_remote_ref_name(head.as_ref(), direction) else { return Ok(None) };
|
||||
if merge.as_ref() == head.as_ref() {
|
||||
return Ok(None);
|
||||
}
|
||||
let target = merge.as_bstr().to_str_lossy().into_owned();
|
||||
let short = head.as_ref().shorten().to_str_lossy().into_owned();
|
||||
Ok(repo
|
||||
.branch_remote_name(short.as_str(), direction)
|
||||
.map(|remote| (remote.as_bstr().to_str_lossy().into_owned(), target)))
|
||||
}
|
||||
|
||||
fn push_remote(r: &Repo) -> IdeResult<String> {
|
||||
let repo = r.gix()?;
|
||||
let from_branch = repo.head_name().map_err(gx)?.and_then(|head| {
|
||||
|
||||
@@ -467,6 +467,32 @@ fn push_with_tags() {
|
||||
assert_eq!(git_in(&bare, &["rev-parse", "main"]), fx.git(&["rev-parse", "HEAD"]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn push_goes_to_an_upstream_with_another_name() {
|
||||
let fx = Fixture::new();
|
||||
let bare = fx._tmp.path().join("origin.git");
|
||||
git_in(fx._tmp.path(), &["init", "-q", "--bare", bare.to_str().unwrap()]);
|
||||
fx.write("a.txt", "1\n");
|
||||
fx.commit_all("one");
|
||||
fx.git(&["remote", "add", "origin", bare.to_str().unwrap()]);
|
||||
fx.git(&["push", "-q", "origin", "main:release/one"]);
|
||||
fx.git(&["fetch", "-q", "origin"]);
|
||||
fx.git(&["checkout", "-q", "-b", "local-name", "--track", "origin/release/one"]);
|
||||
fx.write("a.txt", "2\n");
|
||||
let c2 = fx.commit_all("two");
|
||||
let repo = fx.repo();
|
||||
let (cancel, out) = quiet();
|
||||
|
||||
repo.push(false, false, &cancel, &out).unwrap();
|
||||
assert_eq!(git_in(&bare, &["rev-parse", "release/one"]), c2);
|
||||
assert_eq!(git_in(&bare, &["branch", "--list", "local-name"]), "");
|
||||
|
||||
fx.write("a.txt", "3\n");
|
||||
let c3 = fx.commit_all("three");
|
||||
repo.push_with_tags(false, false, Some(ide_vcs::PushTags::CurrentBranch), &cancel, &out).unwrap();
|
||||
assert_eq!(git_in(&bare, &["rev-parse", "release/one"]), c3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn push_branch_and_up_to_revision() {
|
||||
let fx = Fixture::new();
|
||||
|
||||
Reference in new issue
Заблокувати користувача