source dump of claude code
at main 70 lines 2.0 kB view raw
1import { sep } from 'path' 2import { logEvent } from '../services/analytics/index.js' 3import { execFileNoThrowWithCwd } from './execFileNoThrow.js' 4import { gitExe } from './git.js' 5 6/** 7 * Returns the paths of all worktrees for the current git repository. 8 * If git is not available, not in a git repo, or only has one worktree, 9 * returns an empty array. 10 * 11 * This version includes analytics tracking and uses the CLI's gitExe() 12 * resolver. For a portable version without CLI deps, use 13 * getWorktreePathsPortable(). 14 * 15 * @param cwd Directory to run the command from 16 * @returns Array of absolute worktree paths 17 */ 18export async function getWorktreePaths(cwd: string): Promise<string[]> { 19 const startTime = Date.now() 20 21 const { stdout, code } = await execFileNoThrowWithCwd( 22 gitExe(), 23 ['worktree', 'list', '--porcelain'], 24 { 25 cwd, 26 preserveOutputOnError: false, 27 }, 28 ) 29 30 const durationMs = Date.now() - startTime 31 32 if (code !== 0) { 33 logEvent('tengu_worktree_detection', { 34 duration_ms: durationMs, 35 worktree_count: 0, 36 success: false, 37 }) 38 return [] 39 } 40 41 // Parse porcelain output - lines starting with "worktree " contain paths 42 // Example: 43 // worktree /Users/foo/repo 44 // HEAD abc123 45 // branch refs/heads/main 46 // 47 // worktree /Users/foo/repo-wt1 48 // HEAD def456 49 // branch refs/heads/feature 50 const worktreePaths = stdout 51 .split('\n') 52 .filter(line => line.startsWith('worktree ')) 53 .map(line => line.slice('worktree '.length).normalize('NFC')) 54 55 logEvent('tengu_worktree_detection', { 56 duration_ms: durationMs, 57 worktree_count: worktreePaths.length, 58 success: true, 59 }) 60 61 // Sort worktrees: current worktree first, then alphabetically 62 const currentWorktree = worktreePaths.find( 63 path => cwd === path || cwd.startsWith(path + sep), 64 ) 65 const otherWorktrees = worktreePaths 66 .filter(path => path !== currentWorktree) 67 .sort((a, b) => a.localeCompare(b)) 68 69 return currentWorktree ? [currentWorktree, ...otherWorktrees] : otherWorktrees 70}