Why Interactive Rebase Matters

Interactive rebase is one of the most flexible tools in Git. It lets you revise your local commit history before sharing your work with a team, giving you control over how your changes are presented. With it, you can edit commit messages, combine or split commits, reorder work, and remove revisions entirely.

The key constraint is that an interactive rebase rewrites history: every commit involved gets a new SHA-1 hash, meaning you are technically creating brand-new commits. That is why this technique should only be applied to work that has not been pushed to a shared remote. If teammates have already based their branches on the commits you rewrite, you will break their base.

The Anatomy of a Rebase Session

No matter what you want to accomplish, the workflow is always the same. First, examine your repository's history with git log to identify which commits you want to operate on and how far back you need to go. Then start the interactive session with git rebase -i, specifying the parent commit of the range you care about. An editor opens showing the selected commits in reverse order—oldest at the top, newest at the bottom—and you mark each line with a keyword that tells Git what operation to perform.

For the examples below, we'll work with a repository whose history looks like this:

Showing a Git Tower app screen with the main master branch of a repo selected on the left panel, and a list of existing commits on the right panel.
Note that I’m using the Tower Git desktop GUI in some of my screenshots for easier visualization.

Editing a Commit Message

If the message you need to change belongs to the most recent commit, there is a shortcut that avoids interactive rebase entirely:

$ git commit --amend

This git commit --amend command opens your default editor where you can change both the message and the content of the latest commit. Be aware that amending effectively creates a new commit, so do not use it on anything already pushed to a remote.

For older commits, you must run a rebase. To change one of the last three commit messages, target their parent:

$ git rebase -i HEAD~3

The editor that opens shows all three commits in the range. Here you do not edit the message itself; you only tell Git what to do. Change the word pick to reword on the line for the commit in question. After you save and exit, Git opens another editor with the actual commit message, which you can now revise.

Animated screenshot showing an open terminal that edits the commit and adds a reword command on another line.

Merging Two Commits

To combine commits, mark the later one with squash. Importantly, the squash keyword merges the marked line with the line above it. So to combine two commits into one, identify the parent of the higher one:

$ git rebase -i HEAD~3

In the rebase editor, change pick to squash on the second line:

Showing an open terminal with a squash on line 2 and giants words in red pointing to that line saying that squash combines the marked up line with the line above it.

After saving, a new editor window opens asking for a message for the newly created combined commit. Supply one, save, and the two commits are now a single revision.

Removing a Commit

Deleting a revision from history is straightforward: mark it with the drop keyword in the rebase editor.

drop 0023cdd Add simple robots.txt
pick 2b504be Change headlines for about and imprint
pick 6bcf266 Optimizes markup structure in index page

That commit, along with its changes, will disappear from the branch entirely.

Escape Hatch: Aborting a Rebase

If you realize mid-session that you have made a mistake, there is no need to panic. You can cancel the entire operation and return to the state your repository was in before you started:

$ git rebase --abort

Interactive rebase is a powerful instrument for polishing local work before it reaches a shared branch. Used carefully—only on unpushed commits—it keeps your history clean and your collaborators' branches intact. When you're ready to undo an in-progress rebase or experiment further, the abort command is your quick way out.