Interactive Rebase: squash, edit, reorder

Reviewed & published by Brayan K

Interactive rebase is the editor for your recent history. By the end of this lesson you'll squash messy work-in-progress commits into clean ones, reword and reorder commits, drop mistakes, and pause to edit a commit's content — all before you share your work.

Part of the free Git course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

What You'll Learn

1️⃣ Opening an Interactive Rebase

git rebase -i HEAD~3 opens an editor with a todo list of your last three commits, oldest at the top. Each line starts with an action word (default pick) followed by the commit. You change the action words, optionally reorder the lines, then save and close to apply.

# Interactive rebase lets you REWRITE a series of recent commits:
# squash them together, fix messages, reorder, or drop them entirely.

# Open an editable "todo" list of the last 3 commits
git rebase -i HEAD~3

# Git opens an editor pre-filled like this (oldest at the TOP):
#   pick a1b2c3d Add login form
#   pick b2c3d4e Fix typo in login form
#   pick c3d4e5f Add login validation
#
# Change the word at the start of each line to choose an action,
# reorder the lines to reorder commits, then save & close.

2️⃣ The Actions

A quick tour: pick keeps a commit as-is; reword keeps it but edits the message; squash folds it into the commit above and combines messages; fixup does the same but discards this commit's message; edit pauses so you can amend its content; drop deletes it. Reorder commits just by reordering the lines.

# The actions you'll reach for most:
#
#   pick    keep the commit exactly as it is (the default)
#   reword  keep the changes, but edit the commit MESSAGE
#   squash  fold this commit into the one ABOVE it, combine messages
#   fixup   fold into the one above, but THROW AWAY this message
#   edit    pause here so you can amend the commit's content
#   drop    delete this commit entirely
#
# Reorder commits simply by reordering the lines.

# Example todo: squash the typo fix into the form commit, reword the last
pick a1b2c3d Add login form
fixup b2c3d4e Fix typo in login form
reword c3d4e5f Add login validation

3️⃣ Squashing Commits

The classic use is collapsing several messy commits into one before a pull request. Keep the first as pick and mark the rest squash (or fixup to drop their messages). On saving, Git opens a second editor so you can write one clean combined message.

# A super common cleanup: turn three messy WIP commits into one tidy commit
# before opening a pull request.

git rebase -i HEAD~3

# In the editor, keep the first as pick and squash the rest into it:
#   pick   a1b2c3d Start search feature
#   squash b2c3d4e wip
#   squash c3d4e5f more wip, fix bug
#
# Save & close. Git then opens a second editor to combine the three
# messages into one — clean it up to a single clear message and save.

Your turn. Squash three commits into one and reword it. Fill in the two blanks.

# 🎯 YOUR TURN — replace each ___ then follow the steps in your terminal.
# Goal: squash three messy commits into one and reword it.

# 1) Open an interactive rebase over the last 3 commits
git rebase ___ HEAD~3          # 👉 the flag that makes a rebase interactive

# 2) In the editor, keep the first line as "pick" and change the next two
#    lines' action to ___ so they fold into the first commit.
#    👉 the action that melds a commit into the one above it

# 3) Save & close, then in the message editor write one clear message.

# ✅ Expected: "git log --oneline" now shows ONE commit where there were
#    three, with the single message you wrote.

Common Errors (and the fix)

Pro Tips

📋 Quick Reference

Action / CommandMeaning
git rebase -i HEAD~nEdit the last n commits
pickKeep the commit unchanged
rewordKeep commit, edit its message
squashFold into previous, combine messages
fixupFold into previous, drop this message
editPause to amend the commit
dropDelete the commit

Mini-Challenge: Polish Before a PR

No commands given this time — just the plan. Turn four messy commits into a clean, shareable set.

# 🎯 MINI-CHALLENGE: polish a branch before a pull request.
# No commands given — just the plan. Run each step in your terminal.
#
# 1. On a feature branch, make 4 commits including a couple of "wip" ones
#    and one with a bad message
# 2. Run "git rebase -i HEAD~4"
# 3. fixup the "wip" commits into a real one (discarding their messages)
# 4. reword the bad-message commit into something clear
# 5. Optionally reorder so related commits sit together; save & close
#
# ✅ Expected: a clean, minimal set of commits with clear messages, ready
#    to share. (Only do this on LOCAL, unpushed commits!)

# your commands here

🎉 Lesson Complete!

Practice quiz

What does `git rebase -i` open?

  • A merge tool
  • The remote settings
  • An editable 'todo' list of commits with actions
  • A diff viewer

Answer: An editable 'todo' list of commits with actions. Interactive rebase opens an editor listing the commits and the action to take on each.

In `git rebase -i HEAD~3`, what does HEAD~3 select?

  • The last 3 commits to replay/edit
  • The 3rd commit only
  • 3 branches
  • The first 3 commits ever

Answer: The last 3 commits to replay/edit. HEAD~3 picks the three most recent commits for the interactive rebase.

What does the `pick` action do?

  • Deletes the commit
  • Merges it
  • Renames the branch
  • Keeps the commit as-is

Answer: Keeps the commit as-is. pick keeps the commit unchanged — it's the default action for each line.

What does `squash` (s) do?

  • Deletes a commit
  • Combines a commit into the previous one, keeping BOTH messages to edit
  • Reverses a commit
  • Splits a commit

Answer: Combines a commit into the previous one, keeping BOTH messages to edit. squash folds the commit into the one above and lets you combine the messages.

How does `fixup` (f) differ from `squash`?

  • fixup combines into the previous commit but DISCARDS the fixup's message
  • fixup keeps both messages
  • fixup deletes the commit
  • There is no difference

Answer: fixup combines into the previous commit but DISCARDS the fixup's message. fixup melds the change into the prior commit and throws away its message.

What does `reword` (r) do?

  • Rewrites the code
  • Deletes the message
  • Keeps the commit but lets you change its message
  • Reorders commits

Answer: Keeps the commit but lets you change its message. reword keeps the commit's changes but prompts you to edit its message.

What does `edit` (e) let you do?

  • Only change the message
  • Pause at that commit so you can amend its content or split it
  • Delete the commit
  • Skip the commit

Answer: Pause at that commit so you can amend its content or split it. edit stops the rebase at that commit so you can amend its contents.

How do you DROP a commit entirely in interactive rebase?

  • Use 'pick'
  • Use 'squash'
  • Use 'reword'
  • Use the 'drop' action or delete its line

Answer: Use the 'drop' action or delete its line. Mark the line drop (or remove the line) to discard that commit.

How do you REORDER commits in an interactive rebase?

  • You can't reorder
  • Rearrange the lines in the todo list
  • Use git reorder
  • Change their hashes

Answer: Rearrange the lines in the todo list. Reordering the lines in the todo editor reorders the commits when applied.

Is interactive rebase safe to use on already-pushed, shared commits?

  • Yes, always
  • Only with fixup
  • No — like all rebasing, it rewrites history and shouldn't touch shared commits
  • Only on main

Answer: No — like all rebasing, it rewrites history and shouldn't touch shared commits. Interactive rebase rewrites history, so the golden rule still applies: don't rewrite shared commits.

Continue this course

Frequently asked questions

What is interactive rebase for?

git rebase -i lets you rewrite a series of recent commits before sharing them. You can squash several commits into one, reword messages, reorder commits, pause to edit a commit's contents, or drop commits entirely. It's the standard way to turn a messy string of work-in-progress commits into a clean, readable history before opening a pull request.

What's the difference between squash and fixup?

Both fold a commit into the one directly above it in the todo list. The difference is the message: squash keeps both commits' messages and opens an editor so you can combine them, while fixup melds the change in but silently discards the squashed commit's message, keeping only the message of the commit above. Use fixup for throwaway 'wip' commits whose messages you don't want.

How do I reorder commits?

In the interactive rebase editor, each commit is one line, with the oldest at the top. To reorder commits, simply rearrange those lines and save. Git applies them in the new order. Be aware that reordering commits that touch the same code can cause conflicts, which you resolve and then continue with git rebase --continue.

What does the 'edit' action do?

Marking a commit with edit makes the rebase pause right after applying that commit, dropping you back at the shell. There you can amend its contents (git commit --amend), or even split it into multiple commits, before running git rebase --continue to resume. It's the tool for fixing the contents of an older commit, not just its message.

Is interactive rebase safe?

It's safe on local, unpushed commits and is reversible mid-flight with git rebase --abort. But it rewrites history, so the golden rule of rebasing still applies: never run it on commits you've already pushed and shared, because the rewritten commits get new hashes that diverge from what your teammates already have. Clean up before you push, not after.