Your description of what you thought git cherry-pick
does is close enough to what it actually does to serve as the initial description. (Your proposed use case is thus the main use case.) All we need to do to make it completely accurate is:
- Note that Git's internal implementation uses Git's merge engine, so that you will sometimes see a "merge conflict". In this case, the cherry-pick operation stops in the middle, requiring that you resolve the conflict and use
--continue
to finish it.
- Note that you may cherry-pick more than one commit at a time: in this case Git does each selected commit, one at a time, as in note 1, and then moves on to the next commit.
- Note that with without
-n
, each cherry-pick step (a) requires that the working tree and index be "clean" (match the current commit, more or less) at the beginning, and each commit being copied will have its commit message copied as well, into a new commit, resulting again in this clean state; but with -n
, the initial setup need not be "fully clean" and the operation will not make a new commit on its own.1
- Note that this all uses—at least potentially—the sequencer (to do multiple commits), as do
git revert
and modern git rebase
, and the sequencer can only do one thing at a time, so if you're in the middle of a revert or rebase, some use cases are limited.
As a side note regarding the comments, the term object, in Git, refers to Git's internal object storage. There are four object types: blobs, trees, commits, and annotated tags. A blob object stores any unique file contents (but not a file's name, nor its +x vs -x chmod
state) and this is how Git de-duplicates files whose content is shared between, or even within, any given set of commits. A tree object stores the file name and mode information, a commit object stores the commit metadata (including the hash ID of the tree object that saves the snapshot), and a tag object stores annotated tag data for use by git tag -a
and company. If we ignore the special case of annotated tags, commits need just the remaining three objects: one to store the commit itself, one or more to store tree data, and zero or more to store the file-contents that are stored as the commit's snapshot.
Cherry-picking views the commit as a whole, and compares parent P
vs child C
to see what changed in the given pair of commits. In order to apply those changes to the current (HEAD) commit, it then compares P
vs HEAD
as well, which is why and how it ends up using the merge engine. (For -n
style cherry-picks, it uses the current index rather than the HEAD
commit. Since non--n
cherry-picks require that HEAD
and index match, it can actually just always use the index.)
1There's no proper, strict definition of clean, and the actual implementation tends to be ad-hoc: any command that requires a "clean state" does its own checking and hence determines what it means, for that particular command, to be "clean". However, there is a require_clean_work_tree
function in git-sh-setup
, and this provides a very good starting point for a proper definition. Note how submodules tend to be ignored here, which may not always be appropriate.