Developer Tools

Free .gitignore Generator Online

Generate .gitignore files for any combination of languages, frameworks and editors.

.gitignore Files: A Complete Guide for Developers

A .gitignore file is one of the first things you should create in any new repository. It tells Git which files and directories to ignore — keeping build artifacts, dependencies, secrets, and OS noise out of version control. A missing or incomplete .gitignore leads to bloated repositories, accidentally committed secrets, and noisy git diffs. This guide covers everything you need to know about .gitignore syntax, strategies, and best practices.

What Should Go in .gitignore?

The short rule: ignore generated files; track source files. More specifically:

  • Dependencies: node_modules/, vendor/, .venv/ — reconstructable from lock files
  • Build artifacts: dist/, build/, target/, *.class, *.pyc — generated from source
  • Environment files: .env, .env.local — contain secrets; share .env.example instead
  • IDE settings: .idea/, .vscode/ (except shared settings), *.iml
  • OS files: .DS_Store (macOS), Thumbs.db (Windows), *.lnk
  • Log files: *.log, logs/
  • Cache directories: .cache/, .turbo/, .pytest_cache/, .mypy_cache/
  • Coverage reports: coverage/, htmlcov/, .nyc_output/

What not to ignore: lock files (package-lock.json, yarn.lock, Cargo.lock for applications, uv.lock), configuration files that control behaviour for all contributors (.eslintrc, tsconfig.json, pyproject.toml), and .env.example which documents required environment variables without values.

.gitignore Pattern Syntax

.gitignore uses glob patterns. The key rules:

  • Blank lines and lines starting with # are ignored (comments).
  • A pattern without a slash matches at any depth: *.log matches app.log, logs/app.log, and nested/dir/app.log.
  • A trailing slash means "directory only": build/ ignores the build directory but not a file named build.
  • A leading slash anchors to the root: /build ignores only a build entry at the repo root, not src/build.
  • Double asterisk matches across directories: **/logs matches logs, a/logs, a/b/logs at any depth. src/**/*.test.js matches any .test.js file anywhere inside src/.
  • A leading ! negates a pattern (re-includes a file): *.env then !.env.example ignores all .env files except the example.
  • Ranges in brackets: [abc] matches a, b, or c. [0-9] matches any digit.

Pitfall: if a directory is ignored, you cannot re-include files inside it with !. Git stops descending into ignored directories for performance. To selectively track files inside an otherwise-ignored directory, ignore only specific files rather than the parent directory.

Priority and Multiple .gitignore Files

Git evaluates ignore rules from multiple sources, in order of precedence (higher overrides lower):

  1. Command-line flags: git add --force overrides all ignore rules.
  2. Patterns in .gitignore in the current and parent directories: A pattern in a subdirectory's .gitignore only applies within that subdirectory.
  3. Global gitignore: ~/.gitignore_global (or the path in core.excludesFile config). Apply OS/editor rules here so you don't have to add them to every project.
  4. .git/info/exclude: Per-repository rules that are not tracked by Git. Useful for personal editor settings in a shared repo where you don't want to add IDE rules to the project's .gitignore.

To set up a global gitignore:

# Create and register a global gitignore
touch ~/.gitignore_global
git config --global core.excludesFile ~/.gitignore_global

# Add macOS rules
echo ".DS_Store" >> ~/.gitignore_global
echo "*.swp" >> ~/.gitignore_global

Handling Already-Tracked Files

Adding a rule to .gitignore does not affect files that are already tracked by Git. If you committed node_modules/ before adding the ignore rule, Git still tracks those files. To fix this:

# Stop tracking the directory but keep it locally
git rm --cached -r node_modules/

# Or for a single file
git rm --cached .env

# Then commit the removal
git commit -m "Remove node_modules from tracking"

# Now the .gitignore rule will apply to future changes

Be careful: git rm --cached removes the file from Git's index (the snapshot that will be committed) but leaves the file on your local disk. Other contributors who pull this commit will have the file removed from their working directories too, which is usually the desired behaviour.

Debugging .gitignore: git check-ignore

When a file is being unexpectedly ignored (or not ignored), use git check-ignore to diagnose:

# Check if a file is ignored and why
git check-ignore -v path/to/file.txt

# Output: .gitignore:15:*.txt  path/to/file.txt
# Means: line 15 of .gitignore, pattern *.txt, matches this file

# Check all files in a directory
git check-ignore -v **/*

Another useful command: git status --ignored shows ignored files alongside untracked and modified files, which is helpful for auditing a repository's state.

Language and Framework-Specific Strategies

Node.js / npm: Always ignore node_modules/. Commit package-lock.json or yarn.lock or pnpm-lock.yaml for applications (for reproducible installs). Libraries should not commit lock files (they would conflict with consumers' dependency resolution). Ignore .env but commit .env.example. Also ignore .npm/, .pnpm-store/, and .turbo/ if using Turborepo.

Python: Ignore __pycache__/, *.pyc, *.pyo, .venv/ (or venv/, env/ — use a consistent naming convention). For Django: ignore local_settings.py, db.sqlite3, media/. Ignore .mypy_cache/, .ruff_cache/, .pytest_cache/, and htmlcov/. Commit uv.lock or requirements.txt (generated via pip freeze or uv export).

Java / Maven / Gradle: Ignore target/ (Maven build output), .gradle/, build/ (Gradle). Commit gradlew, gradlew.bat, and the gradle/wrapper/ directory — these are checked-in toolchain definitions, not generated. Ignore IDE files (.idea/, *.iml) unless your team standardises on a specific IDE configuration.

Go: Go modules are relatively clean — ignore *.exe, *.test, *.out, and vendor/ if you use go mod vendor. Commit go.sum. The go.work file for Go workspaces should typically be ignored unless the entire workspace is being tracked together.

Rust: Ignore target/ (the build directory, which can be several GB). For applications, commit Cargo.lock; for libraries, conventionally do not commit it (let consumers determine dependency versions). Ignore *.pdb (debug symbols on Windows).

Monorepo Considerations

In a monorepo (a single repository containing multiple packages or services), .gitignore strategy requires additional thought:

  • Root .gitignore: Add global rules that apply everywhere — OS files, common editor files, shared build artifacts.
  • Package-level .gitignore: Each package can have its own .gitignore for package-specific outputs. Rules in a subdirectory only apply within that subdirectory.
  • Don't duplicate: If a rule already exists at the root level, you don't need to repeat it in package-level files.
  • Turborepo / Nx: Both tools have specific cache directories (.turbo/, .nx/cache/) that should be ignored.

Secrets and .gitignore

A critical misconception: .gitignore is not a security tool. It prevents files from being staged, but it provides no guarantee that secrets won't be committed. If you accidentally commit a secret, it remains in git history — even after adding a .gitignore rule and committing the deletion.

To remove a secret from git history:

  • git-filter-repo (recommended): git filter-repo --path .env --invert-paths — rewrites history to remove all occurrences of the file.
  • BFG Repo Cleaner: bfg --delete-files .env — a faster alternative to git filter-branch for large repositories.
  • Rotate the secret immediately: Assume the secret is compromised the moment it appears in a commit, even briefly. History-rewriting is not sufficient if the remote was pushed — the secret was visible to anyone with access during that window.

Best practice: use a secrets scanner (git-secrets, truffleHog, Gitleaks) as a pre-commit hook or CI check to catch credentials before they are committed.

# Install gitleaks pre-commit hook
gitleaks protect --staged --config .gitleaks.toml

The GitHub Gitignore Template Repository

GitHub maintains an official collection of .gitignore templates at github.com/github/gitignore. These templates are:

  • Community-maintained and regularly updated as ecosystems evolve
  • Used automatically when you create a new repository on GitHub (the "Add .gitignore" dropdown)
  • Available via the GitHub API for programmatic generation

The templates in this generator are derived from and compatible with those official templates, with additions for modern tooling (pnpm, Bun, Vite, Turborepo, uv, Ruff). When new tooling becomes common, templates are updated accordingly.

Checking In vs. Global Ignore: IDE Files

Whether to commit IDE-specific files is a team decision with valid arguments on both sides:

Arguments for committing (e.g. .vscode/settings.json): Ensures consistent editor settings across the team (tab size, format on save, recommended extensions). New contributors get the right setup immediately.

Arguments against: Forces a specific IDE on contributors, causes merge conflicts when settings diverge, pollutes the repository with non-project files.

A common compromise: commit project-specific VS Code settings (recommended extensions, format-on-save, ESLint integration) but keep personal preferences in your global gitignore. Use !.vscode/settings.json to allow committing that specific file while ignoring the rest of .vscode/:

.vscode/*
!.vscode/settings.json
!.vscode/extensions.json
!.vscode/tasks.json

FAQ

Common questions

What is a .gitignore file?

A .gitignore file tells Git which files and directories to skip when tracking changes. Entries are glob patterns — a line like node_modules/ means "ignore any directory named node_modules at any depth". Git reads .gitignore from the repository root and from subdirectories, with more specific rules taking precedence.

Where should I place the .gitignore file?

Place the generated .gitignore in your repository root alongside the .git directory. Git also respects .gitignore files in subdirectories — rules in a subdirectory's .gitignore apply only to files within that directory and its children. For rules that apply globally across all your repos, use ~/.gitignore_global and register it with git config --global core.excludesFile.

Why do I still see ignored files in git status?

If a file was tracked before you added a .gitignore rule for it, Git continues tracking it — .gitignore only prevents untracked files from being added. To stop tracking a file that is already committed: run git rm --cached <file>, then commit the removal. After that, Git will honour the ignore rule.

What does the "!" prefix mean in .gitignore?

A line starting with ! negates a previous pattern, re-including a file that would otherwise be ignored. For example, *.log ignores all log files, but !important.log re-includes that specific file. Note: if a parent directory is ignored, you cannot re-include files inside it — Git stops descending into ignored directories.

Should I commit the .gitignore file?

Yes. Commit .gitignore to the repository so all collaborators share the same ignore rules. This prevents OS-specific files (like .DS_Store on macOS or Thumbs.db on Windows) and IDE settings from polluting other developers' git status. The generated file is safe to commit immediately.

How do I ignore a file that is already tracked?

Adding a pattern to .gitignore does not remove already-tracked files. Run git rm --cached <file> (or git rm --cached -r <directory>) to untrack the file without deleting it locally, then commit. After that, the file remains on your disk but Git ignores future changes to it.

Can I combine multiple technology templates?

Yes — that is the primary purpose of this generator. Select every technology in your stack and the tool merges all their rules into a single .gitignore with clear section headers. Duplicate patterns are collapsed automatically. A typical full-stack project might combine Node.js, React, Python, VS Code, and macOS sections.

Are these templates based on the official GitHub templates?

The rules are derived from and compatible with the official GitHub gitignore templates (github.com/github/gitignore), with additions for common modern tooling (pnpm, Bun, Vite, Turborepo, etc.). The templates are maintained as part of this tool and updated when the ecosystem changes.

More in Developer Tools