As a developer, we always encounter situation where we commit our work in progress. And then later on at some point in time, we want a way to merge all the commits into one an make the commit history clean.
Squashing commits in Git refers to the process of combining multiple commits into a single, consolidated commit. Instead of preserving the entire commit history with all its individual changes, squashing allows you to condense several commits into one, creating a cleaner and more concise history.
The squashing process involves rewriting commit history, and it is typically used to improve the quality and readability of the commit log. This can be beneficial in various scenarios:
- Cleaning up Work-in-Progress Commits:
- During the development process, you might create several small, incremental commits. Squashing these commits before merging into a main or shared branch helps present a more polished and logical set of changes.
- Creating Meaningful Commits:
- Squashing allows you to craft commits with descriptive messages, summarizing the changes introduced, rather than retaining individual commit messages that may be less informative.
- Enhancing Collaboration:
- When collaborating with a team, a clean commit history makes it easier for others to understand the evolution of the codebase. It reduces noise in the log and helps focus on significant milestones or features.
Here’s a simplified example of what happens during a squash:
Before Squashing, let’s says you have a branch name my-feature-branch:
Commit A: Feature X part 1
Commit B: Feature X part 2
Commit C: Feature X part 3
So, how do I cleanup these commit history and keep only one commit in origin? It may seem quite complex but actually it is not. We have to do squash in Git. To do squash process in Git we have to run certain command sequences. Let’s do that with an example.
First checkout to your branch:
git checkout my-feature-branch
Run interactive rebase command as below:
git rebase -i HEAD~3
This opens an interactive rebase window that allows you to modify the commit history of the last three commits which is indicated by ~3. Interactive Rebase Editor (vim) opens with the below lines:
pick A123456 Feature X part 1
pick B789012 Feature X part 2
pick C345678 Feature X part 3
In the interactive rebase window, change the word “pick” to “squash” (or simply “s”) for commits B and C. Leave “pick” as is for commit A.
pick A123456 Feature X part 1
squash B789012 Feature X part 2
squash C345678 Feature X part 3
Save and close the file. If the default editor Git is vim in your system, saving requires pressing Esc first and then type wq to save and exit the editor.
Finally run the following command:
git rebase --continue
If there are conflicts during the rebase, Git will pause, and you’ll need to resolve them.
Now force Push the Changes:
git push origin your-feature-branch --force
Be cautious with force-push, especially on shared branches. Coordinate with your team if needed.
After Squashing:
Commit ABCDEF1 Implement Feature X
In this example, commits B and C have been squashed into a single commit with the message “Implement Feature X.” The commit history is now cleaner and more focused on the feature as a whole. Remember that force-pushing is involved in this process, so it’s important to coordinate with your team, especially if the branch is shared.