.gitignore Mastery โ Keep Junk Out of Git
.env commit kar diya? Beta, key rotate karo aur git rm --cached seekho.
Not every file in your project belongs in Git. Some are generated, some are secrets, some are OS junk.
If you commit node_modules/, your repo becomes 200MB+ of code written by others. Clone takes forever.
If you commit .env, your API keys are visible to anyone with repo access. Career-limiting move.
If you commit build/ or dist/, every merge has binary conflicts that cannot be resolved.
.gitignore tells Git: "These files and folders โ do not track them, do not show them in status, do not include them in commits."
The .gitignore file SHOULD be committed โ it is part of the project, shared with the whole team.
# Without .gitignore โ chaos
git status
# Untracked files:
# node_modules/ โ 50,000 files of dependencies
# .env โ SECRET=abc123 (DANGER!)
# dist/ โ generated build output
# .DS_Store โ macOS junk
# debug.log โ temporary file
# app.js โ YOUR ACTUAL CODE
# With .gitignore โ clean
git status
# Untracked files:
# app.js โ only your actual code
# .gitignore โ the ignore rules themselves
.gitignore uses glob patterns โ simple but powerful matching rules.
*.log โ ignore all .log files anywhere in the repo.
node_modules/ โ ignore the entire node_modules directory (trailing / matters!).
build/ or dist/ โ ignore build output directories.
.env โ ignore the .env file (secrets!).
!.important.log โ negation: do NOT ignore this file even though *.log is ignored.
# comment โ lines starting with # are comments.
temp/ โ ignore any directory named temp.
doc/*.txt โ ignore .txt files directly inside doc/ (not subdirectories).
doc/**/*.txt โ ignore .txt files anywhere inside doc/ (including subdirectories).
# Universal .gitignore template
cat > .gitignore << 'EOF'
# Dependencies
node_modules/
vendor/
.pnp/
.pnp.js
# Build output
dist/
build/
out/
.next/
.nuxt/
# Environment secrets
.env
.env.local
.env.*.local
# OS generated files
.DS_Store # macOS
Thumbs.db # Windows
desktop.ini # Windows
# IDE / Editor
.vscode/ # VS Code (debatable)
.idea/ # IntelliJ
*.swp # Vim swap files
# Logs
*.log
npm-debug.log*
# Testing
coverage/
# But keep this specific file
!.env.example
EOFTHE most common .gitignore mistake: adding a file to .gitignore AFTER Git is already tracking it.
.gitignore only affects UNTRACKED files. If Git is already tracking a file, .gitignore is ignored for that file.
This is incredibly confusing for beginners: "I added .env to .gitignore but git status still shows it!"
Fix: git rm --cached <file> โ remove from Git's tracking index WITHOUT deleting the file from your disk.
--cached means "only remove from the index (staging), keep the working directory file."
After git rm --cached, commit the removal, and THEN .gitignore takes effect.
# THE TRAP: file already tracked
echo "SECRET=abc123" > .env
git add .env
git commit -m "oops: committed .env with secrets"
# Now add to .gitignore
echo ".env" >> .gitignore
git status
# .env is STILL showing as modified! .gitignore didn't work!
# WHY? Because Git is already tracking .env
# .gitignore only applies to UNTRACKED files
# THE FIX: untrack without deleting
git rm --cached .env
# removed from index (tracking), but file still on disk
git status
# deleted: .env (from Git's perspective)
# Untracked: .env (now .gitignore takes effect!)
git add .gitignore
git commit -m "fix: untrack .env and add to gitignore"
# Verify
git status # .env no longer appears!
# CRITICAL: rotate the secret key!
# The old commit still has SECRET=abc123
# Anyone with history access can see it
# Go to your provider and generate a NEW key
git rm --cached to untrack. (3) Add to .gitignore and commit. (4) If it is a public repo, the old commit still has the secret โ use git filter-repo to remove from history, or contact GitHub support.Repo-level .gitignore: committed with the project, shared by all team members. Most common.
Global .gitignore: applies to ALL repos on your machine. For personal OS/editor junk.
Set global: git config --global core.excludesfile ~/.gitignore_global
What goes in global: .DS_Store, Thumbs.db, .idea/, *.swp โ personal editor/OS files.
What goes in repo-level: node_modules/, dist/, .env โ project-specific patterns.
What goes in local-only (.git/info/exclude): personal patterns you do not want to commit to the repo.
Priority: local exclude > repo .gitignore > global .gitignore.
# Set up global gitignore (do this ONCE per machine)
git config --global core.excludesfile ~/.gitignore_global
cat > ~/.gitignore_global << 'EOF'
# OS files โ never commit these
.DS_Store
Thumbs.db
desktop.ini
# Editor files โ personal preference
.idea/
*.swp
*.swo
*~
EOF
# Repo-level .gitignore (committed to the repo)
cat > .gitignore << 'EOF'
# Project-specific
node_modules/
dist/
.env
*.log
coverage/
EOF
# Local-only exclude (NOT committed, personal)
cat > .git/info/exclude << 'EOF'
# My personal patterns that teammates don't need
my-debug-notes.txt
experiments/
EOF
# Verify which file is ignoring a pattern
git check-ignore -v .DS_Store
# /Users/sai/.gitignore_global:2:.DS_Store .DS_Store
# Shows: global gitignore, line 2 is the ruleDo not write .gitignore from scratch โ use templates from github.com/github/gitignore.
Node.js project: ignore node_modules, dist, coverage, .env, logs.
Python project: ignore __pycache__, venv, .pyc, dist, .env.
Common mistake: ignoring package-lock.json or yarn.lock โ DO NOT! These ensure consistent installs.
Common mistake: ignoring .env.example โ this SHOULD be committed (it is the template without real secrets).
Common mistake: ignoring .gitignore itself โ it MUST be committed so the team shares the rules.
Use git check-ignore <file> to test if a file would be ignored.
# Node.js .gitignore (production-ready)
cat > .gitignore << 'EOF'
# Dependencies
node_modules/
# Build
dist/
build/
# Environment
.env
.env.local
.env.*.local
# Logs
*.log
npm-debug.log*
# Testing
coverage/
# OS
.DS_Store
# DO NOT ignore these (common mistakes):
# package-lock.json โ needed for reproducible installs
# .env.example โ template, safe to commit
# .gitignore โ must be committed!
EOF
# Verify your .gitignore
git check-ignore -v node_modules/pkg.js
# .gitignore:2:node_modules/ node_modules/pkg.js โ
git check-ignore -v app.js
# (no output = NOT ignored, will be tracked) โ
# Find ignored files
git status --ignored
# Shows both tracked and ignored files
# GitHub's template collection
# https://github.com/github/gitignore
# Copy the template for your language/frameworkLo kar liya โ Key Points:
- โ .gitignore tells Git which files to NEVER track โ secrets, dependencies, build output, OS junk
- โ
Pattern syntax:
*.log(all logs),node_modules/(directory),!.env.example(negation โ do not ignore) - โ THE TRAP: .gitignore only affects UNTRACKED files โ if Git is already tracking a file, adding it to .gitignore does NOTHING
- โ
Fix:
git rm --cached <file>removes from Git tracking without deleting the file from disk - โ Global .gitignore (core.excludesfile) is for personal OS/editor files that apply to all your repos
- โ .gitignore itself MUST be committed โ it is a shared team configuration
- โ Never ignore package-lock.json (needed for reproducible installs) or .env.example (safe template)
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login