docs-gitignore-subdir-negation
docs-gitignore-subdir-negation)The bug: .gitignore contains docs/* plus !docs/*.md. docs/* matches the directory docs/integrations/ and marks it ignored. Git never descends into ignored directories, so the negation !docs/*.md can never re-include anything inside it — and a file-level negation like !docs/integrations/guide.md is equally unreachable. Result: new doc subdirectories are silently dropped by git add docs/ / git add . (exit 0, nothing staged) or explicitly refused (exit 1, "The following paths are ignored…"), so new docs never get committed.
The fix: un-ignore the directory first, then git descends and the two-level path no longer matches docs/*:
docs/*
!docs/*.md
!docs/integrations/
Verification of the mechanism:
$ printf 'docs/*\n!docs/*.md\n!docs/integrations/\n' > .gitignore
$ git check-ignore docs/integrations/guide.md # exit 1 → NOT ignored anymore
$ git add docs/integrations/guide.md # stages fine
$ git commit -m "docs: add integrations guide"
Why the wrong fix fails — !docs/integrations/guide.md alone is dead because the parent dir docs/integrations/ is already ignored:
$ printf 'docs/*\n!docs/*.md\n!docs/integrations/guide.md\n' > .gitignore
$ git check-ignore docs/integrations/guide.md # exit 0 → STILL ignored
$ git add docs/integrations/guide.md # exit 1 → "The following paths are ignored…"
For deeper trees, add a negation at each level you want to re-include (e.g. !docs/integrations/ then !docs/integrations/api/ for a second level).
The bug: the README says cd 9router/app && docker build -t 9router ., but the repo has no app/ directory (source lives at 9router/), so the documented path rots: cd 9router/app → No such file or directory. The documented command can never run.
The fix: make the repo root the build context and document that explicitly. Dockerfile at repo root:
FROM python:3.12-slim
WORKDIR /srv/9router
COPY 9router/main.py 9router/lib/ ./
CMD ["python", "main.py"]
Fixed doc:
```markdown
Verified with real `git 2.53.0` in a fresh repo and shell-level checks for the docker path (no docker daemon available in this sandbox — no privileges to start `dockerd`; the build was validated statically with the exact checks `docker build` performs first: context sources must exist, plus the shell-level `cd` failure). Test suite: `/tmp/v/docs-gitignore-subdir-negation/verify.sh` (self-contained, fresh repo per run) — **11/11 passed**: | # | Test | Result | |---|------|--------| | T1 | Baseline: new docs subdir is ignored (`docs/*` swallows it) | PASS | | T2 | `docs/README.md` is NOT ignored (`!docs/*.md` works) | PASS | | T3 | Explicit `git add docs/integrations/guide.md` refuses (exit 1) | PASS | | T4 | `git add docs/` exits 0 but **silently skips** the subdir (not staged) | PASS | | T5 | Wrong fix `!docs/integrations/guide.md` alone: still ignored | PASS | | T6 | Fix `!docs/integrations/`: `git check-ignore` no longer matches | PASS | | T7 | Fix: `git add` stages the new doc file | PASS | | T8 | Commit succeeds; file tracked via `git ls-files` | PASS | | T9 | ROT: documented `cd 9router/app` fails (no such dir) | PASS | | T10 | PASS criterion: all `COPY` sources resolve from repo root | PASS | | T11 | Doc fix: README now documents the repo-root build | PASS | Edge cases tested: explicit-path `git add` (loud refusal) vs. bulk `git add docs/` / `git add .` (silent skip — the dangerous case that lets new doc dirs rot uncommitted); file-level negation proving the "cannot reach into ignored dir" rule; `.dockerignore` and `--from=` (multi-stage) sources excluded from context checks; `COPY` of both files and directories.
{"model": "deepseek-v4-flash", "problem_class": "docs-gitignore-subdir-negation", "result": "passed", "tests": 11}