GitInteractive Rebase (-i)

Interactive Rebase (-i)

Interactive rebase is the “edit your history” feature. With git rebase -i you get a list of commits in an editor and can reorder them, rewrite messages, combine several into one, delete some, or even rewrite their content. It is the most powerful single Git command — and the one most often cited by intermediate users as the moment Git really clicked for them.

Launching it

Pick a starting point

Bash
# Rebase the last 5 commits
git rebase -i HEAD~5

# Rebase every commit since branching off main
git rebase -i main

# Rebase to before a specific commit
git rebase -i 1f9ab2c^
The interactive screen

Your editor opens with this

Text
pick 1f9ab2c Add login form
pick d4b1e0c Fix typo
pick c204c1d Add validation
pick a3b2c1d Address review

# Commands:
# p, pick   = use commit
# r, reword = use commit, but edit the commit message
# e, edit   = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup  = like "squash", but discard this commit's log message
# x, exec   = run command (the rest of the line) using shell
# d, drop   = remove commit
# l, label  = label current HEAD with a name
# t, reset  = reset HEAD to a label
# m, merge  = create a merge commit using the original merge commit's message
The commands you’ll use 95% of the time

Command

Effect

pick (default)

Keep this commit as-is

reword (r)

Keep changes, edit the commit message

squash (s)

Combine into previous commit, merge messages

fixup (f)

Combine into previous commit, discard this message

drop (d)

Remove this commit entirely

edit (e)

Pause here so you can amend changes too

reorder

Just move the lines up/down before saving

Common recipes
Combine the last 3 commits into one

Bash
git rebase -i HEAD~3

Edit the file to:

Text
pick   1f9ab2c Add search component
squash d4b1e0c Tweak search styles
squash c204c1d Fix lint

Save and close. Git then opens another editor showing the three messages combined; trim it down to one good message, save, and you’re done.

Reword a commit message

Text
reword 1f9ab2c Add login form
pick   d4b1e0c Fix typo
pick   c204c1d Add validation

After saving, Git stops at the reworded commit and opens another editor for the new message.

Drop a bad commit

Text
pick 1f9ab2c Add login form
drop d4b1e0c Oops committed .env  ← remove this
pick c204c1d Add validation
Reorder commits

Just swap the lines:

Before

Text
pick a Fix typo
pick b Add huge feature

After

Text
pick b Add huge feature
pick a Fix typo

Git replays in the new order. Conflicts are possible if the commits touch the same lines — resolve as normal.

Edit the contents of a commit

Text
edit 1f9ab2c Add login form
pick d4b1e0c Fix typo

Git pauses at the edit commit. Make changes, then:

Bash
git add .
git commit --amend
git rebase --continue
Fixup workflow (everyday clean-up)

Marking a commit as a fixup for an earlier one

Bash
# You forgot to add a file to commit 1f9ab2c.
git add forgotten.js
git commit --fixup 1f9ab2c

# Now rebase interactively — Git groups the fixup with its target
git rebase -i --autosquash 1f9ab2c~1
# The editor pre-arranges the fixup correctly. Save and exit.
Continuing or aborting

Bash
git rebase --continue   # after fixing conflicts or editing a commit
git rebase --skip       # skip this commit (use with care)
git rebase --abort      # cancel everything, restore the pre-rebase state
Inspecting after an interactive rebase

Bash
git log --oneline -10
# Verify the commits look like what you intended

git reflog
# If something went wrong, find the pre-rebase state and reset to it:
git reset --hard HEAD@{<n>}
Pushing after rewrite

Bash
git push --force-with-lease
# Required because hashes changed
Warning
Only ever rewrite history on branches that *only you* have. Force-pushing a shared branch can destroy teammates’ work.
Useful flags
  • --autosquash — auto-positions fixup!/squash! commits.

  • --autostash — stash uncommitted work before, pop after.

  • -x "cmd" — run a command after every commit (great for running tests).

  • --rebase-merges — preserve the topology of merge commits during the rebase.

The mental model
Interactive rebase doesn’t edit the existing commits — it creates NEW commits. The old ones still exist in the reflog for a while in case you need to recover.
Tip
Before pushing a feature branch for review, run git rebase -i main and clean up your commits. Reviewers will see a polished, atomic series instead of your “fix typo / oops / actually fix typo” history.