Merge Types
Merge Types: Fast-Forward, Recursive, and Octopus
After this page you can name the three merge shapes Git actually writes.
Fast-forward
main is an ancestor of feat/ping-json. Merging can just slide main forward. No new commit.
A ← B ← C main
← D ← E feat/ping-json
# after git switch main && git merge feat/ping-json
A ← B ← C ← D ← E main, feat/ping-json
git switch main
git merge feat/ping-jsongit log shows a straight line. git merge --no-ff forces a merge commit even when a fast-forward is possible (Git Flow likes that; trunk-based usually does not).
Recursive (two parents)
The branches diverged. Git writes a merge commit with two parents.
A ← B ← C ← M main
↑ ↑
D ← E feat/ping-json
The default strategy for two heads is ort (the current “recursive” replacement). You rarely pass -s. Git finds a merge base (common ancestor), diffs both sides against it, and applies both diffs to the base.
git switch main
git merge feat/ping-json -m "merge feat/ping-json"
git log --oneline --graph --decorateOctopus (three or more parents)
git merge topic-a topic-b topic-cOne merge commit with several parents. Git only does this when there are no overlapping conflicts. If two topics touch the same hunk, octopus refuses; merge them pairwise instead. You will almost never need octopus on desk-api. Know the name so git log --graph with a commit that has three parents is not a mystery.
A ← B ← C ← M main M has three parents
↑ ↑ ↑
D E F three topic tips
See the parents
git cat-file -p HEAD
git rev-parse HEAD^1 HEAD^2HEAD^1 is the first parent (the branch you had checked out). HEAD^2 is what you merged in.
Abort
git merge --abortReturns the three trees to the pre-merge state while a merge is in progress (MERGE_HEAD exists). After the merge commit exists, abort is too late; git reset (chapter 7) or git revert -m 1 (chapter 10).