From 9c7622dac3d1a385351e6c74354a9e6b9c2037d5 Mon Sep 17 00:00:00 2001 From: "t3-code[bot]" <269035359+t3-code[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 23:34:18 -0400 Subject: [PATCH] fix(server): handle unborn HEAD in VCS status (#5944) Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com> --- apps/server/src/vcs/GitVcsDriverCore.test.ts | 17 +++++++++ apps/server/src/vcs/GitVcsDriverCore.ts | 38 ++++++++++++-------- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/apps/server/src/vcs/GitVcsDriverCore.test.ts b/apps/server/src/vcs/GitVcsDriverCore.test.ts index 6e352f013fe5e38cd35bd9b51755c76a7ae64166..18e594512ee8cc473ff002911c5c11e6dd2600ce 100644 --- a/apps/server/src/vcs/GitVcsDriverCore.test.ts +++ b/apps/server/src/vcs/GitVcsDriverCore.test.ts @@ -1001,6 +1001,23 @@ it.layer(TestLayer)("GitVcsDriver core integration", (it) => { }), ); + it.effect("reports remote status on unborn HEAD without failing", () => + Effect.gen(function* () { + const cwd = yield* makeTmpDir(); + const driver = yield* GitVcsDriver.GitVcsDriver; + yield* driver.initRepo({ cwd }); + const initialBranch = yield* git(cwd, ["symbolic-ref", "--short", "HEAD"]); + + const status = yield* driver.statusDetailsRemote(cwd, { refreshUpstream: false }); + + assert.equal(status.isRepo, true); + assert.equal(status.branch, initialBranch); + assert.equal(status.hasUpstream, false); + assert.equal(status.aheadCount, 0); + assert.equal(status.behindCount, 0); + }), + ); + it.effect("can read cached remote divergence without fetching upstream", () => Effect.gen(function* () { const cwd = yield* makeTmpDir(); diff --git a/apps/server/src/vcs/GitVcsDriverCore.ts b/apps/server/src/vcs/GitVcsDriverCore.ts index 5b9359adaa84408f4a00b1994dc2a015330cc124..1489db9b3ff461900fa556f44f7b00931b39bfb8 100644 --- a/apps/server/src/vcs/GitVcsDriverCore.ts +++ b/apps/server/src/vcs/GitVcsDriverCore.ts @@ -1477,25 +1477,35 @@ export const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* if (branchResult === null) { return NON_REPOSITORY_REMOTE_STATUS_DETAILS; } + let branch: string | null; if (branchResult.exitCode !== 0) { if (isNonRepositoryGitStderr(branchResult.stderr)) { return NON_REPOSITORY_REMOTE_STATUS_DETAILS; } - return yield* new GitCommandError({ - ...gitCommandContext({ - operation: "GitVcsDriver.statusDetailsRemote.branch", - cwd, - args: ["rev-parse", "--abbrev-ref", "HEAD"], - }), - detail: "Git branch lookup failed.", - exitCode: branchResult.exitCode, - stdoutLength: branchResult.stdout.length, - stderrLength: branchResult.stderr.length, - }); - } + if (!isUnbornHeadStderr(branchResult.stderr)) { + return yield* new GitCommandError({ + ...gitCommandContext({ + operation: "GitVcsDriver.statusDetailsRemote.branch", + cwd, + args: ["rev-parse", "--abbrev-ref", "HEAD"], + }), + detail: "Git branch lookup failed.", + exitCode: branchResult.exitCode, + stdoutLength: branchResult.stdout.length, + stderrLength: branchResult.stderr.length, + }); + } - const branchValue = branchResult.stdout.trim(); - const branch = branchValue.length > 0 && branchValue !== "HEAD" ? branchValue : null; + const branchValue = yield* runGitStdout( + "GitVcsDriver.statusDetailsRemote.unbornBranch", + cwd, + ["symbolic-ref", "--quiet", "--short", "HEAD"], + ); + branch = branchValue.trim() || null; + } else { + const branchValue = branchResult.stdout.trim(); + branch = branchValue.length > 0 && branchValue !== "HEAD" ? branchValue : null; + } const upstream = yield* resolveCurrentUpstream(cwd); const upstreamRef = upstream?.upstreamRef ?? null; let aheadCount = 0; -- 2.54.0