-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
Description
gh commands that need to resolve a repository from git remotes (e.g. gh pr list, gh issue list, gh repo set-default) fail when url.<base>.insteadOf rules are configured in git config (typically at the system level in /etc/gitconfig).
Steps to reproduce
- Configure a git
insteadOfrule in system or global config:
# /etc/gitconfig
[url "http://my-proxy:9989/"]
insteadOf = https://github.com/- Clone a GitHub repo (works fine because git applies the rewrite transparently):
git clone https://github.com/owner/repo.git
- Run any
ghcommand that needs to resolve the repo from remotes:
cd repo
gh pr list
Expected behavior
gh pr list should succeed, resolving the repo from the remotes.
Actual behavior
none of the git remotes configured for this repository point to a known GitHub host.
To tell gh about a new GitHub host, please use `gh auth login`
Root cause
In git/client.go, the Remotes() function calls git remote -v to discover remote URLs. However, git remote -v applies url.<base>.insteadOf rewrites before displaying URLs. So when the system config rewrites https://github.com/ to http://my-proxy:9989/, gh sees my-proxy:9989 hostnames instead of github.com.
Later, in pkg/cmd/factory/remote_resolver.go, remotes are filtered by FilterByHosts() against known GitHub hosts. Since my-proxy:9989 is not a known host, all remotes are filtered out, and gh errors.
Meanwhile, git config --get-regexp ^remote\..*\.url$ returns the raw, un-rewritten URLs as stored in .git/config. These retain the original github.com hostname.
Context
This is a common setup in corporate/CI environments where a proxy or credential helper intercepts GitHub traffic via insteadOf rules. The gh SSH translator (go-gh/pkg/ssh) already handles SSH hostname aliasing for a similar reason, but there is no equivalent for HTTP insteadOf rewrites.
Proposed fix
After parsing remotes from git remote -v, additionally read raw URLs via git config --get-regexp ^remote\..*\.(url|pushurl)$ and overwrite the fetch/push URLs on each remote with the un-rewritten values. This is a single extra git config read with negligible cost, and it does not affect git transport commands (which continue to use insteadOf-rewritten URLs as normal).