From 8f4c3daca89d4e2d5c817db5f750f78d628e0ec5 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sat, 25 Jul 2026 15:19:15 -0700 Subject: [PATCH] fix(worktree): only dedupe a linked worktree against a git main checkout Review follow-up: the repos:add guard matched any tracked repo on the main checkout path, including a folder-kind record. A folder repo does not project onto the same project as the git worktree, so matching it would suppress a legitimate add without deduping anything. --- src/main/ipc/repos-add-linked-worktree.test.ts | 12 ++++++++++++ src/main/ipc/repos.ts | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/ipc/repos-add-linked-worktree.test.ts b/src/main/ipc/repos-add-linked-worktree.test.ts index 9ad6b5688e0..d6880848850 100644 --- a/src/main/ipc/repos-add-linked-worktree.test.ts +++ b/src/main/ipc/repos-add-linked-worktree.test.ts @@ -167,6 +167,18 @@ describe('repos:add with git worktrees', () => { expect(mockStore.addRepo).not.toHaveBeenCalled() }) + it('does not match a folder record sitting on the main-checkout path', async () => { + mockStore.getRepos.mockReturnValue([ + { ...trackedMainRepo(), id: 'folder-repo-id', kind: 'folder' } as Repo + ]) + getLinkedWorktreeMainRepoRootMock.mockReturnValue(MAIN_CHECKOUT) + + const result = await callAdd({ path: LINKED_WORKTREE }) + + expect(mockStore.addRepo).toHaveBeenCalledTimes(1) + expect(result).toEqual({ repo: expect.objectContaining({ path: LINKED_WORKTREE }) }) + }) + it('does not match a tracked SSH repo that shares the local main-checkout path', async () => { mockStore.getRepos.mockReturnValue([ { ...trackedMainRepo(), id: 'ssh-repo-id', connectionId: 'builder' } as Repo diff --git a/src/main/ipc/repos.ts b/src/main/ipc/repos.ts index 0c63b851fe3..185096e5ff6 100644 --- a/src/main/ipc/repos.ts +++ b/src/main/ipc/repos.ts @@ -203,11 +203,15 @@ async function addLocalRepoFromPath( const mainRepoRoot = getLinkedWorktreeMainRepoRoot(resolvedPath) if (mainRepoRoot) { const mainRepoKey = normalizeRuntimePathForComparison(mainRepoRoot) + // Why !isFolderRepo: only a git-kind main checkout projects onto the same project as its + // worktree, so matching a folder record would suppress the add without deduping anything. const trackedMainRepo = store .getRepos() .find( (repo) => - !repo.connectionId && normalizeRuntimePathForComparison(repo.path) === mainRepoKey + !repo.connectionId && + !isFolderRepo(repo) && + normalizeRuntimePathForComparison(repo.path) === mainRepoKey ) if (trackedMainRepo) { return { repo: trackedMainRepo, alreadyExisted: true }