Objective
- Improve the readability and maintainability of the Git commit history by consolidating multiple small or intermediate commits into a single meaningful unit.
- This is especially useful before code review or merging into the main branch to ensure a clean and understandable history.
Goal
Guideline
Preferably, ensure the following conditions:
- Commits have not yet been pushed to the remote repository (e.g., GitHub).
- The work is done on a local branch.
Otherwise, you will likely need to use a force push (git push -f
) after rebasing, which can overwrite history on the remote. Please proceed with caution because rewriting commit history on pushed commits can disrupt collaboration.
Steps for consolidating commits
Check recent commits
git log --oneline
Start interactive rebase
To squash the last 3 commits, run:
git rebase -i HEAD~3
The syntax is
git rebase -i <base-commit>
- You can only specify a single base commit to rebase onto
- You cannot run a commad which is working as
git rebase -i <commit-id1> to <commit-id2>
Edit the rebase instruction list
After running the
git rebase
, the output would bepick abc123 fix typonew test case pick def456 add pick ghi789 finalize logic
commit ids are sorted by top to bottom = older to newer. In the above example, the first line (
abc123
) is the oldest of the commits being rebased.If you want to squash the latest two commits into the oldest one, modify it to:
pick abc123 fix typonew test case squash def456 add squash ghi789 finalize logic
Edit the commit message
A new editor screen will prompt you to combine the commit messages. Edit as needed, e.g.:
Finalize logic with test case - Fixed typo - Added test case - Finalized core logic
Then, save and exit. It would be recommended to verify the new commit history by
git log --oneline
If something goes wrong during the rebase, you can cancel it:
git rebase --abort
Appendix: What git rebase
operations are possible?
Command | Description |
---|---|
pick |
Use the commit as-is (no changes to message or content). |
reword |
Keep the commit content, but edit the commit message. |
edit |
Pause and allow you to amend the commit (edit files, message, etc.). |
squash |
Combine this commit with the previous one, and edit the message. |
fixup |
Like squash , but discard this commit’s message (use previous message). |
drop |
Completely remove this commit from history. |