Skip to main content

.gitignore Generator

Combine templates into one clean, deduplicated .gitignore file. Runs in your browser — nothing is sent to a server.

Quick presets

Selected templates

Nothing selected yet — pick a template on the left.
0 Templates
0 Unique rules
0 Lines
Duplicates removed automatically

Appended under their own heading. Lines starting with # are kept as comments.

How to Use the .gitignore Generator

  1. Search or browse the template list and click every stack you use — language, framework, build tool, editor and operating system.
  2. Selected templates appear as chips on the right. Click the × on a chip to remove it.
  3. Add anything project-specific in the Custom rules box, one pattern per line.
  4. Rules shared by two templates are written only once, so the file stays short and readable.
  5. Click Copy .gitignore, or Download to save the file, then place it in the root of your repository.

Everything runs in your browser. No template is fetched from a server and nothing you type is uploaded.

What a .gitignore File Actually Does

A .gitignore file tells Git which paths it should not offer to add to the repository. When Git scans your working directory, any file matching a pattern in .gitignore is skipped: it will not show up as untracked in git status, and a plain git add . will not stage it.

The point is to keep three kinds of files out of version control: generated output (build artifacts, compiled binaries, bundler output), installed dependencies that a package manager can reinstall from a lockfile, and machine-local or secret files such as editor state, OS metadata and environment files holding credentials.

Git looks for a .gitignore in the repository root and in any subdirectory. A rule in a nested .gitignore applies only from that directory downward, and it takes precedence over rules in parent directories. For patterns you want on every repo on your own machine — editor swap files, OS junk — a personal global ignore file is usually the better home, so you do not push your editor preferences into a shared project.

The Gotcha: .gitignore Does Not Affect Files Git Already Tracks

This is the single most common source of confusion. .gitignore only applies to untracked files. If you already committed .env or an entire node_modules/ folder, adding them to .gitignore later changes nothing — Git keeps tracking them and keeps reporting their modifications, because a tracked file is tracked regardless of any ignore rule.

To stop tracking a file while keeping it on disk, remove it from the index:

git rm --cached .env
git rm -r --cached node_modules
git commit -m "Stop tracking ignored files"

The --cached flag is what keeps your local copy; without it, git rm deletes the file. To reset the index for a whole repository after a large .gitignore change, git rm -r --cached . followed by git add . re-applies every ignore rule in one commit.

Security note: removing a secret from the index only stops future commits from carrying it. The value is still in your history, and anyone with the repo can read it. If you committed a real credential, rotate it — do not rely on a later .gitignore or a single git rm --cached.

.gitignore Pattern Syntax

Each line is one pattern. Blank lines are ignored, and a line beginning with # is a comment. The syntax is glob-style, not regular expressions.

Pattern What it matches
*.log * matches any run of characters except a slash. This ignores every .log file, at any depth.
build/ A trailing slash restricts the match to directories. A file named build would not be ignored.
/dist A leading slash anchors the pattern to the directory holding the .gitignore, so only the repo-root dist is ignored, not packages/app/dist.
logs/*.log A pattern containing a slash anywhere but at the end is also anchored to the .gitignore directory.
**/target/ ** crosses directory boundaries. This ignores a target directory at any depth. src/**/tmp matches tmp under src, however deeply nested.
!keep.log ! negates an earlier pattern and re-includes the file. Order matters — the negation must come after the rule that ignored it.
*.py[cod] Square brackets match one character from the set — here .pyc, .pyo and .pyd.
debug?.log ? matches exactly one character other than a slash.
\#notes.txt A backslash escapes a leading # or ! so it is treated as part of the filename rather than a comment or negation.

One important limitation: if a directory is excluded, Git will not look inside it, so a negation cannot re-include a file within an ignored directory. Ignore the contents instead — logs/* followed by !logs/.keep works, while logs/ followed by !logs/.keep does not.

Specifications

Accepts
Text — type or paste
Gives you
copy to clipboard
Where it runs
Your browser — the file is never uploaded
Sign-up
None
Cost
Free, with no usage limits

FAQ

Why are my ignored files still showing up in git status?

Because .gitignore only applies to files Git is not already tracking. Once a file has been committed, Git keeps tracking it forever regardless of any ignore rule. Run git rm --cached path/to/file (or git rm -r --cached folder for a directory) to remove it from the index while keeping it on disk, then commit that change. From the next commit onward the ignore rule takes effect.

Does adding .env to .gitignore remove the secret from my history?

No. Ignoring a file only affects future commits. Any value already committed remains in the repository history and can be recovered by anyone who has a clone. If you pushed a real API key, database password or token, rotate the credential immediately. Rewriting history with a tool such as git filter-repo can scrub the blob, but rotation is the only step that actually protects you.

Should I commit the .gitignore file itself?

Yes. .gitignore belongs in the repository so every contributor gets the same rules. It is one of the few dotfiles you always want tracked. If a pattern is only relevant to your own machine, such as your editor's swap files, put it in a global ignore file or in .git/info/exclude instead, which stays local and is never shared.

Why does my ! negation rule not work?

Two usual causes. First, order: a negation only re-includes a file if it appears after the pattern that ignored it, so putting !gradle/wrapper/gradle-wrapper.jar above *.jar has no effect. Second, excluded directories: Git does not descend into a directory it has excluded, so no rule can re-include anything inside it. Ignore the directory contents with a trailing /* and then negate the specific file.

Can I have more than one .gitignore in a repository?

Yes. Git reads a .gitignore in every directory, and rules apply from that directory downward. A rule in a nested file overrides a conflicting rule in a parent directory, which is handy in a monorepo where each package ignores its own build output. Git also reads .git/info/exclude for repo-local rules that are never committed, plus your global core.excludesFile.

Should I ignore lockfiles like package-lock.json or Cargo.lock?

For applications, no — commit them, so every install and every CI run resolves the exact same dependency versions. For a published library, Cargo.lock is traditionally left uncommitted so downstream consumers pick their own versions. None of the templates on this page ignore a lockfile by default, because committing them is the right choice for the large majority of projects.

Related Tools