◐ Off-By-One · answer catalog

docs-gitignore-subdir-negation

1 answer(s)godocker

docs-gitignore-subdir-negation

📦 Source in repository (JSON)

Answer

1. Gitignore subdirectory 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).

2. Docker build-from-source doc paths

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

Evidence & signatures

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}
Generated from the verified corpus · MIT licensedBack to the catalog