Reputation: 2081
I am trying to drop a list of commits by using git rebase -i HEAD~19
. I have successfully used this method in the past, but when I try running and then quitting vim
without any changes(:q!
) I get this error:
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:
git commit --allow-empty
Otherwise, please use 'git cherry-pick --skip'
interactive rebase in progress; onto dd0b851
I am not cherry picking and not sure why I'm getting an error to skip.
Upvotes: 4
Views: 3904
Reputation: 1324347
You might need to git rebase --empty(=drop|keep|ask)
option:
How to handle commits that are not empty to start and are not clean cherry-picks of any upstream commit, but which become empty after rebasing (because they contain a subset of already upstream changes).
With drop (the default), commits that become empty are dropped.
This is especially useful (now Q2 2024) because the git cherry-pick
done in the background by git rebase
also understand --empty(=drop|keep|ask)
With Git 2.45 (Q2 2024), batch 14, allow git-cherry-pick
(1) to automatically drop redundant commits via a new --empty
option, similar to the --empty
options for git-rebase
(1) and git-am
(1).
See commit ec79d76, commit bd2f9fd, commit 661b671, commit 1b90588, commit c282eba, commit 64a443e, commit 0af3889 (25 Mar 2024) by Brian Lyles (brianmlyles
).
(Merged by Junio C Hamano -- gitster
-- in commit 17381ab, 03 Apr 2024)
cherry-pick
: add--empty
for more robust redundant commit handlingSigned-off-by: Brian Lyles
As with
git-rebase
(1) andgit-am
(1),git-cherry-pick
(1) can result in a commit being made redundant if the content from the picked commit is already present in the target history.
However,git-cherry-pick
(1) does not have the same options available thatgit-rebase
(1) andgit-am
(1) have.There are three things that can be done with these redundant commits: drop them, keep them, or have the cherry-pick stop and wait for the user to take an action.
git-rebase
(1) has the--empty
option added in commit e98c426 ("rebase (interactive-backend): fix handling of commits that become empty", 2020-02-15, Git v2.26.0-rc0 -- merge listed in batch #8), which handles all three of these scenarios.
Similarly,git-am
(1) got its own--empty
in 7c096b8 ("am
: support --empty= to handle empty patches", 2021-12-09, Git v2.35.0-rc0 -- merge listed in batch #7).
git-cherry-pick
(1), on the other hand, only supports two of the three possiblities: Keep the redundant commits via--keep-redundant-commits
, or have the cherry-pick fail by not specifying that option.
There is no way to automatically drop redundant commits.In order to bring
git-cherry-pick
(1) more in-line withgit-rebase
(1) andgit-am
(1), this commit adds an--empty
option togit-cherry-pick
(1).
It has the same three options (keep
,drop
, andstop
), and largely behaves the same.
The notable difference is that forgit-cherry-pick
(1), the default will bestop
, which maintains the current behavior when the option is not specified.Like the existing
--keep-redundant-commits
,--empty=keep
will imply--allow-empty
.The
--keep-redundant-commits
option will be documented as a deprecated synonym of--empty=keep
, and will be supported for backwards compatibility for the time being.
git cherry-pick
now includes in its man page:
previous commit will cause the cherry-pick to fail. To force the inclusion of those commits, use
--empty=keep
.
git cherry-pick
now includes in its man page:
--empty=(drop|keep|stop)
How to handle commits being cherry-picked that are redundant with changes already in the current history.
--
drop
;; The commit will be dropped.keep
;; The commit will be kept. Implies--allow-empty
.stop
;; The cherry-pick will stop when the commit is applied, allowing you to examine the commit. This is the default behavior.Note that
--empty=drop
and--empty=stop
only specify how to handle a commit that was not initially empty, but rather became empty due to a previous commit. Commits that were initially empty will still cause the cherry-pick to fail unless one of--empty=keep
or--allow-empty
are specified.
Upvotes: 1
Reputation: 28944
This is happening because you aren't doing what you think you're doing:
but when I try running and then quitting
vim
without any changes(:q!
)...
When you quit without modifying that file, you are actually still doing the rebase. If you want to exit without doing the rebase, you should delete all the lines in the file (or at least every line that contains a commit on it), and then save and exit. This will display an error and abort the rebase.
The reason just exiting usually works, and appears to do nothing, is because when your history is linear, by default Git won't rewrite a commit if nothing at all about the commit has changed, so it keeps the original commit ID and moves on. This is why you still see "rebasing 1/X..." as it iterates through all the commits and doesn't actually re-write them.
If you history is not linear (meaning you have some merge commits included in the rebase), the merge commits are not included in the to-do list. So this time rebasing will actually rewrite at least some of the commits, because you are missing the merge commits in this rewrite so the graph isn't identical. During the rebase, if it encounters a commit with no changes in it, you will get the message you saw. It stops here because this is considered unusual and it gives you the opportunity to decide what to do. The reason it mentions cherry-pick
is because behind the scenes, rewriting commits during a rebase is essentially doing a cherry-pick of each commit for you.
Side Note: the most likely reason that you would have empty commits in this situation is when you have a similar commit on both sides of a merge commit (which is missing from the rebase to-do list).
Upvotes: 6