fix(worktree): run the create-base warm-up on the routed git host (#17794)

The speculative warm-up that runs while the create composer is open resolved
refs and fetched with host Git even when the project's runtime is a WSL distro,
while both the checkout preparation it feeds (`prepareWorktreeCreateForRepo`,
which already resolves `{ wslDistro }` itself) and the real create path run
inside the distro.

The concrete cost was a discarded fetch: `getCanonicalFetchKey` namespaces the
runtime's remote-fetch cache `wsl:<distro>` vs `local`, so the warm-up's fetch
landed in a namespace create never looks at, and create fetched again. On a
Windows host with no usable host-side Git the probes also failed outright, so
that cohort got no warm-up at all.

Thread the project's worktree Git options through the prefetch (resolved by a
non-throwing helper, because an optimistic warm-up must not surface a
repair-required runtime as a failure) so every probe and fetch runs where create
runs. `gitOptions` is a required argument, so a caller cannot drop the routing
silently. Host-routed calls keep their original arity, so macOS, Linux,
native-Windows-host projects, SSH repos and folder workspaces are unchanged.

Narrower than it looks: for a repo under \\wsl.localhost\<distro>\... the probes
were already routed by cwd, and for a repo on a Windows drive letter host Git
and WSL Git read the same on-disk repository, so the answers were already
correct there. What those cohorts gain is a fetch create can reuse; what they
pay is that the probes now run inside the distro (over /mnt/c for drive-letter
repos, which also newly arms the linked-worktree routing probe) and the
speculative fetch now shares create's per-remote fetch queue, as it always has
on native platforms.

Also collapse the three byte-equivalent copies of `hasLocalWorktreeBaseRef`
(create, prefetch, remote-repo create) into one in
git/worktree-base-ref-probe.ts, drop the host-only `hasLocalCommitObject` that
caused the routing bug, and add the first routing assertions on the create-path
consumers of the now-shared probe.
This commit is contained in:
Neil
2026-08-31 20:32:59 -07:00
committed by GitHub
parent 7f63db7d7a
commit abc099e4c7
17 changed files with 633 additions and 170 deletions
@@ -1,10 +1,7 @@
import type { BranchPrefixStrategy } from '../../shared/ui-chrome-types'
import type { Repo } from '../../shared/repo-types'
import { resolveWorktreeAddBaseRef } from '../../shared/worktree/base-ref'
import { getPRForBranch } from '../github/client'
import { hasCommitObjectViaGitExec } from '../git/commit-object-ref'
import { gitExecFileAsync } from '../git/runner'
import { hasWorktreeBaseCommitRef } from '../git/worktree-base-ref-probe'
import { listWorktrees } from '../git/worktree'
import { computeValidatedBranchName } from '../ipc/worktree-logic'
import { getHostedReviewForBranch } from '../source-control/hosted-review'
@@ -114,23 +111,3 @@ export async function getSelectedHostedReviewForBranch(
}
: null
}
export async function hasLocalWorktreeBaseRef(
repoPath: string,
baseRef: string,
options: { wslDistro?: string } = {}
): Promise<boolean> {
const refExists = (qualifiedRef: string) =>
hasWorktreeBaseCommitRef(repoPath, qualifiedRef, options)
const resolvedBaseRef = await resolveWorktreeAddBaseRef(baseRef, refExists)
if (resolvedBaseRef !== baseRef) {
return true
}
if (baseRef.startsWith('refs/')) {
return refExists(baseRef)
}
return hasCommitObjectViaGitExec(
(gitArgs) => gitExecFileAsync(gitArgs, { cwd: repoPath, ...options }),
baseRef
)
}