TidyURLs
Go to Tools
BLOG
The TidyURLsJournal

Practical guides, tutorials, and insights about URLs, SEO, web development, and online marketing. Learn, troubleshoot, and get the most of the web.

Back to the Journal
TidyURLs Journal

How to Recover a Deleted Git Commit Safely

Practical insights, clear explanations, and useful ideas for understanding the web.

October 25, 20267 min read5 topics
How to Recover a Deleted Git Commit Safely
Explore the details
#Git#Version Control#Git Reflog#Troubleshooting#Developer Tools
October 25, 20267 min read

Accidentally deleting a branch or moving it to the wrong commit can make important work seem lost. Often, the commit is still present in your local repository: Git branch names are references to commits, and removing a name does not necessarily remove the commit object immediately. The key is to find the commit before Git prunes it, then create a reference that keeps it reachable.

This guide explains how to use the reflog to find a deleted commit, restore it as a branch, apply it with cherry-pick, and check for unreachable objects if reflog entries are unavailable. It also covers reset modes and what recovery options remain after pruning.

Key takeaways

  • A branch is a movable reference to a commit; deleting the branch does not always immediately delete the commit itself.
  • Start with git reflog --all and inspect likely commits before changing anything.
  • Create a rescue branch at the recovered commit to keep it reachable.
  • Use git cherry-pick to apply a commit to another branch, or choose a reset mode deliberately when moving the current branch.
  • If a commit object has been pruned and no other copy exists, Git cannot recover it from that repository.

What deleting a Git branch or commit actually means

Git commits are objects identified by hashes. Branch names, such as main or feature/login, are references that point to commits. Moving or deleting a branch changes a reference; it is not the same operation as immediately erasing every associated commit object.

A commit is reachable when it can be found by following references and their history. After a branch is deleted, commits that are no longer reachable may still remain in the repository for a time. The reflog can record where references, including HEAD, previously pointed, which often makes it the quickest recovery route.

Reflogs are local to a repository. They are not normally transferred when you clone or push, and their entries can expire. Git may eventually prune objects that are no longer reachable, so act promptly and avoid cleanup commands while investigating.

Recover a deleted commit with the reflog

1. Check the reflog

From the repository, run:

 git reflog --all --date=iso

Look for a recent entry mentioning the branch switch, reset, commit, or other operation around the time the work disappeared. The output includes a commit hash and a description of the reference update. You can also inspect the HEAD history directly:

 git reflog show HEAD --date=iso

A deleted branch's own reflog may no longer be available, so check HEAD and other listed reflogs too. Reflog entries are clues, not guaranteed backups: they can be missing or expire.

2. Inspect a candidate commit

Copy the hash from a promising entry and examine it before restoring anything:

 git show --stat <commit-hash>
 git log -1 --oneline --decorate <commit-hash>

Confirm that the commit message, date, and changed files match the work you want. Replace <commit-hash> with the actual hash; do not type the angle brackets.

3. Make a rescue branch

Once you have identified the commit, create a branch pointing to it:

 git branch rescue/recovered-work <commit-hash>

This creates a durable reference without moving your current branch. To work from the recovered commit, switch to the rescue branch:

 git switch rescue/recovered-work

Check the branch and history before deciding how to integrate the work. Keeping a rescue branch is safer than immediately resetting a branch or deleting other references.

If the reflog does not show the commit

Git may still have the commit object even when no reflog entry points to it. Ask Git to list unreachable objects:

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

This can produce many results. Look for entries identified as commit, then inspect likely candidates:

 git show --stat <commit-hash>

If you identify the right commit, make a branch reference to it as shown above. Do not assume every unreachable object is your missing work; inspect its contents and history.

Avoid running git gc or commands that prune objects while searching. Garbage collection can remove objects that are no longer reachable once they meet Git's pruning conditions. If the commit has already been pruned, this repository no longer has the object to restore. Check for another copy, such as a developer's clone, a backup, or a remote branch where the commit was pushed. Recovery depends on whether one of those copies still contains it.

Choose the right recovery method

A rescue branch is usually the safest first step. After that, choose how to bring the commit into your intended branch.

Use cherry-pick to apply a commit

If you want the changes on your current branch without moving that branch back to the recovered commit, use:

 git switch <target-branch>
 git cherry-pick <commit-hash>

Cherry-pick applies the changes introduced by the selected commit and creates a new commit on the target branch. The new commit normally has a different hash. If Git reports conflicts, resolve them, stage the resolved files, and continue with git cherry-pick --continue; to abandon the operation, use git cherry-pick --abort.

Use reset only when you intend to move the current branch

git reset changes the current branch's position and, depending on the mode, also changes the index or working tree. First confirm you are on the correct branch and that valuable uncommitted changes are backed up.

ModeBranch referenceIndexWorking tree
--softMoves to the target commitUnchangedUnchanged
--mixed (the default)Moves to the target commitReset to the targetUnchanged
--hardMoves to the target commitReset to the targetUpdated to the target; tracked changes can be discarded

For example, this moves the current branch to the recovered commit while leaving the index and working tree unchanged:

 git reset --soft <commit-hash>

Use --hard only when you intentionally want the index and tracked working-tree files to match the target commit. It can discard tracked changes; it is not a general-purpose recovery command. If your goal is simply to preserve a deleted commit, create a branch instead of resetting.

A safe recovery workflow

  1. Stop cleanup activity. Do not run pruning or garbage-collection commands while you are looking for unreachable work.
  2. Check the current state. Run git status and note the current branch. Save or back up valuable uncommitted changes before switching or resetting.
  3. Search reflogs. Use git reflog --all --date=iso, and inspect likely entries with git show.
  4. Check unreachable objects if needed. Use git fsck --full --no-reflogs --unreachable and inspect candidate commits.
  5. Anchor the commit. Create a rescue branch at the confirmed hash.
  6. Integrate deliberately. Cherry-pick the commit onto another branch, or reset only if you intend to move the current branch.
  7. Verify the result. Review the branch, commit history, and changed files before removing temporary references.

Common mistakes and troubleshooting

  • Assuming a deleted branch is a deleted commit. The branch reference may be gone while the commit object remains recoverable.
  • Using an unfamiliar hash without inspection. Check the commit message and changed files before creating a branch or applying it.
  • Resetting to the wrong commit. A reset moves the current branch. Confirm the branch and target first; prefer a rescue branch when uncertain.
  • Using --hard to “undo” deletion. It can overwrite tracked working-tree changes and does not improve the odds of finding a missing commit.
  • Expecting reflogs on a remote. Reflogs are local records, not a shared history service. Check another clone or remote branches separately.
  • Treating git fsck output as a complete backup. It can help locate objects still present locally, but it cannot recreate an object that has already been pruned.
  • Overlooking a commit that was never made. Reflog and object searches recover commits, not uncommitted edits. For missing uncommitted work, check editor or IDE local history, backups, and other copies of the files.

Conclusion

To recover a deleted Git commit, search the reflog first, inspect the candidate, and create a rescue branch so the commit remains reachable. Use cherry-pick when you want its changes on another branch, and choose reset modes carefully when you intend to move the current branch. If the commit is absent from reflogs and unreachable-object searches because it has been pruned, recovery must come from another copy of the repository or a backup.

References