| author | |
| committer | |
| log | 29825f2f8a7cc2bb47fd32160046d47b5cf44830 |
| tree | 715e8a86572dac8cba5403884bb16c523ed47b3f |
| parent | efcee4b86354fba7457a62d8beafb4011ec3ae52 |
- ignore branch lines starting with `(` when parsing `git branch` output
- add integration test to verify detached HEAD does not appear as a branch2 files changed, 14 insertions(+), 1 deletions(-)
apps/server/src/git/Layers/GitCore.test.ts+12| ... | @@ -266,6 +266,18 @@ it.layer(TestLayer)("git integration", (it) => { | ... | @@ -266,6 +266,18 @@ it.layer(TestLayer)("git integration", (it) => { |
| 266 | }), | 266 | }), |
| 267 | ); | 267 | ); |
| 268 | 268 | ||
| 269 | it.effect("does not include detached HEAD pseudo-refs as branches", () => | ||
| 270 | Effect.gen(function* () { | ||
| 271 | const tmp = yield* makeTmpDir(); | ||
| 272 | yield* initRepoWithCommit(tmp); | ||
| 273 | yield* git(tmp, ["checkout", "--detach", "HEAD"]); | ||
| 274 | |||
| 275 | const result = yield* listGitBranches({ cwd: tmp }); | ||
| 276 | expect(result.branches.some((branch) => branch.name.startsWith("("))).toBe(false); | ||
| 277 | expect(result.branches.some((branch) => branch.current)).toBe(false); | ||
| 278 | }), | ||
| 279 | ); | ||
| 280 | |||
| 269 | it.effect("keeps current branch first and sorts the remaining branches by recency", () => | 281 | it.effect("keeps current branch first and sorts the remaining branches by recency", () => |
| 270 | Effect.gen(function* () { | 282 | Effect.gen(function* () { |
| 271 | const tmp = yield* makeTmpDir(); | 283 | const tmp = yield* makeTmpDir(); |
apps/server/src/git/Layers/GitCore.ts+2-1| ... | @@ -82,7 +82,8 @@ function parseBranchLine(line: string): { name: string; current: boolean } | nul | ... | @@ -82,7 +82,8 @@ function parseBranchLine(line: string): { name: string; current: boolean } | nul |
| 82 | 82 | ||
| 83 | const name = trimmed.replace(/^[*+]\s+/, ""); | 83 | const name = trimmed.replace(/^[*+]\s+/, ""); |
| 84 | // Exclude symbolic refs like: "origin/HEAD -> origin/main". | 84 | // Exclude symbolic refs like: "origin/HEAD -> origin/main". |
| 85 | if (name.includes(" -> ")) return null; | 85 | // Exclude detached HEAD pseudo-refs like: "(HEAD detached at origin/main)". |
| 86 | if (name.includes(" -> ") || name.startsWith("(")) return null; | ||
| 86 | 87 | ||
| 87 | return { | 88 | return { |
| 88 | name, | 89 | name, |