EAD git data_loss ai_generated partial

HEAD is now at <commit> — uncommitted changes permanently lost after git reset --hard

ID: git/reset-hard-data-loss

Also available as: JSON · Markdown
45%Fix Rate
93%Confidence
120Evidence
2018-01-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
2 active

Root Cause

git reset --hard discards ALL uncommitted changes (staged and unstaged) permanently. Unlike committed work which can be recovered via reflog, uncommitted changes have no reflog entry. Staged changes may be partially recoverable from git's object database if gc hasn't run, but unstaged changes are gone forever.

generic

Workarounds

  1. 98% success Use git stash before any destructive operation
    Run 'git stash -u' (includes untracked files) before doing git reset --hard. This saves all working directory changes. You can recover them later with 'git stash pop' or 'git stash apply'. Make this a habit before any reset.

    Sources: https://git-scm.com/docs/git-stash

  2. 55% success Recover staged files from git's object database using git fsck --lost-found
    Run 'git fsck --lost-found' to find dangling blobs (staged files that were added but never committed). Check .git/lost-found/other/ for recovered file contents. This only works for files that were staged ('git add'), and only before 'git gc' runs. Identify files by content since filenames are lost.

    Sources: https://git-scm.com/docs/git-fsck

  3. 95% success Use git reset --soft or --mixed instead of --hard
    Use 'git reset --soft HEAD~1' to undo the last commit but keep all changes staged. Use 'git reset --mixed HEAD~1' (or just 'git reset HEAD~1') to undo the commit and unstage changes but keep them in working directory. Only use --hard when you truly want to discard everything.

    Sources: https://git-scm.com/docs/git-reset

  4. 97% success Recover committed work (not uncommitted) via git reflog
    Run 'git reflog' to find the commit hash before the reset. Then 'git reset --hard <hash>' or 'git checkout -b recovery <hash>' to restore. Reflog entries expire after 90 days by default. This only recovers committed code, not uncommitted working directory changes.

    Sources: https://git-scm.com/docs/git-reflog

Dead Ends

Common approaches that don't work:

  1. Looking in git reflog for uncommitted changes that were lost 95% fail

    Reflog only tracks changes to HEAD (commits, checkouts, rebases). Uncommitted working directory changes and staged-but-not-committed changes are NOT recorded in the reflog. git reflog will show the commit you reset TO, but the uncommitted work that was discarded is not recoverable this way.

  2. Running git reset --hard HEAD~1 expecting it to be easily reversible like git revert 85% fail

    git reset --hard moves the branch pointer AND overwrites the working tree. Unlike git revert (which creates a new commit to undo changes), reset --hard is destructive. The commit itself IS recoverable via reflog, but any uncommitted modifications in the working directory at the time of the reset are permanently lost.

  3. Using git checkout -- . or git restore . thinking it's safer than reset --hard 90% fail

    Both git checkout -- . and git restore . also permanently discard unstaged changes in the working directory. They don't touch staged changes (unlike reset --hard which also destroys staged work), but the effect on unstaged modifications is equally destructive and equally unrecoverable.

Error Chain

Preceded by:
Frequently confused with: