Fix nested .gitignore directory patterns not excluding under --exclude-gitignore#21752
Open
Osamaali313 wants to merge 1 commit into
Open
Fix nested .gitignore directory patterns not excluding under --exclude-gitignore#21752Osamaali313 wants to merge 1 commit into
Osamaali313 wants to merge 1 commit into
Conversation
…e-gitignore `matches_gitignore` computes `relative_path = os.path.relpath(subpath, gi_path)` so it can be matched against the gitignore spec (gitignore patterns are relative to the .gitignore's directory). But it then passes that same gi_path-relative string to `fscache.isdir(...)`, which resolves paths relative to the process cwd. When the matched `.gitignore` lives in a scanned subdirectory (`gi_path != cwd`), `relative_path` does not resolve on the real filesystem, so `isdir` returns False, the trailing "/" is never appended, and directory-only patterns (e.g. `build/`, `node_modules/`) fail to exclude the directory. The sibling `matches_exclude` in the same file does this correctly: it builds the match string with `os.path.relpath(subpath)` but calls `fscache.isdir(subpath)` on the original path. Match `matches_gitignore` to that: stat the original `subpath`, keep using `relative_path` only for the gitignore-spec match.
Contributor
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
Collaborator
|
Please make an issue first. |
Author
|
Thanks — opened #21760 describing the bug (directory-only patterns in a nested |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
matches_gitignore(mypy/modulefinder.py) decides whether to append a trailing/(needed for directory-only gitignore patterns likebuild/) using the wrong path:relative_pathis computed relative to the.gitignore's directory (gi_path) so it can be matched bygi_spec.match_file(...)— that part is correct (gitignore patterns are relative to the gitignore's location). But that same gi_path-relative string is then passed tofscache.isdir(...), which resolves paths relative to the process cwd. When the matched.gitignorelives in a scanned subdirectory (gi_path != cwd), the string doesn't resolve on disk,isdirreturnsFalse, the trailing/is never added, and directory-only patterns in nested.gitignores silently fail to exclude the directory.Evidence (sibling proves intent)
The sibling
matches_excludein the same file does this correctly — it builds the match string viaos.path.relpath(subpath)but callsisdiron the original path:Fix
Stat the original
subpath(keeprelative_pathonly for the gitignore-spec match):Reproduction
subpath = "mypkg/sub"(a real directory), matched against a nested.gitignoreinmypkg/containingsub/:/added?isdir(relative_path))isdir("sub")is False from cwd)isdir(subpath))Reachable from
find_sources.py(andmodulefinder) whenever--exclude-gitignoreis enabled and a nested.gitignoreuses a directory-only pattern.