Suggest an editImprove this articleRefine the answer for “Difference between git reset and git revert?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**git reset** removes commits from history by moving the branch pointer back. **git revert** keeps history intact by adding a new commit that undoes changes. Use reset for local unpushed work; use revert for shared branches. ```bash git reset --hard HEAD~1 # last commit gone git revert HEAD # new commit undoes last one ``` **Key rule:** never reset what teammates already pulled.Shown above the full answer for quick recall.Answer (EN)Image**git reset** and **git revert** are two ways to undo commits in Git. Reset removes commits from history. Revert adds a new commit that cancels them. ## Theory ### TL;DR - `reset` moves your branch pointer backward, erasing commits from history - `revert` adds a new commit with the opposite changes, keeping history intact - Analogy: reset is Ctrl-Z on your commit history; revert is writing "I take that back" as a new message - Rule: reset for local work before pushing; revert for anything already on a shared branch - Force-pushing after reset breaks your teammates' branches ### Quick example ```bash # Starting history: A -> B -> C # You want to undo commit C # reset: C disappears from history git reset --hard HEAD~1 # History: A -> B # revert: C stays, new commit D undoes C's changes git revert HEAD # History: A -> B -> C -> D (D has the opposite changes of C) ``` Two commands, two completely different outcomes. The first is a time machine. The second is a paper trail. ### Key difference `reset` modifies where your branch pointer points. With `--hard`, it also updates your working directory and staging area to match that older commit, wiping out everything in between. `revert` reads the target commit, calculates what the opposite changes would be, and commits those. All previous commits stay exactly where they are. ### When to use - Local commits not yet pushed: `reset` to clean up, squash, or reorganize - Commits already pushed to a shared branch: `revert`, always - Production rollback with CI/CD running: `revert` to keep the audit trail clean - Want to collapse the last 3 local commits into one: `git reset --soft HEAD~3`, then commit once Three modes of `reset` worth knowing: - `--soft` keeps changes staged (ready to commit again) - `--mixed` keeps changes in your working directory, unstaged (this is the default) - `--hard` discards changes entirely ### Comparison table | Aspect | git reset | git revert | |---|---|---| | Rewrites history | Yes | No | | Safe for pushed commits | No | Yes | | Creates a new commit | No | Yes | | Discards commits | Yes | No | | Affects branch pointer | Yes | No | | When to use | Local work before pushing | Shared branches, production | ### How it works internally `reset` updates the HEAD reference and the branch pointer to point to an earlier commit. With `--hard`, the working directory and staging area are also rewritten to match. `revert` works differently: it reads the diff of the target commit, inverts every change, and saves that as a new commit. No existing history is touched. ### Common mistakes **Using reset on a pushed branch** ```bash # WRONG git reset --hard HEAD~1 git push -f origin main # Teammates now have commits that don't exist on remote # Their push gets rejected; merging brings the "deleted" commit back # RIGHT git revert HEAD git push origin main ``` **Mixing up reset modes** ```bash # --soft: changes stay staged git reset --soft HEAD~1 # git status → "Changes to be committed" # --mixed (default): changes move to working directory git reset HEAD~1 # git status → "Changes not staged for commit" # --hard: changes are gone git reset --hard HEAD~1 # git status → clean ``` **Wrong range with revert** ```bash # WRONG: history A -> B -> C, want to revert both B and C git revert B..C # Only reverts C (range excludes the start) # RIGHT git revert B^..C # Or separately: git revert C, then git revert B ``` **Thinking reset --soft is always safe** If you `reset --soft` and then accidentally run `reset --hard` before committing, the changes are gone. They are not in any commit. The staging area is not a safety net. **Recovering from accidental hard reset** ```bash # You ran: git reset --hard HEAD~5 # You need those commits back git reflog # abc1234 HEAD@{0}: reset: moving to HEAD~5 # def5678 HEAD@{1}: commit: feature: add auth git reset --hard HEAD@{1} # Back to before the reset ``` The reflog is local only and expires after 90 days by default. ### Real-world usage - Feature branches: `reset` before the final push to clean up WIP commits - Main/master: `revert` only, never `reset` - GitHub UI: the "Revert" button on a merged PR creates a new PR with a revert commit - CI/CD pipelines: automated rollbacks use `revert` to keep deploy history readable - Debugging: `reset` locally to step through old commits; `revert` to ship the fix ### Follow-up questions **Q:** What happens if you reset a commit that teammates already pulled? **A:** Their local branch now has commits that don't exist on remote. Git refuses their push. If they merge, the deleted commit reappears. If they reset their own branch, they lose their own work. **Q:** Can you revert a revert? **A:** Yes. `git revert D` creates commit E that undoes commit D, bringing back what D had removed. Useful if you reverted something by mistake. **Q:** What is the difference between `git reset HEAD~1` and `git reset --mixed HEAD~1`? **A:** Nothing. `--mixed` is the default. Both undo the commit and leave the changes unstaged in your working directory. **Q:** I lost commits after `reset --hard`. Can I recover them? **A:** Usually yes. Use `git reflog` to find the commit hash, then `git reset --hard <hash>`. Works as long as you have not run garbage collection and it has been under 90 days. **Q:** Why use `reset --soft` instead of `git commit --amend`? **A:** `--amend` only works on the last commit. `git reset --soft HEAD~3` collapses the last 3 commits into one. Stage everything and commit once. Useful for cleaning up WIP history before push. **Q:** (Senior) You are on main, a commit just merged that breaks production. 30 seconds. Reset or revert? **A:** Revert. Reset would rewrite main's history and break everyone's local branches plus any CI/CD that already picked up the commit. Revert creates a new commit that undoes the damage and can be pushed immediately without force. Speed matters, but not at the cost of the whole team's workflow. ## Examples ### Undoing a pushed commit safely ```bash # A bug landed on the shared feature branch in commit abc123 # Reset here would require force-push and break teammates git revert abc123 # Git opens your editor for a commit message # Accept the default or write something descriptive # Result: new commit def456 that undoes abc123's changes git push origin feature/auth # Teammates pull and get the fix automatically # History shows exactly what happened: # ... -> abc123 (buggy) -> def456 (reverts abc123) -> ... ``` No force push. No broken history. Anyone can trace back when the bug was introduced and when it was fixed. ### Recovering commits after reset --hard ```bash # Scenario: you ran this by mistake git reset --hard HEAD~5 # Five commits gone from history # Git's reflog tracks every HEAD movement git reflog # abc1234 HEAD@{0}: reset: moving to HEAD~5 # def5678 HEAD@{1}: commit: feature: add auth # ghi9012 HEAD@{2}: commit: fix: validation bug # Recover everything git reset --hard HEAD@{1} # The 5 commits are back # Note: reflog is local only, expires in 90 days by default ``` The reflog is one of those things you only really appreciate the first time you accidentally hard-reset something important. ### Cleaning up local work before push ```bash # Four messy commits locally, none pushed yet # git log shows: # abc001 (HEAD) fix typo again # abc000 fix typo # ab9999 wip: auth maybe working # ab9998 start auth feature # Collapse into one clean commit git reset --soft HEAD~4 # All changes are now staged, no commits above the base git commit -m "feat: add authentication" # One clean commit in history git push origin feature/auth # Reviewers see one logical unit of work ```For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.