All explainers

Reset vs revert: two ways to undo, one of them destructive

2 min+15 XP

Reset pretends the commit never happened. Revert admits it happened and undoes it in public.

You pushed something broken. Both commands get the bad change out of your working tree. Only one of them is safe to run on a branch other people have.

Undoing commit D, two ways

1 / 3

git reset --hard

mainABCDHEADmain

Four commits. D is the one you regret.

git revert

mainABCDHEADmain

Identical starting point. D is the tip of main.

D is the bad commit and it is currently the tip of main. HEAD points at main, main points at D.

The reset flag that actually matters

reset moves the branch pointer either way. The flag only decides what happens to the changes those commits contained:

FlagBranch pointerStaging areaYour files
--softmoves backkeeps the changes stageduntouched
--mixed (default)moves backunstageduntouched
--hardmoves backdiscardeddiscarded

--soft is the one to reach for when you just want to recommit the same work differently, squashing three messy commits into one, for example. --hard is the only variant that can lose uncommitted work, and it is the one people usually mean when they say reset is dangerous.

Which one to use

The deciding question is never "how bad was the commit". It is has anyone else seen it?

  • Only on your machine? Either works. reset gives a tidier history.
  • Already pushed to a shared branch? revert, every time. Reset would require a force push, and a force push on a branch your team pulls is how people lose commits they had already based work on.

Remember this

  1. 1Reset moves a pointer. Revert adds a commit. That is the entire difference. Everything else follows from it.
  2. 2Pushed already? Use revert. Reset on a shared branch means a force push, and a force push can destroy other people's work.
  3. 3A reset commit is not deleted immediately: git reflog still knows its SHA, so an accidental reset --hard is usually recoverable.

Now try these questions