Ignoring What Doesn't Belong
Real clutter, a real secret, and a .gitignore that should have existed from commit one.
Real projects accumulate real noise: a .DS_Store macOS leaves behind, a build/ directory full of generated output, a .env file holding a real API key. None of these belong in history — .gitignore is the real, permanent contract that keeps git from ever offering to track them.\n\nBut .gitignore has one genuinely important limit: it only affects files git does not already know about. A secret committed BEFORE it was added to .gitignore stays tracked regardless — this lesson hits that exact gotcha for real, and fixes it the right way, with git rm --cached.
Real Clutter, Surveyed
git status
A macOS system file, a generated build directory, and a secrets file — all genuinely untracked and cluttering every status check.
One Real File, Four Real Rules
printf '.DS_Store\nbuild/\n.env\nnotes.txt\n' > .gitignore
git status
All four are now genuinely invisible to git status — only .gitignore itself shows up as new.
Debugging Exactly Which Rule Matches
git check-ignore -v .env
Shows the exact file and line number of the rule responsible — genuinely useful the moment a pattern does not behave as expected.
The Real Gotcha: Already-Tracked Files Are Immune
# A secret committed BEFORE being added to .gitignore stays tracked:
git add .gitignore # adding the pattern later does NOT untrack it
git rm --cached db-credentials.txt # this genuinely does
.gitignore only ever governs files git does not yet know about. Untracking an already-committed file requires git rm --cached — it removes the file from tracking while genuinely leaving it on disk.
.gitignore
A real, plain-text file listing patterns for content git should never offer to track. Confirmed directly in this lab: matching files disappear entirely from git status, as if they were not there at all.
git check-ignore -v <file>
Reports exactly which .gitignore line is causing a specific file to be ignored, including the file and line number. Confirmed directly in this lab pinpointing exactly ".gitignore:3:.env" for the .env rule.
git rm --cached <file>
Removes a file from git's tracking (staging it for a "deleted" commit) while genuinely leaving the actual file untouched on disk. Confirmed directly in this lab: db-credentials.txt was gone from git status afterward but still fully present via ls.
🗑️ Survey the Real Clutter
Create genuine clutter and a genuine secret file, and see git status list them all as untracked.
cd ~/recipes && touch .DS_Storecd ~/recipes && mkdir -p buildcd ~/recipes && printf 'compiled output, do not edit\n' > build/output.txtcd ~/recipes && printf 'API_KEY=super-secret-value\n' > .envcd ~/recipes && git statusstudent@lab:~$ cd ~/recipes && touch .DS_Store student@lab:~$ cd ~/recipes && mkdir -p build student@lab:~$ cd ~/recipes && printf 'compiled output, do not edit\n' > build/output.txt student@lab:~$ cd ~/recipes && printf 'API_KEY=super-secret-value\n' > .env student@lab:~$ cd ~/recipes && git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) .DS_Store .env build/ notes.txt nothing added to commit but untracked files present (use "git add" to track)
📝 Write the Real .gitignore
Cover all four with one real .gitignore file, and confirm with git check-ignore exactly which rule matches which file.
cd ~/recipes && printf '.DS_Store\nbuild/\n.env\nnotes.txt\n' > .gitignorecd ~/recipes && git statuscd ~/recipes && git check-ignore -v .envcd ~/recipes && git check-ignore -v notes.txtstudent@lab:~$ cd ~/recipes && printf '.DS_Store\nbuild/\n.env\nnotes.txt\n' > .gitignore student@lab:~$ cd ~/recipes && git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore nothing added to commit but untracked files present (use "git add" to track) student@lab:~$ cd ~/recipes && git check-ignore -v .env .gitignore:3:.env .env student@lab:~$ cd ~/recipes && git check-ignore -v notes.txt .gitignore:4:notes.txt notes.txt
📸 Commit the Real Contract
Commit .gitignore so these rules are genuinely part of the project's history from now on.
cd ~/recipes && git add .gitignorecd ~/recipes && git commit -m 'Add .gitignore for local clutter and secrets'cd ~/recipes && git statusstudent@lab:~$ cd ~/recipes && git add .gitignore student@lab:~$ cd ~/recipes && git commit -m 'Add .gitignore for local clutter and secrets' [master 30c0990] Add .gitignore for local clutter and secrets 1 file changed, 4 insertions(+) create mode 100644 .gitignore student@lab:~$ cd ~/recipes && git status On branch master nothing to commit, working tree clean
🔓 Hit the Real Gotcha, Then Fix It
Commit a secret BEFORE adding it to .gitignore, discover it stays tracked regardless, then genuinely untrack it.
cd ~/recipes && printf 'DB_PASSWORD=hunter2\n' > db-credentials.txtcd ~/recipes && git add db-credentials.txtcd ~/recipes && git commit -m 'Add database credentials'cd ~/recipes && printf 'db-credentials.txt\n' >> .gitignorecd ~/recipes && git rm --cached db-credentials.txtcd ~/recipes && git add .gitignorecd ~/recipes && git commit -m 'Stop tracking db-credentials.txt'cd ~/recipes && ls db-credentials.txtstudent@lab:~$ cd ~/recipes && printf 'DB_PASSWORD=hunter2\n' > db-credentials.txt student@lab:~$ cd ~/recipes && git add db-credentials.txt student@lab:~$ cd ~/recipes && git commit -m 'Add database credentials' [master 3ae27be] Add database credentials 1 file changed, 1 insertion(+) create mode 100644 db-credentials.txt student@lab:~$ cd ~/recipes && printf 'db-credentials.txt\n' >> .gitignore student@lab:~$ cd ~/recipes && git rm --cached db-credentials.txt rm 'db-credentials.txt' student@lab:~$ cd ~/recipes && git add .gitignore student@lab:~$ cd ~/recipes && git commit -m 'Stop tracking db-credentials.txt' [master 8b5899d] Stop tracking db-credentials.txt 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 db-credentials.txt student@lab:~$ cd ~/recipes && ls db-credentials.txt db-credentials.txt
Lab 1.5.2 complete. Real clutter silenced, a real secret caught and genuinely fixed:\n\n\n Clutter surveyed : ✅ four real untracked files\n .gitignore written : ✅ all four now invisible\n Committed as real contract : ✅ team-wide from here on\n Already-tracked gotcha hit : ✅ fixed with git rm --cached\n
Enable JavaScript to run the live terminal and track your progress.