Guide

How to undo git reset --hard

A hard reset does two things: it moves your branch, and it overwrites your working tree. The first is easy to undo. The second depends on whether git ever saw your changes.

What you can get back

  • Commits the branch pointed to before the reset: yes, from the reflog.
  • Changes you had staged with git add: usually, as loose files, with git fsck.
  • Changes you never staged or committed: not from git. Git never stored them.

Recover commits with the reflog

If you reset to an older commit and lost the ones after it, the previous position is one step back in HEAD’s reflog:

git reflog

9f8e7d6 HEAD@{0}: reset: moving to HEAD~3
4c5d6e7 HEAD@{1}: commit: Add settings page

HEAD@{1} is where you were before the reset. Move back to it:

git reset --hard 'HEAD@{1}'

If you have new uncommitted work since the reset, stash it first with git stash. To look before you move, use git log --oneline 'HEAD@{1}', or put the old commits on a new branch instead: git branch rescue 'HEAD@{1}'.

Rescue staged changes with git fsck

When you git add a file, git writes its contents into the object database. A reset removes the reference to it, not the object. List the orphaned file contents (“dangling blobs”):

git fsck --lost-found

Git copies each one into .git/lost-found/other/, named by its hash, without the original file name. Search them for text you remember:

grep -l "settingsPage" .git/lost-found/other/*
git show <blob-sha> > src/settings.js

Only the last staged version of each file is there. Edits you made after the last git add are not.

Unstaged changes

Git can’t help here because it never stored them. Check other places that might have:

  • Your editor’s local history (VS Code’s Timeline, JetBrains’ Local History) or its undo buffer if the file is still open.
  • Time Machine or another backup of the project folder.

Next time

Before a hard reset, run git stash instead of discarding, or reset with --keep, which refuses to overwrite files you’ve changed: git reset --keep HEAD~3.