git cherry-pick is one of the useful commands in Git that helps you to copy, paste commit(s) from one branch to another. Simple.
Note that cherry-pick will copy the commits so that the original commit will still be present in the source branch.
Most devs will consider cherry-picking is a bad practice that can cause problems like having duplicate commits in multiple branches, messing up with the git history, and others. But cherry-pick is one of the most powerful tools and if you understand how it works and if used with caution, then it can be really useful.
Some use cases of cherry-picking are that you may have some commits in the wrong branch and you can cherry-pick them to the right branch. Other use cases like you won’t need the entire branch to be merged (because it may have staled or something) but you need only particular commits. Then you can cherry-pick those commits to your branch.
How to cherry-pick
git cherry-pick <commit hash>
As you know, you can get the commit hash from git log
or others.
The above command will copy the commit with the corresponding hash and paste it in the current branch you are in.
In the above image, you can see that I have cherry-picked a commit and it has been applied to the current branch develop
.
Consider the below commit history.
A - B - C - D - E - F (Branch A)
\
G - H - I (Branch B)
If we gonna cherry-pick I from branch B then the commit history changes like below
A - B - C - D - E - F - I
\
G - H - I
You can see I is present in both branches now.
In some cases, you don’t need to commit the changes yet. You just need to copy all the changes.
git cherry-pick -n <commit hash>
In this case, git will copy the commit and then it will stage all the changes but it won’t commit the changes in the current branch. You can commit the changes yourselves or you can un-stage some part of it or do anything else.
In the above image, you can see the cherry-picked changes are staged but not committed yet.
git cherry-pick with conflicts
What if there were conflicts when you cherry-pick. Git will pause the cherry-pick. You have to resolve the conflicts and ask the git to continue with the cherry-pick.
In the above example, I have tried to cherry-pick a particular commit but it has resulted in a conflict. You can see the conflict in the above image. So we have to resolve the conflicts and then continue with the cherry-pick.
After resolving the conflicts, you can continue with the cherry-pick with the below command.
git cherry-pick —continue
If you decided to abort the cherry-pick with conflicts, you can use
git cherry-pick —abort
In the above example, I have resolved the conflict, then have staged the file. After that, I’m continuing with the cherry-pick.
git cherry-pick a series of commits
git cherry-pick A..B
In the above command, A and B are commit hashes.
The above command will include all commits from A to B excluding A. And remember A should be older than B.
git cherry-pick A^..B
This command will include all commits from A to B including A.
git cherry-pick a merge commit
Cherry-picking a merge commit is somewhat tricky. When there is a merge there are two branches included. A parent-B branch is merged into the parent-A branch.
So when you are cherry-picking a merge commit you have to specify whether you need to cherry-pick parent-A branch or the parent-B branch.
A - B - C - E - F (branch A)
\ /
G - H - I (branch B)
In this above case, E is the merge commit. And if you run git cherry-pick E
then git will throw a warning. You have to mention the parent branch number.
You can do
git cherry-pick -m 1 E
This will take all commits from C - E.
Or you can do
git cherry-pick -m 2 E
This will take commits from G - H - E.
But when cherry-picking the merge commit, always proceed with caution. There is a high possibility that you can mess up with history. So you have to decide in the given situation whether cherry-picking a merge commit is good or not.
Other useful commands I found
git cherry-pick <branch-name>
This command will copy only the latest commit from the given branch and apply it to the current branch. Remember only the latest commit in the given branch.
git cherry-pick ..<branch-name>
This command will take all the commits from the given branch that are older than the current branch you are in and apply it to the current branch.
Assume you have branches A and B. If you are applying this command from branch A, then all the commits from B that are older than branch A will be applied to branch A.
Points to remember
git cherry-pick <commit-hash> to cherry-pick a commit from another branch.
git cherry-pick -n <commit-hash> to cherry-pick the commit but it won’t commit the changes. It will only stage all the changes.
git cherry-pick —continue or git cherry-pick —abort when you face conflicts while cherry-picking.
git cherry-pick -m to mention the parent branch number when you are cherry-picking a merge commit.
git cherry-pick A..B to cherry-pick a series of commits.
That’s it for today :)
If you have any queries, feedback, or anything you can reply to the email or just add a comment.
If you think you need to cover some particular topic just reply to this email and I will definitely consider :)
No need to commit on do git cherry-pick --continue after git add command and resolving the conflict.
Sorry, but did you have to commit after adding the file with conflict?