By admin , 29 April 2026

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.