Learning Objectives
By the end of this lesson you will be able to:
- Describe what
git mergeandgit rebaseeach do to the commit graph - Explain why rebase changes commit IDs and merge does not
- Read a linear history and a merge-shaped history and say which command produced it
- Name the trade-off each one makes, in one sentence
The Situation
You cut test/PAY-4417 from main on Monday. It is now Thursday, main has eleven new commits, and you need them — a dependency was upgraded and your branch will not build without it.
A───B───C test/PAY-4417
/
D───E───F───G───H main
A, B, C are yours. G and H arrived after you branched. Both commands below get G and H into your branch. They produce different repositories.
Option 1: git merge main
git switch test/PAY-4417
git merge main
Git finds the common ancestor (F), takes both sets of changes, combines them, and records the result as a new commit with two parents:
A───B───C───M test/PAY-4417
/ /
D───E───F───G───────H main
M is the merge commit. Its existence is the point: it is a permanent record that two lines of development met here, on this date, resolving these conflicts.
Nothing that already existed was changed. A, B and C still have the IDs they had on Monday. Anyone who pulled your branch earlier still has a valid, consistent copy.
Option 2: git rebase main
git switch test/PAY-4417
git rebase main
Read the name literally: it changes the base of your branch. Git takes the changes introduced by A, B, C, sets your branch aside, moves to the tip of main, and replays them one at a time:
D───E───F───G───H───A'───B'───C' test/PAY-4417
│
main
The history now claims you started from H. There is no merge commit and no fork in the graph — one straight line.
The Detail That Matters: New IDs
Look at the apostrophes. A' is not A.
A commit's ID is a hash of its content and its parent. Replaying A onto a different parent necessarily produces a different hash. A contained the same diff and the same message, but A' is a new object.
A, B and C still exist in the object database for a while, but nothing points at them any more. As far as the branch is concerned they are gone, replaced by copies.
This one fact is the source of everything else in this module:
- It is why rebase gives you a clean line — the old commits are not preserved, only their changes are.
- It is why rebase is dangerous on a shared branch — a colleague's clone still points at
A,BandC, which your branch no longer contains. - It is why a rebased branch needs a force-push, which you will meet in Lesson 2.
Which History Do You Want?
git merge |
git rebase |
|
|---|---|---|
| Graph shape | Branching, with merge commits | One straight line |
| Existing commits | Untouched | Replaced by copies with new IDs |
| Records that a branch existed | Yes, permanently | No |
| Safe on a shared branch | Yes | No |
| Conflicts | Resolved once, in one merge | Possibly once per replayed commit |
| Push afterwards | Normal push | Force-push required |
Neither column is the correct one. Teams pick a convention and stick to it, and most land somewhere in the middle: rebase your own feature branch to keep it current and tidy, merge it into main at the end so the merge point is recorded.
Why a Tester Should Care
Two very concrete reasons.
Reading history. When a regression appears and you are trying to establish when it landed, a linear history reads top to bottom in date order. A history with fifty merge commits from twelve branches does not, and git log without --graph can list commits in an order that looks like nonsense. In Module 6, git bisect also behaves far more predictably on a mostly linear history.
Pulling a rebased branch. If a developer rebases a branch you have already checked out, your next git pull will try to merge the old commits with their new copies and produce a mess of duplicates and conflicts. Recognising "this branch was rebased" means you reset to the remote version instead of merging — and you will do exactly that in Lesson 3.
Pro Tip:
git log --oneline --graph --allis the fastest way to see which convention a repository actually follows. If the picture is a straight line, the team rebases. If it looks like a railway junction, it merges.
Key Takeaways
mergecombines two lines and records the meeting as a commit with two parentsrebasereplays your commits on top of another branch, producing a straight line- Replayed commits get new IDs — they are copies, not the originals
- Merge preserves history exactly; rebase produces a cleaner history by discarding the original commits
- Rebasing is safe on your own unshared branch and dangerous on a shared one
- A linear history is significantly easier to read, bisect and reason about