FreeToGenerate.com

Everyone quotes “the last matching pattern wins”. It does not explain why !build/keep.txt has no effect under build/ — and this tool shows you the line that actually decided.

Stacks

global
global
global
global
global

The ones marked global belong in your own ~/.gitignore_global, not in a repository. Your editor's folder is your business, not the project's.

2 patterns

These negations can never take effect

  • 2: !build/keep.txt

An earlier pattern excludes a directory above the one being re-included. Exclude the directory's contents instead — a trailing /* rather than a trailing / — and the negation starts working.

Would this path be ignored?

Ignored

Decided by line 1: build/

build The decision was made on the parent directory, not on the file. Git never looks inside an excluded directory, so a negation below it is never reached.

Templates are a curated subset of github/gitignore, dedicated to the public domain under CC0. They are a starting point, not an authority — a template that has not caught up with some new build directory is incomplete rather than wrong. Snapshot taken 2026-08-02

Also available in: Español · Português · Français · العربية

Gitignore generator

Compose a .gitignore from templates, then check a real path against it and get the verdict plus the line — and the directory — that produced it.

What is a .gitignore generator?

A .gitignore file tells git which paths to leave alone: build output, dependency folders, editor droppings, anything you do not want in the history. A generator gives you a sensible starting file for the stacks you use, so you are not writing node_modules from memory every time you start a repository.

The generating half is the easy half, and on its own it is not worth much — you cannot verify a list of patterns by looking at it. So this page pairs it with the part that can be checked: paste a path and it tells you whether git would ignore it, and which line made that decision.

That second half is where the surprises live. A .gitignore is not a list of files, it is a set of pattern rules with precedence, anchoring and directory semantics, and the rule people quote about it is incomplete in a way that bites almost everyone eventually.

How to use it

  1. Tick the stacks you are using. The file is composed from templates with a heading per stack. The ones marked global belong in your own ~/.gitignore_global rather than in the repository — your editor's folder is your business, not the project's.
  2. Edit the file freely. It is an ordinary textarea. Paste an existing .gitignore in instead if what you want is the checker.
  3. Type a path and read the verdict. You get ignored or not ignored, the line number and text of the deciding pattern, and — when it applies — the parent directory the decision was actually made on.

Why !build/keep.txt does nothing, and what to write instead

The rule everybody repeats is that the last matching pattern wins. That is true as far as it goes, and it predicts the wrong answer for the single most common .gitignore question. Given build/ on one line and !build/keep.txt on the next, the file stays ignored. Git agrees: ask it and it names line 1, the directory rule, as the decider.

The reason is that git does not walk a flat list of patterns against your path. It walks the path's directories from the top down, and once a directory is excluded it never descends into it. There is no opportunity for a pattern below to re-include anything, because nothing inside is ever looked at.

The fix is one character. Exclude the directory's contents rather than the directory: build/* instead of build/. Then git does descend, the negation is reached, and build/keep.txt is kept while everything else in there stays ignored. This tool flags the broken form for you — it lists any negation that an earlier rule has made unreachable, so you find out before committing rather than after wondering why the file never showed up.

The rest of the syntax is worth knowing too, and the checker exercises all of it: a slash anywhere but the end anchors a pattern to the file's own directory, so /build only matches at the root while build matches at any depth; a trailing slash restricts a pattern to directories; an asterisk stops at a slash but a double asterisk crosses one; and a leading exclamation mark negates, unless you escape it.

Honest limits

The templates are a starting point, not an authority. They are a curated subset of the public-domain set that github publishes, and the date this snapshot was taken is printed under the tool. A template that has not caught up with some new build directory is incomplete, which you can see and fix in the textarea; that is a different thing from being wrong.

This page also reasons about one .gitignore file at a time. A real repository can have several — one per directory, plus .git/info/exclude, plus your global file — and git applies them in order of increasing specificity, so a rule in a subdirectory beats one at the root. The checker answers for the file in the box, relative to where that file sits.

Two more things a path alone cannot tell you. A file that is already tracked keeps being tracked no matter what you add to .gitignore, because the ignore rules apply to untracked files; you need git rm --cached to stop following it. And this reasons about patterns rather than about your disk, so it treats the path exactly as typed — the checkbox is there because whether something is a directory changes the answer for patterns ending in a slash.

Finally, the verdicts here were checked against git itself rather than against another implementation: a generated sweep of 252 pattern and path combinations, run through a real repository, with no disagreements.

Why is it free?

Because it costs nothing to run. The matching happens in your browser; no file is uploaded, no server sees your paths, and there is no account.

The templates are public domain, the pattern rules come from git's own documented behaviour, and the test that compares this implementation against git is committed alongside the code.