Rebasing
git rebase replays your commits on top of another branch for a linear history.
git rebase <base-branch>Rebasing moves your commits so they start from the tip of another branch, producing a straight, linear history instead of a merge commit.
Merge vs rebase
- Merge preserves exactly what happened, adding a merge commit.
- Rebase rewrites your commits onto a new base for a cleaner line.
The golden rule
Never rebase commits that others have already pulled. Rebasing rewrites history, and shared history should not change.
Interactive rebase
git rebase -i lets you reorder, squash, edit, or drop commits before sharing them.
Example
# Replay your feature commits on the latest main
git switch feature/search-bar
git rebase main
# Tidy the last 3 commits before pushing
git rebase -i HEAD~3When to use it
- A developer rebases their feature branch onto main before opening a pull request so the diff is clean and reviewers see no merge commits.
- A team squashes eight 'WIP' commits into two meaningful commits using interactive rebase before pushing to a shared branch.
- A developer rebases to pull in a critical security fix from main without creating a merge commit in the feature branch history.
More examples
Rebase feature branch onto main
Replays the feature branch's commits on top of the latest main, producing a linear history with no merge commit.
git switch feature/payments
git fetch origin
git rebase origin/main
# Successfully rebased and updated refs/heads/feature/paymentsInteractive rebase to squash commits
Interactive rebase lets you combine noisy work-in-progress commits into a single, well-described commit before the code is reviewed.
# Squash last 4 commits interactively
git rebase -i HEAD~4
# In the editor that opens, change:
# pick a1b2c3d Add login skeleton
# squash 4e5f6a7 WIP
# squash 8b9c0d1 more WIP
# squash 2e3f4a5 Fix typoResolve a conflict during rebase
When a replayed commit conflicts with a commit on main, you resolve the file, stage it, and continue replaying the remaining commits.
git rebase origin/main
# CONFLICT in src/api.js
# Edit the conflict, then:
git add src/api.js
git rebase --continue
# Or bail out entirely
# git rebase --abort
Discussion