How to Recover a Git Commit After Accidentally Running git reset --hard

You run git reset --hard to clean up a Git repository, press Enter, and suddenly realize you've just removed changes you still needed. Maybe you reset to the wrong commit, discarded work you hadn't backed up, or followed a command from a tutorial without fully understanding what it would do.

The first instinct is often to run more Git commands immediately. Don't do that just yet.

Depending on what happened, you may be able to recover your work using Git's reflog, an earlier commit, a dangling Git object, or your code editor's local history. The important thing is to identify what was lost before attempting to repair the repository.

One distinction matters from the start: recovering a commit is usually easier than recovering uncommitted changes. If your work was committed before the reset, Git may still have a reference to it. If you had uncommitted edits that were discarded by git reset --hard, recovery is less certain.

First, Stop Making Changes to the Repository

If you've just run the command, avoid running cleanup commands such as git gc, git prune, or other commands that remove unreachable Git objects. Don't delete the repository or reclone it over your current project either.

Git often retains information about previous branch positions and commits even after a reset moves the current branch backward. That information can give you a route back to the missing commit.

If the work is especially important, make a separate copy of the repository directory before attempting recovery. A normal file copy is fine, provided you include the hidden .git directory. Without that directory, you won't have the repository's local commit history and object database.

Open the terminal in your project folder and check the current state:

git status
git log --oneline --decorate -10

The first command shows the current working-tree state. The second displays recent commits reachable from your current references. If the missing commit doesn't appear, don't assume it is permanently gone. The next place to look is the reflog.

Check Git Reflog for the Missing Commit

The reflog records recent changes to references such as HEAD and local branches. When you use git reset --hard, Git normally records the previous position of HEAD in this log.

Run:

git reflog

You may see output similar to this:

a82f631 HEAD@{0}: reset: moving to HEAD~2
c47a920 HEAD@{1}: commit: Add profile settings
8d12f54 HEAD@{2}: commit: Fix login validation
f06a311 HEAD@{3}: checkout: moving from feature to main

Your commit hashes and messages will be different. In this example, the reset moved the repository backward, but the reflog still shows the earlier commit, c47a920.

Look for the entry immediately before the accidental reset or find the commit message associated with the work you lost. The position HEAD@{1} often refers to the previous HEAD position, but don't rely on that number blindly. Additional Git commands can change the reflog entries.

To inspect a candidate commit, run:

git show --stat c47a920

Replace c47a920 with the actual hash from your reflog. This shows which files the commit changed, helping you confirm that you've found the correct work.

If the commit is correct, you've found the most important piece of information needed for recovery.

Recover the Commit Without Rewriting Your Current Branch

When you're unsure which commit to restore, creating a separate branch is a safer option than immediately resetting your existing branch again.

Suppose the missing commit hash is c47a920. Run:

git branch recovery-work c47a920

This creates a new branch named recovery-work pointing to that commit. It doesn't move your current branch or discard its current state.

Next, switch to the recovery branch:

git switch recovery-work

Inspect the files and confirm that the expected changes are present. If the commit contains the work you need, you can keep working from this branch or bring the commit back into your original branch.

If you want to preserve your original branch and restore the missing commit to it, switch back to that branch and use git cherry-pick:

git switch main
git cherry-pick c47a920

Replace main with your actual branch name and use the correct commit hash. Cherry-picking applies the changes from that commit as a new commit on the current branch. If the changes are already present, or the branch histories have diverged, you may need to resolve conflicts or choose a different recovery method.

If you simply want your branch to point back to the recovered commit, you can also reset it to that commit. However, that changes the branch position and can discard other changes. Inspect your current state before choosing that approach.

What If You Reset to the Wrong Commit?

Sometimes the commit isn't missing; you simply moved the branch to the wrong point in history.

For example, you might have run:

git reset --hard HEAD~3

This moves the current branch backward by three commits, provided those commits were on the branch's current history. If you intended to remove only the most recent commit, you may have moved too far.

Run git reflog and identify the branch position from before the reset. After confirming the correct hash, you can create a recovery branch as described above.

If you have verified that you want the current branch to return to that exact commit, you can run:

git reset --hard c47a920

Use the actual commit hash, not the example above. Be aware that this command overwrites the tracked files in your working tree and moves the current branch. Any tracked changes that exist only in the current working tree can be lost again.

For that reason, I recommend creating the recovery branch first when there is any uncertainty. It gives you a stable reference to the recovered commit before you make further changes.

What If the Work Was Never Committed?

This is where recovery becomes more difficult.

Git reflog records reference movements, not a complete history of every edit you make to every file. If you edited a file, never committed it, and then ran git reset --hard, those edits may not be recoverable through the reflog alone.

There are still a few places worth checking.

Check your editor's local history. Visual Studio Code users may have access to Timeline entries or local file history, depending on the file, editor version, extensions, and available backups. Other editors may provide their own local-history features. These can sometimes restore edits that Git never recorded.

Check operating-system backups. If File History, a backup application, or cloud file versioning was enabled, look for an earlier version of the affected file. OneDrive or another synchronization service may have version history for files stored in a synced folder, though availability depends on the service and account.

Inspect Git's unreachable objects. In some circumstances, Git has written file contents or commit objects that are no longer reachable through the usual branches and references. You can investigate them with:

git fsck --full --no-reflogs --unreachable

The command may report unreachable commits, trees, or blobs. A blob contains file content, but it doesn't necessarily include the filename or folder structure. A dangling commit, if one exists, may be easier to inspect because it preserves a snapshot of a repository tree.

If you find a promising dangling commit, inspect it before attempting recovery:

git show --stat HASH

Replace HASH with the object ID reported by Git. If it contains the missing work, create a branch pointing to that commit so it remains accessible.

Keep your expectations realistic: Git does not necessarily save every uncommitted edit as a recoverable object. If the changes were never committed, staged, or otherwise written into Git's object database, Git may have nothing to recover.

Why the Usual Git Recovery Commands Can Make Things Worse

When trying to recover lost work, avoid copying commands from random answers without checking what they do.

  • Running another git reset --hard blindly: This can overwrite more tracked changes or move your branch away from the commit you need.
  • Deleting the .git folder: This removes the local repository metadata, including the reflog and local object database you may need for recovery.
  • Running Git cleanup commands: Garbage collection or pruning can eventually remove unreachable objects that might otherwise help you recover lost commits.
  • Cloning the repository again and deleting the old folder: A fresh clone may not contain commits that were never pushed to the remote, and deleting the old directory can remove your remaining recovery options.
  • Assuming a successful push means everything was backed up: Only commits that were actually pushed to a remote are available there. Uncommitted edits and local-only commits aren't automatically uploaded.

When recovery is uncertain, preserve the original repository and work on a copy. A few minutes spent identifying the correct commit is better than making the missing work harder to recover.

How to Prevent This From Happening Again

You don't have to avoid git reset --hard entirely. It can be useful when you intentionally want to discard tracked working-tree changes and reset to a known state. The problem is running it without confirming what will be lost.

Before using it, check:

git status
git log --oneline -5

If you have uncommitted work worth keeping, commit it or create a separate backup before resetting. If you only want to inspect an older commit, use a temporary branch or detached checkout instead of immediately moving your main branch.

For example, to create a checkpoint before making risky changes, run:

git add .
git commit -m "Save work before cleanup"

Only stage everything if you have reviewed the files and are comfortable committing them. Otherwise, stage specific files by name. You should also avoid committing secrets, credentials, generated files, or other unwanted content.

For work that matters, push your commits to a remote repository when appropriate. A remote backup provides another recovery route if the local repository becomes damaged.

Final Thoughts

Accidentally running git reset --hard doesn't always mean your work is gone forever. If you lost a committed change, start with git reflog, identify the correct commit, and create a recovery branch before changing your current branch again.

If the missing work was never committed, check your editor's local history, backups, and any potentially recoverable Git objects. Recovery is not guaranteed, but preserving the repository gives you the best chance.

The most important rule is simple: don't rush into another destructive command while trying to undo the first one. Find the missing commit, confirm its contents, and choose the recovery method that protects the work you still have.

Post a Comment

0 Comments