guide

What to Ignore and What to Commit

Guidelines for ignoring build output, dependencies, caches and secrets while committing lockfiles, example configs and team editor settings, plus nested .gitignore files, keeping empty directories and merging templates.

A good .gitignore is judged by its criteria, not its length. There is one criterion: can someone who freshly clones the repository reproduce the same result from the source and configuration alone? Ignore what can be recreated, and commit what cannot be recreated or what pins down the result.

What to ignore

TypeExamplesReason
Build outputdist/, build/, target/, *.o, *.classRebuilt from source
Installed dependenciesnode_modules/, vendor/ (PHP), .venv/Reinstalled from the manifest and lockfile
Caches and logs.cache/, .pytest_cache/, *.log, coverage/Change on every run
Local environment and secrets.env, *.pem, local.properties, *.tfstateDiffer per person or environment, or must not leak
Personal tool state.DS_Store, *.swp, .idea/workspace.xmlUnrelated to the project (global gitignore recommended)

What to commit

Putting .gitignore in subdirectories

.gitignore is not limited to the root. A .gitignore in a subdirectory works relative to that directory and takes precedence over the files above it. In a monorepo where each package needs different rules, keeping a separate file in each package folder is easier to read.

repo/
├── .gitignore          # shared: .DS_Store, .env, coverage/
├── apps/web/.gitignore # .next/, out/
└── services/api/.gitignore # target/

Keeping empty directories

git tracks only files and does not store empty directories. When the folder must exist but its contents should be ignored, as with a log folder, put a marker file inside the folder and restore it with a negation rule.

/log/*
!/log/.keep

Names such as .keep or .gitkeep are only conventions, not an official git feature. Any name works. Alternatively, placing a .gitignore with the following contents in that folder ignores everything except itself.

*
!.gitignore

When merging templates

Keep rules short and specific

Overly broad rules such as *.json swallow configuration files too. Narrow paths as much as possible (/dist/), and add a trailing slash to directories to distinguish them from files with the same name. A one-line comment above a rule explaining why lets the next person decide whether it is safe to remove.

References

← PreviousWhy Is It Ignored? Debugging with git check-ignore