Add support for an additional exclusion file besides .gitignore and .geminiignore (#16487)

Co-authored-by: Adam Weidman <adamfweidman@google.com>
This commit is contained in:
Alisa
2026-01-27 17:19:13 -08:00
committed by GitHub
parent 18efe82ddc
commit adc8e11bb1
40 changed files with 1394 additions and 612 deletions
+28 -11
View File
@@ -23,7 +23,7 @@ import {
FileExclusions,
COMMON_DIRECTORY_EXCLUDES,
} from '../utils/ignorePatterns.js';
import { GeminiIgnoreParser } from '../utils/geminiIgnoreParser.js';
import { FileDiscoveryService } from '../services/fileDiscoveryService.js';
import { execStreaming } from '../utils/shell-utils.js';
import {
DEFAULT_TOTAL_MAX_MATCHES,
@@ -148,7 +148,7 @@ class GrepToolInvocation extends BaseToolInvocation<
> {
constructor(
private readonly config: Config,
private readonly geminiIgnoreParser: GeminiIgnoreParser,
private readonly fileDiscoveryService: FileDiscoveryService,
params: RipGrepToolParams,
messageBus: MessageBus,
_toolName?: string,
@@ -243,6 +243,21 @@ class GrepToolInvocation extends BaseToolInvocation<
signal.removeEventListener('abort', onAbort);
}
if (!this.params.no_ignore) {
const uniqueFiles = Array.from(
new Set(allMatches.map((m) => m.filePath)),
);
const absoluteFilePaths = uniqueFiles.map((f) =>
path.resolve(searchDirAbs, f),
);
const allowedFiles =
this.fileDiscoveryService.filterFiles(absoluteFilePaths);
const allowedSet = new Set(allowedFiles);
allMatches = allMatches.filter((m) =>
allowedSet.has(path.resolve(searchDirAbs, m.filePath)),
);
}
const searchLocationDescription = `in path "${searchDirDisplay}"`;
if (allMatches.length === 0) {
const noMatchMsg = `No matches found for pattern "${this.params.pattern}" ${searchLocationDescription}${this.params.include ? ` (filter: "${this.params.include}")` : ''}.`;
@@ -361,12 +376,11 @@ class GrepToolInvocation extends BaseToolInvocation<
rgArgs.push('--glob', `!${exclude}`);
});
if (this.config.getFileFilteringRespectGeminiIgnore()) {
// Add .geminiignore support (ripgrep natively handles .gitignore)
const geminiIgnorePath = this.geminiIgnoreParser.getIgnoreFilePath();
if (geminiIgnorePath) {
rgArgs.push('--ignore-file', geminiIgnorePath);
}
// Add .geminiignore and custom ignore files support (if provided/mandated)
// (ripgrep natively handles .gitignore)
const geminiIgnorePaths = this.fileDiscoveryService.getIgnoreFilePaths();
for (const ignorePath of geminiIgnorePaths) {
rgArgs.push('--ignore-file', ignorePath);
}
}
@@ -472,7 +486,7 @@ export class RipGrepTool extends BaseDeclarativeTool<
ToolResult
> {
static readonly Name = GREP_TOOL_NAME;
private readonly geminiIgnoreParser: GeminiIgnoreParser;
private readonly fileDiscoveryService: FileDiscoveryService;
constructor(
private readonly config: Config,
@@ -538,7 +552,10 @@ export class RipGrepTool extends BaseDeclarativeTool<
true, // isOutputMarkdown
false, // canUpdateOutput
);
this.geminiIgnoreParser = new GeminiIgnoreParser(config.getTargetDir());
this.fileDiscoveryService = new FileDiscoveryService(
config.getTargetDir(),
config.getFileFilteringOptions(),
);
}
/**
@@ -591,7 +608,7 @@ export class RipGrepTool extends BaseDeclarativeTool<
): ToolInvocation<RipGrepToolParams, ToolResult> {
return new GrepToolInvocation(
this.config,
this.geminiIgnoreParser,
this.fileDiscoveryService,
params,
messageBus ?? this.messageBus,
_toolName,