git merge (three-way)
When histories diverge.
When both branches have commits the other doesn't have, a fast-forward is impossible. Git must find where the histories split, compare what each branch changed since then, combine those changes, and record the result in a brand-new merge commit — a commit with two parents.
Step Through the Merge
Press the button repeatedly to walk through each phase Git executes internally.
main (commit C) and feature (commit E). They have diverged — neither is an ancestor of the other.Step 1: Common Ancestor
Git uses a graph search (the "Lowest Common Ancestor" algorithm) to find the most recent commit reachable from both branch tips. This is the merge base — the snapshot that both branches started diverging from.
Everything that happened before this commit is shared history. Only the commits after it are unique to each branch.
Step 2: Two Diffs
Git computes two diffs — base → main and base → feature. These tell it exactly what each branch changed independently.
If a line was changed on one branch only, Git takes that change automatically. If the same line was changed on both branches differently, that is a merge conflict and Git asks you to resolve it.
Step 3: The Merge Commit
Git records the combined result as a new commit object. Unlike every other commit, this one has two parent hashes in its object data — one pointing back to the tip of main, one to the tip of feature.
This is why git log --graph draws a fork and a rejoin at merge commits — the graph structure is literally in the parent pointers.
Anatomy of a Merge Commit
A merge commit looks like any other commit object except for the second parent line. That extra pointer is everything.