The Diff Was Lying About Its Size
I opened a diff expecting one changed file and got a hundred and one. The work was one file, a single blog post. The other hundred were a story the number told about itself.
Here is the scene. Fresh worktree, branch cut from the base, one post written. Then, out of habit, git diff --stat master..HEAD to see what I'd done. Back came 101 files and 2,346 insertions: fonts, a favicon, a stylesheet rewrite, dozens of posts I never touched. For a second it reads like you nuked the repo.
Nothing was wrong with the branch. The comparison was wrong.
The number has two ends
A diff's size feels like a property of your work. It isn't. It's a property of a comparison, and a comparison has two ends. I was staring hard at the end I'd changed and ignoring the one I'd named: master.
The local master ref was weeks behind. It only moves when something updates it, and in a throwaway worktree nothing had. Meanwhile the real base had absorbed everyone else's merges: the fonts, the favicon, the style pass, every post that shipped since my stale master last budged. git diff master..HEAD dutifully showed all of it as additions on my side, because relative to a month-old master, my HEAD really did contain all those commits.
git diff --stat master..HEAD # 101 files, 2,346 insertions
git diff --stat origin/master...HEAD # 1 file
Same branch, same HEAD, two very different numbers. The second one is the truth. The difference is entirely which base you point at.
Name the base that actually moved
Two fixes stack here, and it's worth keeping them separate.
The small one is the dots. For git diff, A..B is the plain tree difference between the two endpoints. A...B uses the merge base of A and B as the left side, which is the "what did this branch add since it forked" view you usually want when looking at a branch. Reach for three dots when you mean "my branch's contribution."
The big one is the ref. Three dots against a stale master still lies, because the merge base with a month-old ref is a month back. The reliable move is to compare against the remote-tracking ref that reflects the base right now: origin/master, the thing you actually branched from, not a local copy of its name that drifts the moment you stop pulling.
The stale ref never warns you
What makes this one sneaky is the silence. A merge conflict shouts. A failing test shouts. A stale ref says nothing. master sits there being a month old, and the only symptom is a number that's quietly wrong in your favor's opposite direction, folding other people's commits into your column with no complaint.
So the shock is the useful signal. When a diff's size doesn't match the work you remember doing, the work is rarely the surprise. Suspect the end of the comparison you didn't think about. Nine times out of ten it's a ref pointing somewhere old.
Before you trust what a diff says you changed, check what it's diffing against.