Keywords: Git | commit squashing | interactive rebase
Abstract: This article provides a comprehensive guide on how to merge multiple Git commits into a single commit using interactive rebase (git rebase -i). Based on real-world Q&A data, it addresses common issues such as misusing git merge --squash and offers step-by-step solutions. Topics include the principles of interactive rebase, detailed procedures, cautions, and comparisons with alternative methods, aiding developers in version history management.
Introduction
In software development, frequent commits can lead to cluttered version histories. For instance, a user made two commits on a branch: the first added homepage.html and contacts.html, while the second added homepage.php and deleted the previous HTML files. Merging such related commits into one simplifies the history and enhances readability. Drawing from Q&A data, this article explores how to achieve commit squashing with Git's interactive rebase feature.
Fundamentals of Interactive Rebase
Interactive rebase is a powerful Git tool that allows modification of commit history. Using the git rebase -i command, users can reorder, edit, combine, or delete commits. For squashing commits, the key is to merge changes from multiple commits into a single commit while preserving all modifications.
For example, with two consecutive commits—Commit 1 and Commit 2—interactive rebase opens an editor listing these commits. By changing the instruction for the second commit from pick to squash or s, Git merges the changes from the second commit into the first during the rebase process.
Detailed Step-by-Step Procedure
Assume the user is on the firstproject branch with two commits to merge. Follow these steps:
- Initiate Interactive Rebase: Run
git rebase -i HEAD~2. Here,HEAD~2refers to the two commits back from the current HEAD. Git opens the default editor (e.g., Vim or VS Code) with content like:pick abc123 Commit 1: Added files pick def456 Commit 2: Modified files - Modify Commit Instructions: Change the second line's
picktosquashor its shorthands. The modified content appears as:
This instructs Git to squash the second commit into the first.pick abc123 Commit 1: Added files squash def456 Commit 2: Modified files - Save and Exit the Editor: After saving the file and closing the editor, Git processes the squashing and opens another editor for the new commit message.
- Edit the Commit Message: In the second editor, Git displays a combined version of the original messages. Users can delete this and enter a custom message, e.g.:
Save and exit to complete the rebase.Combined commit: Added and updated homepage files - Verify the Result: Run
git log --onelineto check the commit history and confirm the merge.
Cautions and Potential Issues
When using interactive rebase, consider the following:
- History Rewriting: Rebase alters commit history. If the branch has been pushed to a remote repository, use
git push -ffor force-pushing. This may cause collaboration issues, so it is advisable to operate on private or unshared branches. - Commit Order: If commits are not the most recent, adjust the N value in
HEAD~N. For example, usegit rebase -i HEAD~3to merge three commits. - Editor Configuration: Git uses the system's default editor. Users unfamiliar with Vim should configure an alternative editor (e.g., VS Code) to avoid errors.
Comparison with Other Methods
Besides interactive rebase, Git offers other squashing methods, such as git merge --squash. However, as noted in the Q&A data, running git merge --squash alone may display command options instead of executing, because it requires a branch parameter, e.g., git merge --squash branch-name.
Compared to interactive rebase, git merge --squash squashes commits during branch merging but requires manual committing of changes. This method suits branch integration scenarios but offers less control. Interactive rebase is more flexible, enabling precise history management.
Practical Application Example
Referencing the Q&A data, the user's scenario involves file additions and deletions. Through interactive rebase, these two commits can be merged into one, described as "Initial homepage setup." Below is a code example simulating this process:
# Assume initial state with two commits
git log --oneline
# Output: abc123 Added homepage.html and contacts.html
# def456 Added homepage.php and deleted old files
# Initiate interactive rebase
git rebase -i HEAD~2
# In the editor, change the second line to squash
# After saving, Git processes the squash and opens the commit message editor
# Enter a new message: "Initial homepage setup with PHP migration"
# Verify after rebase completion
git log --oneline
# Output: xyz789 Initial homepage setup with PHP migrationThis example demonstrates consolidating scattered changes into a logical unit, improving history clarity.
Conclusion
Interactive rebase is an effective tool in Git for managing commit history, particularly for squashing multiple related commits. Based on real Q&A, this article systematically explains the operational flow, principles, and cautions. By correctly using git rebase -i, developers can optimize version control and avoid cluttered histories. It is recommended to back up branches before operation and use history rewriting cautiously in collaborative environments.