Git Reset, Revert & Cherry-Pick Explained with Examples
In this tutorial, you'll learn about Git Reset, Revert & Cherry. We cover key concepts, practical examples, and best practices.
Git provides multiple ways to undo changes — reset, revert, and cherry-pick — each with different effects on history and safety for shared branches.
In this tutorial, you'll learn three essential Git commands for undoing changes: reset, revert, and cherry-pick. Every developer makes mistakes — committing to the wrong branch, introducing a bug, or wanting to apply a specific fix without merging an entire branch. By the end, you'll know exactly which command to use for each scenario and how to avoid losing work.
flowchart TD
A[Need to undo?] --> B{Changes shared?}
B -->|Yes| C[Use revert]
B -->|No| D{Uncommitted?}
D -->|Yes| E[git checkout . or git restore]
D -->|No| F{Keep changes?}
F -->|Yes| G[git reset --soft]
F -->|No| H[git reset --mixed or --hard]
C --> I[Want specific commit?]
I --> J[Use cherry-pick]
Git Reset: Moving the HEAD Pointer
git reset moves the current branch pointer backward or forward, optionally modifying the staging area and working directory. It comes in three modes.
--soft: Keep Everything
echo "bad commit" > mistake.txt
git add mistake.txt
git commit -m "Oops, wrong commit"
git reset --soft HEAD~1
Expected output: No output. The commit is undone, but mistake.txt remains staged and ready for a new commit.
--mixed (default): Unstage Changes
git reset --mixed HEAD~1
# Or simply: git reset HEAD~1
After this, the commit is undone and changes are unstaged but still in your working directory. This is the default mode.
--hard: Discard Everything
git reset --hard HEAD~1
Expected output:
HEAD is now at a1b2c3d Previous commit message
This discards the commit and the changes. Use with extreme caution — unrecoverable unless you find the commit hash in git reflog.
Git Revert: Safe Undo for Shared Branches
git revert creates a new commit that undoes a previous commit. It never rewrites history, making it safe for branches that others have pulled.
echo "bug" > app.py
git add app.py
git commit -m "Add bug"
git revert HEAD
Expected output:
[main e5f6g7h] Revert "Add bug"
1 file changed, 1 deletion(-)
Revert an older commit using its hash:
git revert a1b2c3d
# This creates a commit that undoes changes from a1b2c3d
Git Cherry-Pick: Apply Specific Commits
Cherry-pick applies a specific commit from one branch onto your current branch. Use it when you need a single fix without merging the entire source branch.
git checkout main
git cherry-pick a1b2c3d
Expected output:
[main b7c8d9e] Fix login bug
Date: Mon Jun 22 10:00:00 2026 +0000
1 file changed, 2 insertions(+), 1 deletion(-)
Cherry-pick multiple commits:
git cherry-pick a1b2c3d e5f6g7h
The commits are applied in order. If conflicts occur, resolve them, then git cherry-pick --continue.
Reset vs Revert vs Cherry-Pick
| Command | Rewrites History | Safe for Shared Branches | Use Case |
|---|---|---|---|
reset --soft |
Yes | No | Undo local commit, keep staged |
reset --mixed |
Yes | No | Undo local commit, unstage |
reset --hard |
Yes | No | Discard local commit and changes |
revert |
No | Yes | Undo a pushed commit safely |
cherry-pick |
No | Yes | Apply a specific commit elsewhere |
Common Errors
| Error | Cause | Fix |
|---|---|---|
fatal: ambiguous argument HEAD~1 |
No parent commit | Use a specific hash instead |
Cannot revert multiple commits |
Wrong syntax | List commits separated by space |
cherry-pick is empty |
Changes already applied | Check what the commit changed |
reset --hard lost my changes |
Uncommitted work discarded | Check git reflog for recovery |
revert: needs merge |
Commit is a merge | Use git revert -m 1 <hash> |
Already up to date after reset |
Reset to same place | Verify your target with git log |
stash dropped alongside reset |
Stashed work lost | git stash list to verify |
pathspec did not match after revert |
File already deleted | Revert the delete commit |
You are in 'detached HEAD' state |
Reset to a non-branch pointer | Create a branch: git switch -c |
nothing to commit after cherry-pick |
No conflicts but nothing applied | Commit was already in history |
Practice Questions
Challenge
Create a repository with five commits. On the third commit, introduce a bug. Use git revert to undo the buggy commit on main. Then cherry-pick a feature commit from a separate feature branch onto main. Finally, use git reset --soft to amend the last commit message. Write the complete command sequence.
Real-World Task
In a production repository, you pushed a commit that introduced a security vulnerability. Other developers have already pulled your branch. Use git revert HEAD to create a safe revert commit. Then cherry-pick the bugfix from your development branch. Push the revert and the fix. This scenario occurs regularly in DevSecOps workflows where security patches must be applied without rewriting shared history.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro