fix(core): Preserve escaped characters in gitignore patterns (#11171)

Co-authored-by: Jacob Richman <jacob314@gmail.com>
This commit is contained in:
Eric Rahm
2025-10-20 10:03:22 -07:00
committed by GitHub
parent d52ec522f1
commit 518a9ca314
2 changed files with 23 additions and 6 deletions

View File

@@ -234,4 +234,20 @@ src/*.tmp
);
});
});
describe('Escaped Characters', () => {
beforeEach(async () => {
await setupGitRepo();
});
it('should correctly handle escaped characters in .gitignore', async () => {
await createTestFile('.gitignore', '\\#foo\n\\!bar');
// Create files with special characters in names
await createTestFile('bla/#foo', 'content');
await createTestFile('bla/!bar', 'content');
// These should be ignored based on the escaped patterns
expect(parser.isIgnored('bla/#foo')).toBe(true);
expect(parser.isIgnored('bla/!bar')).toBe(true);
});
});
});

View File

@@ -35,7 +35,10 @@ export class GitIgnoreParser implements GitIgnoreFilter {
const relativeBaseDir = isExcludeFile
? '.'
: path.dirname(path.relative(this.projectRoot, patternsFilePath));
: path
.dirname(path.relative(this.projectRoot, patternsFilePath))
.split(path.sep)
.join(path.posix.sep);
return content
.split('\n')
@@ -68,11 +71,11 @@ export class GitIgnoreParser implements GitIgnoreFilter {
if (!isAnchoredInFile && !p.includes('/')) {
// If no slash and not anchored in file, it matches files in any
// subdirectory.
newPattern = path.join('**', p);
newPattern = path.posix.join('**', p);
}
// Prepend the .gitignore file's directory.
newPattern = path.join(relativeBaseDir, newPattern);
newPattern = path.posix.join(relativeBaseDir, newPattern);
// Anchor the pattern to a nested gitignore directory.
if (!newPattern.startsWith('/')) {
@@ -89,9 +92,6 @@ export class GitIgnoreParser implements GitIgnoreFilter {
newPattern = '!' + newPattern;
}
// Even in windows, Ignore expects forward slashes.
newPattern = newPattern.replace(/\\/g, '/');
return newPattern;
})
.filter((p) => p !== '');
@@ -173,6 +173,7 @@ export class GitIgnoreParser implements GitIgnoreFilter {
const gitignorePath = path.join(dir, '.gitignore');
if (fs.existsSync(gitignorePath)) {
const patterns = this.loadPatternsForFile(gitignorePath);
this.cache.set(dir, patterns);
ig.add(patterns);
} else {