Skip to content
ZeroServer.tools
All guides

What to Put in .gitignore (and Why)

June 5, 2026 · 3 min read

A .gitignore file tells Git which files and directories to leave untracked. Getting it wrong means committing files that shouldn't be in the repository — credentials, build output, editor config, OS artefacts — or spending time on merge conflicts in files nobody should have committed in the first place.

What to always ignore

Dependency folders

Never commit installed dependencies. They can always be restored from your lock file and are often OS-specific or architecture-specific:

node_modules/   # Node.js
vendor/         # Go, PHP (Composer)
venv/ / .venv/  # Python virtualenv
target/         # Rust / Maven

Build output

Compiled and generated output is reproducible from source. Committing it bloats the repository and causes constant noise in diffs:

dist/
build/
out/
*.class   # Java
*.o       # C/C++ object files

Environment files

Environment files contain secrets (API keys, database passwords). They must never enter version control:

.env
.env.local
.env.*.local

If you need to document which environment variables are required, commit a .env.example file with placeholder values and add .env (but not .env.example) to .gitignore.

OS artefacts

macOS creates .DS_Store in every directory it touches. Windows creates Thumbs.db. These are OS-specific and meaningless to other developers:

.DS_Store       # macOS
Thumbs.db       # Windows
Desktop.ini     # Windows

Editor / IDE files

Editor config files that are personal preferences (keybindings, workspace layout) should not be shared:

.idea/          # JetBrains IDEs
*.suo / *.user  # Visual Studio
.vscode/        # VS Code (workspace-specific settings)

Note: if your team has agreed on shared VS Code settings (recommended extensions, formatter config), it is fine to commit .vscode/settings.json and .vscode/extensions.json while still ignoring .vscode/ — use negation patterns to opt specific files back in:

.vscode/
!.vscode/settings.json
!.vscode/extensions.json

.gitignore pattern syntax

Pattern Meaning
*.log All .log files in any directory
build/ The build directory (trailing / = directory only)
/dist Only dist at the repo root (leading / = anchored)
!keep.log Re-include keep.log even if *.log ignores it
**/*.snap Any .snap file at any depth
doc/**/*.txt All .txt files inside doc/

Rules are processed top-to-bottom. A negation (!) only un-ignores a file if its parent directory is not itself ignored — so !node_modules/keep.txt has no effect if node_modules/ is ignored.

Combining stacks

Most projects span multiple stacks. A Next.js project on macOS, built in VS Code, should combine the Next.js, Node.js, macOS, and VS Code sections — there is no reason to pick just one. The .gitignore Generator lets you tick any combination of tech stacks and generates the merged file instantly.

What not to ignore

  • Lock files (package-lock.json, yarn.lock, Cargo.lock, poetry.lock). These pin exact dependency versions and ensure reproducible installs. They belong in version control.
  • Config files (tsconfig.json, eslint.config.js, .prettierrc). These define project-wide rules and should be shared.
  • Migration files and schema definitions — they are history and should not be lost.

The global gitignore

You can define a personal global .gitignore for OS and editor artefacts so you don't have to add them to every project. Set it up once:

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

Then put macOS, Windows, and your editor entries in ~/.gitignore_global. The project-level .gitignore can then focus on language and framework specifics.

Checking what is being ignored

To see which files Git is currently ignoring:

git status --ignored
git check-ignore -v path/to/file   # explain why a specific file is ignored

If you have already committed a file that should be ignored, add it to .gitignore and then run:

git rm --cached path/to/file

This removes it from tracking without deleting it from disk. Commit the change and it will no longer appear in future diffs.