I am trying to merge 2 commits into 1, so I followed “squashing commits with rebase” from git ready.
I ran
git rebase --interactive HEAD~2
In the resulting editor, I change pick
to squash
and then save-quit, but the rebase fails with the error
Cannot 'squash' without a previous commit
Now that my work tree has reached this state, I’m having trouble recovering.
The command git rebase --interactive HEAD~2
fails with:
Interactive rebase already started
and git rebase --continue
fails with
Cannot 'squash' without a previous commit
If you rebase feature-x on top of origin/develop, you do this on your local repo. This means feature-x is still in the state before rebasing in the remote repository. Since they don't have the same ancestor anymore, git will try to merge. To update the remote branch, you can do a force push.
If you're currently on your "commit 1", and the commit you want to merge, "commit 2", is the previous commit, you can run git rebase -i HEAD~2 , which will spawn an editor listing all the commits the rebase will traverse.
Use git rebase -i <after-this-commit> and replace "pick" on the second and subsequent commits with "squash" or "fixup", as described in the manual.
The error message
Cannot 'squash' without a previous commit
means you likely attempted to “squash downward.” Git always squashes a newer commit into an older commit or “upward” as viewed on the interactive rebase todo list, that is into a commit on a previous line. Changing the command on your todo list’s very first line to squash
will always produce this error as there is nothing for the first commit to squash into.
First get back to where you started with
$ git rebase --abort
Say your history is
$ git log --pretty=oneline a931ac7c808e2471b22b5bd20f0cad046b1c5d0d c b76d157d507e819d7511132bdb5a80dd421d854f b df239176e1a2ffac927d8b496ea00d5488481db5 a
That is, a was the first commit, then b, and finally c. After committing c we decide to squash b and c together:
(Note: Running git log
pipes its output into a pager, less
by default on most platforms. To quit the pager and return to your command prompt, press the q
key.)
Running git rebase --interactive HEAD~2
gives you an editor with
pick b76d157 b pick a931ac7 c # Rebase df23917..a931ac7 onto df23917 # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. #
(Notice that this todo list is in the reverse order as compared with the output of git log
.)
Changing b’s pick
to squash
will result in the error you saw, but if instead you squash c into b (newer commit into the older or “squashing upward”) by changing the todo list to
pick b76d157 b squash a931ac7 c
and save-quitting your editor, you'll get another editor whose contents are
# This is a combination of 2 commits. # The first commit's message is: b # This is the 2nd commit message: c
When you save and quit, the contents of the edited file become commit message of the new combined commit:
$ git log --pretty=oneline 18fd73d3ce748f2a58d1b566c03dd9dafe0b6b4f b and c df239176e1a2ffac927d8b496ea00d5488481db5 a
Interactive rebase rewrites history. Attempting to push to a remote that contains the old history will fail because it is not a fast-forward.
If the branch you rebased is a topic or feature branch in which you are working by yourself, no big deal. Pushing to another repository will require the --force
option, or alternatively you may be able, depending on the remote repository’s permissions, to first delete the old branch and then push the rebased version. Examples of those commands that will potentially destroy work is outside the scope of this answer.
Rewriting already-published history on a branch in which you are working with other people without very good reason such as leaking a password or other sensitive details forces work onto your collaborators and is antisocial and will annoy other developers. The “Recovering From an Upstream Rebase” section in the git rebase
documentation explains, with added emphasis.
Rebasing (or any other form of rewriting) a branch that others have based work on is a bad idea: anyone downstream of it is forced to manually fix their history. This section explains how to do the fix from the downstream’s point of view. The real fix, however, would be to avoid rebasing the upstream in the first place. …
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