git status finally clicked for me when I stopped thinking of it as comparing files. It compares three trees.
The three trees are:
- Working directory — files you edit
- Index (staging area) — .git/index, the pre-commit manifest
- HEAD — the last commit on your branch
When you run git status, Git roughly does:
- Index vs HEAD → "Changes to be committed"
- Working directory vs Index → "Changes not staged for commit"
- Files with no Index entry (and not ignored) → "Untracked files"
Try it once and you will remember it:
mkdir status-demo && cd status-demo
git init
echo "# demo" > README.md
git status
git add README.md
git status
git commit -m "first commit"
git status
echo "new line" >> README.md
git status
What to watch: before git add, README is untracked. After git add, Git writes a blob into .git/objects and creates .git/index. After commit, index and HEAD match, so status is clean. After you edit again, working directory and index differ, so it shows modified.
Why is it so fast on huge repos? Git caches file stats (mtime, size, inode) in the index and skips re-hashing unchanged files. Only changed stats trigger a real hash check.
Common confusion:
- M in first column of git status -s = staged. M in second column = unstaged. MM = both.
- git status is read-only. It does not fix anything.
- For scripts, use git status --porcelain, not the human output.
Source: Pro Git — Recording Changes: https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository
Top comments (0)