# Files changed · PR \#18537 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/18537/diffs)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

[fix\(server\): worktree creation no longer times out fetching busy repos](https://git.cafe/pingdotgg/t3code/pull/18537.md)

Version: 7

Head commit: e0882fad916b3a5f9020313149a87e503aa5ddae

Base commit: c274a251510e4bb035f8479a7f1e96443cd2503c

Comparison base: c274a251510e4bb035f8479a7f1e96443cd2503c

Showing up to 20 entries from this revision. If the pull request changes, reopen the first page before continuing.

## apps/server/src/vcs/GitVcsDriverCore.test.ts

Status: modified; +41; −2

```diff
@@ -2034,6 +2034,7 @@
         }
         yield* git(cwd, ["add", "."]);
         yield* git(cwd, ["update-index", "--chmod=+x", "mode-only.sh"]);
+        yield* git(cwd, ["checkout-index", "--force", "mode-only.sh"]);
         yield* git(cwd, ["commit", "-m", "rename and add files"]);
         const preview = yield* driver.getReviewDiffPreview({
           cwd,
@@ -4173,8 +4174,7 @@
             .pipe(Effect.result, Effect.forkChild({ startImmediately: true }));
           yield* Deferred.await(started);
           if (failure === "timeout") {
-            yield* TestClock.adjust("31 seconds");
-            yield* TestClock.adjust("31 seconds");
+            yield* TestClock.adjust("301 seconds");
           }
           const result = yield* Fiber.join(fetching);
           assert.isTrue(Result.isFailure(result));
@@ -4192,6 +4192,45 @@
         }),
     );
 
+    it.effect("allows remote fetches to run longer than the default command timeout", () =>
+      Effect.gen(function* () {
+        const delegate = yield* ChildProcessSpawner.ChildProcessSpawner;
+        const fetchStarted = yield* Deferred.make<void>();
+        const delayedFetchSpawner = ChildProcessSpawner.make((command) =>
+          Effect.gen(function* () {
+            if (ChildProcess.isStandardCommand(command) && command.args[0] === "fetch") {
+              yield* Deferred.succeed(fetchStarted, undefined);
+              yield* Effect.sleep("31 seconds");
+            }
+            return yield* delegate.spawn(command);
+          }),
+        );
+        const driver = yield* makeGitVcsDriverCore().pipe(
+          Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, delayedFetchSpawner),
+          Effect.provide(layerServerConfig),
+        );
+        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]);
+        yield* git(cwd, ["update-ref", "-d", `refs/remotes/origin/${initialBranch}`]);
+
+        const fetching = yield* driver
+          .fetchRemote({ cwd, remoteName: "origin", refName: initialBranch })
+          .pipe(Effect.forkChild({ startImmediately: true }));
+        yield* Deferred.await(fetchStarted);
+        yield* TestClock.adjust("31 seconds");
+        yield* Fiber.join(fetching);
+
+        assert.equal(
+          yield* git(cwd, ["rev-parse", `refs/remotes/origin/${initialBranch}`]),
+          yield* git(cwd, ["rev-parse", initialBranch]),
+        );
+      }),
+    );
+
     it.effect("creates a worktree from the latest fetched remote commit", () =>
       Effect.gen(function* () {
         const cwd = yield* makeTmpDir();
```

## apps/server/src/vcs/GitVcsDriverCore.ts

Status: modified; +4; −0

```diff
@@ -49,6 +49,9 @@
 const DEFAULT_TIMEOUT_MS = 30_000;
 const gitProcesses = Semaphore.makeUnsafe(8);
 const WORKTREE_ADD_TIMEOUT_MS = 300_000;
+// The fetch before `git worktree add` downloads everything the remote gained since
+// the last fetch; on busy repositories that alone outlasts the 30s default.
+const FETCH_REMOTE_TIMEOUT_MS = WORKTREE_ADD_TIMEOUT_MS;
 const WORKTREE_REMOVE_TIMEOUT_MS = Duration.toMillis(Duration.minutes(5));
 const DEFAULT_MAX_OUTPUT_BYTES = 1_000_000;
 const OUTPUT_TRUNCATED_MARKER = "\n\n[truncated]";
@@ -3730,6 +3733,7 @@
       const options = {
         env: STATUS_UPSTREAM_REFRESH_ENV,
         fallbackErrorDetail: `git fetch ${input.remoteName} failed`,
+        timeoutMs: FETCH_REMOTE_TIMEOUT_MS,
       };
       // Another fetch in the same repository, such as the background status
       // poll, can win the race for a remote-tracking ref. The loser fails, but
```
