DevLogTechnical writing
Tutorials

Tidy Your Git History with Interactive Rebase

October 03, 2026

Your commit history is the story you tell your team. Right now it probably reads like a messy first draft: wip, fix, oops, "actually works now". Git gives you a safe way to rewrite that story into something readable — but only for commits you have not pushed yet.

1. Start the rebase

git rebase --interactive (short: git rebase -i) replays a range of commits and lets you decide what happens to each one: keep it, squash it, reword it, or drop it.

Point the command at the commit before the ones you want to edit:

# edit the last N commits
git rebase -i HEAD~3

# edit everything on your branch since it left main
git rebase -i main

HEAD~3 means "three commits back from HEAD" — it edits the three commits after that point, not the commit itself.

2. Read the todo list

Your editor opens a file listing the commits, oldest first:

pick a1b2c3d add login form
pick b2c3d4e fix typo
pick c3d4e5f more css tweaks

Each line has a command word, a commit hash, and a short message. Git executes them top to bottom when you save and quit.

3. Know the commands

The first word on each line decides what happens:

4. Squash three commits into one

Say your last three commits are scattered typo fixes. Run:

git rebase -i HEAD~3

Keep the first line as pick and change the other two to squash:

pick a1b2c3d add login form
squash b2c3d4e fix typo
squash c3d4e5f more css tweaks

Save and close. Git asks for one combined message (it merges the three originals for you), and when you save again the three commits collapse into one. git log --oneline now shows a single clean commit — the code is identical, only the history is tidier.

5. Reword and drop

To fix just a commit message, mark its line reword: Git stops, lets you retype the message, and continues without touching the code. To remove a commit entirely, change its line to drop (or delete the line). It is usually safer to drop than to hand-edit a previous commit's contents by force.

6. The critical warning

Never rebase commits that already live on a shared branch. Rebase creates new commits with new hashes, so the rewrite diverges from what your teammates pulled. Putting it back on the remote requires a force push, and git push --force-with-lease at best — which can silently overwrite their work. Keep interactive rebase for local, unpushed commits only.

7. Recover from mistakes

If a rebase goes wrong mid-way, bail out:

git rebase --abort

That returns your branch to exactly where it was when the rebase started. If you only notice a problem afterwards, git reflog shows every place HEAD has been; git reset --hard <sha> jumps back to the one you want. Nothing is ever lost while the commit still exists.

Interactive rebase does not change what your code does — it changes how your work reads. Squash the noise, write a straight story, then push.

← More Tutorials