Introduction to Rebasing
Rebasing is the second way to integrate changes from one branch into another (merging is the first). Instead of joining two histories with a merge commit, rebasing moves your branch’s commits on top of another branch, producing a linear, straight-line history. It is one of the most powerful — and most polarising — features in Git.
The setup
Before rebase
A───B───C───F ◀── main (HEAD)
\
D───E ◀── feature-xAfter rebase
git switch feature-x git rebase main
The picture after
A───B───C───F───D'───E' ◀── feature-x D and E were replayed onto F as new commits D' and E'.
feature-x’s commits have been rewritten to sit on top of main’s current tip. Same content, new commits (different hashes, different parent). The branch now appears as if you had branched off F to begin with.
Why rebase?
Linear history. No merge commits, no diamond shapes.
git logreads like a straight timeline.Cleaner code review. Reviewers see your commits applied on the latest
main, not mingled with merge noise.Easier bisecting. A linear history makes
git bisect(binary search for bugs) more accurate.Updating a long-lived branch. Keep your feature branch in sync with
mainwithout a merge commit cluttering it.
The classic rebase workflow
Keep feature-x up to date with main
# 1. Get the latest main git switch main git pull # 2. Move your feature commits on top of main git switch feature-x git rebase main # 3. (If conflicts) resolve them, then continue git rebase --continue # 4. Force-push (history was rewritten) git push --force-with-lease
The trade-off
Merging preserves what literally happened. The history is a true graph showing parallel work.
Rebasing rewrites history to be neat. The graph becomes a straight line, at the cost of pretending the work was always sequential.
Neither is wrong. Pick what fits your team’s values.
The golden rule of rebasing
Variants of rebase
git rebase main— the basic form: move my commits onto main.git rebase -i main— interactive: pick, reword, squash, drop commits as you go.git rebase --onto target source— surgical: move a specific range of commits onto a different base.git pull --rebase— when pulling, rebase your local commits on top of new remote commits (no merge commit).
Rebase in three sentences
Git records the diff of each of your commits.
Resets your branch to the new base.
Re-applies your diffs one at a time, creating new commits.
What can go wrong
Conflicts. Each replayed commit may conflict — you fix and
git rebase --continue.Lost work via force-push. Rebasing a shared branch and force-pushing can stomp on teammates’ work.
Confusing history. Aggressive rebasing can make commits that never really existed look like reality.
git pull --rebase. It keeps your local branch linear with upstream without merge commits — a small win every single day.