Advanced

Cleaning up the mess before you share it

Interactive rebase earned its scary reputation in one afternoon when I squashed six messy commits into a story anyone could read. History rewriting, done right, feels like editing.

What you will see

56a5371 topic-commit 27a38f7 main-commit 43fcdc7 initial

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

Replay my branch's commits on top of the latest main so history stays a straight line. I watched the branch move and the commits come back with new hashes, no merge commit in sight.

1

Make a base commit on main, then a topic branch with a commit. Then main drifts away with its own commit, so the two branches have separate lines of history.

printf 'v1\n' > app.py git add app.py git commit -m initial git checkout -b topic printf 'topic work\n' > topic.txt git add topic.txt git commit -m topic-commit git checkout main printf 'main work\n' > main.txt git add main.txt git commit -m main-commit git log --oneline --all

Before you run it, say out loud what it will print. Then open the answer.

What it prints
27a38f7 main-commit 36782ec topic-commit 43fcdc7 initial
`--all` shows both branches together. At this point topic and main each hold their own commit above the shared `initial`.
2

Switch to the topic branch and rebase it onto main. Git replays topic's commit on top of main's latest commit, rewriting history into a straight line.

git checkout topic git rebase main

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Successfully rebased and updated refs/heads/topic.
git may show a `Rebasing (1/1)` line before the success message. Each replayed commit gets a new hash, which is exactly why rebasing is only safe on work nobody else has pulled.
3

Confirm the history is now a single clean line with no merge commit. The topic commit now sits directly on top of the main commit.

git log --oneline

Before you run it, say out loud what it will print. Then open the answer.

What it prints
56a5371 topic-commit 27a38f7 main-commit 43fcdc7 initial
Compare this to a merge, which would add an extra merge commit joining the two lines. Rebase keeps things linear by rewriting hashes instead.

Data Flow

Rebase replays your commits onto a new base, giving them new hashes and a cleaner shape.
1 Pick the base commit to replay onto
↓
2 List each commit in order
↓
3 Replay them one at a time
↓
4 Update the branch pointer
↓
5 History becomes linear and clean
Why this works
The interactive todo list

Those words in the editor do real work:

CommandDoes
pickKeep the commit as it is
squashFold it into the one above
rewordChange its message
dropRemove it entirely

Edit the list, save, and git replays the commits in the new arrangement. This is editing your history the same way you would edit a document.

When you have a choice

Rebase vs merge

Both join branches, but they leave different fingerprints:

ActionResult
mergeNew merge commit, preserves every old commit
rebaseLinear history, no merge commit

Rebase rewrites the commits it touches. That makes history cleaner but means a rebased commit on your machine no longer matches the one on anyone else's. The rule of thumb: rebase only your own unshared work.

Examples

Rewrite the last few commits

git rebase -i HEAD~3

-i opens your editor with a list of the last three commits, oldest first. Next to each is the word pick. Change that word to reword, squash, or drop, save, and git plays the commits back in the new order you asked for.

Turn a pile into one commit

pick a1 fix login
squash b2 wip
squash c3 fix again

squash folds later commits into the first, giving you one clean commit instead of three. I use it before every push, because a tidy history is what makes it easy for others to follow your work later.

Stay current without merge noise

git rebase main

This replays your branch's commits on top of the latest main. The result is a straight line with no extra merge commit. My branches always look tidy afterward, though rebase does rewrite each commit's hash, which is exactly why you should never rebase work others have already pulled.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Stealing a single commit
Previous Lesson
Stealing a single commit
Next Lesson
Framing the moment you are proud of
Framing the moment you are proud of →