Skip to content

repository.Current() ignores gh-resolved and selects the wrong repo when a remote is named "github" #286

Description

@aspiers

repository.Current() selects a repository by ranking remotes on their name alone, and never consults the gh-resolved git config value that gh repo set-default writes — even though Remotes() reads that value into Remote.Resolved immediately beforehand. In a repository where the fork is on a remote named github and the parent is on origin, Current() returns the fork, contradicting both the user's explicit gh repo set-default choice and gh's own answer for the same repository.

Current behaviour

Remotes() (internal/git/remote.go:43) calls setResolvedRemotes(remotes) at line 49, populating Remote.Resolved (field at line 18, set at line 144) from git config --get-regexp ^remote\..*\.gh-resolved$. Line 50 then sorts by remoteNameSortScore (line 30): upstream=3, github=2, origin=1, everything else 0. Current() (pkg/repository/repository.go:119) takes filteredRemotes[0] at line 152. Resolved appears zero times in the body of Current().

So the value is parsed and then discarded.

Reproduction

git init repro && cd repro
git remote add origin git@github.com:parent-org/example.git
git remote add github git@github.com:my-user/example.git
git config remote.origin.gh-resolved base    # what `gh repo set-default` writes
package main

import (
	"fmt"
	"github.com/cli/go-gh/v2/pkg/repository"
)

func main() {
	r, err := repository.Current()
	fmt.Printf("Current() -> %s/%s (host %s) err=%v\n", r.Owner, r.Name, r.Host, err)
}

Result with go-gh v2.13.0:

Current() -> my-user/example (host github.com) err=<nil>

Expected parent-org/example. gh repo set-default --view in the same directory correctly prints parent-org/example.

Removing the gh-resolved setting produces identical output, confirming the value has no effect on the result. GH_REPO=parent-org/example does override correctly.

Expected behaviour

Current() should prefer a remote whose Resolved value is set, ahead of the name-based ranking. cli/cli already has exactly this in context/remote.go:51:

func (r Remotes) ResolvedRemote() (*Remote, error) {
	for _, rr := range r {
		if rr.Resolved != "" {

go-gh populates the same field but has no equivalent, so the two libraries disagree about the same repository.

The gh-resolved support was added in 9cb500d ("Add support for selected default remote", 2021-09-27), which suggests wiring it into Current() was intended and simply missed.

Impact

Consumers silently operate on the wrong repository, with no error. Surfaced via gh-dash, whose smart filtering injects repo:<owner>/<name> from Current() and so shows an empty PR list for a fork with no PRs.

Environment

  • go-gh v2.13.0 (and current trunk — code unchanged)
  • gh 2.96.0, go 1.25.12, Linux

Prior search

Searched go-gh and cli/cli issues and PRs, all states, for gh-resolved, repository.Current, remote sorting/precedence, and fork-vs-upstream selection. Closest existing items are #274 (SSH-alias translation) and cli/cli#13027 (proxy URLs failing host detection); neither covers this.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions