I'm a bit new to the whole rebasing feature within git. Let's say that I made the following commits:
A -> B -> C -> D
Afterwards, I realize that D
contains a fix which depends on some new code added in A
, and that these commits belong together. How do I squash A
& D
together and leave B
& C
alone?
$ git checkout master
$ git log --oneline
$ git rebase --onto HEAD^^^ HEAD^
$ git log --oneline
For those using SourceTree:
Make sure you haven't already pushed the commits.
Squash with previous
You can run
git rebase --interactive
and reorder D before B and squash D into A.Git will open an editor, and you see a file like this:
Now you change the file that it looks like this:
And git will now meld the changes of A and D together into one commit, and put B and C afterwards. When you don't want to keep the commit message of D, you can also use the "fix" keyword.
Note: You should not change commits that have been pushed to another repo in any way unless you know the consequences.
git log --oneline -4
git rebase --interactive
Type
i
(Put VIM in insert mode)Change the list to look like this (You don't have to remove or include the commit message). Do not misspell
squash
!:Type Esc then
ZZ
(Save and exit VIM)Type
i
Change the text to what you want the new commit message to look like. I recommend this be a description of the changes in commit
A
andD
:Type Esc then
ZZ
git log --oneline -4
git show E
You have now created a new commit
E
. CommitsA
andD
are no longer in your history but are not gone. You can still recover them at this point and for a while bygit rebase --hard D
(git rebase --hard
will destroy any local changes!).Interactive rebase works well until you have big feature branch with 20-30 commits and/or couple of merges from master or/and fixing conflicts while you was commiting in your branch. Even with finding my commits through history and replacing
pick
withsquash
doesn't worked here. So i was looking for another way and found this article. I did my changes to work this on separate branch:Before this I got my pull request with about ~30 commits with 2-3 merges from master + fixing conflicts. And after this I got clear PR with one commit.