Overview
Regardless of the size of the project, when you work with a group of programmers, it can be difficult to handle changes between multiple Git branches. Sometimes, instead of merging an entire Git branch into another branch, it is better to select and move a few specific commits. This process is called “cherry-pick”.
This article will introduce the what, why and how of “Cherry-pick”.
Let’s get started~
What is Cherry-pick?
With cherry-pick
the command, Git can merge selected commits from any branch into the current Git HEAD branch .
When executing git merge
or git rebase
, all commits of a branch will be merged. The cherry-pick
command allows you to select individual commits for integration.
The difference is shown below:
△ When using merge: When performing merge or rebase, all commits of a branch will be integrated.
△ When using cherry-pick: Allows you to select individual commits to integrate. In this case, only C2 is integrated into the master branch, not C4.
Why use Cherry-pick?
The following situation may make it easier to understand the role of “Cherry-pick”.
Imagine you are implementing new features for the upcoming weekly spring. Once your code is ready, you’ll push it to the remote branch, ready for testing.
However, the client is not satisfied with all the changes and requires you to submit only certain changes. Because the customer has not approved all changes for the next release, git rebase
the expected results will not occur. Because git rebase
or git merge
will include all adjustments from the previous sprint.
Cherry-pick can solve this problem! Because cherry-pick only looks at changes added in commits, it will only bring in approved changes and will not add other commits.
There are other reasons to use “cherry-pick”:
- This is very important for fixing bugs because bugs in development branches are set with their commits.
- By using
git cherry-pick
instead of other options (such asgit diff
) to apply specific changes to commit, you can avoid unnecessary fights. - This is a useful tool if a complete branch merge cannot be performed because the versions of various Git branches are incompatible.
When to use Cherry-pick?
In short: use as little as possible . The reason why you should use cherry-pick as little as possible is that it can easily produce “duplicate” commits: when you use cherry-pick to integrate a commit into the HEAD branch, Git must create a new commit with exactly the same content. However, this is a completely new commit object, with its own SHA identifier. You also lose the ability to track commit history.
If you make a lot of commits out of order, these commits will be recorded in your branch, which may lead to undesirable results in your Git branch.
Whenever it can be integrated using a traditional merge or reset, it should be done. Cherry-picking should be reserved for situations where this is not possible, such as having to create a hotfix or just wanting to save one or a few commits from an abandoned branch.
How to use the Cherry-pick command?
Process overview
Here are the steps:
- Pull the local branch. use
git fetch
. - Go back to the branch you want to merge into. You would probably
git checkout main
do this by running - Find the commit you want to pull into the branch. Go to
git log
, get a unique commit hash for each commit. - “Cherry-pick” the commit you want to add to the branch. Run the following command:
git cherry-pick <commit sha>
. This will pull only this commit into the current branch. - (Optional) In some cases, it may be necessary to resolve conflicts manually.
- Push this branch as usual:
git push origin main
.
Specific commands
In cherry-pick
the simplest form of the command, you simply use the SHA identifier of the commit you want to integrate into the current HEAD branch.
To get the commit hash, you can use git log
the command:
git log --oneline
Once you know the hash of the commit, you can use cherry-pick
the command.
The syntax is as follows:
git cherry-pick <commit sha>
📝 Notes :
<commit sha>
Can be multiple
For example:
git cherry-pick 85c5532
This will apply the specified changes exclusively to the currently checked-out branch.
If you want to make further changes, you can also instruct Git to add the changes to your working copy and commit them.
The syntax is as follows:
git cherry-pick <commit sha> --no-commit
like:
git cherry-pick 85c5532 --no-commit
If you want to select multiple commits at once, add their commit hashes separated by spaces:
git cherry-pick hash1 hash3
When picking commits, you cannot use git pull
the command because it will take the commits from one repository and automatically merge them into another repository. cherry-pick
command is a tool designed to avoid this happening; instead use git fetch
, which will get the commits but not apply them.
Cherry-pick in action
To try the process, launch a terminal and build a sample project:
mkdir fruit.git
cd fruit.git
git init .
Create some data and submit:
echo "Kiwifruit" > fruit.txt
git add fruit.txt
git commit -m 'First commit'
Now, create a fork of the project to represent the remote developer:
mkdir ~/fruit.fork
cd !$
echo "Strawberry" >> fruit.txt
git add fruit.txt
git commit -m 'Added a fruit"
This is a valid commit. Now, create a bad commit, something you don’t want merged into your project:
echo "Rhubarb" >> fruit.txt
git add fruit.txt
git commit -m 'Added a vegetable that tastes like a fruit"
Go back to your canonical repository and fetch the commits from your imaginary developer (using git fetch
fetch):
$ cd ~/fruit.git
$ git remote add dev ~/fruit.fork
$ git fetch dev
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 6 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done...
$ git log –oneline dev/master
e858ab2 Added a vegetable that tastes like a fruit
0664292 Added a fruit
b56e0f8 First commit
You’ve fetched the commits from the hypothetical developer, but haven’t merged them into your repository yet. You want to accept the second commit, but not the third, so use cherry-pick
:
git cherry-pick 0664292
Now, the second commit is in your repository:
$ cat fruit.txt
Kiwifruit
Strawberry
Push the changes to the remote server and you’re done!
Cherry-pick multiple submissions in action
Select several commits from dev to merge:
git cherry-pick 85c5532 366a196 53ebe44 --no-commits
Then, maybe the first merge will have conflicts, resolve them manually, and merge git add
specific files or git rm
.
Continue cherry-pick:
git cherry-pick --continue
The second commit may have no conflicts and be merged directly.
The third commit may have conflicts again, resolve them manually, and git add
re-commit specific files or git rm
.
Continue cherry-pick:
git cherry-pick --continue
Finally, execute it again git cherry-pick --continue
, and you will be prompted that there is no task running.
At this point, you can submit:
git push origin main
Conclusion
Cherry-pick is a powerful command, and using it without a proper understanding of what might happen can cause trouble. Still, it might save your life (at least your day job) when you screw up and commit to the wrong branch.