Ignoring Files with .gitignore
Keep dependencies, secrets, build output and system junk out of your repository with .gitignore patterns, check why a file is ignored, and stop tracking files you committed by mistake.
On this page 12 sections
Introduction
Not every file in your project folder belongs in Git. Downloaded libraries, passwords and API keys, compiled files and your operating system’s hidden files should all stay out. A file called .gitignore tells Git which files to pretend do not exist, so they never show up as untracked and are never added by git add ..
- Which kinds of files should never be committed.
- How to write .gitignore patterns.
- How to check why Git is ignoring a file.
- How to stop tracking a file you already committed.
What Should Not Be Committed
| Kind of file | Examples | Why ignore it |
|---|---|---|
| Dependencies | node_modules/, venv/, vendor/ | Huge, and anyone can reinstall them from package.json or requirements.txt |
| Secrets | .env, credentials.json, *.pem | Anyone with access to the repo could read your passwords and keys |
| Build output | dist/, build/, *.class, *.exe | Generated from the source code, so it can always be rebuilt |
| System files | .DS_Store (macOS), Thumbs.db (Windows) | Created by your operating system, meaningless to others |
| Logs and temp files | *.log, *.tmp | Change constantly and are only useful on your machine |
| Personal editor settings | .vscode/, .idea/ | Your preferences, not the project’s (some teams do share these on purpose) |
Priya’s project has grown. She committed her VS Code settings folder (.vscode/), installed a small development server with npm (creating node_modules/ and package.json), stored an API key for a contact form in .env, and her Mac created a .DS_Store file:
git statusClick Run to see what this code prints.
Only package.json belongs in the repository — it lists the dependencies so others can install them. One careless git add . would publish her API key.
Creating a .gitignore
Create a file named exactly .gitignore (starting with a dot, no extension) in the top folder of the repository:
# Dependencies (anyone can reinstall them with npm install)node_modules/
# Secrets: never commit these.env
# Operating system junk.DS_StoreThumbs.dbgit statusClick Run to see what this code prints.
The ignored files have disappeared from the list. The .gitignore file itself shows up, because it should be committed — that way everyone who works on the project gets the same rules:
git add .gitignore package.jsongit commit -m "Add .gitignore and package.json"Click Run to see what this code prints.
Pattern Rules
| Pattern | Matches |
|---|---|
| notes.txt | Any file named notes.txt, in any folder |
| *.log | Every file ending in .log |
| build/ | Any folder named build (the trailing / means “folders only”) |
| /todo.md | Only todo.md in the top folder (a leading / anchors the pattern) |
| docs/*.pdf | PDF files directly inside docs/, but not in its subfolders |
| **/temp | A file or folder named temp at any depth |
| !keep.log | Exception: do track keep.log even though *.log is ignored |
| # comment | Lines starting with # are comments |
GitHub maintains ready-made .gitignore templates for almost every language and framework in its public github/gitignore repository, and offers to add one when you create a new repository on github.com.
This .gitignore is for a Node.js project that keeps its database password in a .env file. What important line is missing?
node_modules/ dist/ *.log .DS_Store
Checking Ignored Files
When a file is ignored and you do not know why, ask Git. git check-ignore -v shows which file and which line is responsible:
git check-ignore -v .env node_modules/live-server/index.jsClick Run to see what this code prints.
Each line reads: the .gitignore file, the line number, the pattern, then the path. You can also list every ignored file with --ignored; ignored files are marked !!:
git status --short --ignoredClick Run to see what this code prints.
Files Already Committed
Here is a rule that surprises many people: .gitignore only affects files Git is not already tracking. Priya committed .vscode/settings.json earlier. She adds .vscode/ to .gitignore, but Git keeps tracking the file:
git status --shortClick Run to see what this code prints.
Only the .gitignore change appears; the settings file is still part of the repository. To stop tracking it without deleting it from your computer, remove it from Git’s index with --cached:
git rm -r --cached .vscodeClick Run to see what this code prints.
git status --shortClick Run to see what this code prints.
git add .gitignoregit commit -m "Stop tracking editor settings"Click Run to see what this code prints.
The commit deletes the file from the repository, but ls .vscode still shows settings.json on Priya’s computer. From now on the folder is ignored.
You commit config.json, then add config.json to .gitignore and edit config.json again. What does git status show?
A Global .gitignore
Files like .DS_Store come from your computer, not the project. Instead of adding them to every repository, you can set up a personal ignore file once:
git config --global core.excludesFile ~/.gitignore_globalThen list your system and editor files in ~/.gitignore_global. Keep project-specific rules (dependencies, build folders, .env) in the project’s own .gitignore, so they protect everyone on the team.
If You Commit a Secret
If an API key or password reaches a commit that has been pushed, assume someone has copied it — bots scan public repositories within minutes. First revoke or rotate the key with the service that issued it. Then remove the file and add it to .gitignore. Deleting it in a new commit is not enough on its own, because the old commit still contains it.
Removing a secret from all of history requires a history-rewriting tool such as git filter-repo, and everyone must re-clone afterwards — which is why rotating the key comes first. GitHub also blocks many recognisable secrets from being pushed with its push protection feature.
Common Mistakes
- Creating .gitignore after the first git add . — by then the files are already tracked.
- Naming the file gitignore.txt or .gitignore.txt; it must be exactly .gitignore.
- Ignoring package.json or requirements.txt, which others need to install dependencies.
- Thinking a deleted secret is safe because it is gone from the latest commit.
Frequently Asked Questions
Yes. A .gitignore in a subfolder applies to that folder and its contents. Most projects use one file at the top, which is easier to maintain.
Commit a .env.example with the variable names and placeholder values (never real secrets), and ignore the real .env. New team members copy the example and fill in their own values.
Git tracks files, not folders, so empty folders are never committed. Put a file inside (often an empty .gitkeep) if you need the folder to exist.
Key Takeaways
- Never commit dependencies, secrets, build output or system files.
- List patterns in a .gitignore at the top of the repository, and commit that file.
- git check-ignore -v explains why a file is ignored.
- .gitignore does not affect tracked files; use git rm --cached to stop tracking one.
- If a secret is pushed, rotate it first — deleting the file does not remove it from history.
Summary
Priya’s repository now contains only what belongs in it. With a clean foundation, it is time for Git’s most powerful idea: branches, which let you work on new features without touching your working version.