When you are working with version control, you may have multiple commits that you would like to combine into a single commit. Or perhaps you want to change their order, clean up your commit history, or prepare changes for a pull request. Git's interactive rebase feature makes this easy. For a quick reference of Git commands, check out our Git Command Reference tool.
Why Squash Commits?
Squashing commits is useful when you want to:
- Combine multiple small commits into one meaningful commit
- Clean up your commit history before merging to main/master
- Group related changes together
- Remove "work in progress" or "fix typo" commits
- Create a cleaner, more professional commit history
Cleaner Commit History
One of the primary advantages of squashing commits is achieving a cleaner, more manageable commit log. This simplification helps anyone looking into the project history to grasp the significant changes without getting lost in a sea of minor updates.
Enhanced Collaboration
When working in a team, a tidy commit history can significantly improve the collaborative process. It reduces the complexity new members face when they join the project and helps maintain clarity about what changes have been made and why.
Easier Rollbacks
By consolidating multiple related changes into a single commit, it becomes easier to revert changes if something goes wrong. Instead of having to undo or fix several individual commits, developers can revert a single squashed commit, which can save a lot of time and reduce the risk of errors in the rollback process.
Preparing Your Branch
Before you begin the squash process, ensure your working branch is up-to-date and checked out:
# Switch to your feature branch
git checkout feature-branch
# Update your branch (if necessary)
git fetch origin
git rebase origin/main
Finding the Commits to Squash
First you need to determine how far back you want to go. Open a command prompt or terminal window, navigate to your Git Repository.
Next, type:
git log -10
The above command will show the last 10 commits. If that does not go far enough back, increase the number 10.
Starting Interactive Rebase
Once you have identified the commits you wish to squash, run the git rebase command:
git rebase -i HEAD~10
The above command will open a git rebase window showing you the last 10 commits. Adjust this number as needed.
Understanding the Rebase Interface
Each line shown will have the word "pick" at the beginning. Here is what the rebase window looks like:
pick abc1234 First commit message
pick def5678 Second commit message
pick ghi9012 Third commit message
# Rebase commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
Squashing Your Commits
Any commits you wish to squash, replace the word "pick" with the letter "s" (for squash) or "f" (for fixup).
Important guidelines:
- Leave the first commit in the list set to "pick" - this is what other commits will be squashed into
- Replace "pick" with "s" for commits you want to squash into the previous commit
- Be sure to leave at least one commit as "pick" so there's something to squash into
For example, to squash the second and third commits into the first:
pick abc1234 First commit message
s def5678 Second commit message
s ghi9012 Third commit message
Editing the Combined Commit Message
After you save and close the rebase file, Git will prompt you to edit the combined commit message. You can:
- Keep all the original commit messages
- Write a new single message that describes all the changes
- Delete unwanted messages and keep only the relevant ones
Completing the Rebase
Once you've edited the commit message and saved the file, Git will complete the rebase and your commits will be squashed together.
Important Notes
- Don't rebase published commits: Only squash commits that haven't been pushed to a shared repository, or be prepared to force push
- Force push carefully: If you've already pushed the commits, you'll need to force push:
git push --force - Backup your work: Consider creating a backup branch before rebasing:
git branch backup-branch
Common Issues and Solutions
Issue: "Cannot 'squash' without a previous commit"
- Solution: Make sure the first commit in your rebase list is set to "pick"
Issue: Merge conflicts during rebase
- Solution: Resolve conflicts, then run
git rebase --continue
Issue: Want to abort the rebase
- Solution: Run
git rebase --abortto return to the state before rebasing
Best Practices
Do's
- Squash commits before creating a pull request - Clean up your history before code review
- Squash during feature development - Consider squashing commits regularly throughout development rather than waiting until merge time
- Keep meaningful commit messages - When squashing, revise the commit message to reflect the overall impact of the combined changes
- Use descriptive commit messages - Explain the "why" not just the "what"
- Test before squashing - Make sure the branch is fully functional and tested before squashing
- Communicate with your team - Keep your team informed about your squashing plans in collaborative environments
- Consider your team's preferences - Follow your team's commit history conventions
Don'ts
- Don't squash commits that have already been merged to main - Respect the shared history
- Don't lose granular history - Be careful not to squash commits that contain important individual changes that may need to be tracked separately
- Don't squash shared commits - Never squash commits that have already been pushed to a shared repository where others might have based work on them
- Avoid excessive squashing - Don't squash commits indiscriminately—each squashed commit should still be meaningful and represent a logical unit of work
Mastering Git's rebase and squash features will help you maintain a clean, professional commit history that makes code review and debugging much easier.
Alternative Methods to Squash Commits
Method 1: Soft Reset
If interactive rebase feels complex, use soft reset for a simpler approach:
# Undo last 3 commits, keeping changes staged
git reset --soft HEAD~3
# Create a single new commit
git commit -m "Combined feature: description of all changes"
Method 2: Merge Squash
When merging a feature branch, squash all commits into one:
# From main branch
git merge --squash feature-branch
git commit -m "Add feature: complete description"
This is ideal for pull request workflows where you want to preserve the feature branch history but merge cleanly.
Method 3: GitHub/GitLab Squash Merge
Most Git platforms offer "Squash and merge" as a PR merge option. This automatically combines all PR commits into one when merging, without manual rebase.
Related Resources
- Git Command Reference - Quick lookup for common Git commands
- Diff Checker - Compare code changes before committing
- CI/CD Best Practices - Integrate clean Git history into your pipeline