How does .gitignore work and what are its precedence rules?
Learn how .gitignore filters untracked files, why last-match-wins, how negation and directory scope work, and why it never untracks committed files.
Expected Interview Answer
.gitignore is a plain-text file listing glob patterns that tell Git which untracked files and directories to skip when staging and reporting status, so build artifacts and secrets stay out of the repository.
Git evaluates ignore rules from multiple sources in a defined order: command-line, per-directory .gitignore files (deepest directory wins), .git/info/exclude, and the global core.excludesFile. Within a single file, the LAST matching pattern wins, and a leading ! negates an earlier ignore. A critical caveat is that .gitignore only affects untracked files — a file already tracked by Git keeps being tracked until you explicitly run git rm --cached.
- Keeps build output, dependencies, and secrets out of version control
- Reduces noise in git status and diffs
- Shares ignore conventions with the whole team via a committed file
- Supports per-directory and global scopes
- Allows fine-grained re-inclusion with negation patterns
AI Mentor Explanation
Think of a match scorer who is told to record every delivery but ignore the warm-up throws before the over. The .gitignore is that standing instruction sheet: some events never make it into the official scorebook. And just as a player already named on the team sheet stays on it even if you later add an ignore note, a file Git already tracks keeps being tracked until you formally strike it out.
Step-by-Step Explanation
Step 1
Create the file
Add a .gitignore at the repo root (or in any subdirectory) and commit it so the whole team shares the rules.
Step 2
Write patterns
Use globs like node_modules/, *.log, or build/; a trailing slash matches directories, a leading / anchors to that directory.
Step 3
Negate exceptions
Prefix a pattern with ! to re-include something an earlier rule ignored, e.g. *.log then !important.log.
Step 4
Understand precedence
Deeper-directory .gitignore beats shallower; within a file the last matching pattern wins; command-line and .git/info/exclude also participate.
Step 5
Untrack already-tracked files
Ignoring never removes tracked files — run git rm --cached <file> and commit to stop tracking while keeping it on disk.
What Interviewer Expects
- Knows .gitignore only affects untracked files
- Can explain last-match-wins within a file
- Understands directory-level and global scopes
- Knows negation with ! and its limits (can't re-include if parent dir is ignored)
- Mentions git rm --cached for already-tracked files
Common Mistakes
- Assuming adding a rule removes an already-committed file
- Believing the first matching pattern wins instead of the last
- Trying to un-ignore a file whose parent directory is ignored
- Confusing .gitignore with .git/info/exclude scope
- Forgetting a trailing slash to target directories
Best Answer (HR Friendly)
“A .gitignore is a simple list telling Git which files to leave out of the project history, like build outputs or passwords. The catch is it only works on files Git isn't already tracking, and when rules conflict, the most specific or last-listed one takes effect.”
Code Example
# .gitignore contents
node_modules/
*.log
!important.log # negation: keep this one
build/
# Ignoring does NOT untrack an already-committed file:
git rm --cached secrets.env
git commit -m "Stop tracking secrets.env"
# Check why a path is ignored (shows the winning rule):
git check-ignore -v build/output.jsFollow-up Questions
- Why does adding a file to .gitignore not remove it from the repository?
- How do you ignore a file only for yourself without committing the rule?
- Why can't you un-ignore a file inside an ignored directory with a single ! rule?
- What is the difference between .gitignore and .git/info/exclude?
- How does git check-ignore help debug ignore rules?
MCQ Practice
1. Within a single .gitignore file, which pattern takes effect when multiple match the same path?
Git applies the last matching pattern in the file, which is why negation rules must come after the broad ignore they modify.
2. What happens if you add an already-committed file to .gitignore?
.gitignore only affects untracked files; a tracked file must be removed from the index with git rm --cached to stop being tracked.
3. What does a leading ! on a .gitignore pattern do?
A leading ! negates a previous ignore rule, re-including the file — but it cannot re-include files whose parent directory is itself ignored.
Flash Cards
Does .gitignore remove already-tracked files? — No. It only affects untracked files. Use git rm --cached to stop tracking a committed file.
Which pattern wins within one .gitignore file? — The last matching pattern wins, so negations (!) must follow the broad rule they override.
What does a leading ! mean? — It negates a previous ignore rule and re-includes the file — unless its parent directory is already ignored.
Personal, uncommitted ignore rules? — Put them in .git/info/exclude or a global core.excludesFile instead of the shared .gitignore.
How to debug why a path is ignored? — Run git check-ignore -v <path> to see the exact file and line of the winning rule.