Two ways to combine branches: fast-forward and three-way merge
Every branch exists to come back together
The Branching course built one line of history off main and left it there on purpose. add-discount-percentage sits two commits ahead, untouched by main. A branch that never rejoins isn't finished work: it's an experiment nobody acted on. git merge is how it comes home.
Case one: fast-forward
If main hasn't changed at all since the branch split off, joining them is trivial: Git just moves main's pointer forward to match:
Before: a ─▶ b (main)
\
c ─▶ d (feature)
After: a ─▶ b ─▶ c ─▶ d (main, feature)
git switch main
git merge feature
Updating b8e3f1a..7c6b5a4
Fast-forward
app/models/product.rb | 3 +++
1 file changed, 3 insertions(+)
No new commit is created: main becomes a pointer to the same commit feature already points to. This is the exact mechanism git pull used back in the Remotes course whenever your local branch had nothing of its own.
Case two: three-way merge
On any active project, main gains its own commits while the branch is in progress. Then a fast-forward is impossible. The two histories have diverged and both need to be kept:
Before: e (main)
/
a ─▶ b ─▶ c ─▶ d
\
f ─▶ g (feature)
After: e ─────────────┐
/ ▼
a ─▶ b ─▶ c ─▶ d h (main)
\ ▲
f ─▶ g ──────────┘
git switch main
git merge feature
Merge made by the 'ort' strategy.
app/models/product.rb | 3 +++
1 file changed, 3 insertions(+)
Git creates commit h: a merge commit with two parents (e and g), combining both lines of history into one. To work out what changed on each side, Git compares three commits: the common ancestor (d, the last commit both branches share) and the two tips. Hence "three-way".
Confirming which kind just happened
git log --oneline --graph -5
A fast-forward shows a single straight line, no fork. A three-way merge shows the fork explicitly, with a merge commit joining the lines back: visually, the diagrams above.
Forcing a merge commit even when fast-forward is possible
Some teams prefer every feature to leave a visible mark in main's history, even when a fast-forward would technically work:
git merge --no-ff feature
This always creates a merge commit, so "this group of commits was one feature" stays readable as a unit in the log. Some teams standardize on it; Git doesn't require it.
Key takeaways
- A fast-forward merge just moves
main's pointer forward: no new commit, possible only whenmainhas no commits of its own since the branch split off. - A three-way merge creates a merge commit with two parents, combining diverged histories using their common ancestor.
git log --oneline --graphshows you which kind happened: a straight line versus a visible fork rejoined.git merge --no-ffforces a merge commit even when a fast-forward is possible, for teams that want feature boundaries visible in history.
Keep going with lesson 2
When Git can't merge automatically: conflicts
Shows how a conflict happens when both sides change the same lines, and what git status reports.
A free account also gives you the quizzes, your progress and notes, and the discussion.