From becf5bf482d3c76c1c475488d0abf61ff2418791 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Thu, 27 Aug 2026 23:12:36 -0400 Subject: [PATCH] refactor(core): retain changed worktrees directly (#45709) --- packages/core/src/worktree.ts | 12 ++++-------- packages/core/test/worktree.test.ts | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/packages/core/src/worktree.ts b/packages/core/src/worktree.ts index ef0569cc2b8..be89c715e30 100644 --- a/packages/core/src/worktree.ts +++ b/packages/core/src/worktree.ts @@ -334,10 +334,10 @@ const layer = Layer.effect( Effect.map((sets) => new Map(sets.flat(2).map((item) => [item.directory, item] as const)).values().toArray()), ) const removed = checked.filter((item) => !item.exists).map((item) => item.directory) - const result = yield* db + const changes = yield* db .transaction((tx) => Effect.all({ - updated: Effect.forEach(discovered, (item) => + updated: Effect.filter(discovered, (item) => ops.create( { projectID: input.projectID, @@ -346,15 +346,11 @@ const layer = Layer.effect( }, tx, ), - ), - removed: Effect.forEach(removed, (directory) => ops.remove(input.projectID, directory, tx)), + ).pipe(Effect.map((items) => items.map((item) => item.directory))), + removed: Effect.filter(removed, (directory) => ops.remove(input.projectID, directory, tx)), }), ) .pipe(Effect.orDie) - const changes = { - updated: discovered.filter((_, index) => result.updated[index]).map((item) => item.directory), - removed: removed.filter((_, index) => result.removed[index]), - } yield* changed(input.projectID, changes.updated.length > 0 || changes.removed.length > 0) return changes }) diff --git a/packages/core/test/worktree.test.ts b/packages/core/test/worktree.test.ts index 417f9b60458..87d49cd0f57 100644 --- a/packages/core/test/worktree.test.ts +++ b/packages/core/test/worktree.test.ts @@ -542,13 +542,20 @@ describe("Worktree", () => { const worktree = yield* Worktree.Service const bus = yield* Bus.Service const target = abs(`${input.root.path}-worktree-external`) + const unchanged = abs(`${input.root.path}-worktree-existing`) yield* Effect.addFinalizer(() => - Effect.promise(() => fs.rm(target, { recursive: true, force: true })).pipe(Effect.ignore), + Effect.promise(() => + Promise.all([target, unchanged].map((item) => fs.rm(item, { recursive: true, force: true }))), + ).pipe(Effect.ignore), ) yield* Effect.promise(() => $`git worktree add --detach ${target} HEAD`.cwd(input.root.path).quiet()) + yield* Effect.promise(() => $`git worktree add --detach ${unchanged} HEAD`.cwd(input.root.path).quiet()) yield* input.db .insert(WorktreeTable) - .values({ project_id: input.projectID, directory: target }) + .values([ + { project_id: input.projectID, directory: target }, + { project_id: input.projectID, directory: unchanged, strategy: "git" }, + ]) .run() .pipe(Effect.orDie) const fiber = yield* bus @@ -557,18 +564,24 @@ describe("Worktree", () => { yield* Effect.yieldNow const discovered = abs(yield* Effect.promise(() => fs.realpath(target))) + const existing = abs(yield* Effect.promise(() => fs.realpath(unchanged))) expect(yield* worktree.refresh({ projectID: input.projectID })).toEqual({ updated: [discovered], removed: [] }) expect(yield* stored(input.projectID)).toEqual( [ { directory: input.sourceDirectory, strategy: null }, { directory: discovered, strategy: "git" }, + { directory: existing, strategy: "git" }, ].toSorted((a, b) => a.directory.localeCompare(b.directory)), ) expect(Array.from(yield* Fiber.join(fiber))[0]?.data).toEqual({ projectID: input.projectID }) yield* Effect.promise(() => $`git worktree remove --force ${target}`.cwd(input.root.path).quiet()) - expect(yield* worktree.refresh({ projectID: input.projectID })).toEqual({ updated: [], removed: [discovered] }) + yield* Effect.promise(() => $`git worktree remove --force ${unchanged}`.cwd(input.root.path).quiet()) + expect(yield* worktree.refresh({ projectID: input.projectID })).toEqual({ + updated: [], + removed: [discovered, existing].toSorted(), + }) expect(yield* stored(input.projectID)).toEqual([{ directory: input.sourceDirectory, strategy: null }]) }), )