diff --git a/apps/server/src/routes/worktree/routes/list.ts b/apps/server/src/routes/worktree/routes/list.ts index 785a5a88..93d93dad 100644 --- a/apps/server/src/routes/worktree/routes/list.ts +++ b/apps/server/src/routes/worktree/routes/list.ts @@ -74,23 +74,8 @@ export function createListHandler() { } else if (line.startsWith('branch ')) { current.branch = line.slice(7).replace('refs/heads/', ''); } else if (line === '') { - if (current.path) { + if (current.path && current.branch) { const isMainWorktree = isFirst; - - // If branch is missing (can happen for main worktree in some git states), - // fall back to getCurrentBranch() for the main worktree - let branchName = current.branch; - if (!branchName && isMainWorktree) { - // For main worktree, use the current branch we already fetched - branchName = currentBranch || ''; - } - - // Skip if we still don't have a branch name (shouldn't happen, but be safe) - if (!branchName) { - current = {}; - continue; - } - // Check if the worktree directory actually exists // Skip checking/pruning the main worktree (projectPath itself) let worktreeExists = false; @@ -104,15 +89,15 @@ export function createListHandler() { // Worktree directory doesn't exist - it was manually deleted removedWorktrees.push({ path: current.path, - branch: branchName, + branch: current.branch, }); } else { // Worktree exists (or is main worktree), add it to the list worktrees.push({ path: current.path, - branch: branchName, + branch: current.branch, isMain: isMainWorktree, - isCurrent: branchName === currentBranch, + isCurrent: current.branch === currentBranch, hasWorktree: true, }); isFirst = false; @@ -122,48 +107,6 @@ export function createListHandler() { } } - // Handle the last worktree entry if output doesn't end with blank line - if (current.path) { - const isMainWorktree = isFirst; - - // If branch is missing (can happen for main worktree in some git states), - // fall back to getCurrentBranch() for the main worktree - let branchName = current.branch; - if (!branchName && isMainWorktree) { - // For main worktree, use the current branch we already fetched - branchName = currentBranch || ''; - } - - // Only add if we have a branch name - if (branchName) { - // Check if the worktree directory actually exists - // Skip checking/pruning the main worktree (projectPath itself) - let worktreeExists = false; - try { - await secureFs.access(current.path); - worktreeExists = true; - } catch { - worktreeExists = false; - } - if (!isMainWorktree && !worktreeExists) { - // Worktree directory doesn't exist - it was manually deleted - removedWorktrees.push({ - path: current.path, - branch: branchName, - }); - } else { - // Worktree exists (or is main worktree), add it to the list - worktrees.push({ - path: current.path, - branch: branchName, - isMain: isMainWorktree, - isCurrent: branchName === currentBranch, - hasWorktree: true, - }); - } - } - } - // Prune removed worktrees from git (only if any were detected) if (removedWorktrees.length > 0) { try { diff --git a/apps/ui/tests/git/worktree-integration.spec.ts b/apps/ui/tests/git/worktree-integration.spec.ts deleted file mode 100644 index 421590fa..00000000 --- a/apps/ui/tests/git/worktree-integration.spec.ts +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Worktree Integration E2E Test - * - * Happy path: Display worktree selector with main branch - */ - -import { test, expect } from '@playwright/test'; -import * as fs from 'fs'; -import { - waitForNetworkIdle, - createTestGitRepo, - cleanupTempDir, - createTempDirPath, - setupProjectWithPath, - waitForBoardView, - authenticateForTests, -} from '../utils'; - -const TEST_TEMP_DIR = createTempDirPath('worktree-tests'); - -interface TestRepo { - path: string; - cleanup: () => Promise; -} - -test.describe('Worktree Integration', () => { - let testRepo: TestRepo; - - test.beforeAll(async () => { - if (!fs.existsSync(TEST_TEMP_DIR)) { - fs.mkdirSync(TEST_TEMP_DIR, { recursive: true }); - } - }); - - test.beforeEach(async () => { - testRepo = await createTestGitRepo(TEST_TEMP_DIR); - }); - - test.afterEach(async () => { - if (testRepo) { - await testRepo.cleanup(); - } - }); - - test.afterAll(async () => { - cleanupTempDir(TEST_TEMP_DIR); - }); - - test('should display worktree selector with main branch', async ({ page }) => { - await setupProjectWithPath(page, testRepo.path); - await authenticateForTests(page); - await page.goto('/'); - await page.waitForLoadState('load'); - await waitForNetworkIdle(page); - await waitForBoardView(page); - - // Wait for the worktree selector to appear (indicates API call completed) - const branchLabel = page.getByText('Branch:'); - await expect(branchLabel).toBeVisible({ timeout: 10000 }); - - // Wait for the main branch button to appear - // This ensures the worktree API has returned data with the main branch - const mainBranchButton = page.locator('[data-testid="worktree-branch-main"]'); - await expect(mainBranchButton).toBeVisible({ timeout: 15000 }); - - // Verify the branch name is displayed - await expect(mainBranchButton).toContainText('main'); - }); -});