Overview
Rebase replays commits onto a new base and rewrites their SHAs, so use it only on commits that have not been pushed to a shared branch. Command lookup is in git-commands; when to prefer merge is in git.
Interactive todo commands
git rebase -i <base> opens a todo list; change the leading verb.
| Command | Short | Effect |
|---|---|---|
pick | p | Keep the commit. |
reword | r | Keep it; edit the message. |
edit | e | Stop to amend or split the commit. |
squash | s | Meld into the previous commit; combine messages. |
fixup | f | Meld into the previous commit; keep only its message. |
drop | d | Delete the commit. |
exec | x | Run a shell command (for example the tests) after the previous commit. |
break | b | Pause; continue with git rebase --continue. |
label, reset, merge, update-ref | l, t, m, u | Rebuild merge topology (--rebase-merges) and move stacked branch refs. |
Rebase —onto
git rebase --onto <newbase> <upstream> [<branch>] replays the commits in upstream..branch onto newbase.
| Goal | Command |
|---|---|
| Move a branch to a new base | git rebase --onto <newbase> <oldbase> <branch> |
Move feature-b off a merged feature-a onto main | git rebase --onto main feature-a feature-b |
| Keep only the newest K commits of a branch | git rebase --onto main <branch>~K <branch> |
| Drop one commit from the history | git rebase --onto <bad>~ <bad> |
| Move one commit to another branch | git cherry-pick <sha> |
Conflicts
Resolve a conflict, stage it, then continue; abort when unsure.
| Step | Command |
|---|---|
| See conflicted files | git status |
| Resolve, then stage | git add <file> |
| Apply the next commit | git rebase --continue |
| Restore the pre-rebase state | git rebase --abort |
| Resolve with a merge tool | git mergetool |
| Drop the current commit (only if it is now empty) | git rebase --skip |
During a rebase, ours is the branch you rebase onto and theirs is your commit being replayed; see git-merge-strategies.
Autosquash and safety flags
Mark fixes with --fixup at commit time and let autosquash fold them in.
git commit --fixup=<sha> # creates "fixup! <subject>"
git rebase -i --autosquash main # reorders and marks it fixup
git config --global rebase.autoSquash true # make --autosquash the default
git config --global rebase.updateRefs true # keep stacked branches in sync| Flag | Effect |
|---|---|
--force-with-lease (on git push) | Publish a rebased branch only if the remote has not moved. |
--autostash | Stash and reapply a dirty working tree around the rebase. |
--update-refs | Move other branches that point at rebased commits. |
--rebase-merges | Keep merge commits instead of flattening them. |
Gotchas
Avoid these; each forces teammates to recover or loses a commit.
| Gotcha | Fix |
|---|---|
| Rebasing a shared branch forces every collaborator to recover. | Rebase only local or single-owner branches. |
| A dirty working tree aborts the rebase. | Commit, stash, or pass --autostash. |
| Interactive rebase flattens merge commits. | Pass --rebase-merges. |
--skip discards a commit, not just its conflict. | Use it only when the base already contains the change. |
| After a force-push, teammates have a diverged branch. | They run git fetch then git reset --hard origin/<branch>. |