fix(core): respect respectGitIgnore setting in @file injection path (#3197)

pathReader.ts hardcoded respectGitIgnore: true when filtering files for
@{path} injection (used by slash commands), ignoring the user's
context.fileFiltering.respectGitIgnore setting. This meant gitignored
files were silently dropped even when the user explicitly set the
setting to false.

Now reads the filtering options from config instead of hardcoding.

Fixes #3142
This commit is contained in:
tanzhenxin 2026-04-13 17:56:35 +08:00 committed by GitHub
parent 0026777828
commit 189df1b098
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 38 additions and 4 deletions

View file

@ -20,6 +20,10 @@ const createMockConfig = (
cwd: string,
otherDirs: string[] = [],
mockFileService?: FileDiscoveryService,
fileFilteringOptions?: {
respectGitIgnore: boolean;
respectQwenIgnore: boolean;
},
): Config => {
const workspace = new WorkspaceContext(cwd, otherDirs);
const fileSystemService = new StandardFileSystemService();
@ -29,6 +33,11 @@ const createMockConfig = (
getTargetDir: () => cwd,
getFileSystemService: () => fileSystemService,
getFileService: () => mockFileService,
getFileFilteringOptions: () =>
fileFilteringOptions ?? {
respectGitIgnore: true,
respectQwenIgnore: true,
},
getTruncateToolOutputThreshold: () => 2500,
getTruncateToolOutputLines: () => 500,
getContentGeneratorConfig: () => ({
@ -340,6 +349,29 @@ describe('readPathFromWorkspace', () => {
expect(resultText).not.toContain('invisible');
expect(mockFileService.filterFiles).toHaveBeenCalled();
});
it('should pass respectGitIgnore: false from config to filterFiles', async () => {
mock({
[CWD]: {
'ignored.txt': 'ignored content',
},
});
const mockFileService = {
filterFiles: vi.fn((files) => files),
} as unknown as FileDiscoveryService;
const config = createMockConfig(CWD, [], mockFileService, {
respectGitIgnore: false,
respectQwenIgnore: true,
});
await readPathFromWorkspace('ignored.txt', config);
expect(mockFileService.filterFiles).toHaveBeenCalledWith(
['ignored.txt'],
{
respectGitIgnore: false,
respectQwenIgnore: true,
},
);
});
});
it('should throw an error for an absolute path outside the workspace', async () => {

View file

@ -72,9 +72,10 @@ export async function readPathFromWorkspace(
const relativeFiles = files.map((p) =>
path.relative(config.getTargetDir(), p),
);
const filteringOptions = config.getFileFilteringOptions();
const filteredFiles = fileService.filterFiles(relativeFiles, {
respectGitIgnore: true,
respectQwenIgnore: true,
respectGitIgnore: filteringOptions.respectGitIgnore,
respectQwenIgnore: filteringOptions.respectQwenIgnore,
});
const finalFiles = filteredFiles.map((p) =>
path.resolve(config.getTargetDir(), p),
@ -93,9 +94,10 @@ export async function readPathFromWorkspace(
} else {
// It's a single file, check if it's ignored.
const relativePath = path.relative(config.getTargetDir(), absolutePath);
const singleFileFilteringOptions = config.getFileFilteringOptions();
const filtered = fileService.filterFiles([relativePath], {
respectGitIgnore: true,
respectQwenIgnore: true,
respectGitIgnore: singleFileFilteringOptions.respectGitIgnore,
respectQwenIgnore: singleFileFilteringOptions.respectQwenIgnore,
});
if (filtered.length === 0) {