I want to squash several commits together in the middle of a branch without modifying the commits before and after.
I have :
A -- B -- C -- D -- E -- F -- G
A -- H -- E -- F -- G
B -- C -- D
You can do an interactive rebase and hand select the commits which you want to squash. This will rewrite the history of your
master branch, but since you have not pushed these commits, there should not be any negative aftermath from this besides what might happen on your own computer.
Start with the following:
git checkout master git rebase -i HEAD~6
This should bring up a window showing you the following list of 7 commits, going back 6 steps from the HEAD of your
pick 07c5abd message for commit A pick dl398cn message for commit B pick 93nmcdu message for commit C pick lst28e4 message for commit D pick 398nmol message for commit E pick 9kml38d message for commit F pick 02jmdmp message for commit G
The first commit shown (
A above) is the oldest and the last is the most recent. You can see that by default, the option for each commit is
pick. If you finished the rebase now, you would just be retaining each commit as it is, which is effectively a no-op. But since you want to squash certain middle commits, edit and change the list to this:
pick 07c5abd message for commit A pick dl398cn new commit message for "H" goes here squash 93nmcdu message for commit C squash lst28e4 message for commit D pick 398nmol message for commit E pick 9kml38d message for commit F pick 02jmdmp message for commit G
Note carefully what is happening above. By typing
squash you are telling Git to merge that commit into the one above it, which is the commit which came immediately before it. So this says to squash commit
D backwards into commit
C, and then to squash
B, leaving you with just one commit for commits
D. The other commits remain as is.
Save the file (: wq on Git Bash in Windows), and the rebase is complete. Keep in mind you can get merge conflicts from this as you might expect, but there is nothing special about resolving them and you can carry on as you would with any regular rebase or merge.