Two-dot versus three-dot
The single most-confused syntax in Git: .. versus ... in git diff and git log. They mean different things in different commands. Get this right and a whole class of confusion vanishes.
For git log
git log main..feature # commits on feature but not on main
git log main...feature # commits on either, but not both
Two-dot is the asymmetric difference; three-dot is the symmetric difference.
For git diff
git diff main..feature # diff between tips
git diff main...feature # diff between merge-base and feature tip
For diff, ... shows what feature added relative to where it diverged from main - the "what this PR will introduce" view. Two-dot shows the cumulative state diff between tips, including changes on main that feature lacks.
The PR review pattern
git diff main...feature/oauth # what oauth adds beyond the merge base
This is what GitHub shows in a PR. Use it locally to review your own change before pushing.
Listing commits in a branch
git log main..feature --oneline
git log feature --not main --oneline
git rev-list main..feature
All three list commits on feature not yet on main.
Showing commits unique to each side
git log --left-right --oneline main...feature
# < sha1 commit only on main
# > sha2 commit only on feature
Stat overview
git diff --stat main..feature
git diff --shortstat main...feature
For large diffs, the stat output is a quick "how big is this?" gauge before reading the full patch.
Diffing specific files
git diff main..feature -- src/checkout.js
git diff main...feature -- 'src/**'
Comparing across remotes
git fetch origin
git diff origin/main...origin/feature
Compare any two refs - branches, tags, remote-tracking refs, even bare SHAs.
Tools for richer comparison
git difftool main...feature # use configured diff tool
git range-diff main..v1 main..v2 # compare patch series
gh pr diff 123 # PR-aware diff via GitHub CLI
Word-level and stat-level views
git diff --word-diff main...feature # highlight word-level changes
git diff --color-words main...feature
git diff --numstat main..feature # machine-readable counts
The mental model
A..B- "from A to B" - in log, commits unique to B; in diff, raw tip-to-tip.A...B- "between A and B" - in log, commits unique to either; in diff, what B contributes since divergence.
Memorise: for diffing PR contents, always use three dots. For listing what is "ahead", two dots. The right syntax saves entire cycles of confusion.