What does cherry-picking a commit with Git mean?

1,692,509

Solution 1

Cherry picking in Git means to choose a commit from one branch and apply it onto another.

This is in contrast with other ways such as merge and rebase which normally apply many commits onto another branch.

  1. Make sure you are on the branch you want to apply the commit to.

     git switch master
    
  2. Execute the following:

     git cherry-pick <commit-hash>
    

N.B.:

  1. If you cherry-pick from a public branch, you should consider using

     git cherry-pick -x <commit-hash>
    

    This will generate a standardized commit message. This way, you (and your co-workers) can still keep track of the origin of the commit and may avoid merge conflicts in the future.

  2. If you have notes attached to the commit they do not follow the cherry-pick. To bring them over as well, You have to use:

     git notes copy <from> <to>
    

Additional links:

Solution 2

This quote is taken from: Version Control with Git

Using git cherry-pick The command git cherry-pick commit applies the changes introduced by the named commit on the current branch. It will introduce a new, distinct commit. Strictly speaking, using git cherry-pick doesn’t alter the existing history within a repository; instead, it adds to the history. As with other Git operations that introduce changes via the process of applying a diff, you may need to resolve conflicts to fully apply the changes from the given commit . The command git cherry-pick is typically used to introduce particular commits from one branch within a repository onto a different branch. A common use is to forward- or back-port commits from a maintenance branch to a development branch.

$ git checkout rel_2.3
$ git cherry-pick dev~2 # commit F, below

before: before

after: after

Also, here is a very nice in action video tutorial about it: Youtube: Introduction to Git cherry-pick

Solution 3

Cherry picking in Git is designed to apply some commit from one branch into another branch. It can be done if you eg. made a mistake and committed a change into wrong branch, but do not want to merge the whole branch. You can just eg. revert the commit and cherry-pick it on another branch.

To use it, you just need git cherry-pick hash, where hash is a commit hash from other branch.

For full procedure see: http://technosophos.com/2009/12/04/git-cherry-picking-move-small-code-patches-across-branches.html

Solution 4

Short example of situation, when you need cherry pick

Consider following scenario. You have two branches.

a) release1 - This branch is going to your customer, but there are still some bugs to be fixed.

b) master - Classic master branch, where you can for example add functionality for release2.

NOW: You fix something in release1. Of course you need this fix also in master. And that is a typical use-case for cherry picking. So cherry pick in this scenario means that you take a commit from release1 branch and include it into the master branch.

Solution 5

I prepared step-by-step illustrations what cherry-pick does — and an animation of these illustrations (near the end).

  1. Before cherry-picking
    (we are going to do a cherry-pick of the commit L from the branch feature): enter image description here

  1. Starting the command git cherry-pick feature~2
    (feature~2 is the 2nd commit before
    feature, i.e. the commit L): enter image description here

  1. After performing the command (git cherry-pick feature~2): enter image description here

The same animated: enter image description here


Note:

The commit L' is from the user's point of view (commit = snapshot) the exact copy of the commit L.

Technically (internally), it's a new, different commit (because e.g. L contains a pointer to K (as its parent), while L' contains a pointer to E).

Share:
1,692,509
Rahul
Author by

Rahul

I am a AWS certified solution architect, Node.js developer and a Machine learning enthusiast.

Updated on July 08, 2022

Comments

  • Rahul
    Rahul almost 2 years

    Recently, I have been asked to cherry-pick a commit.

    So what does cherry-picking a commit in git mean? How do you do it?

    • Levent Divilioglu
      Levent Divilioglu over 8 years
      Instead of merge, with cherry-picking re-committing from a branch to the target branch (ex: master) is easier.
    • U. Windl
      U. Windl about 3 years
      Could one say?: "Cherry-picking a commit means creating a temporary branch on HEAD, merging the diff of that commit into it, then fast-forward HEAD." Or in simple words: "Merging a single commit".
  • Nav
    Nav about 10 years
    Is cherry picking really necessary? Won't a mixed reset or a soft reset do a similar job?
  • parasrish
    parasrish almost 8 years
    when cherry-picked commits are taken on some branch (b1) and later delivered to master. And if branch b1 (from which commits were originally picked) is also tried to be delivered to master. How about the conflicts? Is that taken care or how does it work?
  • Teoman shipahi
    Teoman shipahi over 7 years
    @parasrish Yes, they are already taken care with your previous merges. So you did changes a,b,c,d from (b1) branch. You cherry picked only "c". Then in future once you merge from (b1) to master, since "c" changes are same, it will only merge a,b,d and remain "c" changes. But if you rollback your merge, then you will go back changes with "c" in it. You will need to roll them back separately.
  • Nagappa L M
    Nagappa L M about 7 years
    git push is last step to take changes on master
  • Emile Vrijdags
    Emile Vrijdags almost 7 years
    FYI: A commit semantically contains all the files of the working tree of that moment (and the commit hash of the previous commit), so you are not applying a whole commit to another commit, but the changes a commit did on the previous commit "cherry-pick commit applies the changes introduced by the named commit on the current branch" Most ppl tend to think of commit as changes (like svn was iirc), but it is not, each commit refers to the complete working tree. Though this doesn't make a difference in this case, it can help in understanding why git works like it does.
  • Aluan Haddad
    Aluan Haddad almost 7 years
    I find this to be a quite helpful view of things. It implies why cherry-pick behaves the way it does when the target branch is later merged back into the source branch. Thank you, sir.
  • Thomas Bitonti
    Thomas Bitonti almost 7 years
    It should be emphasized: In the example as given, only the difference (F - E) is applied to Z. That is a narrow case. Cherry-pick may be used to apply the differences of multiple commits, say, all of the differences between two non-adjacent commits. For example, following from above, (F - E), (E - D), (D - C), and (C - B). That is equivalent to applying the difference (F - B).
  • Thomas Bitonti
    Thomas Bitonti almost 7 years
    Also, what happens if the selected Commit (F in the example) has more than one immediate predecessor?
  • Teoman shipahi
    Teoman shipahi almost 7 years
    @ThomasBitonti I think it is pretty clear only the difference (F - E) is applied to Z. Letters indicate commits, and single commit applied over Z. You can clearly see it in the command as well. Also OP asked for "What is cherry picking", not how to apply "Multiple Cherry Picks". Moreover applying cherry pick from single commit is not a narrow case, it is pretty much a wide case scenario.
  • TahoeWolverine
    TahoeWolverine almost 7 years
    I'm confused by what the ~2, the #, and the ", above" accomplish in the example; any explanation?
  • RBT
    RBT almost 7 years
    @Zitrax are notes different from commit message? My single git cherry-pick command was able to bring over my commit message as well. Are you talking about something else? I didn't need to run git notes command at all to accomplish it.
  • Zitrax
    Zitrax almost 7 years
    @RBT Yes notes are different from the commit message, the commit message follows the commit on cherry-pick. See git-scm.com/docs/git-notes
  • jcanizales
    jcanizales over 6 years
    Nav, the difference would be the same as with rebasing: with cherrypicking you get automerge and don't carry over unwanted stuff from the other branch.
  • j2emanue
    j2emanue about 6 years
    @Teoman shipahi so what i was thinking of doing is using git cherry-pick instead of git merge when i have finished a feature and want to merge it into my master branch. so anytime i do a feature and its 100% complete,i'd like to do git cherry-pick with the last commit hash instead of git merge or git rebase, what are your thoughts on this ? why dont more people do this after a feature is complete ?
  • j2emanue
    j2emanue about 6 years
    i would like to use cherry pick instead of git merge after a feature is done. everyone always does git merge feature_branch when they are completed a feature. why not use cherry-pick command ? do you have any thoughts ?why bother squashing commits if i can cherry-pick
  • Teoman shipahi
    Teoman shipahi about 6 years
    @j2emanue I think you should definitely do git merge, instead of git cherry-pick in your case. Then you will get full benefit of keep tracking of history, and git branching ideology. git cherry-pick should be used in very rare cases, like you created a branch, then changed 10 different files just for testing a feature, and just changes in only one of the files (or full commit depending on the what you commit) makes sense. So instead of merge, you can cherry pick that file. Otherwise, for adding feature or bug fixes, branching and merging is way to go.
  • Teoman shipahi
    Teoman shipahi about 6 years
    @j2emanue in other words, cherry-pick will only take changes of last-commit. If you commit 3 different times, and if you cherry pick last one, it will not take changes on first and second commit. Merge command will take all your changes and apply to your target (master) branch.
  • mfaani
    mfaani over 5 years
    This seems like a very good answer. Would you mind editing your answer and reply to tahoewolverine's comment about what cherry-pick dev~2 # commit F, above does? The answer is made complex for one who's coming to learn one git command and now he's introduced with 2 more command/options to learn of
  • Akin Hwan
    Akin Hwan over 5 years
    do you need to type out the entire commit hash or can you tab complete?
  • Suncat2000
    Suncat2000 about 5 years
    Cherry-picking does not apply just the changes from a single commit (E-F) to Z. It applies changes (E-F) to Y-(E-Y)-Z. I haven't yet found a workaround to this frustrating behavior.
  • canbax
    canbax almost 5 years
    You might just need the other way. You fixed a bug in master and you should cherry-pick that to release1. Also they might be repositories rather than branches
  • Saurabh Patil
    Saurabh Patil almost 5 years
    This is confusing. I think here you're on a branch other than master, right? And when you mentioned two commits you're referring to the <from> and <to> commits to define the range you want to cherry-pick. Correct? It would greatly help if the scenario is described. Good addition though. Thanks.
  • FreeLightman
    FreeLightman over 4 years
    Why do not use merge for it?
  • Jasper-M
    Jasper-M over 4 years
    I would: create branch off release, fix it in the branch, merge branch in release, merge release in master.
  • Priyank Thakkar
    Priyank Thakkar about 4 years
    Does it mean, L' will be N -> M -> L on branch master? or it will exclusively bring commit L on master branch
  • MarianD
    MarianD about 4 years
    @PriyankThakkar, yes, exclusively L, nothing else (as you can see from pictures / animation).
  • mins
    mins about 4 years
    Certainly the most interesting answer, because it talks about what is important, the files, not the commit as a whole.
  • Paŭlo Ebermann
    Paŭlo Ebermann over 3 years
    »The commit L' is from the user's point of view (commit = snapshot) the exact copy of the commit L.« – No, it's not the same snapshot (unless the snapshots K and E were already the same), just the same difference (i.e. E→L' = K→L).
  • Paŭlo Ebermann
    Paŭlo Ebermann over 3 years
    You could see a rebase as a combination of reset and cherry-pick.
  • Paŭlo Ebermann
    Paŭlo Ebermann over 3 years
    @j2emanue Compared to a real merge, cherry-pick will flatten the history, which can give you non-compiling code in the middle if you don't pay attention. Compared to a squash merge, it's more difficult to use because you need to pay attention to take all commits with you.
  • MarianD
    MarianD over 3 years
    @Paŭlo, you extracted this sentence out of context, not reading just the next one...:-) Moreover, the differences E→L' and K→L are not the same.
  • Burgito
    Burgito over 3 years
    This needs more consideration, the result of cherry pick can lead to dangerous paths ^^
  • mandelf
    mandelf over 3 years
    As I mentioned in my reply above, beware: cherry-picking will not apply the changes (as in : the lines of code which have changed) but the commit (meaning the whole files which have changed)
  • Jovylle
    Jovylle over 3 years
    Yeah, but the changes in K is also applied right.?
  • MarianD
    MarianD over 3 years
    @Jovylle, think about a commit as a snapshot, not as differences between them. Differences git don't save, only the current full content of files. So changes from K to L don't matter, only the current status of L.
  • U. Windl
    U. Windl about 3 years
    I think this answer could be improved by showing some example output like "the standardized" commit message. Does that include the original branch name, commit ID and log message? (I haven't cherry-picked yet, but I guess "yes")
  • U. Windl
    U. Windl about 3 years
    I think this answer requires to explain the relationship between branches: If release1 is expected to be merged into master later, it might not make sense to cherry-pick (IMHO). You would also want to rebase master1 after having cherry-picked, I guess.
  • LeanMan
    LeanMan over 2 years
    One thing that isn't noted about git cherry-pick is that file blobs are what are stored in in commits so cherry-pick applies the file blob of that commit to your HEAD. This also means that if changes exist in your file blob that were essentially built upon parent commits, those get implicitly applied too. So its not a patch file that only applies the file changes from parent.
  • information_interchange
    information_interchange over 2 years
    What happens if the underlying branch changed, such that the cherry pick doesn't make sense?