Skip to content

GitIgnoreSpec behaviors differ from git #81

Description

@lumina37

Here is the demo for pathspec:

from pathlib import Path

import pathspec

exclude_lines=["*", "!libfoo", "!libfoo/**"]
exclude_spec = pathspec.GitIgnoreSpec.from_lines(exclude_lines)

print(exclude_spec.match_file(Path("./libfoo/__init__.py")))

In pathspec==0.11.2 the result is True, which means ./libfoo/__init__.py is excluded.


Another demo to check the behavior of Git:

Directory structure be like

demo-project
├── libfoo
│   └── __init__.py
└── .gitignore

Then check ignorance with command git check-ignore -v ./libfoo/__init__.py

Expect no output, which means ./libfoo/__init__.py is not excluded.


I suppose this difference is caused by the priority between directory and file patterns.

if dir_mark:
# Pattern matched by a directory pattern.
priority = 1
else:
# Pattern matched by a file pattern.
priority = 2
if pattern.include and dir_mark:
out_matched = pattern.include
out_priority = priority
elif priority >= out_priority:
out_matched = pattern.include
out_priority = priority

Including pattern !/libfoo/** is treated as a directory pattern and will be overridden by the excluding file pattern *, thus the ./libfoo/__init__.py will get excluded.

p.s. I've googled this priority mechanism several hours, but still could not find out any documentation mentioning it.


Other platform info:
pathspec 0.11.2
Git 2.40.1.windows.1
Windows 11 22H2 (22621.2134)
Python 3.11.4

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions