Skip to content

Fix explicit **/*/** matching top-level directories - #171

Open
mayur-dhavan wants to merge 4 commits into
cpburnz:masterfrom
mayur-dhavan:fix/globstar-star-globstar-descendant
Open

mayur-dhavan wants to merge 4 commits into
cpburnz:masterfrom
mayur-dhavan:fix/globstar-star-globstar-descendant

Conversation

@mayur-dhavan

Copy link
Copy Markdown

An explicit **/*/** pattern is caught by the */ normalization special case in GitIgnoreSpecPattern.__normalize_segments and compiles to a bare /, so GitIgnoreSpec.from_lines(['**/*/**']).match_file('a/') returns True while Git does not exclude a itself during traversal. Verified against a real tree: with .gitignore containing **/*/** and !a/keep.txt, git add -A -n shows it would stage a/keep.txt — Git does not exclude a itself, so the negation re-includes the file. pathspec instead reports match_file('a/keep.txt') as True (ignored), because the degenerate / regex makes the excluded-ancestor rule treat a as excluded, which suppresses the negation. Directory behavior is checked through traversal and the staging dry run; git check-ignore on a trailing-slash path can report a different verdict.

*/ and **/*/** are not equivalent in Git: the latter requires a descendant segment after the *. Under */ + !a/keep.txt, Git cannot re-include the canary (the parent directory is excluded); under **/*/** + !a/keep.txt, it can and does.

This change restricts the special case to the directory form it was written for (*/, is_dir_pattern=True) and lets an explicit **/*/** go through segment translation, which requires a descendant segment after the * (^(?s:.+/)?[^/]+/[^/]). Regression tests cover the directory verdict and the negation re-inclusion; the existing terminal-globstar tests from #137/#138/#164 are unchanged and still pass.

The gitwildmatch path already answers both probes the way Git does. The deprecated GitIgnoreBasicPattern still returns a bare / for this pattern and is left untouched.

Closed, unmerged PR #155 included the same condition change as part of a broader patch. This PR targets the still-reproducible **/*/** case on current master, with regression tests for the directory verdict and negation re-inclusion. PR #164 addressed the separate folder/**/ case.

Refactor directory pattern handling for efficiency.
Add tests for GitIgnore patterns with globstar syntax.
Copilot AI balanced review requested due to automatic review settings October 26, 2026 07:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants