Git Cherry-pick and Revert Tutorial
Learn how to copy specific commits across branches with cherry-pick and how to safely undo merged changes with revert, including conflict handling and recovery.
What you'll learn
- ✓What cherry-pick really does
- ✓When revert is safer than reset
- ✓Cherry-picking ranges of commits
- ✓Reverting merge commits
- ✓How to recover from a botched undo
Prerequisites
- •Comfort with git checkout, commit, and merge
What and Why
Two of git’s most useful surgical tools are cherry-pick and revert. They sound similar but solve opposite problems:
- Cherry-pick takes a commit from another branch and applies its patch onto the current branch.
- Revert creates a new commit that undoes the effect of an earlier commit, without rewriting history.
Use cherry-pick to pull a hotfix into a release branch. Use revert to back out a bad change on main without forcing anyone to rebase.
Mental Model
Both operations are patch-replay. Git computes the diff of the target commit and applies it as a new commit on HEAD. Cherry-pick replays the patch as-is; revert replays the inverse patch.
Cherry-pick C2 from feat into main:
feat: A --- C1 --- C2 --- C3
|
| apply patch of C2
v
main: A --- B --------- C2'
Revert C2 on main:
main: A --- B --- C2 --- D
\
\ apply inverse of C2
v
main: A --- B --- C2 --- D --- ~C2 Hands-on Example
Cherry-pick a hotfix into a release branch:
git checkout release/1.4
git cherry-pick 8a2c10f # the commit on main
git push origin release/1.4
Cherry-pick a range (exclusive of the lower bound):
git cherry-pick 8a2c10f^..d3f9c2a
Cherry-pick without committing (stage the changes but let you tweak first):
git cherry-pick -n 8a2c10f
# edit, then commit yourself
git commit -m "Backport: fix CSRF on /api/login"
Revert a bad commit on main:
git checkout main
git revert 7b1e0a3
git push origin main
This creates a new commit named like Revert "...". Everyone who pulls main gets the fix; no one has to rewrite anything.
Reverting a merge commit requires telling git which parent to keep. Parent 1 is usually the branch you merged into:
git revert -m 1 <merge-commit-sha>
Without -m, git refuses because it does not know which side of the merge to undo.
Common Pitfalls
Cherry-pick conflicts. Common when the source and target branches have diverged. Resolve manually, then:
git add <files>
git cherry-pick --continue
Empty cherry-picks. If the change already exists on the target branch, the cherry-pick is empty. Skip it:
git cherry-pick --skip
Or allow empty:
git cherry-pick --allow-empty 8a2c10f
Reverting a revert. Sometimes you revert, realize the change was actually needed, and want it back. Cherry-pick the original commit again, or revert the revert:
git revert <revert-sha>
Forgetting -m on merge revert. The error message is clear, but the consequence of guessing -m 2 instead of -m 1 is reverting the wrong side and re-introducing the bug.
Cherry-picking instead of merging. If you cherry-pick the same commit into two long-lived branches and later merge those branches, git can sometimes get confused about whether the change is “the same.” Prefer real merges for ongoing integration; reserve cherry-pick for one-off backports.
Practical Tips
Always cherry-pick with -x when backporting. It appends (cherry picked from commit ...) to the message, which makes archaeology much easier later:
git cherry-pick -x 8a2c10f
For repeated backports between main and release branches, consider git’s built-in rerere to remember conflict resolutions:
git config --global rerere.enabled true
Subsequent cherry-picks reuse your earlier conflict resolutions automatically.
When reverting a merge, immediately think about how to re-introduce the change cleanly. The reverted merge cannot simply be re-merged — git considers those commits already on the branch. You will need to revert the revert or rebase the original feature branch onto the current main.
To preview what a cherry-pick will do without applying it, try:
git diff main..feat -- path/to/file
Or generate a patch and inspect it:
git format-patch -1 8a2c10f --stdout
Recover from a cherry-pick or revert you regret using the reflog:
git reflog
git reset --hard HEAD@{3}
Just remember that reset --hard is destructive — make sure your working tree is clean first.
Wrap-up
Cherry-pick is for copying a specific change between branches. Revert is for undoing a change without rewriting history. Both are safe by default — they create new commits and leave the originals untouched. Use -x to track provenance, -m 1 to revert merges, and the reflog to escape any mistake. Mastering these two commands lets you ship hotfixes, back out bad releases, and untangle history on shared branches without ever needing the dangerous “force push everyone, sorry” message in your team chat.
Related articles
- Git Git Rebase vs Merge: When to Use Which
A clear, practical guide to choosing between git rebase and git merge, with safe workflows for feature branches, shared branches, and pull requests.
- Git Git Stash Tutorial: Saving Work in Progress
Learn how to use git stash to safely shelve uncommitted changes, switch contexts, and recover work using push, pop, apply, and branch workflows.
- Git Git Bisect: Find the Commit That Introduced a Bug
Learn how to use git bisect to perform binary search through your commit history and pinpoint the exact commit that introduced a bug in your codebase.
- Git Git Rebasing Strategies for Clean Team Histories
Advanced git rebase strategies for teams: interactive rebase workflows, rebase --onto, autosquash, and policies that keep shared branches clean without rewriting public history.