Lesson 3 of 7 in Branching & Merging

Merge commits

Story: Two timelines that both moved on can't just be lined up. Juno will show you how to join them.

A fast-forward only works while your branch hasn't moved since the other one split off. Often both have: you committed on main while contact was still in progress. The branches have diverged: each has commits the other doesn't.

A merge commit joins two branches

git merge contact can't fast-forward then. Instead, git makes a merge commit: a new commit on the branch you're on, with two parents, your branch's commit and the other branch's. Its files combine the changes made on both sides since they split.

$ git merge contact
Merge made by the 'ort' strategy.
 contact.html | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 contact.html

ort is the name of the method git uses to combine the changes; you can ignore it. Below it, git sums up what the merge brought into your files.

A merge commit gets a ready-made message, Merge branch 'contact'. On your own computer, git first opens your text editor with that message, so you can change it; saving it as it is is fine.

Only the branch you're on moves. contact still points at its own commit, which is now in main's history too, so git branch -d contact can delete it.

When both branches changed the same lines of the same file, git can't combine them by itself. That's a merge conflict, and it's the next Lesson. In this one, the branches always change different files.

Reading a merge in the history

git log --oneline --graph draws the two lines of history and where they join:

*   1c0c498 (HEAD -> main) Merge branch 'contact'
|\
| * 5b2a470 (contact) Add a contact page
* | a6b0f1b Make the heading purple
|/
* a4b8d97 Style the heading
* ab89288 Add the home page
* 37d7cf7 Add a README

A merge commit on purpose: --no-ff

When a merge can fast-forward, git merge does, and afterwards nothing in the history shows that those commits were ever on a branch of their own. git merge --no-ff <branch> ("no fast-forward") makes a merge commit anyway. Many teams merge finished work this way: the work's commits stay grouped behind one merge commit, which is easy to find later.

When the branches have diverged, --no-ff changes nothing: git makes a merge commit either way.

Command What it does
git merge <branch> Fast-forwards when it can. When the branches have diverged, makes a merge commit that joins them.
git merge --no-ff <branch> Always makes a merge commit, even when git could fast-forward.

New commands

  • git merge --no-ff

Explainer: A merge commit joins two lines of history

project: your repo, you are here37d7cf7 Add a README37d7cf7ab89288 Add the home pageab89288a4b8d97 Style the headinga4b8d975b2a470 Add a contact page5b2a470a6b0f1b Make the heading purplea6b0f1b1c0c498 Merge branch 'contact'1c0c4980d0f228 Add a footer0d0f2288018408 Merge branch 'footer'8018408HEAD → maincontactfooter
The repository at the end of the Explainer.
Graph as text

project: your repo, you are here

  • HEAD → main at 8018408 "Merge branch 'footer'"

Branches and tags

  • contact at 5b2a470 "Add a contact page"
  • footer at 0d0f228 "Add a footer"
  • main at 8018408 "Merge branch 'footer'"

Commits, newest first

  1. 8018408 "Merge branch 'footer'"; parents 1c0c498 and 0d0f228; refs: HEAD → main
  2. 0d0f228 "Add a footer"; parent 1c0c498; refs: footer
  3. 1c0c498 "Merge branch 'contact'"; parents a6b0f1b and 5b2a470
  4. a6b0f1b "Make the heading purple"; parent a4b8d97
  5. 5b2a470 "Add a contact page"; parent a4b8d97; refs: contact
  6. a4b8d97 "Style the heading"; parent ab89288
  7. ab89288 "Add the home page"; parent 37d7cf7
  8. 37d7cf7 "Add a README"; no parent

Challenge 1 of 3

Story: Both timelines moved on while you were away, Agent. Join them.

Since contact-page was made, both it and main have a new commit: a contact page on contact-page, and a purple heading on main. Merge contact-page into main, so main has both. You're on main.

Unlocks after Basics.

Terminal

Unlocks after Basics.

This Lesson can be played once Basics is complete. Its text and Explainer are open to everyone.