Lesson Completion
Back to course

Comparing Commit Ranges

Intermediate
7 minutes4.7Git

The Hook (The "Byte-Sized" Intro)

Two dots or three? A..B and A...B look similar but mean completely different things — and they behave differently in git log vs git diff. Getting this wrong gives you the wrong answer: you'll think 5 commits changed when 50 actually did. Two minutes learning the difference saves hours of confusion.

📖 What is Comparing Commit Ranges?

Git uses .. and ... operators to define ranges of commits for comparison. Their meaning differs between git log and git diff.

Conceptual Clarity

In git log:

SyntaxMeaning
A..BCommits in B but NOT in A
A...BCommits in A or B but NOT both (symmetric difference)

In git diff:

SyntaxMeaning
A..BDiff between A and B (same as git diff A B)
A...BDiff between the common ancestor of A and B, and B

Visual example:

main: A ─ B ─ C ─ D \ feature: E ─ F git log main..feature → E, F (only on feature) git log feature..main → D (only on main since fork) git log main...feature → D, E, F (on either, not both) git diff main..feature → diff D vs F git diff main...feature → diff C vs F (from fork point)

Real-Life Analogy

  • A..B = "What did you do that I didn't?" (one-sided comparison)
  • A...B = "What did either of us do since we split up?" (symmetric)

Visual Architecture

flowchart TD TWO_DOT["A..B<br/>In B, not in A"] --> LOG1["git log: Commits unique to B"] TWO_DOT --> DIFF1["git diff: Snapshot A vs B"] THREE_DOT["A...B<br/>Symmetric difference"] --> LOG2["git log: Exclusive to either"] THREE_DOT --> DIFF2["git diff: Fork point vs B"] style TWO_DOT fill:#1a1a2e,stroke:#ffd700,color:#ffd700 style THREE_DOT fill:#0f3460,stroke:#53d8fb,color:#53d8fb

Why It Matters

  • PR reviews: main..feature shows exactly what a PR adds.
  • Release notes: v1.0..v2.0 shows all new commits.
  • Code review: main...feature shows changes since the fork point (like GitHub PR diff).
  • Debugging: Compare specific ranges to narrow when a bug was introduced.

Code

bash
# ─── Commits on feature not on main ─── git log main..feature --oneline # E, F # ─── Commits on main not on feature ─── git log feature..main --oneline # D # ─── Symmetric difference ─── git log main...feature --oneline # D, E, F # ─── Diff between two tags ─── git diff v1.0..v2.0 --stat # ─── Diff from fork point (like GitHub PR) ─── git diff main...feature # ─── Count commits in a range ─── git rev-list --count main..feature # 2

Key Takeaways

  • A..B in log = commits in B not in A. In diff = snapshot A vs B.
  • A...B in log = symmetric difference. In diff = fork point vs B.
  • main..feature is what you'd see in a PR — changes unique to the feature.
  • main...feature diff matches GitHub's PR diff (from merge base).

Interview Prep

  • Q: What is the difference between A..B and A...B in git log? A: A..B shows commits reachable from B but not from A (what B has that A doesn't). A...B shows commits reachable from either A or B but not both (symmetric difference — what's exclusive to each).

  • Q: Why does git diff A...B differ from git diff A..B? A: A..B diffs the snapshots at A and B directly. A...B diffs the common ancestor of A and B against B — showing only what B introduced since diverging. The ... form matches what GitHub shows in PRs.

  • Q: How do you count the number of commits a branch is ahead? A: git rev-list --count main..feature counts commits on feature not on main.

Topics Covered

Git HistoryComparison

Tags

#git#ranges#diff#comparison

Last Updated

2026-02-13