.gitignore: Ignoring Files and Keeping Secrets Safe
In this tutorial, you'll learn about .gitignore: ignoring files and keeping secrets safe. We cover key concepts, practical examples, and best practices.
A .gitignore file tells Git which files to ignore using glob patterns, keeping compiled binaries, dependencies, and credentials out of version control.
In this tutorial, you'll learn how to write effective .gitignore files that keep your repositories clean and secure. A well-configured .gitignore prevents compiled binaries, dependencies, IDE configs, and — most importantly — secrets and credentials from ever entering version control. By the end, you'll create comprehensive .gitignore files for any project type.
flowchart TD
A[git add .] --> B{Matches .gitignore?}
B -->|Yes| C[Ignored - not tracked]
B -->|No| D{Already tracked?}
D -->|Yes| E[Staged - tracked]
D -->|No| F[Untracked]
F --> G{Should be ignored?}
G -->|Yes| H[Add to .gitignore]
G -->|No| I[Add normally]
Basic Patterns
# Ignore a specific file
secrets.env
# Ignore a directory
node_modules/
# Ignore by extension
*.log
*.pyc
# Ignore everything in a directory with subdirs
build/**/*
# Negate pattern (don't ignore this)
!build/important.txt
# Ignore files in root only
/secret.txt
Language-Specific Files
# Python
__pycache__/
*.py[cod]
*.egg-info/
dist/
*.egg
# Node.js
node_modules/
npm-debug.log*
.env
dist/
# Java
*.class
*.jar
target/
!.mvn/wrapper/maven-wrapper.jar
Keeping Secrets Out of Git
The most common security incident in Git is accidentally committing secrets. Protect against it:
# Secrets and credentials
.env
.env.local
*.key
*.pem
credentials.json
service-account.json
config/secrets*
# IDE and OS files
.vscode/
.idea/
.DS_Store
Thumbs.db
But what if a secret is already committed? Remove it from history:
# Remove a committed file from index but keep locally
git rm --cached .env
echo ".env" >}} .gitignore
git add .gitignore
git commit -m "Remove .env from tracking"
# Remove a secret from all history (dangerous - rewrites history)
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch .env" \
--prune-empty --tag-name-filter cat -- --all
Expected output after adding to .gitignore:
The file .env will now be ignored.
Global .gitignore
Set up a global ignore for files you never want to commit in any repository:
git config --global core.excludesFile ~/.gitignore_global
Then add your global patterns:
# OS files
.DS_Store
Thumbs.db
Desktop.ini
# Editor files
.vscode/
.idea/
*.swp
*.swo
*~
# Logs
*.log
Testing Your .gitignore Patterns
Test whether a pattern matches before committing:
# Check if a specific file would be ignored
git check-ignore -v node_modules/package.json
Expected output:
.gitignore:3:node_modules/ node_modules/package.json
If no output, the file is not ignored.
.gitignore for Security Tools
When working with security tools, ignore scan outputs and reports:
# Security tool outputs
nmap-output.xml
burp-*
zap-report.html
nessus-*.csv
snyk-report.json
trivy-results.sarif
# Penetration test artifacts
exploits/
wordlists/
payloads/
Tracking Empty Directories
Git doesn't track empty directories. To commit an empty directory, add a .gitkeep file:
mkdir logs
touch logs/.gitkeep
git add logs/
.gitignore for Common Project Types
Python Project
# Bytecode
__pycache__/
*.py[cod]
# Virtual environment
venv/
.venv/
# Build artifacts
dist/
*.egg-info/
# IDE
.vscode/
.idea/
# Environment
.env
.env.local
Node.js Project
# Dependencies
node_modules/
# Build output
dist/
build/
.next/
# Environment
.env
.env.local
.env.production
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
Common Errors
| Error | Cause | Fix |
|---|---|---|
.gitignore ignored |
File already tracked | git rm --cached to untrack |
fatal: previous rebase directory |
.gitignore mishandled |
Use git rebase --abort or clean |
| Pattern not matching | Wrong pattern syntax | Test with git check-ignore |
.env still shows in status |
Already tracked before .gitignore added | git rm --cached .env first |
negate pattern not working |
Order matters | Place negate after the general rule |
| Secret pushed by team member | No pre-commit hook | Add pre-commit secret scanner |
.gitignore in subfolder overrides root |
Nested .gitignore intended behavior | Use !/ to negate from root |
Practice Questions
Challenge
Create a .gitignore for a full-stack JavaScript project with a Python backend. The frontend uses Node.js (ignore node_modules, build output), the backend uses Python (ignore __pycache__, .egg-info), and both share environment variable files. Include patterns for IDE files, OS files, compiled assets, and test coverage reports. Also add a global .gitignore for your machine.
Real-World Task
Audit an existing repository for accidentally committed secrets. Use git log --diff-filter=A --name-only to find files that were added. Check for .env, *.pem, and credentials.json files. If found, use git filter-repo to purge them from history and rotate any leaked credentials. Add a pre-commit hook using a tool like git-secrets or truffleHog to prevent future leaks. This process is standard security practice at DodaTech for all projects including Durga Antivirus Pro.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro