04 · Rebase¶
← Overview · Prev: Everyday workflow · Next: Undo and recovery →
Rebase replays your commits on top of a new base, giving a clean, linear history.
Before: main: A - B - C - D After: main: A - B - C - D
\ \
feature: E - F feature: E' - F'
E' and F' contain the same changes as E and F but have new SHAs, because their parent changed.
What git does¶
git fetch origin— download the remote state (working files untouched).- Find your commits: those reachable from
HEADbut not fromorigin/main. - Temporarily reset your branch to
origin/main. - Re-apply each of your commits in order, creating new commits.
- If a replay conflicts, stop and let you resolve it.
The everyday sequence¶
git fetch origin
git rebase origin/main
# conflict? edit files, then:
git add <resolved-files>
git rebase --continue # or: git rebase --skip / git rebase --abort
git push --force-with-lease # required after rebasing an already-pushed branch
git-adm: git-adm rebase (--continue, --abort, --skip, --explain). git-adm push detects a
diverged branch after a rebase and uses --force-with-lease automatically.
Rules of thumb¶
- Never rebase a branch other people have checked out. Rewriting SHAs forces everyone to reconcile. Your own feature branches are fine.
- Use
--force-with-lease, never bare--force: it refuses to overwrite commits you have not seen. - Rebase before you push the first time, or before the PR is reviewed; avoid rewriting history mid-review unless your team is fine with it.
- During conflict resolution,
git addevery resolved file (including things like aversionfile); otherwise the rebase can commit a deletion. - Set
pull.rebase=trueandrebase.autoStash=true(setup).
Rebase vs merge¶
| Merge | Rebase | |
|---|---|---|
| History | Non-linear; merge commits record joins | Linear |
| Original commits | Preserved as-is | Rewritten (new SHAs) |
| Conflict handling | Resolve once | Possibly once per replayed commit |
| Safe on shared branches | Yes | No |
| Best for | Integrating long-lived shared branches | Tidying your own branch before a PR |
Squash your branch into one commit¶
git rebase -i origin/main
# in the editor: keep the first "pick", change the others to "squash" (or "fixup" to discard their messages)
Auto-squash workflow:
git commit --fixup <sha> # mark a commit as a fix for <sha>
git rebase -i --autosquash origin/main
git-adm push offers to squash on the first push when there is more than one commit.
Interactive rebase commands¶
pick keep · reword edit message · edit stop to amend · squash meld into previous (keep message) ·
fixup meld into previous (drop message) · drop delete the commit · reorder lines to reorder commits.
Move a branch onto a different base¶
git rebase --onto <new-base> <old-base> <branch>
Example: feature-b was branched from feature-a, which was squash-merged into main:
git rebase --onto main feature-a feature-b
Undo a rebase¶
git reflog # find the entry from just before the rebase started
git reset --hard <sha> # or: git reset --hard ORIG_HEAD (right after finishing)
git-adm: git-adm undo. More in Undo and recovery.
Reading¶
- https://git-scm.com/book/en/v2/Git-Branching-Rebasing
- https://www.warp.dev/terminus/undo-a-git-rebase
- Video: "Learn Git Rebase in 6 minutes" (YouTube id
f1wnYdLEpgI)