The !-exceptions in the generated .gitignore are computed by a grep pattern
that hardcodes the project name, while the top ignore line comes from
GITIGNORE_PATTERNS_TOP. A project that overrides GITIGNORE_PATTERNS_TOP -
jw-pkg's Makefile sets it to empty - still gets the hardcoded exceptions,
and patterns a project adds there get no exceptions at all, so the two can
drift apart.
Derive the exception pattern from the same variable:
- new GITIGNORE_PATTERNS_TOP_INV joins the patterns of
GITIGNORE_PATTERNS_TOP with |, each wrapped in word boundaries, plus the
__init__.py pattern
- GITIGNORE_PATTERNS_END greps the tracked files for that alternation with
grep -E instead of a hardcoded BRE, so the dot in __init__.py is literal
instead of matching any character
With the default GITIGNORE_PATTERNS_TOP the generated .gitignore is
byte-for-byte identical to before.
Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v1.0.0
Signed-off-by: Jan Lindemann <jan@janware.com>