In case you are using the Tower Git client, using Interactive Rebase to squash some commits is very simple: just select the commits you want to combine, right-click any of them, and select the "Squash Revisions..." option from the contextual menu.
So the differences are: squash does not touch your source branch ( tmp here) and creates a single commit where you want. rebase allows you to go on on the same source branch (still tmp ) with: a new base.
The first one is to use the git merge command with the squash flag (two dashes there). And the second one is through an interactive rebase. The first option (merge) is very simple to perform.
I had a similar problem which I solved as follows:
This is the commit group I wanted to squash:
1 s 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 pick 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users
As you can see, I wanted no. 4, but 1, 2 and 3 had no previous commit to squash into. Hence the Cannot 'squash' without a previous commit error.
My solution was to use the r
option for # r, reword = use commit, but edit the commit message
So my commits list looked like this:
1 r 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 s 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users
After saving, the interactive shell asked me for the rewording of the chosen commit.
After that, my commit log resulted in a single commit which resulted in a cleaner commit history.
Interactive rebase presents commits in the reverse order of what you are used to when using git log
. git rebase -i
replays the selected commits in the exact (top-down) order they are listed in the saved rebase instructions file. When squashing, the commit selected for squashing is combined with the commit that precedes it in the (edited) list, i.e. the commit from the previous line. In your case - there is no previous commit for 56bcce7
. You have to do one of the following
git rebase -i HEAD~3
(if you want to squash 56bcce7
into 684f917
)If you mean to combine 56bcce7
with e43ceba
, and e43ceba
doesn't depend on 56bcce7
, then simply reorder them:
r e43ceba Lint.py: Replace deprecated link
s 56bcce7 Closes #2774
UPDATE: Gus's answer below suggests a better way of doing the same, without reordering the two commits:
r 56bcce7 Closes #2774
s e43ceba Lint.py: Replace deprecated link
This will squash/merge the two commits into one. When the interactive rebase asks for a reworded commit message for 56bcce7
, provide the commit message that describes the union of 56bcce7
and e43ceba
.
I had this problem and the reason why it happened in my case was that, you cannot squash older commits onto a new commit. Here is an example say you have 3 commits:
1 pick 01mn9h78 The lastest commit
2 pick a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back
Now if you say git rebase -i HEAD~3
and you do something like
1 pick 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 s 093479uf An old commit i made a while back
This will result in the error:
error: cannot 'squash' without a previous commit You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'. Or you can abort the rebase with 'git rebase --abort'.
Solution :
When squashing commits, you should squash recent commits to old ones not vice versa thus in the example it will be something like this:
1 s 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back
This will work fine, incase you want all your commit messages, I would suggest fixup instead of squash.
Squash with the reverse logic. You'll be able to select the desired commit message at the later step.
pick
the first commit that you don't want the commit-message for.squash
or fixup
the commit(s) that you want to merge, until the one that has the commit message that you actually wanted.pick 56bcce7 Closes #2774
squash e43ceba Lint.py: Replace deprecated link
:x
)Lint.py: Replace deprecated link
).:x
)Hope it's clearer for somebody ✌🏽
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With