git rebase
Intermediate Git CLI Dangerous
Summary: git rebase <base> takes the commits your branch added and applies them again on top of <base>, producing new commits with new hashes and a straight history.
Dangerous — rebasing rewrites commits. It is routine on a branch only you have, and disruptive on any branch someone else has checked out, because their copies no longer match (lesson 2.7).
What it does
Finds the commits on your branch that are not on <base>, sets your branch to <base>, and re-applies each of those commits in order. Each re-application can conflict, and each produces a new commit: same change and message, different parent, therefore a different hash.
Why it exists
To bring a branch up to date without a merge commit, and to tidy a messy branch before review. The result is a history that reads as though the work had started today.
When to use it
- Updating your own unshared branch onto a newer
mainbefore asking for review. - Cleaning up commits before a merge request, with
-i(lesson 18.5). - When your team requires a linear history and the platform asks you to rebase.
When not to use it
- On
main, a release branch, or any branch a colleague has. - After reviewers have started commenting: their comments attach to commits you are about to replace.
- When the rebase conflicts repeatedly: abort and
git mergeinstead.
Syntax
| Form | Meaning |
|---|---|
git rebase <base> |
Replay the current branch's commits onto <base> |
git rebase --continue |
After resolving a conflict, carry on |
git rebase --skip |
Drop the commit being replayed Dangerous |
git rebase --abort |
Undo everything, back to before the rebase |
git rebase -i <base> |
Interactive: reorder, squash, reword, drop |
git rebase --onto <new> <old> <branch> |
Move a branch from one base to another |
Examples
$ git switch docs/12-windows-install-steps
$ git rebase mainSuccessfully rebased and updated refs/heads/docs/12-windows-install-steps.The hash changes, which is the whole point and the whole risk:
$ git log --oneline --graph --all --decorate* 5f181fc (HEAD -> docs/12-windows-install-steps) docs: add Windows steps to installation guide (#12)
* 1a01760 (origin/main, origin/HEAD, main) feat: add Coast Walk trail (#29)
| * 510f1e0 (origin/docs/12-windows-install-steps) docs: add Windows steps to installation guide (#12)
|/
* 8fa922e (tag: v1.2.0) Initial import of trailguideTwo commits with the same message: the new one on top of main, and the original still on the remote. So the next push is refused:
$ git pushhint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.Do not follow that hint after a rebase; replace the remote branch instead:
$ git push --force-with-leaseTo https://gitlab.com/northwind-trails/trailguide.git
+ 510f1e0...5f181fc docs/12-windows-install-steps -> docs/12-windows-install-steps (forced update)A conflict pauses the rebase and names the commit being replayed:
$ git rebase mainAuto-merging docs/faq.md
CONFLICT (content): Merge conflict in docs/faq.md
error: could not apply e755292... docs: reword licence answer (#42)
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".Expected result
Your branch's commits are re-created on the new base with new hashes; the originals remain until nothing references them. The working tree ends on the rebased branch. A pushed branch then needs --force-with-lease.
Common mistakes
git pullafter a rebase, following the push hint. It merges the pre-rebase commits back in. Use--force-with-leaseon your own branch.- Plain
--force. It overwrites even if a colleague pushed since;--force-with-leasechecks first. - Rebasing a shared branch. Everyone else's clone diverges.
--skipto silence a conflict. It deletes the commit.git commitmid-rebase instead ofgit rebase --continue, which leaves a stray commit. Abort and start again.
How to undo or recover
- Mid-rebase:
git rebase --abortrestores everything. - After finishing, if it went wrong:
git reflogshows where the branch was before, thengit reset --hard <hash>returns to it (lesson 12.1). - After force-pushing a bad rebase: the same reflog recovery locally, then another
--force-with-leaseto put the good version back, and a message to the team.
In VS Code
Command Palette → Git: Rebase Branch…. The force push appears on the sync menu once the branch has diverged; check that Git: Use Force Push With Lease is enabled in Settings.
In IntelliJ IDEA
Branches popup → point at a branch → Rebase current onto…, or Git → Rebase… for the full dialog including Interactive. Force push offers --force-with-lease by default.
Related commands
git merge is the safe alternative · git push with --force-with-lease is required afterwards · git reflog recovers from a bad rebase · git pull --rebase applies the same idea when pulling.
Lessons that use this command
Rebasing explained; merge or rebase? · Rebase conflicts · What rewrites history.