fix(git): prefer the upstream remote over a tracked origin when finding the repository (follow gh)

Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni committed 2026-10-18 18:59:04 +02:00
1 parent 2a221d0a81
commit 517d164d8a
3 files changed
+16 -8

No files matched your search

+9 -5
View File
@@ -16,7 +16,7 @@ var ErrAmbiguousRemote = errors.New("ambiguous repository: select --remote or --
// DiscoverRemote names the remote used for repository discovery: preferred when set, otherwise
// the base remote pr checkout recorded for the current branch, the current branch's upstream
// remote unless it is a pulls/<owner>/<repo> head remote, then upstream, origin, or the only remote.
// remote unless it is a pulls/<owner>/<repo> head remote or origin beside an upstream remote (a fork clone), then upstream, origin, or the only remote.
// When repository is not nil, it names the repository of a remote tea can act on, or returns ""
// for one on another forge. Those steps then skip such remotes, and the other remotes decide when
// they name exactly one repository; with none of them usable the choice is the name-based one.
@@ -43,19 +43,23 @@ func DiscoverRemote(ctx context.Context, runner Runner, dir, preferred string, r
if strings.HasPrefix(tracking, "pulls/") {
tracking = ""
}
names, namesErr := runner.Output(ctx, dir, false, "remote")
available := strings.Fields(names)
// In a fork clone, branches pushed to the fork track origin, but the base repository is upstream.
if tracking == "origin" && slices.Contains(available, "upstream") {
tracking = ""
}
for _, remote := range []string{pullBaseRemote(ctx, runner, dir, branch), tracking} {
if try(remote) {
return remote, nil
}
}
names, err := runner.Output(ctx, dir, false, "remote")
if err != nil {
if namesErr != nil {
if fallback != "" {
return fallback, nil
}
return "", err
return "", namesErr
}
available := strings.Fields(names)
for _, name := range []string{"upstream", "origin"} {
if slices.Contains(available, name) && try(name) {
return name, nil
+2
View File
@@ -38,6 +38,8 @@ func TestDiscoverRemote(t *testing.T) {
{name: "recorded pull base", runner: discoverRunner{head: "main", tracking: "fork", base: "upstream", "remote": "origin\nupstream\nfork"}, want: "upstream"},
{name: "removed pull base", runner: discoverRunner{head: "main", tracking: "fork", base: "gone", "remote": "origin\nfork"}, want: "fork"},
{name: "local branch upstream", runner: discoverRunner{head: "main", tracking: ".", "remote": "origin\nfork"}, want: "origin"},
{name: "fork clone branch tracking origin", runner: discoverRunner{head: "main", tracking: "origin", "remote": "origin\nupstream"}, want: "upstream"},
{name: "branch tracking origin without upstream", runner: discoverRunner{head: "main", tracking: "origin", "remote": "origin\nfork"}, want: "origin"},
{name: "upstream remote", runner: discoverRunner{"remote": "origin\nupstream"}, want: "upstream"},
{name: "origin remote", runner: discoverRunner{"remote": "fork\norigin"}, want: "origin"},
{name: "sole remote", runner: discoverRunner{"remote": "fork"}, want: "fork"},