From 5df18b68c3830581721eaf8dfb866cce303f61c9 Mon Sep 17 00:00:00 2001 From: Hieu Le <78847613+hieu-lee@users.noreply.github.com> Date: Sun, 1 Nov 2026 10:21:48 +0100 Subject: [PATCH] perf(server): worktree creation spawns fewer git processes Thread launch resolved the worktree base remote twice (git remote plus git for-each-ref each time, plus a driver lookup). It now resolves once and hands the result to the fetch. createWorktree read checkout.workers and the base-ref comparison one after the other after the base was known. Both are read-only, so they now share one round trip before git worktree add. The single-branch base fetch now passes --no-tags like the other scoped fetches, so a repository with many tags no longer advertises and follows them for one branch. Co-Authored-By: Claude Sonnet 5.5 --- apps/server/src/git/GitWorkflowService.ts | 1 + .../ThreadLaunchService.test.ts | 23 +++++++ .../orchestration-v2/ThreadLaunchService.ts | 21 ++++--- apps/server/src/vcs/GitVcsDriver.ts | 14 ++++- apps/server/src/vcs/GitVcsDriverCore.test.ts | 49 +++++++++++++++ apps/server/src/vcs/GitVcsDriverCore.ts | 61 +++++++++++-------- 6 files changed, 131 insertions(+), 38 deletions(-) diff --git a/apps/server/src/git/GitWorkflowService.ts b/apps/server/src/git/GitWorkflowService.ts index fdc00849af2d0..bf89c7cc1baaa 100644 --- a/apps/server/src/git/GitWorkflowService.ts +++ b/apps/server/src/git/GitWorkflowService.ts @@ -105,6 +105,7 @@ export class GitWorkflowService extends Context.Service< readonly fetchWorktreeBaseCommit: (input: { readonly cwd: string; readonly refName: string; + readonly remote?: GitVcsDriver.GitWorktreeBaseRemote; }) => Effect.Effect< { readonly commitSha: string; readonly remoteRefName: string } | null, GitCommandError diff --git a/apps/server/src/orchestration-v2/ThreadLaunchService.test.ts b/apps/server/src/orchestration-v2/ThreadLaunchService.test.ts index d3c62a7e134bd..b19666ec8e377 100644 --- a/apps/server/src/orchestration-v2/ThreadLaunchService.test.ts +++ b/apps/server/src/orchestration-v2/ThreadLaunchService.test.ts @@ -1114,6 +1114,29 @@ it.effect.each(["stable", "upstream/release"])( ), ); +it.effect("fetches the origin base from the remote it already resolved", () => { + let fetchInput: Deferred.Deferred | null = null; + const harness = makeHarness({ + fetchWorktreeBaseCommit: (input) => Deferred.succeed(fetchInput!, input).pipe(Effect.as(null)), + }); + return Effect.gen(function* () { + fetchInput = yield* Deferred.make(); + const launches = yield* ThreadLaunch.ThreadLaunchService; + yield* launches.launch( + launchInput({ + command: "command:launch:resolved-remote", + thread: "thread:launch:resolved-remote", + workspace: { type: "worktree", baseRef: "main", startFromOrigin: true }, + }), + ); + assert.deepEqual(yield* Deferred.await(fetchInput), { + cwd: project.workspaceRoot, + refName: "main", + remote: { remoteName: "origin", branchName: "main" }, + }); + }).pipe(Effect.provide(harness.layer)); +}); + it.effect("shows the fetch diagnosis when preparing a worktree from origin fails", () => { const detail = "Git could not authenticate with the remote. Check Git credentials or SSH access on the server, then retry."; diff --git a/apps/server/src/orchestration-v2/ThreadLaunchService.ts b/apps/server/src/orchestration-v2/ThreadLaunchService.ts index b68eef4b2a40c..4ab38c4b305e3 100644 --- a/apps/server/src/orchestration-v2/ThreadLaunchService.ts +++ b/apps/server/src/orchestration-v2/ThreadLaunchService.ts @@ -396,20 +396,23 @@ const make = Effect.gen(function* () { } let startRef = input.workspaceStrategy.baseRef; let baseRefName = input.workspaceStrategy.baseRef; - const shouldFetch = - input.workspaceStrategy.startFromOrigin === true && - (yield* git - .resolveWorktreeBaseRemote({ - cwd: project.workspaceRoot, - refName: input.workspaceStrategy.baseRef, - }) - .pipe(Effect.mapError(mapError(input, "provision-worktree", threadId)))) !== null; + const remote = + input.workspaceStrategy.startFromOrigin === true + ? yield* git + .resolveWorktreeBaseRemote({ + cwd: project.workspaceRoot, + refName: input.workspaceStrategy.baseRef, + }) + .pipe(Effect.mapError(mapError(input, "provision-worktree", threadId))) + : null; + const shouldFetch = remote !== null; yield* setupTracker.stageStatus(threadId, "fetch", shouldFetch ? "running" : "skipped"); - if (shouldFetch) { + if (remote !== null) { const remoteBase = yield* git .fetchWorktreeBaseCommit({ cwd: project.workspaceRoot, refName: input.workspaceStrategy.baseRef, + remote, }) .pipe(Effect.mapError(mapError(input, "provision-worktree", threadId))); if (remoteBase !== null) { diff --git a/apps/server/src/vcs/GitVcsDriver.ts b/apps/server/src/vcs/GitVcsDriver.ts index fe49a6b1391af..3cd9e36cfe46c 100644 --- a/apps/server/src/vcs/GitVcsDriver.ts +++ b/apps/server/src/vcs/GitVcsDriver.ts @@ -285,6 +285,11 @@ export interface GitWriteConfigValueInput { readonly value: string; } +export interface GitWorktreeBaseRemote { + remoteName: string; + branchName: string; +} + export interface GitSetBranchUpstreamInput { cwd: string; branch: string; @@ -392,10 +397,13 @@ export class GitVcsDriver extends Context.Service< ) => Effect.Effect; readonly resolveWorktreeBaseRemote: ( input: GitFetchWorktreeBaseCommitInput, - ) => Effect.Effect<{ remoteName: string; branchName: string } | null, GitCommandError>; - /** Fetches the configured upstream, explicit remote ref, or origin; null uses the local base. */ + ) => Effect.Effect; + /** + * Fetches the configured upstream, explicit remote ref, or origin; null uses the local base. + * A caller that already ran `resolveWorktreeBaseRemote` passes its result as `remote`. + */ readonly fetchWorktreeBaseCommit: ( - input: GitFetchWorktreeBaseCommitInput, + input: GitFetchWorktreeBaseCommitInput & { readonly remote?: GitWorktreeBaseRemote }, ) => Effect.Effect; readonly fetchRemoteBranch: ( input: GitFetchRemoteBranchInput, diff --git a/apps/server/src/vcs/GitVcsDriverCore.test.ts b/apps/server/src/vcs/GitVcsDriverCore.test.ts index d9a48457f8a38..3c6cd9112701d 100644 --- a/apps/server/src/vcs/GitVcsDriverCore.test.ts +++ b/apps/server/src/vcs/GitVcsDriverCore.test.ts @@ -5413,6 +5413,55 @@ it.layer(layerTest)("GitVcsDriver core integration", (it) => { }), ); + it.effect("fetches a worktree base without downloading tags", () => + Effect.gen(function* () { + const cwd = yield* makeTmpDir(); + const remote = yield* makeTmpDir("git-remote-"); + const { initialBranch } = yield* initRepoWithCommit(cwd); + yield* git(remote, ["init", "--bare"]); + yield* git(cwd, ["remote", "add", "origin", remote]); + yield* git(cwd, ["push", "-u", "origin", initialBranch]); + const localHead = yield* git(cwd, ["rev-parse", "HEAD"]); + yield* git(cwd, ["commit", "--allow-empty", "-m", "tagged release"]); + const remoteHead = yield* git(cwd, ["rev-parse", "HEAD"]); + yield* git(cwd, ["tag", "v1"]); + yield* git(cwd, ["push", "origin", initialBranch, "v1"]); + yield* git(cwd, ["tag", "-d", "v1"]); + yield* git(cwd, ["reset", "--hard", localHead]); + yield* git(cwd, ["update-ref", "-d", `refs/remotes/origin/${initialBranch}`]); + const driver = yield* GitVcsDriver.GitVcsDriver; + + assert.deepEqual(yield* driver.fetchWorktreeBaseCommit({ cwd, refName: initialBranch }), { + commitSha: remoteHead, + remoteRefName: `origin/${initialBranch}`, + }); + assert.equal(yield* git(cwd, ["tag", "--list", "v1"]), ""); + }), + ); + + it.effect("fetches the remote a caller already resolved for the worktree base", () => + Effect.gen(function* () { + const cwd = yield* makeTmpDir(); + const remote = yield* makeTmpDir("git-remote-"); + const { initialBranch } = yield* initRepoWithCommit(cwd); + yield* git(remote, ["init", "--bare"]); + yield* git(cwd, ["remote", "add", "origin", remote]); + yield* git(cwd, ["push", "origin", initialBranch]); + const head = yield* git(cwd, ["rev-parse", "HEAD"]); + const driver = yield* GitVcsDriver.GitVcsDriver; + + assert.isNull(yield* driver.fetchWorktreeBaseCommit({ cwd, refName: "unpublished" })); + assert.deepEqual( + yield* driver.fetchWorktreeBaseCommit({ + cwd, + refName: "unpublished", + remote: { remoteName: "origin", branchName: initialBranch }, + }), + { commitSha: head, remoteRefName: `origin/${initialBranch}` }, + ); + }), + ); + it.effect("fails instead of falling back when the worktree base remote is unreachable", () => Effect.gen(function* () { const cwd = yield* makeTmpDir(); diff --git a/apps/server/src/vcs/GitVcsDriverCore.ts b/apps/server/src/vcs/GitVcsDriverCore.ts index 11580f4c26e18..87f1daabdc1c8 100644 --- a/apps/server/src/vcs/GitVcsDriverCore.ts +++ b/apps/server/src/vcs/GitVcsDriverCore.ts @@ -4147,7 +4147,17 @@ export const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* const progress = options?.progress; const onCheckoutProgress = progress?.onCheckoutProgress; - const checkoutWorkers = (yield* readConfigValue(input.cwd, "checkout.workers")) ?? "0"; + // Both reads leave the repository alone, so they share one round trip before the checkout. + const [configuredCheckoutWorkers, base] = yield* Effect.all( + [ + readConfigValue(input.cwd, "checkout.workers"), + input.newRefName && input.baseRefName + ? resolveBranchBase(input.cwd, input.baseRefName) + : Effect.succeed(null), + ], + { concurrency: "unbounded" }, + ); + const checkoutWorkers = configuredCheckoutWorkers ?? "0"; yield* executeGitWithStableDiagnostics( "GitVcsDriver.createWorktree", input.cwd, @@ -4253,32 +4263,27 @@ export const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* } const newRefName = input.newRefName; - if (newRefName && input.baseRefName) { - const base = yield* resolveBranchBase(input.cwd, input.baseRefName); - if (base) { - yield* Effect.gen(function* () { + if (newRefName && base) { + yield* Effect.gen(function* () { + yield* writeConfigValue({ + cwd: input.cwd, + key: branchBaseConfigKey(newRefName), + value: base.branchName, + }); + if (base.baseRef.startsWith("refs/remotes/")) { + // The base key names a branch on the host; this one keeps the remote it came from. yield* writeConfigValue({ cwd: input.cwd, - key: branchBaseConfigKey(newRefName), - value: base.branchName, + key: `branch.${newRefName}.t3-merge-base-ref`, + value: base.baseRef, }); - if (base.baseRef.startsWith("refs/remotes/")) { - // The base key names a branch on the host; this one keeps the remote it came from. - yield* writeConfigValue({ - cwd: input.cwd, - key: `branch.${input.newRefName}.t3-merge-base-ref`, - value: base.baseRef, - }); - } - }).pipe( - Effect.catchTags({ - GitCommandError: () => - Effect.logWarning( - "worktree base-ref configuration failed; using base-branch fallback", - ), - }), - ); - } + } + }).pipe( + Effect.catchTags({ + GitCommandError: () => + Effect.logWarning("worktree base-ref configuration failed; using base-branch fallback"), + }), + ); } return { @@ -4444,7 +4449,11 @@ export const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* const branch = parseRemoteRefWithRemoteNames(input.refName, [input.remoteName])?.branchName ?? input.refName; const scopedArgs = [ - ...args, + "fetch", + "--quiet", + "--no-tags", + "--", + input.remoteName, `+refs/heads/${branch}:refs/remotes/${input.remoteName}/${branch}`, ]; const result = yield* runFetch(scopedArgs); @@ -4524,7 +4533,7 @@ export const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* const fetchWorktreeBaseCommit: GitVcsDriver.GitVcsDriver["Service"]["fetchWorktreeBaseCommit"] = Effect.fn("fetchWorktreeBaseCommit")(function* (input) { - const target = yield* resolveWorktreeBaseRemote(input); + const target = input.remote ?? (yield* resolveWorktreeBaseRemote(input)); if (target === null) return null; const { remoteName, branchName } = target; const remoteRefName = `${remoteName}/${branchName}`;