CPCODELAB
Git & GitHub

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 changes

git 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 commit

Never 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