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 Tutorial: Find the Bad Commit Fast
Use git bisect to binary-search through history and pinpoint the commit that introduced a regression, with manual and automated examples.
- Git Git Large File Storage (LFS) Tutorial
Set up Git LFS to version large binaries like images, models, and datasets without bloating your repository, including tracking, migration, and CI tips.