Using .gitignore Effectively
The .gitignore file tells Git which files and directories to ignore. Proper use of .gitignore keeps your repository clean and avoids committing sensitive or unnecessary files.
Why .gitignore?
Some files shouldn't be tracked:
| Category | Examples |
|---|---|
| Dependencies | node_modules/, vendor/ |
| Build outputs | dist/, build/, *.o |
| Environment | .env, credentials.json |
| IDE settings | .idea/, .vscode/ |
| OS files | .DS_Store, Thumbs.db |
| Logs | *.log, logs/ |
| Secrets | *.pem, *.key |
Basic Syntax
# Comment
file.txt # Specific file
*.log # All .log files
/config.json # Only in root directory
build/ # Directory
!important.log # Negation (don't ignore this)
Pattern Matching
Wildcards
# * matches anything except /
*.txt # All .txt files
test*.js # test1.js, test_utils.js, etc.
# ** matches directories
**/logs # logs anywhere in tree
src/**/test # src/test, src/a/test, src/a/b/test
# ? matches single character
file?.txt # file1.txt, fileA.txt
Character Classes
# [abc] matches any one of a, b, c
*.[oa] # *.o or *.a files
# [0-9] matches range
log[0-9].txt # log0.txt through log9.txt
Directory vs File
# Trailing slash means directory only
build/ # Ignore build directory
build # Ignore file OR directory named build
Anchoring
# Leading slash anchors to root
/config.json # Only root config.json
config.json # config.json anywhere
# Patterns without slash match anywhere
*.log # Matches logs/debug.log, tmp/error.log
Common .gitignore Files
Node.js / JavaScript
# Dependencies
node_modules/
package-lock.json # Sometimes ignored, sometimes not
# Build
dist/
build/
.next/
out/
# Environment
.env
.env.local
.env*.local
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# IDE
.idea/
.vscode/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Coverage
coverage/
.nyc_output/
Python
# Byte-compiled
__pycache__/
*.py[cod]
*$py.class
# Virtual environment
venv/
.venv/
ENV/
# Distribution
dist/
build/
*.egg-info/
# IDE
.idea/
.vscode/
*.pyc
# Environment
.env
.python-version
# Testing
.coverage
htmlcov/
.pytest_cache/
General Purpose
# IDE
.idea/
.vscode/
*.sublime-*
# OS
.DS_Store
.DS_Store?
._*
Thumbs.db
# Logs
*.log
logs/
# Environment
.env
.env.local
*.local
# Secrets
*.pem
*.key
secrets/
credentials.json
# Build
dist/
build/
out/
Negation Patterns
Include files that would otherwise be ignored:
# Ignore all log files
*.log
# But keep important.log
!important.log
# Ignore all in dir except one file
build/*
!build/.gitkeep
# Complex negation
*.config
!production.config
Note: You can't un-ignore a file if its parent directory is ignored:
# This WON'T work
build/
!build/important.txt # Still ignored!
# This works
build/*
!build/important.txt
Multiple .gitignore Files
Repository Root
Main .gitignore at project root.
Subdirectories
Each directory can have its own .gitignore:
project/
├── .gitignore # Root rules
├── src/
│ └── .gitignore # src-specific rules
└── docs/
└── .gitignore # docs-specific rules
Subdirectory rules add to, don't override, parent rules.
Personal Ignores
For rules specific to you (not shared):
# Add to .git/info/exclude
echo ".myide" >> .git/info/exclude
Global Ignores
For all repositories:
# Create global gitignore
git config --global core.excludesfile ~/.gitignore_global
# Add to ~/.gitignore_global
echo ".DS_Store" >> ~/.gitignore_global
echo ".idea/" >> ~/.gitignore_global
Checking Ignored Files
See What's Ignored
# Check if file is ignored
git check-ignore -v file.txt
# List all ignored files
git status --ignored
# See which rule ignores a file
git check-ignore -v path/to/file
Debug Ignores
git check-ignore -v --no-index path/to/file
Ignoring Already-Tracked Files
.gitignore only affects untracked files. To ignore a file that's already tracked:
# Remove from Git (keep file locally)
git rm --cached filename
# Then add to .gitignore
echo "filename" >> .gitignore
# Commit the changes
git commit -m "Remove and ignore filename"
For Directory
git rm -r --cached directory/
echo "directory/" >> .gitignore
git commit -m "Remove and ignore directory"
Templates
GitHub Templates
GitHub provides templates: github.com/github/gitignore
# Download for your project type
curl -o .gitignore https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
gitignore.io
Generate custom .gitignore: gitignore.io
# Via command line
curl -sL https://www.toptal.com/developers/gitignore/api/node,react,macos > .gitignore
Best Practices
1. Start Early
Add .gitignore before first commit.
2. Be Specific
# Good: specific
node_modules/
.env
# Bad: too broad
*
3. Use Comments
# Dependencies
node_modules/
# Build outputs
dist/
build/
# Environment variables - NEVER commit these
.env
.env.local
4. Don't Ignore Important Files
Don't ignore:
- Source code
- Configuration templates
- Documentation
- Lock files (usually)
5. Keep It Updated
Add new patterns as project evolves.
Summary
.gitignoreprevents tracking unwanted files- Use patterns:
*,**,?,[abc] - Trailing
/means directory only - Leading
/anchors to root - Use
!for negation - Multiple
.gitignorefiles work together - Use global ignores for personal IDE/OS files
- Use templates from GitHub or gitignore.io
- Remember:
.gitignoreonly affects untracked files
In the next lesson, we'll learn about branch naming conventions.

