feat(core): Cache ignore instances for performance (#16185)

This commit is contained in:
Eric Rahm
2026-01-09 13:22:53 -08:00
committed by GitHub
parent ea7393f7fd
commit e04a5f0cb0

View File

@@ -6,7 +6,7 @@
import * as fs from 'node:fs';
import * as path from 'node:path';
import ignore from 'ignore';
import ignore, { type Ignore } from 'ignore';
export interface GitIgnoreFilter {
isIgnored(filePath: string): boolean;
@@ -14,30 +14,30 @@ export interface GitIgnoreFilter {
export class GitIgnoreParser implements GitIgnoreFilter {
private projectRoot: string;
private cache: Map<string, string[]> = new Map();
private globalPatterns: string[] | undefined;
private processedExtraPatterns: string[] = [];
private cache: Map<string, Ignore> = new Map();
private globalPatterns: Ignore | undefined;
private processedExtraPatterns: Ignore;
constructor(
projectRoot: string,
private readonly extraPatterns?: string[],
) {
this.projectRoot = path.resolve(projectRoot);
this.processedExtraPatterns = ignore();
if (this.extraPatterns) {
// extraPatterns are assumed to be from project root (like .geminiignore)
this.processedExtraPatterns = this.processPatterns(
this.extraPatterns,
'.',
this.processedExtraPatterns.add(
this.processPatterns(this.extraPatterns, '.'),
);
}
}
private loadPatternsForFile(patternsFilePath: string): string[] {
private loadPatternsForFile(patternsFilePath: string): Ignore {
let content: string;
try {
content = fs.readFileSync(patternsFilePath, 'utf-8');
} catch (_error) {
return [];
return ignore();
}
const isExcludeFile = patternsFilePath.endsWith(
@@ -52,7 +52,7 @@ export class GitIgnoreParser implements GitIgnoreFilter {
.join(path.posix.sep);
const rawPatterns = content.split('\n');
return this.processPatterns(rawPatterns, relativeBaseDir);
return ignore().add(this.processPatterns(rawPatterns, relativeBaseDir));
}
private processPatterns(
@@ -155,7 +155,7 @@ export class GitIgnoreParser implements GitIgnoreFilter {
);
this.globalPatterns = fs.existsSync(excludeFile)
? this.loadPatternsForFile(excludeFile)
: [];
: ignore();
}
ig.add(this.globalPatterns);
@@ -198,15 +198,13 @@ export class GitIgnoreParser implements GitIgnoreFilter {
this.cache.set(dir, patterns);
ig.add(patterns);
} else {
this.cache.set(dir, []); // Cache miss
this.cache.set(dir, ignore());
}
}
}
// Apply extra patterns (e.g. from .geminiignore) last for precedence
if (this.processedExtraPatterns.length > 0) {
ig.add(this.processedExtraPatterns);
}
ig.add(this.processedExtraPatterns);
return ig.ignores(normalizedPath);
} catch (_error) {