Hard
With this option, both the HEAD pointer and the working directory's contents are updated to match the specified commit.
With this option, both the HEAD pointer and the working directory's contents are updated to match the specified commit. Any changes made since then will be lost.
This discards work:
--hard is the only common Git command that throws away changes with no undo.
Uncommitted edits and untracked-but-staged files are overwritten, not moved
anywhere. Everything it deletes that had been committed is still in the
reflog, so run git reflog before you panic.
What each part of a reset does
git reset --hard <commit> moves three things at once:
- HEAD and the branch it points at go to
<commit> - the index is rewritten to match
- your working tree is overwritten to match
Nothing is stashed first. That is the difference from --soft and --mixed,
which leave the file contents alone and only move the branch and index.
The everyday use
git reset --hard origin/main
Discarding your local commits and matching the remote exactly. Useful when a branch has gone wrong and you have decided to start it again from the remote, and worth doing before force-pushing so you are not discarding anyone else's work either. See Git Push --force.
The everyday mistake
Running it with the wrong argument, or without checking what you are about to throw away. Before you do:
git status # is anything uncommitted?
git log --oneline HEAD~5..HEAD # what would go?
git stash # or just stash, and keep it
git stash followed by git reset --hard gives you the same result with a way
back. That is the habit worth building: reach for stash first, and treat
--hard as the thing you do once you have already saved a copy.
Recovering afterwards
git reflog
git switch -c recovered <hash>
The reflog records every position HEAD has held, including commits that a reset
moved past. This is the safety net that makes experimenting with --hard less
scary than it looks.
Free Resources
official: