Directory Pattern Matching: Beware Substring Matches¶
Date: 2025-11-04
Context: .git/ pattern excluded .gitconfig, breaking git configuration
The Problem¶
Substring matching for directory patterns causes false positives:
# BROKEN: ".git" substring matches ".gitconfig"
if pattern.endswith("/") and pattern.rstrip("/") in path_str:
return True # BUG!
Impact: .gitconfig was never symlinked to home directory.
The Solution¶
Check for complete path components:
if pattern.endswith("/"):
dir_name = pattern.rstrip("/")
if f"/{dir_name}/" in path_str or path_str.startswith(f"{dir_name}/"):
return True
Results:
/.git/matchesfoo/.git/bar✓.git/matches.git/config✓.gitdoes NOT match.gitconfig✓
Key Learnings¶
- Check complete path components - substring matching is almost never correct for paths
- Test similar filenames -
.git/vs.gitconfig,node_modules/vsnode_modules.txt - Write regression tests - prevent fixed bugs from returning
Testing¶
Always test edge cases:
# Directory should be excluded
assert should_exclude(Path(".git/config"))
assert should_exclude(Path("foo/.git/hooks"))
# Similar-named files should NOT be excluded
assert not should_exclude(Path(".gitconfig"))
assert not should_exclude(Path(".gitignore"))
assert not should_exclude(Path(".github/workflows/ci.yml"))