Skip to content

.gitignore Generator

Build a .gitignore by selecting your stack — Node, Python, Java, Go, Ruby, Rust, .NET, plus OS files and editors. Combines official-style templates into one ready-to-use file.

Tick the languages, tools, and editors your repo uses. The generator combines the relevant templates into a single .gitignore — no overlap, ready to drop at the root of your repo.

Languages

Operating systems

Editors

Tools

Pick at least one template

Download
 

A .gitignore file lives in a Git repository and lists patterns of files Git should refuse to track. Anything matched by a .gitignore pattern is invisible to git status and git add, even when the file exists in the working tree. The tool above generates .gitignore files for common stacks; nothing leaves your machine.

Pattern syntax

A .gitignore pattern looks glob-like but has Git-specific extensions. The full reference is in the Git documentation; the patterns that come up daily:

PatternWhat it matches
node_modulesAny directory or file named node_modules anywhere in the repo
node_modules/Same — but only when it’s a directory
/node_modulesA node_modules only at the root of the repo
*.logAny file ending in .log, anywhere
**/buildAny build directory, anywhere
build/**Everything inside any build directory
!important.logNegation — re-include important.log if it would otherwise be ignored
# commentA comment (lines starting with # are skipped)

A trailing slash means “directory only.” A leading slash anchors the pattern to the location of the .gitignore file. Without a leading slash, the pattern is matched anywhere in the tree below the .gitignore.

Anchoring

node_modules        ← anywhere in the tree
/node_modules       ← only at the same level as this .gitignore
src/node_modules    ← only at this exact path (relative to .gitignore)

The first form is the most common — it ignores all node_modules directories at any depth, which is what you almost always want.

Per-stack defaults

Different language ecosystems generate different “junk” files. Standard .gitignore patterns:

StackCommon entries
Node.jsnode_modules, npm-debug.log*, .env, dist/, coverage/, .next/, .parcel-cache
Python__pycache__/, *.py[cod], .venv/, *.egg-info/, .pytest_cache/, .mypy_cache/
Java*.class, target/, .gradle/, build/
Gobinaries (no extension on Linux, .exe on Windows), *.test, *.out, go.work (vendor/ only if you don’t commit vendored modules)
Rusttarget/, **/*.rs.bk (commit Cargo.lock — Cargo’s default since 2023)
Ruby / Rails.bundle/, log/*.log, tmp/, vendor/bundle, coverage/, .byebug_history
.NET / C#bin/, obj/, *.user, *.suo, .vs/

Each per-stack page on this site has the corresponding ignore list. See Python, Node, Java, Go, Rust, .NET / C#, Ruby / Rails.

OS and editor entries

Independent of language stack, every .gitignore typically also has:

# OS
.DS_Store           # macOS Finder metadata
Thumbs.db           # Windows thumbnail cache
ehthumbs.db
*.swp               # Vim swap files

# Editors
.idea/              # JetBrains IDE
.vscode/            # VS Code (often kept; see below)
*.sublime-*

The .vscode/ directory is contentious. Some teams ignore it (per-developer preferences shouldn’t be shared); some commit it (shared launch configs and recommended extensions are useful). Pick a team convention.

Negation patterns

# Ignore the whole logs directory…
logs/
# …except keep the example log file
!logs/example.log

Negation re-includes a file. Two restrictions:

  • A negated pattern can’t re-include a file from an ignored directory. If the parent dir is ignored, the file inside is ignored regardless of negation. To re-include, you have to not ignore the parent dir directly.
  • Order matters. Later patterns override earlier ones. A negation has to come after the pattern it negates.

Files Git is already tracking

.gitignore only affects untracked files. If a file is already tracked, adding it to .gitignore doesn’t make Git stop tracking it. To remove it from tracking while keeping it in the working tree:

git rm --cached path/to/file
git commit -m "stop tracking accidentally-committed file"

This is the standard procedure for “I committed .env and now want it untracked.” The file stays in your working tree; Git stops watching it.

Global gitignore

Patterns specific to your machine (your editor’s swap files, your OS’s thumbnail cache) belong in a global gitignore, not in every project’s .gitignore:

git config --global core.excludesfile ~/.gitignore_global

Then edit ~/.gitignore_global to include .DS_Store, *.swp, etc. The project .gitignore is for project-relevant patterns (build outputs, dependencies); the global is for machine-relevant ones.

Common pitfalls

  • Adding a pattern after committing a file. Doesn’t untrack. Use git rm --cached (above).
  • Whitespace at end of pattern. A line ending with a space is a literal pattern that matches nothing useful. Many editors auto-trim; some don’t.
  • Comments mid-line. node_modules # the dependency dir ignores a literal “node_modules # the dependency dir” path. Comments must be on their own line.
  • Using shell-style escaping. .gitignore patterns are not shell glob; quotes don’t help. To match a literal *, escape with \*.
  • Forgetting the trailing slash. build matches both files and directories named build; build/ matches only directories. The latter is usually what you want.

For language-specific defaults, see the Python, Node, Java, Go, Rust, .NET, Ruby pages.