Tutorial
Git rebase without fear: a practical guide
Rebase gives you a clean, readable history. Learn the three situations where you will use it, and the one rule that keeps you safe.
Rebase has a scary reputation, mostly because people first meet it while fixing a mess. Used deliberately, it is just a way to replay your commits on top of a newer base. This guide covers the three jobs you will actually use it for.
What rebase does
Say you branched from main last week, and main has moved on since. A merge ties the two histories together with an extra merge commit. A rebase lifts your commits and replays them one by one on top of the latest main, as if you had started today.
Your changes are the same. The history is a straight line.
Job 1: bring your branch up to date
git switch my-feature
git fetch origin
git rebase origin/mainIf a commit conflicts, Git pauses and tells you which file. Fix the file, then continue:
git add path/to/file
git rebase --continueIf it turns into a tangle, you can always back out and return to where you started:
git rebase --abortJob 2: tidy your commits before review
Interactive rebase lets you clean up work-in-progress commits. To edit your last four commits:
git rebase -i HEAD~4Git opens a list. Change the word at the start of each line to say what you want:
| Command | What it does |
|---|---|
pick | Keep the commit as it is |
reword | Keep the changes, edit the message |
squash | Merge into the previous commit and combine messages |
fixup | Merge into the previous commit and discard the message |
drop | Remove the commit entirely |
A typical cleanup turns "WIP", "fix typo" and "actually fix it" into one commit with a proper message.
Job 3: publish the rewritten branch
Rebasing changes commit hashes, so Git will refuse a normal push. Use the safer force option:
git push --force-with-leaseUnlike --force, this fails if someone else pushed to the branch since you last fetched, so you cannot overwrite their work by accident.
Your safety net
Even a bad rebase is recoverable. Git remembers where your branch pointed before, and git reflog lists it:
git reflog
git reset --hard HEAD@{5}Find the entry from before the rebase, and reset to it. Nothing is lost until Git garbage-collects it, which takes weeks.
A simple habit
Rebase onto main before you open a pull request, squash the noise, and push with --force-with-lease. Reviewers will read a clean story, and you will stop dreading the command.