Skip to content
This repository was archived by the owner on Aug 6, 2026. It is now read-only.

Commit 5dd41ee

Browse files
authored
fix(git): handle missing remote branch comparisons (#3881)
1 parent f69bcf4 commit 5dd41ee

2 files changed

Lines changed: 90 additions & 0 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import type { GhExecResult } from "@posthog/git/gh";
2+
import { beforeEach, describe, expect, it, vi } from "vitest";
3+
4+
const execGhMock = vi.hoisted(() => vi.fn());
5+
6+
vi.mock("@posthog/git/gh", () => ({ execGh: execGhMock }));
7+
8+
import { GitService } from "./service";
9+
10+
function ghResult(overrides: Partial<GhExecResult> = {}): GhExecResult {
11+
return {
12+
stdout: "",
13+
stderr: "",
14+
exitCode: 0,
15+
...overrides,
16+
};
17+
}
18+
19+
describe("GitService", () => {
20+
beforeEach(() => {
21+
execGhMock.mockReset();
22+
});
23+
24+
it("returns no changed files when the remote branch does not exist yet", async () => {
25+
execGhMock
26+
.mockResolvedValueOnce(ghResult({ stdout: "main\n" }))
27+
.mockResolvedValueOnce(
28+
ghResult({
29+
stderr: "gh: Not Found (HTTP 404)\n",
30+
exitCode: 1,
31+
}),
32+
);
33+
34+
await expect(
35+
new GitService().getBranchChangedFiles("posthog/code", "feature/new"),
36+
).resolves.toEqual([]);
37+
});
38+
39+
it("returns changed files from a successful comparison", async () => {
40+
execGhMock
41+
.mockResolvedValueOnce(ghResult({ stdout: "main\n" }))
42+
.mockResolvedValueOnce(
43+
ghResult({
44+
stdout: JSON.stringify({
45+
files: [
46+
{
47+
filename: "src/example.ts",
48+
status: "added",
49+
additions: 3,
50+
deletions: 0,
51+
sha: "abc123",
52+
},
53+
],
54+
}),
55+
}),
56+
);
57+
58+
await expect(
59+
new GitService().getBranchChangedFiles("posthog/code", "feature/new"),
60+
).resolves.toEqual([
61+
{
62+
path: "src/example.ts",
63+
status: "added",
64+
originalPath: undefined,
65+
linesAdded: 3,
66+
linesRemoved: 0,
67+
sha: "abc123",
68+
patch: undefined,
69+
},
70+
]);
71+
});
72+
73+
it("preserves non-404 comparison failures", async () => {
74+
execGhMock
75+
.mockResolvedValueOnce(ghResult({ stdout: "main\n" }))
76+
.mockResolvedValueOnce(
77+
ghResult({
78+
stderr: "gh: authentication failed (HTTP 401)\n",
79+
exitCode: 1,
80+
}),
81+
);
82+
83+
await expect(
84+
new GitService().getBranchChangedFiles("posthog/code", "feature/new"),
85+
).rejects.toThrow("Failed to fetch branch files");
86+
});
87+
});

packages/workspace-server/src/services/git/service.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,9 @@ export class GitService extends TypedEventEmitter<GitCloneEvents> {
12361236
]);
12371237

12381238
if (result.exitCode !== 0) {
1239+
if (/HTTP 404\b/.test(`${result.stderr} ${result.error ?? ""}`)) {
1240+
return [];
1241+
}
12391242
throw new Error(
12401243
`Failed to fetch branch files: ${result.stderr || result.error || "Unknown error"}`,
12411244
);

0 commit comments

Comments
 (0)