Undoing Changes: restore, reset, and revert
13 min read
The Right Tool for Undoing
Git has several undo mechanisms. Choosing the wrong one can discard work permanently or rewrite shared history. Know the difference.
git restore — Discard Working Directory Changes
git restore discards uncommitted changes, returning files to the last committed state. This is destructive — changes are gone with no recovery.
bash
git restore index.html # discard changes to one file
git restore . # discard ALL uncommitted changes
git restore --staged index.html # unstage a file (keep working dir changes)git reset — Move the Branch Pointer
git reset moves the current branch pointer to a different commit. The three modes determine what happens to changes along the way:
--soft— move pointer, keep changes staged. Good for redoing a commit.--mixed(default) — move pointer, keep changes in working directory but unstaged.--hard— move pointer, discard all changes. Permanent data loss risk.
bash
git reset --soft HEAD~1 # undo last commit, keep changes staged
git reset --mixed HEAD~1 # undo last commit, keep changes unstaged
git reset --hard HEAD~1 # undo last commit, DESTROY changesgit revert — Safe Undo for Shared History
git revert creates a new commit that undoes the changes from a previous commit. It does not rewrite history, making it safe to use on shared branches like main.
bash
git revert abc1234 # create a commit that undoes abc1234
git revert HEAD # revert the most recent commitNever run git reset --hard on main or any shared branch. If a bad commit has already been pushed, use git revert to undo it safely without rewriting history for your teammates.
Ready to test yourself?
Practice Git & GitHub— quiz & coding exercises