41 lines · 1.4 KB · TypeScript
RawDownload
import { execFileSync } from 'child_process'; /** * Normalize a repo-relative path for git index lookups. */function normalizeRepoRelativePath(repoRelativePath: string): string {  return repoRelativePath.replace(/\\/g, '/').replace(/^\.\/+/, '').replace(/\/+$/, '');} /** * True when the path is recorded in the index as a git submodule (mode 160000, gitlink). * * WHY: Review bots often anchor threads on submodule roots (e.g. `plugins/plugin-sql`). * There is no regular file text at line N; snippet reads fail and PRR used to dismiss as * generic stale / "unreadable". This check uses the index so it works even when the * submodule is not checked out in the worktree. */export function isTrackedGitSubmodulePath(workdir: string, repoRelativePath: string): boolean {  const normalized = normalizeRepoRelativePath(repoRelativePath);  if (!normalized) return false;  try {    const out = execFileSync('git', ['ls-files', '-s', '--', normalized], {      cwd: workdir,      encoding: 'utf8',      stdio: ['ignore', 'pipe', 'pipe'],      maxBuffer: 256 * 1024,    });    for (const line of out.split('\n')) {      const trimmed = line.trim();      if (!trimmed) continue;      const m = trimmed.match(/^160000\s+\S+\s+\d\t(.+)$/);      if (m) {        const indexedPath = normalizeRepoRelativePath(m[1]!);        if (indexedPath === normalized) return true;      }    }    return false;  } catch {    return false;  }}