PATHS & GIT RULES

Gitignore testerwith rule traces

Try one root .gitignore and candidate paths. A trailing / marks a directory.

Gitignore tester

.gitignore rules

Candidate paths

Rules and candidate strings stay in this browser; no repository is read or changed.

Path results

Enter at least one candidate path.

Path conventions and scope

Paths are relative to this .gitignore directory. Use / separators; end a directory with /. Absolute paths, drive prefixes, backslashes, empty segments, . and .. are rejected. Spaces are preserved.

One root .gitignore, untracked-path simulation, case-sensitive UTF-8 byte matching. No nested files, global excludes, index state or filesystem detection.

Up to 50 physical rule lines and 200 nonempty candidate lines; 256 characters per rule, 512 per path, 32 path segments. Controls are rejected. Worker stops after 2 seconds.

Results are outdated or being calculated.

A file exception can look correct and still fail because its parent directory is ignored. This Gitignore tester makes that distinction visible: the deciding rule can belong to an ancestor, even when a later line names your file exactly.

Use this gitignore debugger with a small set of candidate paths to review a change before editing your repository. Each result distinguishes ignored, explicitly restored and unmatched paths through the deciding rule and the complete rule-prefix history.

Why use this Gitignore tester

Find the directory that blocks an exception

build/ excludes the directory before Git can examine build/keep.txt. A later !build/keep.txt cannot rescue it. In contrast, cache/* leaves cache/ traversable, so !cache/keep.txt can restore that child. This Gitignore tester identifies the blocking ancestor instead of labelling every negation a successful exception.

A closed parent folder blocks all children, while an open folder allows one child through an exception.

Read a rule change in its actual order

An ignore rule, an exception and another ignore rule can change a path three times. The history records the result after every physical line, including comments and blank lines. Compare the deciding line before and after a new pattern to see whether it changed the path itself or a parent directory.

A file moves through three ordered gates, switching from excluded to included and back to excluded.

Reproduce a path problem precisely

01

Mark directories and keep the same base

Paste paths relative to the directory containing your single .gitignore. Enter build/ for a directory and build for a file. A leading / anchors a rule, but is invalid in the candidate input. Candidate spaces are literal, so do not trim a filename just to make it match.

02

Inspect the first excluded ancestor

Expand the history under a result. If a parent is excluded, restore that directory first or exclude its children with a pattern such as cache/*. A negative child pattern cannot cross an excluded parent. The line displayed after a step is the deciding line, which may be earlier than that step.

03

Pause automatic runs to compare changes

Automatic testing waits 350 ms after an edit. Turn it off to use Test rules or Ctrl/Cmd+Enter. An edit immediately makes the report stale. Example and Clear show a preview first; Undo restores both inputs and results. JSON includes history, while TSV exports the complete path summary.

From patterns to an explainable result

Gitignore patterns, not a generic glob

The ignore 7.0.9 engine supplies Git-style pattern matching for *, ?, bracket ranges and **. The wrapper matches UTF-8 bytes with case sensitivity, so one ? does not stand for an entire multibyte character. Brace expansion and regular-expression syntax are not extra matching modes.

Physical deciding lines

Comments and empty lines keep their place in the history. For each reachable node, the last matching pattern decides whether it is excluded or restored. Duplicate positive rules therefore report the last matching line, not merely the first pattern that happened to ignore the path.

Two reports for different reviews

Use JSON to retain original paths, rule text and every prefix snapshot. Use TSV for a compact summary with directory status, ignored status, deciding line, pattern and blocking parent. The exported report includes all candidate rows even when only 50 are displayed; formula-like TSV cells receive a protective apostrophe.

What this simulation includes

One rule file and no tracked-file state
This Gitignore tester simulates one root .gitignore for untracked paths. It does not combine nested .gitignore files, .git/info/exclude, global excludes or command-line patterns. It cannot tell whether a real file is already tracked, staged, a symlink or present on disk.
Literal candidate strings
Candidates use / and explicit trailing directory slashes. Absolute and Windows-style paths, . or .. segments, controls and malformed Unicode are rejected. Blank candidate lines are skipped; a line containing spaces is a filename. Rule comments start with #; escape an initial # or ! to match it literally. Unescaped trailing rule spaces are ignored.
Bounded work with explicit failure
The maximum is 50 physical rule lines, 200 nonempty candidates, 256 UTF-16 code units per rule, 512 per path and 32 segments per path. One final line ending is not an extra rule. A background worker is terminated after 2 seconds, and stale or failed results cannot be exported.
Verify repository-specific behaviour with Git
Case sensitivity is fixed and matching uses the ignore package through public APIs. This is a focused simulation, not every Git command and configuration. Use git check-ignore -v in the actual repository for the final check. A rule that matches none of these candidates may still apply to other files; it is not automatically redundant. Multiple stars are supported only as a complete ** path segment. Forms such as ***/foo and a**/b are rejected because the engine differs from Git binaries on these combinations.

Gitignore tester questions

Why can a file remain ignored after a ! pattern?

An excluded parent prevents Git from visiting its children. A child exception cannot reopen that parent. Restore the directory first, or use a children-only pattern such as build/* and then a specific child exception. This Gitignore tester names the blocking parent alongside the deciding rule.

How do build and /build differ?

build can match that name at any depth; /build is anchored to the directory containing this .gitignore. A middle slash also makes a pattern relative to that base. Test both build and src/build to see the difference without changing any repository files.

Will logs/ ignore a regular file called logs?

No. The rule logs/ applies only to directories. Enter logs/ as a candidate directory, and logs as a candidate file. This explicit marker is necessary because the browser does not inspect a filesystem or infer a file type from the other candidates.

How do the three ** patterns work?

A leading **/ matches at any depth; a trailing /** matches descendants; a/**/b matches zero or more directories between a and b. Single * and ? do not cross /. The matcher uses UTF-8 bytes, so ? covers one byte rather than a whole multibyte character.

Why does Git report changes to an ignored file?

A tracked file stays tracked when you add it to .gitignore. This tool has no index information and evaluates candidate strings as untracked paths. Use Git in your repository to inspect the tracked state before interpreting an ignored result as a change to version control.

Found a path case worth checking?

Check your next ignore change

Use the Gitignore tester with both a path that should be excluded and one that should survive. Include the parent directory itself when you are investigating a failed exception.

Keep the exported history alongside your review, then confirm the real repository with Git before changing its rules.