How do I squash specific commits on a local branch?
You can do this with rebase
. Assuming commits A–J are on a local branch branchname
built on top of master
, then you can do this:
git checkout branchname
git rebase -i master
You'll be presented with an interactive window like this:
pick A Commit message A
pick B Commit message B
pick C Commit message C
pick D Commit message D
pick E Commit message E
...
Interactive rebase provides instructions for your scenario, so you should change "pick" to "squash" for C and D (and the same for G, H and J):
pick A Commit message A
pick B Commit message B
squash C Commit message C
squash D Commit message D
pick E Commit message E
This will squash B, C and D into a single commit, allowing you to change the commit message.
If you're happy to use the commit message of B, you can use "fixup" instead of "squash" and you won't be prompted to update the commit message.
The interactive window is very powerful, and you can reorder commits as much as you want, or even just delete the line (or change the prefix to "drop") and that commit will be removed. For instance, if E fixes a typo that you made in A, you can do this:
pick A Commit message A
fixup E Commit message E
pick B Commit message B
pick C Commit message C
pick D Commit message D
However, when you reorder commits, you run the risk of having to resolve conflicts along the way. You can always use git rebase --abort
to return to your original state.
git log --oneline
git checkout your-branch
git rebase -i HEAD~3
write your comments, then :wq(write and quit) and press Enter.
git log --oneline