git cherry-pick
Advanced Git CLI Careful
Summary: git cherry-pick <hash> takes the change introduced by one commit and applies it to the branch you are on, as a new commit with a new hash. The original stays where it was.
Careful — it copies rather than moves, so the same change can end up on two branches with different hashes, which confuses later merges if you forget the second half of the job.
What it does
Computes the diff of the named commit against its parent, applies it to the current branch, and commits it with the same message and author. Because the parent is different, the new commit has a different hash.
Why it exists
Sometimes a change is needed on a branch it was not made on: a fix on main that must also go into a release branch, or a commit made on the wrong branch entirely. Merging the whole branch would bring everything; cherry-pick brings one commit.
When to use it
- Backports: a fix on
mainneeds to go ontorelease/1.2(lesson 13.5). - A commit on the wrong branch: copy it to the right one, then remove it from the wrong one (lesson 12.7).
- Rescuing one commit from a branch that is otherwise being abandoned.
When not to use it
- To bring a whole branch's work across:
git mergeorgit rebase. - Repeatedly, between long-lived branches. If you are cherry-picking every fix, the branches have a structural problem worth discussing.
Syntax
| Form | Effect |
|---|---|
git cherry-pick <hash> |
Copy that commit onto the current branch |
git cherry-pick <a> <b> |
Copy two commits, in the order given |
git cherry-pick <a>..<b> |
Copy a range, excluding <a> itself |
git cherry-pick -n <hash> |
Apply the change but do not commit |
git cherry-pick -x <hash> |
Add a "(cherry picked from commit …)" line to the message |
git cherry-pick --continue |
After resolving a conflict and staging the files |
git cherry-pick --abort |
Stop and return to the state before |
-x is worth using on backports: it records where the change came from, which is exactly the question someone asks six months later.
Examples
Copy a commit onto a release branch:
$ git switch release/1.2
$ git cherry-pick 95a0014[release/1.2 83d3709] docs: add Windows steps to installation guide (#12)
1 file changed, 4 insertions(+)Note the new hash, 83d3709: this is a copy, and the original 95a0014 is untouched on its own branch.
Escape a conflicting cherry-pick:
$ git cherry-pick --abortExpected result
One new commit on the current branch with the same message and author as the original, and a different hash. git log --oneline -1 confirms it.
Common mistakes
- Thinking it moves the commit. It copies; removing the original is a separate step.
- Cherry-picking a merge commit without
-m, which fails for the same reason asgit revert. - Forgetting
-xon a backport, losing the record of where the change came from. - Cherry-picking instead of merging when the whole branch is wanted, which produces duplicate commits and awkward merges later.
- Cherry-picking a commit that depends on an earlier one, which conflicts or, worse, applies cleanly and behaves oddly.
How to undo or recover
- Mid-operation:
git cherry-pick --abort. - After it committed and before pushing:
git reset --hard HEAD~1. - After pushing:
git revertthe copy.
In VS Code
The Source Control graph's commit context menu offers Cherry Pick Commit when the GitHub or GitLab extension is installed.
In IntelliJ IDEA
Right-click a commit in the Log → Cherry-Pick. IntelliJ applies it to the current branch and opens the commit dialog.
On GitLab and GitHub
GitLab offers Cherry-pick on a merged merge request and on a commit page, creating a new branch and merge request. GitHub has no button; the usual route is a new pull request created from a local cherry-pick.
Related commands
git revert, which applies a commit backwards · git rebase, which is cherry-pick applied to a whole branch · git log to find the hash · git merge when you want everything.