Chapter 1.5โ˜• 12 min read

.gitignore Mastery โ€” Keep Junk Out of Git

.env commit kar diya? Beta, key rotate karo aur git rm --cached seekho.

01Why .gitignore โ€” Keep Junk Out of Git

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
The most dangerous .gitignore mistake: NOT ignoring .env files. If you push API keys, database passwords, or JWT secrets to GitHub, bots will find them within MINUTES. These bots scan every public push 24/7. Once a secret is in Git history, it is there forever โ€” even if you delete the file. You MUST rotate the key immediately.
02Pattern Syntax โ€” Glob Patterns Explained

.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
EOF
03The Trap โ€” Already Tracked Files & git rm --cached

THE 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
๐Ÿ’ก If you accidentally commit a secret: (1) Rotate the key IMMEDIATELY โ€” invalidate it on the provider side. (2) 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.
04Global vs Repo-level vs Local .gitignore

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 rule
05Best Practices & Common Mistakes

Do 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/framework

Lo 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)
Course Search
Search across all chapters & stages
๐Ÿ“–

Search the course

Type any topic โ€” branching, stash, rebase, hooks โ€” and jump straight to that chapter.

merge branchesgit stashundo commitrebase