.gitignore
In short
A .gitignore file is a plain-text file listing patterns for files and folders Git should not track, such as dependencies, build output, logs, and secrets.
What is a .gitignore file?
A .gitignore file tells Git which files to leave out of version control. Every project produces files that shouldn't be committed: downloaded dependencies like node_modules, compiled build output, log files, editor settings, and operating system clutter like .DS_Store. Listing them in .gitignore keeps them out of git status and prevents them from being added by accident.
Each line in the file is a pattern. A plain name like debug.log matches that file in any folder, a trailing slash like dist/ matches only directories, * matches any characters so *.log matches every log file, and a leading ! re-includes something an earlier pattern excluded. Lines starting with # are comments. You usually put a .gitignore at the root of the repository and commit it so the whole team shares the same rules, though subfolders can have their own as well.
A .gitignore is like a 'do not pack' list for a move: it tells the movers which items stay behind so they don't clutter the new house. Ready-made templates exist for most languages and frameworks, and many project generators create one for you automatically.
The most common confusion is that .gitignore only affects untracked files. If a file was already committed, adding it to .gitignore won't stop Git from tracking it; you must first remove it from the index with git rm --cached. Ignoring a secret, such as an .env file of environment variables, also doesn't undo a leak: if it was ever committed and pushed, it stays in the history, so you should revoke it and create a new one.
Key takeaways
.gitignorelists patterns for files Git should not track.- Typical entries include dependencies, build output, logs, and
.envfiles with secrets. - Patterns support wildcards (
*), directory rules (dist/), comments (#), and exceptions (!). - It only affects untracked files; use
git rm --cachedto stop tracking an already committed file.
Example
# Create a .gitignore for a typical Node.js project
cat > .gitignore <<'EOF'
# Dependencies and build output
node_modules/
dist/
# Logs and local secrets, but keep the example file
*.log
.env
!.env.example
EOF
# Stop tracking a file that was committed before it was ignored
git rm --cached debug.log
git commit -m "Stop tracking debug.log"Readers ask
Why is my .gitignore not working?
The most common reason is that the file was already tracked before you added the rule, because .gitignore only affects untracked files. Run git rm --cached <file> (add -r for a folder) and commit, and use git check-ignore -v <file> to see which rule, if any, matches.
Should I commit the .gitignore file?
Yes. Committing .gitignore shares the same ignore rules with everyone on the team. For personal rules, such as files created by your own editor, use .git/info/exclude or a global ignore file set with git config --global core.excludesFile.
Does .gitignore protect secrets?
Only if the secret was never committed. If a file containing passwords or API keys was ever pushed, it remains in the repository history, so revoke the exposed keys and issue new ones.
See also
- GitVersion Control, p. 10Git is a free, open-source distributed version control system that tracks changes to files over time, so developers can collaborate and undo mistakes.
- RepositoryVersion Control, p. 34A repository is the storage location for a project, holding all of its files plus the complete history of every change recorded by a version control system.
- CommitVersion Control, p. 5A commit is a saved snapshot of a project's files in Git, recorded with a unique ID, an author, a timestamp, and a message describing what changed.
- Environment VariableDevOps & Cloud, p. 20An environment variable is a named value set outside a program, by the operating system or runtime, that the program reads to configure its behavior.
- API KeySecurity, p. 1An API key is a unique secret string that identifies an application or project when it calls an API, used to control access, track usage, and apply rate limits.
Spotted a mistake or something missing on this page?Suggest an edit