* Result returned by `tryWarmWorktreeAdd()` on a warm-path hit. * `gitmodulesPresent` is reported by the fused SSH command so the caller * can skip the post-worktree submodule-sync probe (another SSH RT) when * the workspace has no `.gitmodules`.
(
params: WorkspaceInitParams,
nhp: string
)
| 2569 | * the workspace has no `.gitmodules`. |
| 2570 | */ |
| 2571 | private async tryWarmWorktreeAdd( |
| 2572 | params: WorkspaceInitParams, |
| 2573 | nhp: string |
| 2574 | ): Promise<{ gitmodulesPresent: boolean } | null> { |
| 2575 | const { projectPath, branchName, trunkBranch, workspacePath, initLogger, abortSignal } = params; |
| 2576 | |
| 2577 | // Local prerequisites — all computed without any SSH calls. |
| 2578 | // |
| 2579 | // STARTUP-PERF: We deliberately use only the snapshot **digest** to gate |
| 2580 | // the warm path (no separate ref-manifest check). The digest is the |
| 2581 | // sha256 of `git show-ref --heads` output: if it matches the digest |
| 2582 | // persisted on the remote at sync time, the local heads MUST be the same |
| 2583 | // (modulo a sha256 collision). Skipping the manifest verification saves |
| 2584 | // both an SSH round-trip and a `git show-ref` parse pass — both are pure |
| 2585 | // overhead on the warm path because they always agree when the digests |
| 2586 | // match. If a digest mismatch happens, we fall through to the slow path, |
| 2587 | // which independently re-verifies via the full manifest before pushing. |
| 2588 | const layout = this.getProjectLayout(projectPath); |
| 2589 | // Try the fs-direct fast reader first; fall back to `git show-ref` only |
| 2590 | // when the cheap path can't handle the project layout. The fallback keeps |
| 2591 | // the warm path correct against worktree gitdir indirection, reftables, |
| 2592 | // and symref'd branch heads, which `fastReadGitHeadsRefs` deliberately |
| 2593 | // refuses to interpret. |
| 2594 | const headsOutput = |
| 2595 | (await fastReadGitHeadsRefs(projectPath)) ?? (await readGitHeadsRefs(projectPath)); |
| 2596 | if (headsOutput == null || headsOutput.length === 0) { |
| 2597 | // No local refs means a freshly-init'd local repo (no commits) or a |
| 2598 | // non-git directory. Either way the slow path needs to run. |
| 2599 | return null; |
| 2600 | } |
| 2601 | const snapshotDigest = crypto.createHash("sha256").update(headsOutput).digest("hex"); |
| 2602 | const baseRepoPathArg = expandTildeForSSH(layout.baseRepoPath); |
| 2603 | const baseRepoUnbornHeadArg = shescape.quote(BASE_REPO_UNBORN_HEAD_REF); |
| 2604 | const currentSnapshotPathArg = expandTildeForSSH(layout.currentSnapshotPath); |
| 2605 | const workspacePathArg = expandTildeForSSH(workspacePath); |
| 2606 | const workspaceParentArg = expandTildeForSSH( |
| 2607 | workspacePath.includes("/") ? workspacePath.substring(0, workspacePath.lastIndexOf("/")) : "~" |
| 2608 | ); |
| 2609 | |
| 2610 | // CORRECTNESS (origin-freshness): When the local project has an `origin` |
| 2611 | // remote, the slow path always prefers `origin/<trunkBranch>` over the |
| 2612 | // bundle ref so new workspaces base on the freshest upstream tip — see |
| 2613 | // `resolveFreshWorkspaceSourceBase()`. The warm path must match this or |
| 2614 | // it would silently check out a stale local snapshot when upstream has |
| 2615 | // advanced. We fold the same `git fetch origin <trunk>` into the fused |
| 2616 | // SSH script (single round-trip on the wire; the network hop to the |
| 2617 | // upstream stays on the datacenter side, so adding it preserves the |
| 2618 | // single-SSH-RTT envelope on the *client* side). |
| 2619 | const { originUrl } = await this.getOriginUrlForSync(projectPath, initLogger); |
| 2620 | |
| 2621 | // The remote bundle ref to base the worktree on. Prefer an exact match for |
| 2622 | // the requested branch (most projects use `main` or the trunk branch name |
| 2623 | // as the bundle ref), and we can let the remote script pick the first |
| 2624 | // available bundle ref as a fallback. |
| 2625 | const bundleRefArg = shescape.quote(`${BUNDLE_REF_PREFIX}${trunkBranch}`); |
| 2626 | const bundleRefFallbackPrefix = shescape.quote(BUNDLE_REF_PREFIX); |
| 2627 | |
| 2628 | const branchArg = shescape.quote(branchName); |
no test coverage detected