How to Squash Commits That Are Already Pushed in Git
- Understanding Commit Squashing
- Method 1: Using Interactive Rebase
- Method 2: Reset and Recommit
- Method 3: Using Git Merge with Squash Option
- Conclusion
- FAQ

When working with Git, you may find yourself in a situation where you need to clean up your commit history. Squashing commits is a useful technique that allows you to combine multiple commits into a single one, making your Git history cleaner and easier to understand. However, squashing commits that have already been pushed to a remote repository can be a bit tricky.
In this article, we will explore various methods to squash those commits safely and effectively. Whether you’re a seasoned developer or a newcomer to Git, this guide will provide you with the insights you need to manage your commit history like a pro.
Understanding Commit Squashing
Before diving into the methods, let’s clarify what squashing commits means. Squashing is the process of merging multiple commits into one, thereby reducing clutter in your commit history. This can be particularly helpful when you have several small commits that represent incremental changes or fixes. By squashing them, you create a more cohesive narrative of your project’s development.
Method 1: Using Interactive Rebase
One of the most common ways to squash commits is through interactive rebase. This method allows you to rewrite your commit history by selecting which commits to squash. Here’s how to do it:
- First, identify the number of commits you want to squash. For example, if you want to squash the last three commits, you’ll run the following command:
git rebase -i HEAD~3
- This command opens an editor with a list of the last three commits. You’ll see something like this:
pick 1234567 Commit message 1
pick 2345678 Commit message 2
pick 3456789 Commit message 3
- Change the word “pick” to “squash” (or “s”) for the commits you want to squash into the first one. It should look like this:
pick 1234567 Commit message 1
squash 2345678 Commit message 2
squash 3456789 Commit message 3
-
Save and close the editor. You’ll be prompted to write a new commit message for the squashed commit.
-
Finally, force-push the changes to the remote repository:
git push origin branch-name --force
Output:
Counting objects: 3, done.
Writing objects: 100% (3/3), 345 bytes | 345.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To https://github.com/username/repo.git
+ 1234567...3456789 branch-name -> branch-name (forced update)
This process effectively squashes your selected commits into one, providing a cleaner commit history. However, be cautious when using force-push, as it can overwrite changes in the remote repository.
Method 2: Reset and Recommit
If you prefer a more manual approach, you can reset your branch to a previous commit and then recommit your changes. Here’s how to do it:
- First, identify the commit hash you want to reset to. You can find this by running:
git log
- Once you have the commit hash, reset your branch:
git reset --soft commit-hash
- This command moves your HEAD pointer to the specified commit while keeping your changes staged. Now, you can create a new commit that represents all the changes:
git commit -m "New commit message for squashed changes"
- Finally, force-push the changes to the remote repository:
git push origin branch-name --force
Output:
Counting objects: 2, done.
Writing objects: 100% (2/2), 456 bytes | 456.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
To https://github.com/username/repo.git
+ 1234567...new-hash branch-name -> branch-name (forced update)
This method gives you complete control over the commit message and allows you to consolidate your changes into a single commit. However, like the previous method, use force-push with caution.
Method 3: Using Git Merge with Squash Option
Another method to squash commits is by using the merge command with the --squash
option. This is particularly useful when you want to merge a feature branch into the main branch while squashing all the commits from the feature branch into one.
- First, switch to the branch you want to merge into:
git checkout main
- Then, use the merge command with the
--squash
option:
git merge feature-branch --squash
- This command prepares the changes from the feature branch for a single commit without actually creating a merge commit. Now, commit the changes:
git commit -m "Merged feature branch with squashed commits"
- Finally, push the changes to the remote repository:
git push origin main
Output:
Counting objects: 1, done.
Writing objects: 100% (1/1), 123 bytes | 123.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/username/repo.git
old-hash..new-hash main -> main
This method is straightforward and preserves the original feature branch without altering its commit history. It’s an excellent choice when you want to keep your main branch clean and concise.
Conclusion
Squashing commits that have already been pushed to a remote repository is a vital skill for any developer looking to maintain a tidy Git history. Whether you choose to use interactive rebase, reset and recommit, or the merge with squash option, each method has its advantages. Remember to use force-push cautiously, as it can overwrite changes in the remote repository. By mastering these techniques, you can ensure that your project’s commit history remains clear and comprehensible.
FAQ
-
Can I squash commits that have been pushed to a shared branch?
Yes, but be cautious as it can affect other collaborators. Communicate with your team before proceeding. -
What happens if I don’t force-push after squashing commits?
Your local changes won’t reflect in the remote repository, and the commit history will remain unchanged. -
Is it safe to use
git push --force
?
While it is safe in certain scenarios, you should be careful when overwriting shared branches. Always check with your team. -
Can I squash commits without modifying the commit messages?
Yes, during the interactive rebase, you can choose to keep the original commit messages by selecting the appropriate options. -
How do I revert a squashed commit if I make a mistake?
You can find the commit hash before the squash and reset to that commit usinggit reset --hard commit-hash
.
John is a Git and PowerShell geek. He uses his expertise in the version control system to help businesses manage their source code. According to him, Shell scripting is the number one choice for automating the management of systems.
LinkedIn