MCPcopy Create free account
hub / github.com/Noumena-Network/code / copyWorktreeIncludeFiles

Function copyWorktreeIncludeFiles

src/utils/worktree.ts:403–516  ·  view source on GitHub ↗
(
  repoRoot: string,
  worktreePath: string,
)

Source from the content-addressed store, hash-verified

401 * that directory is expanded with a second scoped `ls-files` call.
402 */
403export async function copyWorktreeIncludeFiles(
404 repoRoot: string,
405 worktreePath: string,
406): Promise<string[]> {
407 let includeContent: string
408 try {
409 includeContent = await readFile(join(repoRoot, '.worktreeinclude'), 'utf-8')
410 } catch {
411 return []
412 }
413
414 const patterns = includeContent
415 .split(/\r?\n/)
416 .map(line => line.trim())
417 .filter(line => line.length > 0 && !line.startsWith('#'))
418 if (patterns.length === 0) {
419 return []
420 }
421
422 // Single pass with --directory: collapses fully-gitignored dirs (node_modules/,
423 // .turbo/, etc.) into single entries instead of listing every file inside.
424 // In a large repo this cuts ~500k entries/~7s down to ~hundreds of entries/~100ms.
425 const gitignored = await execFileNoThrowWithCwd(
426 gitExe(),
427 ['ls-files', '--others', '--ignored', '--exclude-standard', '--directory'],
428 { cwd: repoRoot },
429 )
430 if (gitignored.code !== 0 || !gitignored.stdout.trim()) {
431 return []
432 }
433
434 const entries = gitignored.stdout.trim().split('\n').filter(Boolean)
435 const matcher = ignore().add(includeContent)
436
437 // --directory emits collapsed dirs with a trailing slash; everything else is
438 // an individual file.
439 const collapsedDirs = entries.filter(e => e.endsWith('/'))
440 const files = entries.filter(e => !e.endsWith('/') && matcher.ignores(e))
441
442 // Edge case: a .worktreeinclude pattern targets a path inside a collapsed dir
443 // (e.g. pattern `config/secrets/api.key` when all of `config/secrets/` is
444 // gitignored with no tracked siblings). Expand only dirs where a pattern has
445 // that dir as its explicit path prefix (stripping redundant leading `/`), the
446 // dir falls under an anchored glob's literal prefix (e.g. `config/**/*.key`
447 // expands `config/secrets/`), or the dir itself matches a pattern. We don't
448 // expand for `**/` or anchorless patterns -- those match files in tracked dirs
449 // (already listed individually) and expanding every collapsed dir for them
450 // would defeat the perf win.
451 const dirsToExpand = collapsedDirs.filter(dir => {
452 if (
453 patterns.some(p => {
454 const normalized = p.startsWith('/') ? p.slice(1) : p
455 // Literal prefix match: pattern starts with the collapsed dir path
456 if (normalized.startsWith(dir)) return true
457 // Anchored glob: dir falls under the pattern's literal (non-glob) prefix
458 // e.g. `config/**/*.key` has literal prefix `config/` → expand `config/secrets/`
459 const globIdx = normalized.search(/[*?[]/)
460 if (globIdx > 0) {

Callers 1

performPostCreationSetupFunction · 0.85

Calls 6

readFileFunction · 0.85
execFileNoThrowWithCwdFunction · 0.85
mkdirFunction · 0.85
searchMethod · 0.80
logForDebuggingFunction · 0.70
addMethod · 0.45

Tested by

no test coverage detected