Git reset vs. revert: undo without losing work
Choose reset for controlled local pointer changes and revert for shared history, with safer backups and commands for each repository state.
Reset moves a branch pointer and may also change the index or working tree. Revert creates a new commit that applies the inverse of an earlier commit. For history others may already have, revert is usually the safer collaboration choice.
Choose by whether history is shared
| Goal | Safer starting point |
|---|---|
| Undo a published commit | git revert <commit> |
| Uncommit local work but keep it staged | git reset --soft HEAD~1 |
| Unstage a path | git restore --staged <path> |
| Move a private branch while keeping files | git reset --mixed <commit> |
Revert records the correction
git revert <commit>
Git creates a new commit. Original history remains reachable, making the correction understandable to collaborators and continuous deployment systems. Reverting a merge requires choosing the mainline parent and deserves extra review.
Reset changes the current branch
--soft moves the branch while leaving the index and files. The default mixed mode resets the index but keeps working-tree edits. Both can be useful for unpublished local cleanup.
High risk:
git reset --hardoverwrites tracked working-tree changes and the index. It can destroy uncommitted work.
Before any reset that changes history:
git status
git branch backup/before-reset
git log --oneline --decorate -10
Then select the exact commit rather than copying a generic HEAD~N blindly. Do not force-push a reset shared branch without an explicit team decision.
Recovery tools
If a branch was moved accidentally, git reflog often records its previous tip. Create a recovery branch at the identified commit before attempting further cleanup:
git reflog
git branch recovery/accidental-reset <commit>
The Git undo cheat sheet maps commands to working-tree, index, and commit states.