Table of contents
Open Table of contents
What is git cherry-pick?
git cherry-pick
is one of the most useful git commands, allowing you to copy and paste commits from one branch to another.
git cherry-pick
does not affect the original commit, so the commit remains in the source branch.
Many developers consider the use of git cherry-pick
to be a bad practice, as it can cause issues such as having duplicate commits in multiple branches, ruining the git history, among others.
However, by understanding how git cherry-pick
works and using it with caution, it is one of the most useful tools in git.
Some use cases of git cherry-pick
are:
- Copying a commit made on the wrong branch to the correct branch and deleting the original commit.
- Copying a quick fix to the pre-production branch when it’s an urgent error.
- Sharing changes between backend and frontend when the code is in the same repository.
How to use cherry-pick
To copy a commit, we need the hash of the commit to be copied and be positioned in the branch where we want to paste the commit.
The use of the git cherry-pick
command is as follows:
git cherry-pick <commit hash>
Note: The commit hash can be obtained using the
git log
command or directly from Github.
Example: We have a fix for an urgent bug that we can’t wait for the current work in the develop branch to finish, the fix is within the commit ecd878a
on the dev
branch, to transfer this fix to the master
branch we position ourselves on that branch and run the command git cherry-pick <commit hash>
.
a - b - c - d master
\
e - f (fix urgent bug) - g - h dev
cherry-pick-test on master
$ git cherry-pick ecd878a60bd061912d395a5ea1f30d0729a360d0
[master 87dce58] fix urgent bug
Date: Thu Sep 9 11:44:55 2021 -0500
1 file changed, 1 insertion(+), 1 deletion(-)
a - b - c - d - f (fix urgent bug) master
\
e - f (fix urgent bug) - g - h dev
Copying Changes Without the Commit
In some cases, we do not want to copy the commit itself, but only the changes, either for a review or to make adjustments to the code.
git cherry-pick -n <commit hash>
Continuing the previous example, instead of directly copying the commit, we can copy the changes and keep them in the stage
.
cherry-pick-test on master
$ git cherry-pick -n ecd878a
cherry-pick-test on master
$ git status
On branch master
Changes to be committed:
(use git restore --staged <file>... to unstage)
modified: index.js
Note: With
git cherry-pick
, we can use the short version of the hash.
Conflicts
Just like with git merge
, we can have conflicts when copying a commit with git cherry-pick
, in this case git will pause the copy process and ask us to resolve the conflict.
Once the conflict has been resolved, we need to tell git that we are ready to resume the copy process, with the following command:
git cherry-pick —continue
In case you want to cancel the copy process, you can indicate it with the following command:
git cherry-pick —abort
Copying a series of commits
git cherry-pick <commit A hash>..<commit B hash>
<commit A hash>
and <commit B hash>
are two different commits belonging to the same branch. git cherry-pick
will copy all the commits found between commit A and commit B, excluding commit A. Commit A must be prior to commit B.
If we want to copy all the commits found between commit A and commit B, including commit A, the command should be as follows:
git cherry-pick <commit A hash>^..<commit B hash>
Summary:
git cherry-pick <commit hash>
: to copy one commit from another branch to the current branch.git cherry-pick -n <commit hash>
: to copy the changes of a commit from another branch to the current branch.git cherry-pick —continue
: to continue with the copy of a commit after resolving conflicts.git cherry-pick —abort
: to cancel the copy of a commit after resolving conflicts.git cherry-pick <commit A hash>..<commit B hash>
: to copy all commits between commit A and commit B excluding commit A.git cherry-pick <commit A hash>^..<commit B hash>
: to copy all commits between commit A and commit B including commit A.
I hope this information is helpful for your day-to-day use of git.