NB: This is a rewording of an earlier post of mine (now deleted). The rewording intends to give the post a different focus.
Upon running git cherry-pick
, git
reported that there was a conflict. I resolved the conflict, and then ran git cherry-pick --continue
. At this point, $GIT_EDITOR
popped up a COMMIT_EDITMSG
buffer pre-populated with the cherry-picked commit's original message along with some additional info, which included the warning:
# It looks like you may be committing a cherry-pick.
# If this is not correct, please remove the file
# .git/CHERRY_PICK_HEAD
# and try again.
I checked to see what happened if I "deleted" (actually, just temporarily renamed) the .git/CHERRY_PICK_HEAD
file. The immediate outward effect this had was to remove the |CHERRY-PICKING
indication from my git
-aware prompt.
Other than this change in my prompt, and possibly some differences in the pre-populated information in the COMMIT_EDITMSG
buffer, what difference would it make to perform the commit with or without the .git/CHERRY_PICK_HEAD
file in place?
To be more precise, I'm trying to compare two scenarios here.
In the first scenario, I run
% git cherry-pick --continue
...and (disregarding the warning quoted earlier) I proceed with the commit as usual.
In the second scenario, I run
% rm .git/CHERRY_PICK_HEAD
% git commit
...and proceed with the commit as usual.
(Assume that I use the same commit message in both scenarios.)
How would the end results of these two scenarios differ?
Examples of git cherry pick The --no-commit option will execute the cherry pick but instead of making a new commit it will move the contents of the target commit into the working directory of the current branch.
To change the commit message when cherry-picking, use “git cherry-pick” with the “-e” option. As illustrated in this example, your default editor will open and it will let you change the commit message. When you are satisfied with the edits, save your file and your commit message should be saved successfully.
to choose only the best or most suitable from a group of people or things: They cherry-picked the most promising potential customers and concentrated their efforts on them.
The answer depends on what you were doing. Using --continue
finishes the sequence—but if the sequence was just the one cherry-pick, there wasn't really a sequence anyway.
Either way, however, removing the .git/CHERRY_PICK_HEAD
definitely has one additional significant effect: finishing a conflicted cherry-pick re-uses the original commit's author-name-email-and-date information. You are always the committer of any new commit, but all commits have not just one person-and-timestamp: each new commit has two entries, one for "committer" (you, making the commit, just now) and one for "author" (whoever wrote the original commit, and whenever they did that). Cherry-pick preserves the authorship information from the original commit.
Both git cherry-pick
and git revert
—which are actually the same command internally; revert just "works backwards"—use what Git calls the sequencer. That is, you can pick multiple commits all at once:
git cherry-pick notthis..that thistoo
to cherry pick all commits "after" notthis
, up through and including that
, and also the one specific commit thistoo
. You might, for instance, decide to cherry-pick every commit on feature/X
that grows from develop
, plus one bug fix commit fix-1234
, for testing purposes:
git checkout master
git checkout -b testbranch
git cherry-pick develop..feature/X fix-1234
Anyway, the point here is that this might cherry-pick a dozen or more commits, and somewhere along the way there could be a merge conflict, that requires that git cherry-pick
stop and get assistance.
Aside: the model here—the Unix/Linux command line—is that you enter a command into a command-interpreter called a shell. The shell passes control of the human-interface to the new command, which retains it until the command finishes and exits. Once the command exits, there is no trace left of the command itself: anything permanent must be saved in files.
So: If cherry-pick must stop, how will it know where to resume? The answer is by saving information in files. If you're cherry-picking a single commit, Git saves just the CHERRY_PICK_HEAD
file, which records the ID of the commit being cherry-picked. If you're cherry-picking multiple commits, though, Git saves the conflicted commit as for a single commit, and saves the remaining information in a sequencing directory (whose location has moved some over time).
Running git cherry-pick --continue
directs the (new, separate instance of) cherry pick command to pick up where the previous one left off. Git will first run a git commit
for you, then locate the sequencing information and finish as much of the sequence as it can, stopping again at the next conflict, or finishing all the cherry-picks.
Running git commit
instead, Git will notice the CHERRY_PICK_HEAD
file and use that as you have seen. When the commit finishes, that command exits and does nothing with the sequencer. If there is sequencer data left behind, you can now git cherry-pick --continue
: Git will notice that the commit is already done and simply continue / finish the sequencer operation.
Note that you can, instead of finishing the operation, use git cherry-pick --abort
. This terminates the operation and puts things back to the way they were before you started. As of Git 2.19, you can instead use git cherry-pick --quit
to stop (a la --abort
) but not put things back to how they were before you started. That is, it stops any future cherry-picking operations, without undoing the ones you have done so far. (This operation was missing before 2.19.)
The git status
command now notices if there is a sequence in progress, and reports that you are in the middle of whatever it is you were doing. (This is a big improvement from the Git 1.7 era, when it didn't.)
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