Part IV: Chapter 4.6

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.

ABCDEmain HEADfeatureInitialSetup DBAuth fixNew UIUI polish
Git starts at 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.

Terminal
$git switch main
$git merge feature
Merge made by the 'ort' strategy.
dashboard.js | 45 ++++++++++++++++
1 file changed, 45 insertions(+)
$# Inspect the merge commit object:
$git cat-file -p HEAD
tree 9a8b7c6d...
parent c3d4e5f6... ← tip of main before merge
parent e5f6g7h8... ← tip of feature
author Badu <badu@git.com> 1777265969 -0700
Merge branch 'feature'
$# The graph in the log:
$git log --oneline --graph
* m1n2o3p Merge branch 'feature'
|\
| * e5f6g7h UI polish
| * d4e5f6g New UI
* | c3d4e5f Auth fix
|/
* a1b2c3d Setup DB