Skip to content

Merge and rebase: two ways to catch up

Merge records what happened; rebase rewrites it to look tidier.

Lesson 3 of 4 · about 3 minutes

What each one does to history

Merge takes the work on two branches and makes a new commit with two parents. The history keeps its shape: you can see that a branch existed and when it came back.

Rebase takes your commits and replays them one at a time on top of another commit, making new commits with new ids. The history comes out as a straight line, as though you had started from the newer base all along.

Neither is better. Merge is honest about what happened and produces a busier graph; rebase produces a graph that is easy to read and is a story rather than a record. Teams reasonably choose either, and mixing them without agreeing is what produces a mess.

The one rule that prevents most pain

Do not rebase commits other people have pulled. Rebasing makes new commits with new ids, so anyone who has the old ones now has a diverged history, and their next pull produces duplicates or a conflict that looks inexplicable.

On your own unpushed branch, rebase freely. Once it is shared, merge instead — or agree with the people sharing it before rewriting anything. `git push --force-with-lease` exists for the case where you must, and is safer than `--force` because it refuses when the remote has moved since you last looked.

Conflicts are a question, not an error

A conflict means both sides changed the same lines and Git will not guess. It marks the file with both versions and stops, waiting for you.

Resolving is three steps: edit the file so it is what you want with no markers left, `git add` it to say it is resolved, and `git rebase --continue` or `git commit`. If the whole thing turns out to be a mistake, `git rebase --abort` or `git merge --abort` puts everything back exactly as it was — those two commands are the reason a conflict is not worth panicking about.

Worked examples

  • Catch up a private branch without a merge commit

    /git fetch && git rebase origin/main/

    Against: On a feature branch nobody else has pulled

    On a shared branch use git merge origin/main instead: rebasing would hand everyone else a diverged history.

  • Undo a rebase that went wrong

    /git rebase --abort/

    Against: Mid-conflict

    Everything returns to how it was before the rebase started. Nothing is lost.

Check yourself

Practice questions written for this lesson — not past exam papers.

Practise every question in this subject

  1. Why should you avoid rebasing commits others have pulled?

  2. What does git merge --abort do mid-conflict?