From 9b7b6cb30f6aca1836c6a89e5eee6f7b1f6d4636 Mon Sep 17 00:00:00 2001 From: James Long Date: Fri, 8 May 2026 22:45:44 -0400 Subject: [PATCH] feat(core): be smarter about generating a worktree name (#26368) --- packages/opencode/src/worktree/index.ts | 4 ++- .../opencode/test/project/worktree.test.ts | 29 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/worktree/index.ts b/packages/opencode/src/worktree/index.ts index 088dc9eb35..27d2e41cd6 100644 --- a/packages/opencode/src/worktree/index.ts +++ b/packages/opencode/src/worktree/index.ts @@ -361,13 +361,15 @@ export const layer: Layer.Layer< } const primary = yield* canonical(ctx.worktree) + const primaryName = pathSvc.basename(primary).toLowerCase() return yield* Effect.forEach(parseWorktreeList(result.text), (entry) => Effect.gen(function* () { if (!entry.path) return undefined const directory = yield* canonical(entry.path) if (directory === primary) return undefined + const name = pathSvc.basename(directory).toLowerCase() return { - name: pathSvc.basename(directory), + name: name === primaryName ? pathSvc.basename(pathSvc.dirname(directory)) : name, directory, ...(entry.branch ? { branch: entry.branch.replace(/^refs\/heads\//, "") } : {}), } diff --git a/packages/opencode/test/project/worktree.test.ts b/packages/opencode/test/project/worktree.test.ts index b191a3c952..4f0ead54e4 100644 --- a/packages/opencode/test/project/worktree.test.ts +++ b/packages/opencode/test/project/worktree.test.ts @@ -200,6 +200,35 @@ describe("Worktree", () => { ) }) + describe("list", () => { + it.live("uses parent folder name when worktree basename matches the primary worktree", () => + provideTmpdirInstance( + (dir) => + Effect.gen(function* () { + const svc = yield* Worktree.Service + const parent = path.join(path.dirname(dir), `${path.basename(dir)}-parent`) + const target = path.join(parent, path.basename(dir)) + const branch = `same-basename-list-${Date.now()}` + + yield* Effect.promise(() => fs.mkdir(parent, { recursive: true })) + yield* Effect.promise(() => $`git worktree add -b ${branch} ${target}`.cwd(dir).quiet()) + + const list = yield* svc.list() + const directory = yield* Effect.promise(() => fs.realpath(target).catch(() => target)) + + expect(list).toContainEqual({ + name: path.basename(parent), + branch, + directory: directory.toLowerCase(), + }) + + yield* svc.remove({ directory: target }) + }), + { git: true }, + ), + ) + }) + describe("remove edge cases", () => { it.live("remove non-existent directory succeeds silently", () => provideTmpdirInstance(