What you already know
Retrieval · lessons 04 and 05Two from memory. Both are load-bearing for the decision at the end.
What makes a merge commit different from every other commit?
A rebase replays three commits. How many of the three get new hashes?
One branch, three histories
Claim + proof · three clonesHere is a branch of the shape an agent actually produces: three commits, one of which is a fixup for a typo it made two commits earlier. Meanwhile main moved on.
$ git log --graph --oneline --decorate --all * 27553c3 (HEAD -> main) Note the log level | * a8648d0 (feature) Add jitter | * 480c76f Fix a typo in the backoff constant | * 232f0b8 Add exponential backoff |/ * 82636c0 Add a timeout * d1ae31c Add the API client
“Fix a typo in the backoff constant” is the commit nobody wants in main forever. It is also the whole argument for squashing.
Three identical copies of that repository, and each one lands the branch a different way. GitHub calls them merge commit, squash and merge, and rebase and merge (GitHub docs); each maps onto a plain git command you already know.
Merge commit — git merge --no-ff feature.
$ git log --graph --oneline --decorate --all
* ebce595 (HEAD -> main) Merge branch 'feature'
|\
| * a8648d0 (feature) Add jitter
| * 480c76f Fix a typo in the backoff constant
| * 232f0b8 Add exponential backoff
* | 27553c3 Note the log level
|/
* 82636c0 Add a timeout
* d1ae31c Add the API clientEvery original commit survives, with its own hash, and a new commit records that the two lines joined. The fixup is in main forever.
Squash — git merge --squash feature, then one commit.
$ git log --graph --oneline --decorate --all * daefc52 (HEAD -> main) Add exponential backoff and jitter (#42) * 27553c3 Note the log level | * a8648d0 (feature) Add jitter | * 480c76f Fix a typo in the backoff constant | * 232f0b8 Add exponential backoff |/ * 82636c0 Add a timeout * d1ae31c Add the API client
One new commit on main, with no link to the branch at all. The three originals are still sitting on feature, untouched and unreferenced by main.
Rebase-merge — git rebase main on the branch, then a fast-forward.
$ git log --graph --oneline --decorate --all
* 3e51c0b (HEAD -> main, feature) Add jitter
* 8a9a98d Fix a typo in the backoff constant
* 3ea4a0e Add exponential backoff
* 27553c3 Note the log level
* 82636c0 Add a timeout
* d1ae31c Add the API clientPerfectly linear, and every commit preserved — but every one of them rewritten. 3ea4a0e is a new object; the original 232f0b8 is abandoned.
All three produce byte-identical files. Checked out, the three repositories above are indistinguishable. What differs is only the history — and history is not decoration, it is the thing you read when something breaks at 2am.
git log --graph --oneline --decorate on a project you did not write tells you which method it uses within seconds: diamonds mean merge commits, a flat line with “(#123)” suffixes means squash, a flat line with ordinary messages means rebase-merge.
What each one costs
You have read the first 2 steps in full — a claim and the verification that settles it. The rest of this lesson, and the 9 lessons after it, open when subscriptions do. Nothing that is free today will be taken away then.