authorgravatar for 46866023+GuilhermeVieiraDev@users.noreply.github.comGuilherme Vieira <46866023+GuilhermeVieiraDev@users.noreply.github.com> 2026-04-30 05:29:48+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-04-29 21:29:48-07:00
log69d9a659a36ee246c543e46a522556918ed4ed9e
tree7bdfe12960ef799bb665b2cf5b50bee1a966a754
parent9acf46a76d60e31098034267b36fd4f6e3a15ea6
signature Signed by PGP key B5690EEEBB952194

fix(git): hide stale merged/closed PRs on the default branch (#1966)


2 files changed, 37 insertions(+), 1 deletions(-)

apps/server/src/git/Layers/GitManager.test.ts+30
......@@ -1188,6 +1188,36 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => {
11881188 }),
11891189 );
11901190
1191 it.effect("status hides merged PRs on the default branch", () =>
1192 Effect.gen(function* () {
1193 const repoDir = yield* makeTempDir("t3code-git-manager-");
1194 yield* initRepo(repoDir);
1195
1196 const { manager } = yield* makeManager({
1197 ghScenario: {
1198 prListSequence: [
1199 JSON.stringify([
1200 {
1201 number: 23,
1202 title: "Merged PR",
1203 url: "https://github.com/pingdotgg/codething-mvp/pull/23",
1204 baseRefName: "feature/status-default-branch-target",
1205 headRefName: "main",
1206 state: "MERGED",
1207 mergedAt: "2026-01-30T10:00:00Z",
1208 updatedAt: "2026-01-30T10:00:00Z",
1209 },
1210 ]),
1211 ],
1212 },
1213 });
1214
1215 const status = yield* manager.status({ cwd: repoDir });
1216 expect(status.branch).toBe("main");
1217 expect(status.pr).toBeNull();
1218 }),
1219 );
1220
11911221 it.effect("status prefers open PR when merged PR has newer updatedAt", () =>
11921222 Effect.gen(function* () {
11931223 const repoDir = yield* makeTempDir("t3code-git-manager-");
apps/server/src/git/Layers/GitManager.ts+7-1
......@@ -688,7 +688,13 @@ export const makeGitManager = Effect.fn("makeGitManager")(function* () {
688688 branch: details.branch,
689689 upstreamRef: details.upstreamRef,
690690 }).pipe(
691 Effect.map((latest) => (latest ? toStatusPr(latest) : null)),
691 Effect.map((latest) => {
692 if (!latest) return null;
693 // On the default branch, only surface open PRs.
694 // Merged/closed matches are usually reverse-merge history, not the thread's PR context.
695 if (details.isDefaultBranch && latest.state !== "open") return null;
696 return toStatusPr(latest);
697 }),
692698 Effect.catch(() => Effect.succeed(null)),
693699 )
694700 : null;