· 4 min read
How to Separate Real Changes From Formatting
Heshan Fernando
Co-founder & COO
A pull request touches 84 lines. Someone ran the formatter, so 78 of those are reindentation. Six lines actually changed, and finding them means reading all 84.
Reviewers deal with this by skimming, which is precisely the failure mode a review exists to prevent.
Ignore whitespace first, always
The first toggle on any diff should be whitespace handling.
With whitespace ignored, the 84-line diff becomes six lines. Those six are the review. Whatever else the formatter did is provably behaviour-neutral, because formatting only moves characters that the parser discards.
The habit worth building is to look at the whitespace-ignored diff first and the full diff second, rather than the other way round. The first tells you what the change does; the second confirms nothing odd happened in the reformatting.
A large gap between the two counts is itself information: it means a formatter ran, which is worth knowing and is usually better as a separate commit.
| View | Shows | Use for |
|---|---|---|
| Full diff | Everything | Confirming the formatting run |
| Whitespace ignored | Behavioural changes | The actual review |
| Word-level | Changed tokens in a line | Single-line edits |
Word-level diffs for single-line changes
A line diff marks a whole line as changed even if one character differs. On a 140-character line with a changed variable name, that means finding the difference by eye across two nearly identical lines.
A word-level or character-level diff highlights only what changed within the line. For configuration files, long function signatures and prose in code comments, it turns a hunting exercise into a glance.
It is less useful on lines that were rewritten entirely, where a line-level view is clearer. Most diff tools offer both, and knowing which to reach for is the skill.
Formatting belongs in its own commit
The underlying fix for all of this is process rather than tooling.
A commit that reformats a file and changes its behaviour is a commit nobody can review properly. Splitting them costs nothing:
Commit one — formatting only, with a message saying so. Reviewable by confirming the diff is whitespace-only.
Commit two — the behavioural change, now a small readable diff.
Repositories that enforce formatting in CI rarely have this problem, because files are always formatted and a formatting commit never happens. Repositories that do not accumulate a reformat every time someone with different editor settings touches a file.
Diff the right unit
What you compare matters as much as how.
Two versions of a file is the common case and the least informative when a change spans several files.
A commit shows one logical change if the commits are well-made, and a mixture if they are not. This is the argument for small commits — they are the unit review actually happens at.
A whole branch against its base shows the net effect and hides the sequence, which is right for understanding what will land and wrong for understanding how it was reached.
When a diff is hard to read, the problem is frequently that the wrong unit is being compared rather than that the tool is inadequate. A 900-line branch diff split into six commits is six readable reviews.
Common mistakes to avoid
- Reviewing the full diff when the whitespace-ignored view is the review.
- Mixing formatting and behavioural changes in one commit.
- Using a line-level diff for a single-character change on a long line.
- Assuming a large diff means a large change.
- Pasting proprietary code into a hosted diff service when a browser-based one keeps it local.
How to do it with Code Snippet Version Diff
The Code Snippet Version Diff diffs in the browser with both toggles.
- Paste both versions.
- Turn whitespace off first — that view is the actual change.
- Switch to word-level for lines where one token differs.
- If the two counts differ a lot, a formatter ran and the change should have been two commits.
Other developer tools are in the tools directory.
Frequently asked questions
Why ignore whitespace?
Because a formatting pass touches every line and buries the behavioural changes. Formatting cannot alter behaviour, so the whitespace-ignored diff is the part worth reviewing.
What is a word-level diff?
One that highlights the changed characters within a line rather than marking the whole line. On a long line with one changed token it is the difference between seeing the change and searching for it.
Is my code uploaded?
No. Diffing runs in the browser, which matters when comparing proprietary code or anything containing configuration.
Final thought
Look at the whitespace-ignored view first. Six lines is a review; eighty-four is a skim, and a skim is how changes get through.