From 7f2a95fe14c18b3feba039df6b88c6c47a846d04 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Sat, 28 Feb 2026 11:10:18 -0800 Subject: [PATCH] Prefer open PR when resolving git status PR - Update GitManager PR selection to return the latest open PR before merged ones - Add regression test covering open-vs-merged ordering by updatedAt --- apps/server/src/git/Layers/GitManager.test.ts | 47 +++++++++++++++++++ apps/server/src/git/Layers/GitManager.ts | 5 ++ 2 files changed, 52 insertions(+) diff --git a/apps/server/src/git/Layers/GitManager.test.ts b/apps/server/src/git/Layers/GitManager.test.ts index b8d0ad1aab8a4270e99cb62067256c88629a6ff4..88d26f7710877e9f9eaf01a4dd5f153afedde0e6 100644 --- a/apps/server/src/git/Layers/GitManager.test.ts +++ b/apps/server/src/git/Layers/GitManager.test.ts @@ -373,6 +373,53 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { }), ); + it.effect("status prefers open PR when merged PR has newer updatedAt", () => + Effect.gen(function* () { + const repoDir = yield* makeTempDir("t3code-git-manager-"); + yield* initRepo(repoDir); + yield* runGit(repoDir, ["checkout", "-b", "feature/status-open-over-merged"]); + + const { manager } = yield* makeManager({ + ghScenario: { + prListSequence: [ + JSON.stringify([ + { + number: 45, + title: "Merged PR", + url: "https://github.com/pingdotgg/codething-mvp/pull/45", + baseRefName: "main", + headRefName: "feature/status-open-over-merged", + state: "MERGED", + mergedAt: "2026-01-31T10:00:00Z", + updatedAt: "2026-02-01T10:00:00Z", + }, + { + number: 46, + title: "Open PR", + url: "https://github.com/pingdotgg/codething-mvp/pull/46", + baseRefName: "main", + headRefName: "feature/status-open-over-merged", + state: "OPEN", + updatedAt: "2026-01-30T10:00:00Z", + }, + ]), + ], + }, + }); + + const status = yield* manager.status({ cwd: repoDir }); + expect(status.branch).toBe("feature/status-open-over-merged"); + expect(status.pr).toEqual({ + number: 46, + title: "Open PR", + url: "https://github.com/pingdotgg/codething-mvp/pull/46", + baseBranch: "main", + headBranch: "feature/status-open-over-merged", + state: "open", + }); + }), + ); + it.effect("status is resilient to gh lookup failures and returns pr null", () => Effect.gen(function* () { const repoDir = yield* makeTempDir("t3code-git-manager-"); diff --git a/apps/server/src/git/Layers/GitManager.ts b/apps/server/src/git/Layers/GitManager.ts index 5deaf6ed4c40daca9db215cb7f959ad2a0b70031..27ad13af2767b81e1796c0a34030130c6b59e850 100644 --- a/apps/server/src/git/Layers/GitManager.ts +++ b/apps/server/src/git/Layers/GitManager.ts @@ -223,6 +223,11 @@ export const makeGitManager = Effect.gen(function* () { const right = b.updatedAt ? Date.parse(b.updatedAt) : 0; return right - left; }); + + const latestOpenPr = parsed.find((pr) => pr.state === "open"); + if (latestOpenPr) { + return latestOpenPr; + } return parsed[0] ?? null; }); -- 2.54.0