TIL: git diff anywhere
Many are familiar with the output of
git diff when reviewing changes before a
commit or when browsing through a repo’s history. What fewer people know is that
this same tool can compare regular files outside of any git repo. And it’s very
convenient compared to the default
Consider the following alias:
alias diff='git --no-pager diff --color=auto --no-ext-diff --no-index'
Here’s the rundown on the command:
git --no-pager diff: execute
git diffbut don’t pipe output into a pager
--color=auto: colorize output if possible
--no-ext-diff: compute differences using
gititself, not by an external diff driver
--no-index: never try to treat the files as part of a git repo, regardless of whether an index exists
Whether to use
-p (pipe through pager) or
--no-pager (never pipe through
pager) is really up to you, I prefer the unpaged output.
Also note that
git diff will work recursively if the parameters are
directories instead of files. Which is a sensible default, no more
But wait, there’s more!
-w (or its longer spelling
--ignore-all-space) ignores all
differences in whitespaces. Notice how the line “Hello” is not displayed as
changed in the screenshot above. This is particularly useful when enclosing code
into a new block (e.g. when wrapping code in an if statement) or when switching
from tabs to spaces. Some IDEs do this automatically and make it hard to review
changes before committing.
-w to the rescue!
--word-diff aggregates changes in juxtaposed words and displays the
difference in a compact manner. It even works across multiple lines or when the
whole paragraph has been reflowed.
That’s an invaluable help when diff’ing markdown documents, where changing parts of a sentence and reflowing at the 80 character mark would otherwise show every single line in a paragraph as changed.
Talking about beautiful diffs, git 2.9 comes with a new heuristic:
It tries to keep hunk boundaries at blank lines, shifting the hunk “up” whenever the bottom of the hunk matches the bottom of the preceding context, until we hit a blank line.
If that sounds awfully complicated, refer to the example below. It’s straight from beautiful diffs on the Github blog.
Enable the new heuristic by passing the delightfully obvious option
--compaction-heuristic. Or, more practically, set
in your git config:
> git config --global diff.compactionHeuristic true