Introduction
During daily software development, it is common to end up with a messy commit history full of logs like “WIP,” “fix typo,” or “testing deployment.”
If you merge these commits directly into your main branch, finding where a specific bug was introduced or understanding why a line of code was added becomes extremely difficult.
Git’s interactive rebase (git rebase -i) allows you to clean up your commit history before creating a pull request. You can squash multiple commits into one, edit commit messages, reorder history, or delete redundant changes. This article covers the step-by-step workflow of utilizing interactive rebasing.
1. What is Interactive Rebase?
git rebase -i is a command that opens an interactive editor screen displaying a list of your commits within a specified range. By modifying instructions in this list, Git applies those changes to your branch history sequentially.
Core Usecases
- Squash: Merge small, intermediary commits (e.g., “typo fix”) into a single, clean commit.
- Reword: Modify commit messages to match team naming conventions.
- Drop: Completely delete unnecessary commits from history.
- Edit: Pause the rebase process at a specific commit to add or remove files.
2. Basic Step-by-Step Workflow
Let’s look at how to run a rebase to clean up your local branch.
Step 1: Specify the Rebase Range
If you want to edit the last three commits on your current branch, run:
git rebase -i HEAD~3
To edit all commits since your branch diverged from another branch (e.g., main), run:
git rebase -i main
Step 2: Configure the Todo List
Running the command opens your system’s default text editor (e.g., Vim, Nano, or VS Code) displaying a list of commits:
pick a1b2c3d WIP: Started login interface
pick e5f6g7h fixed typo in input
pick i9j0k1l Added login validation
# Rebase a1b2c3d..i9j0k1l onto z9y8x7w
# ...
- Note: The commits are displayed in chronological order: oldest at the top, newest at the bottom.
- Change the keyword at the start of each line to tell Git how to handle that specific commit.
Core Action Commands
| Command | Abbreviation | Action |
|---|---|---|
| pick | p | Use the commit as-is (default). |
| reword | r | Use the commit, but edit the commit message. |
| edit | e | Use the commit, but pause the rebase to edit files. |
| squash | s | Merge this commit into the previous (older) commit and combine messages. |
| fixup | f | Merge this commit into the previous commit, discarding this commit’s message. |
| drop | d | Completely remove this commit. |
Practical Example
To merge the typo fix and validation commit into the initial “Started login interface” commit, edit the file as follows:
pick a1b2c3d WIP: Started login interface
f e5f6g7h
s i9j0k1l
e5f6g7his set tofixup (f), meaning it merges intoa1b2c3dand its message is discarded.i9j0k1lis set tosquash (s), merging into the parent while prompting you to rewrite the final combined commit message.
Save and close the editor to begin the rebase.
Step 3: Write the Final Commit Message
If you selected squash, Git opens another editor screen to finalize the combined message:
# This is a combination of 2 commits.
# This is the 1st commit message:
WIP: Started login interface
# This is the commit message #2:
Added login validation
Rewrite this into a clean commit message:
feat: Implement login page with validation rules
- Designed form fields for email and passwords.
- Added client-side red border indicators on input validation errors.
Save and close the editor. Git will apply the changes, squashing the three commits into a single node.
3. Resolving Conflicts During Rebase
If a conflict occurs, Git pauses the rebase and highlights the conflicting lines.
- Resolve conflicts manually: Edit the conflicting source code files to choose the correct changes.
- Stage the changes: Run
git add <filename>(do not rungit commit). - Continue the rebase: Run:
git rebase --continue
If you get stuck or make a mistake, abort the entire process and return your branch to its pre-rebase state by running:
git rebase --abort
4. The Golden Rule of Rebasing
While rebase is incredibly useful, you must follow one strict guideline:
WarningNever rebase commits that have already been pushed to a public/shared repository branch (e.g., main or develop) where other developers are working.
Rebasing changes commit hashes. If you push modified hashes to a shared branch, it breaks other developers’ local history tracking, leading to merge conflicts and potential code loss. Only rebase local commits or commits on your isolated pull request branch.
Conclusion
Using git rebase -i lets you save your work in progress as small local commits, then tidy them up into a clean feature commit before sharing your code with the team. Start using interactive rebase to keep your repository history readable.
