Theory
Theory: A Branch is a Name; a Merge is a Node with Two Parents
Creating a branch does not copy files. It writes a ref. Merging either slides that ref (fast-forward) or writes a commit with two parents (a join).
Invariants
git switch -c feat= writerefs/heads/featat currentHEAD, pointHEADat it.- Fast-forward is legal iff the current tip is an ancestor of the other tip.
- A three-way merge diffs base→ours and base→theirs and applies both to the base. The merge base is the unique best common ancestor (usually).
- Conflict markers are unmerged index stages (1 base, 2 ours, 3 theirs) spilled into the working tree.
- During a merge,
--oursisHEAD. During a rebase,--oursis the upstream. That swap is the theory, not a bug.
fast-forward three-way merge
A ← B ← C main A ← B ← C ← M main
← D ← E ↑ ↑
D ← E
Why merge commits exist
They record that two lines of work met, and they keep both sides’ hashes stable. Rebase prefers a straight first-parent chain and pays with new hashes. Neither changes the fact that Git stores snapshots.
What can break
- Merging with uncommitted work that overlaps the incoming tree.
- Resolving markers but forgetting
git add(merge stays open). git merge --abortafter the merge commit exists (too late).
How to read this chapter
Create/switch, merge types, three-way, conflicts, fast-forward, lab; then mergetool, ours/theirs, orphan, comparing branches, rerere.