gitignore‑explain
git check-ignore -v, but paste‑and‑see
1 .gitignore
2 Paths to check
One repo‑relative path per line. A trailing / marks a directory (needed for dir‑only rules like dist/); anything else is treated as a file.
3 Verdicts
| Path | Verdict | Deciding rule | Copy why |
|---|
Paste rules on the left and list paths below them — every path gets a verdict here instantly, no Generate button. Click a row to pin its deciding line in the source pane.
Honest limits
- This tool does not read your repo. It models git’s documented matching (last match wins, parent‑directory exclusion beats negation,
dir/rules,!re‑inclusion) for the one.gitignoreyou paste — it cannot know about files git already tracks, which git never ignores regardless of rules. - One root source only. The pasted rules are treated as the repo‑root
.gitignore. Nestedsub/.gitignorefiles are not resolved: the core treats every source as rooted at the repo root and does not rebase a nested file’s patterns relative to its own directory, so don’t paste one here and expect git’s answer. - Case‑sensitive, matching git on case‑sensitive filesystems (Linux):
*.LOGdoes not matcha.log. On default macOS/Windows filesystems git setscore.ignoreCase=trueand matches case‑insensitively, so answers can differ there. - A path with a trailing
/is checked as a directory; without one, as a file. Getting this wrong flips verdicts for dir‑only patterns —build/ignores the directorybuild/but not a file namedbuild. - Malformed input (absolute paths,
..segments) returns the core’s structured error verbatim instead of a guessed verdict.
Your rules and paths never leave this browser: all matching runs locally, so nothing you paste is ever sent anywhere. It models git’s documented matching for one pasted .gitignore and does not read your repo. The page’s only network use is a single anonymous, self-hosted page-view count.
What this tool does — and its honest limits
What it does. This is git check-ignore -v as a paste‑and‑see
page: paste your .gitignore, list some repo‑relative paths, and every path gets a
verdict — ignored, not ignored, or re‑included — plus the
exact line number and pattern that decided it. Click a verdict row and the deciding line lights up in
the source pane. Everything recomputes live on every keystroke; there is no Generate button and
nothing is uploaded.
Why real git semantics matter. Popular free web gitignore checkers run
minimatch, a generic glob matcher that implements none of gitignore’s precedence rules:
no “last matching pattern wins”, no negation ordering, and — the classic trap —
no rule that a negation cannot re‑include a file when a parent directory of it is excluded.
Worked example: with the two rules dist/ then !dist/keep.js, git still
ignores dist/keep.js, because git’s own documentation says “It is not possible
to re‑include a file if a parent directory of that file is excluded.” A minimatch‑based
checker reports it as kept — a provably wrong answer you might ship a .gitignore on.
This page also gets /‑anchoring precedence and dir‑only (build/
vs a file named build) right.
How it’s verified. The matching engine is golden‑tested against a real
git binary: 11 golden vectors plus 30 adversarial vectors across ten edge‑case families
(negation chains, ** positions, \#/\! escapes, trailing spaces,
CRLF, case sensitivity…) are regenerated from actual git check-ignore -v output on
every test run — 57 tests total. Per‑pattern glob matching is delegated to the vendored,
pinned node‑ignore 5.3.2 (MIT); git’s precedence semantics are implemented on top.
Honest limits — read before trusting a verdict.
(1) It models matching for the one .gitignore you paste and
does not read your repo — in particular it cannot know about files git already
tracks, which git never ignores regardless of rules.
(2) Your global gitignore (core.excludesFile, e.g.
~/.config/git/ignore) and .git/info/exclude are not consulted.
(3) Nested sub/.gitignore files are not rebased: the pasted rules are treated as the
repo‑root .gitignore, so a nested file’s patterns would need rebasing before
pasting.
(4) Matching is case‑sensitive, like git on Linux
(core.ignoreCase=false): *.LOG does not match a.log. On default
macOS/Windows filesystems git folds case, so answers can differ there.
(5) A trailing / on a checked path marks it as a directory; getting that wrong flips
verdicts for dir‑only patterns. Malformed input (absolute paths, .. segments)
returns a structured error instead of a guessed verdict.
The library ships with this page. The verdicts are produced by an MIT‑licensed CommonJS engine running entirely in this tab over the vendored node‑ignore matcher — the exact code that renders these verdicts is the library, and it ships with the page.