-
-
Notifications
You must be signed in to change notification settings - Fork 340
Description
.gitignore files don't have to live at the root of the working directory:
Patterns read from a .gitignore file in the same directory as the path, or in any parent directory (up to the top-level of the working tree), with patterns in the higher level files being overridden by those in lower level files down to the directory containing the file. These patterns match relative to the location of the .gitignore file.
Hatchling assumes that there is at most one .gitignore file, and that it describes paths relative to the project root. This mismatches the behavior of git in a couple of ways:
- If .gitignore is found in any of the ancestors of the project root, the paths are interpreted relative to the wrong path. The issue is also propagated to sdists, because the .gitignore file is copied as-is to the source directory.
Example
my-repo-root
├── .gitignore
└── foobar
├── LICENSE.txt
├── README.md
├── ignore_me
├── foobar
│ ├── __about__.py
│ └── __init__.py
├── pyproject.toml
└── tests
└── __init__.py
.gitignore might contain the pattern foobar/ignore_me
, which would be effective enough for git. But Hatchling would not be able to apply the pattern to exclude ignore_me. If a file with the same name happened to be in the inner foobar
directory, it would be accidentally excluded.
- Per-directory .gitignore files are ignored.
I don't use Mercurial anymore, but I imagine that 1 would apply there as well. Mercurial restricts .hgignore files to live at the root of the repo, so there can't be multiple ones. But you could have a project in a sub-directory of a hg repo.
It would be nice if Hatch/Hatchling could do the same thing the VCS does.
I don't know if a solution for 1 would involve, at sdist building time, to rewrite .gitignore to make relative patterns (those with /
not at the end) relative to the project directory (or write the modified patterns into the sdist pyproject.toml instead of including the .gitignore file).
Per-directory .gitignores complicate things a bit. It implies that when traversing parents you cannot stop at the first .gitignore you find, because there can be a more general one up above. Traversal should stop when you reach the root of the working tree (i.e. when you find .git
). But when you unpack an sdist you don't have a .git.
And I don't even want to start thinking about submodules.