From 0c4cb77b9907da0c3679f55846c43ca0fbf53f12 Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Fri, 24 Apr 2026 18:56:54 -0400 Subject: [PATCH] fix(ssh): detect git repos by ancestry for listFiles fallback The .git existence check only works at the repo root, not from subdirectories of a checkout (e.g. /repo/packages/app added as a folder). Use `git rev-parse --is-inside-work-tree` instead, which walks up the directory tree and correctly detects git ancestry. --- src/relay/fs-handler.ts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/relay/fs-handler.ts b/src/relay/fs-handler.ts index c9f358fd325..bb2ca22974c 100644 --- a/src/relay/fs-handler.ts +++ b/src/relay/fs-handler.ts @@ -8,10 +8,10 @@ import { rename, cp, rm, - realpath, - access + realpath } from 'fs/promises' -import { extname, join } from 'path' +import { extname } from 'path' +import { execFile } from 'child_process' import type { RelayDispatcher } from './dispatcher' import type { RelayContext } from './context' import { expandTilde } from './context' @@ -233,13 +233,16 @@ export class FsHandler { if (rgAvailable) { return listFilesWithRg(rootPath) } - // Why: git ls-files only works inside git repos. Check for .git first so - // we don't misclassify a git repo with only ignored files as a non-git - // folder — that would surface .gitignore'd files via the readdir fallback. - const isGitRepo = await access(join(rootPath, '.git')).then( - () => true, - () => false - ) + // Why: git ls-files only works inside git repos. Use rev-parse to detect + // git ancestry — unlike checking for a local .git entry, this works from + // subdirectories of a checkout (e.g. /repo/packages/app added as a folder). + // Without this, a git subdirectory would fall through to readdir and + // surface .gitignore'd build artifacts. + const isGitRepo = await new Promise((resolve) => { + execFile('git', ['rev-parse', '--is-inside-work-tree'], { cwd: rootPath }, (err) => + resolve(!err) + ) + }) if (isGitRepo) { return listFilesWithGit(rootPath) }