I Ran git reset --hard in the Wrong Window
DEV Community

I Ran git reset --hard in the Wrong Window

git reset --hard HEAD~3 - run in the wrong repository window, at 6:40pm, immediately followed by the specific kind of silence that happens when you realize what you just did before your brain finishes processing it. Three commits of uncommitted-adjacent work, gone from the working tree in under a second. The first, most important fact: it's very likely still there git reset --hard moves the branch pointer and resets the working tree, but Git doesn't actually delete commit objects just because nothing points at them anymore - they sit in the object database, unreferenced, until garbage collection eventually cleans them up, which for most repos happens rarely enough that "eventually" can mean weeks. git reflog a1b2c3d HEAD@{0}: reset: moving to HEAD~3 e4f5g6h HEAD@{1}: commit: add retry logic to payment webhook 7h8i9j0 HEAD@{2}: commit: fix currency rounding k1l2m3n HEAD@{3}: commit: initial webhook handler The reflog is a local log of everywhere HEAD has pointed recently, and it survives a reset because a reset is just another entry in it, not an erasure of the ones before it. git reset --hard e4f5g6h Working tree restored to exactly the state before the reset, all three commits back, in the time it takes to read this sentence. When the reflog isn't enough If the commits were never made at all - you ran reset --hard on genuinely uncommitted changes - the reflog can't help, because it only tracks where HEAD and branches have pointed, not file contents that were never committed. That's a real loss, and the only real defense against it is committing early and often, including throwaway "wip" commits you intend to squash later, specifically because an uncommitted change has no recovery path at all. If the commits were committed and the reflog entry has expired - Git's default is to keep unreachable reflog entries for 90 days, reachable ones for longer - git fsck --unreachable can sometimes still find dangling commit objects directly: git fsck --unreachable --no-reflog | grep commit git show # inspect before deciding it's the one you want Why I test destructive Git operations before running them for real, now The reflog saved this specific mistake, and it also taught me not to rely on remembering it exists at 6:40pm under stress. The actual habit that stuck: for anything genuinely destructive and unfamiliar - an interactive rebase across a long history, a filter-branch, anything with --hard or --force in it - I run it first against a disposable clone of the repo, confirm it does what I think it does, then run it for real. # rehearse the risky operation somewhere it can't hurt anything krova cubes create git-rehearsal --cpu 1 --ram 2 --disk 10 # clone, attempt the operation, inspect the result, then destroy regardless of outcome Running the rehearsal on a disposable Krova Cube costs a few minutes and effectively nothing, and destroying it afterward means there's no cleanup step to skip - the environment simply stops existing once I have my answer. I run Krova, so read the specific workflow as informed rather than neutral, but the underlying discipline - rehearse destructive Git operations somewhere disposable before running them on a repo you care about - is worth adopting regardless of what you rehearse it on. What I'd check first Before assuming lost work is actually lost, run git reflog and read it fully - the commit you want is very likely sitting in there under a hash you haven't looked at yet. And before your next genuinely destructive Git command, consider whether rehearsing it somewhere disposable costs you anything at all compared to finding out the hard way. Top comments (0)

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.