mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-10 14:10:37 -07:00
fix(core): Respect user's .gitignore preference (#15482)
Co-authored-by: Gaurav <39389231+gsquared94@users.noreply.github.com>
This commit is contained in:
@@ -28,6 +28,10 @@ class MockConfig {
|
||||
return true;
|
||||
}
|
||||
|
||||
getFileFilteringRespectGitIgnore() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getFileFilteringRespectGeminiIgnore() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -253,6 +253,7 @@ describe('RipGrepTool', () => {
|
||||
getTargetDir: () => tempRootDir,
|
||||
getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
|
||||
getDebugMode: () => false,
|
||||
getFileFilteringRespectGitIgnore: () => true,
|
||||
getFileFilteringRespectGeminiIgnore: () => true,
|
||||
getFileFilteringOptions: () => ({
|
||||
respectGitIgnore: true,
|
||||
@@ -277,6 +278,7 @@ describe('RipGrepTool', () => {
|
||||
getTargetDir: () => tempRootDir,
|
||||
getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
|
||||
getDebugMode: () => false,
|
||||
getFileFilteringRespectGitIgnore: () => true,
|
||||
getFileFilteringRespectGeminiIgnore: () => true,
|
||||
getFileFilteringOptions: () => ({
|
||||
respectGitIgnore: true,
|
||||
@@ -844,6 +846,7 @@ describe('RipGrepTool', () => {
|
||||
getWorkspaceContext: () =>
|
||||
createMockWorkspaceContext(tempRootDir, [secondDir]),
|
||||
getDebugMode: () => false,
|
||||
getFileFilteringRespectGitIgnore: () => true,
|
||||
getFileFilteringRespectGeminiIgnore: () => true,
|
||||
getFileFilteringOptions: () => ({
|
||||
respectGitIgnore: true,
|
||||
@@ -956,6 +959,7 @@ describe('RipGrepTool', () => {
|
||||
getWorkspaceContext: () =>
|
||||
createMockWorkspaceContext(tempRootDir, [secondDir]),
|
||||
getDebugMode: () => false,
|
||||
getFileFilteringRespectGitIgnore: () => true,
|
||||
getFileFilteringRespectGeminiIgnore: () => true,
|
||||
getFileFilteringOptions: () => ({
|
||||
respectGitIgnore: true,
|
||||
@@ -1477,6 +1481,70 @@ describe('RipGrepTool', () => {
|
||||
expect(result.llmContent).toContain('L1: secret log entry');
|
||||
});
|
||||
|
||||
it('should disable gitignore rules when respectGitIgnore is false', async () => {
|
||||
const configWithoutGitIgnore = {
|
||||
getTargetDir: () => tempRootDir,
|
||||
getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
|
||||
getDebugMode: () => false,
|
||||
getFileFilteringRespectGitIgnore: () => false,
|
||||
getFileFilteringRespectGeminiIgnore: () => true,
|
||||
getFileFilteringOptions: () => ({
|
||||
respectGitIgnore: false,
|
||||
respectGeminiIgnore: true,
|
||||
}),
|
||||
storage: {
|
||||
getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
|
||||
},
|
||||
isPathAllowed(this: Config, absolutePath: string): boolean {
|
||||
const workspaceContext = this.getWorkspaceContext();
|
||||
if (workspaceContext.isPathWithinWorkspace(absolutePath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const projectTempDir = this.storage.getProjectTempDir();
|
||||
return isSubpath(path.resolve(projectTempDir), absolutePath);
|
||||
},
|
||||
validatePathAccess(this: Config, absolutePath: string): string | null {
|
||||
if (this.isPathAllowed(absolutePath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const workspaceDirs = this.getWorkspaceContext().getDirectories();
|
||||
const projectTempDir = this.storage.getProjectTempDir();
|
||||
return `Path not in workspace: Attempted path "${absolutePath}" resolves outside the allowed workspace directories: ${workspaceDirs.join(', ')} or the project temp directory: ${projectTempDir}`;
|
||||
},
|
||||
} as unknown as Config;
|
||||
const gitIgnoreDisabledTool = new RipGrepTool(
|
||||
configWithoutGitIgnore,
|
||||
createMockMessageBus(),
|
||||
);
|
||||
|
||||
mockSpawn.mockImplementationOnce(
|
||||
createMockSpawn({
|
||||
outputData:
|
||||
JSON.stringify({
|
||||
type: 'match',
|
||||
data: {
|
||||
path: { text: 'ignored.log' },
|
||||
line_number: 1,
|
||||
lines: { text: 'secret log entry\n' },
|
||||
},
|
||||
}) + '\n',
|
||||
exitCode: 0,
|
||||
}),
|
||||
);
|
||||
|
||||
const params: RipGrepToolParams = { pattern: 'secret' };
|
||||
const invocation = gitIgnoreDisabledTool.build(params);
|
||||
await invocation.execute(abortSignal);
|
||||
|
||||
expect(mockSpawn).toHaveBeenLastCalledWith(
|
||||
expect.anything(),
|
||||
expect.arrayContaining(['--no-ignore-vcs', '--no-ignore-exclude']),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should add .geminiignore when enabled and patterns exist', async () => {
|
||||
const geminiIgnorePath = path.join(tempRootDir, GEMINI_IGNORE_FILE_NAME);
|
||||
await fs.writeFile(geminiIgnorePath, 'ignored.log');
|
||||
@@ -1484,6 +1552,7 @@ describe('RipGrepTool', () => {
|
||||
getTargetDir: () => tempRootDir,
|
||||
getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
|
||||
getDebugMode: () => false,
|
||||
getFileFilteringRespectGitIgnore: () => true,
|
||||
getFileFilteringRespectGeminiIgnore: () => true,
|
||||
getFileFilteringOptions: () => ({
|
||||
respectGitIgnore: true,
|
||||
@@ -1549,6 +1618,7 @@ describe('RipGrepTool', () => {
|
||||
getTargetDir: () => tempRootDir,
|
||||
getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
|
||||
getDebugMode: () => false,
|
||||
getFileFilteringRespectGitIgnore: () => true,
|
||||
getFileFilteringRespectGeminiIgnore: () => false,
|
||||
getFileFilteringOptions: () => ({
|
||||
respectGitIgnore: true,
|
||||
|
||||
@@ -366,6 +366,10 @@ class GrepToolInvocation extends BaseToolInvocation<
|
||||
}
|
||||
|
||||
if (!no_ignore) {
|
||||
if (!this.config.getFileFilteringRespectGitIgnore()) {
|
||||
rgArgs.push('--no-ignore-vcs', '--no-ignore-exclude');
|
||||
}
|
||||
|
||||
const fileExclusions = new FileExclusions(this.config);
|
||||
const excludes = fileExclusions.getGlobExcludes([
|
||||
...COMMON_DIRECTORY_EXCLUDES,
|
||||
|
||||
Reference in New Issue
Block a user