git rebase --autosquash
Scenario
When working in a feature branch, I make some changes to a file and then commit these changes. Later on, I make some additional changes to the same file on the same lines, and I want to squash these changes into the first commit touching the file.
Git rebase
You can do an rebase --interactive
(or git rebase -i
for short), and change the commit line from a pick
to a fixup
and place the commit beneath the commit to be squashed into.
This cleans up your commits, but it can be tedious if you have more than just a few commits you want to squash. That is where --autosquash
comes into the picture.
From the man git-rebase page:
--autosquash
When the commit log message begins with "squash! ..." (or "fixup! ..."), and there is a commit whose title begins with the same ..., automatically modify the todo list of rebase -i so that the commit marked for squashing comes right after the commit to be modified, and change the action of the moved commit from pick to squash (or fixup).
So by prefixing the commit message with either fixup!
or squash!
followed by the wording of the commit message to be squashed into, an interactive rebase will setup the todo list for you automatically.
Example
Say I have three commits (git log
), and I want commit 5929914
to be squashed into commit 13e88b0
:
commit 5929914169c97c08e9da967ba5f6d49704aaa999
More changes to Fix query for finding rows
commit 11c85ef5b907541b1b5f8fa7ef72e5d2c4f7b55c
Add unique constraint for calendar audiences
commit 13e88b0f2ec738b7ae61cc91a80067f0aed91c32
Fix query for finding rows
When I issue git rebase HEAD~3 -i
I see the following list:
pick 13e88b0 Fix query for finding rows
pick 11c85ef Add unique constraint for calendar audiences
pick 5929914 More changes to Fix query for finding rows
If I reword my commit message per the documentation for --autosquash
to be the following, commit 5929914
should be automatically positioned under commit 13e88b0
with the action changed to fixup
:
commit 5929914169c97c08e9da967ba5f6d49704aaa999
fixup! Fix query for finding rows
commit 11c85ef5b907541b1b5f8fa7ef72e5d2c4f7b55c
Add unique constraint for calendar audiences
commit 13e88b0f2ec738b7ae61cc91a80067f0aed91c32
Fix query for finding rows
Now with the command: git rebase HEAD~3 -i --autosquash
I get the following automatically changed in my todo list:
pick 13e88b0 Fix query for finding rows
fixup 5929914 fixup! Fix query for finding rows
pick 11c85ef Add unique constraint for calendar audiences
Voila! Now stop wasting your time moving around fixup and squashes
Written by Ben Simpson
Related protips
4 Responses
Note that you can use the commit SHA of the target commit as the message as well
@bsimpson: I think you should add that note somewhere in the article, not many people are going to see that in the comments ;)
Using the commit title is recommended. The reason is interesting and subtle. I have had reason to do multiple passes using git rebase --interactive --autosquash. Sometimes, it is necessary to avoid to many conflicts if you can rebase in multiple passes. Using the title allows the commit number to change without loosing the reference to the commit.
Thanks for this! I've been using git commit --fixup
without knowing about the rebase option.
Note that you could turn this on by default for all rebases, by:
$ git config --global rebase.autosquash true