fix(git): skip upstream remote probes when the remote is absent (#18455)

* fix(git): skip upstream remote probes when the remote is absent

Issue and PR resolvers listed remotes by probing `git remote get-url
upstream` on every poll, including origin-only clones where that remote
cannot exist. List remotes once, cache against git config, and skip the
probe unless `upstream` is present.

* fix(git): avoid stale remote probe cache entries

* fix(github): observe origin repository probe failures

* fix(github): observe verified origin probe failures

* fix(github): skip missing upstream probe for PR lists

* test(github): scope the #9171 lazy-resolution guard to default-branch commands

The guard asserted that no git command runs for an open PR, using "no git at
all" as a proxy for "no default-branch resolution". Remote-name listing is a
separate concern, so allow it and keep every other command forbidden; the
symbolic-ref/rev-parse resolution this issue is about stays unreachable.

---------

Co-authored-by: Neil <neil@stably.ai>
This commit is contained in:
Wooseong Kim
2026-09-13 20:18:22 -07:00
committed by GitHub
co-authored by Neil
parent 16d1ab81d3
commit 31db2774f8
13 changed files with 1016 additions and 241 deletions
@@ -2,6 +2,7 @@ import type { ClassifiedError } from '../../../../shared/classified-error'
import type { IssueSourcePreference } from '../../../../shared/repo-types'
import type { ParsedTaskQuery } from '../../../../shared/task-query'
import { GITHUB_WORK_ITEMS_SSH_REMOTE_REQUIRED_MESSAGE } from '../../../../shared/work-items'
import { shouldProbeGitRemote } from '../../../git/remote-name-listing'
import type { LocalGitExecOptions, OwnerRepo } from '../../gh-utils'
import {
getGitHubApiRepositoryForRemote,
@@ -134,9 +135,27 @@ export async function resolvePrWorkItemSource(
connectionId?: string | null,
localGitOptions: LocalGitExecOptions = {}
): Promise<ResolvedPrWorkItemSource> {
const originCandidatePromise = getOriginGitHubApiRepository(
repoPath,
connectionId,
localGitOptions
)
// Why: PR list/count polling must not spawn a failing upstream lookup on
// origin-only clones, while still preserving upstream-first resolution when
// the remote is configured or remote discovery fails open.
const upstreamCandidatePromise = shouldProbeGitRemote(
repoPath,
'upstream',
connectionId,
localGitOptions
).then((shouldProbe) =>
shouldProbe
? getGitHubApiRepositoryForRemote(repoPath, 'upstream', connectionId, localGitOptions)
: null
)
const [originCandidate, upstreamCandidate] = await Promise.all([
getOriginGitHubApiRepository(repoPath, connectionId, localGitOptions),
getGitHubApiRepositoryForRemote(repoPath, 'upstream', connectionId, localGitOptions)
originCandidatePromise,
upstreamCandidatePromise
])
// Why: fork-contribution PRs live on the upstream repo (the fork's own PR
// list is almost always empty), so 'auto' resolves upstream-first exactly