Find lost data in Git

Written on November 19, 2025

A script to find lost Git commits, stashes, or other changes


This script helped me find lost stashes that contained a lot of important changes, so I wanted to share it here for others who might find themselves in a similar situation.

Important: Git's garbage collection eventually deletes unreachable commits (typically after 30 days), so run this script as soon as you realize something is missing.

#!/bin/bash
#
# git-find-lost-code.sh
# A script to find lost Git commits, stashes, or other changes.
#
# This script searches for "lost" commits in two places:
# 1. Unreachable commits: Commits that are no longer referenced by any branch,
#    tag, or stash. This is where dropped stashes and hard-resets end up.
# 2. The Reflog: A log of all recent movements of HEAD, which acts as a
#    powerful safety net.
#
# USAGE:
#   chmod +x git-find-lost-code.sh
#   ./git-find-lost-code.sh [optional/path/to/file]
#
# If you provide a file path, the script will only show commits that modified
# that specific file. If you don't, it will show ALL lost commits it can find.
# Note: Without a file path, the reflog search may output many commits.

set -e

FILE_PATH="$1"

# --- Method 1: Search Dangling (Unreachable) Commits ---
echo "---"
echo "🔎 Searching for dangling (unreachable) commits..."
echo "---"
UNREACHABLE_COMMITS=$(git fsck --unreachable | grep commit | cut -d' ' -f3)

if [ -z "$UNREACHABLE_COMMITS" ]; then
    echo "No dangling commits found."
else
    FOUND_IN_FSCK=0
    for commit in $UNREACHABLE_COMMITS; do
        if [ -n "$FILE_PATH" ]; then
            # If a file path is provided, check if the commit modified it
            if git show --name-only --pretty="" "$commit" 2>/dev/null | grep -q "^${FILE_PATH}$"; then
                echo "✅ Found dangling commit [$commit] that modified '$FILE_PATH':"
                git log -n 1 --oneline --stat "$commit"
                echo "------------------------------------------------"
                FOUND_IN_FSCK=1
            fi
        else
            # If no file path, just show all dangling commits
            echo "✅ Found dangling commit [$commit]:"
            git log -n 1 --oneline --stat "$commit"
            echo "------------------------------------------------"
            FOUND_IN_FSCK=1
        fi
    done
    if [ "$FOUND_IN_FSCK" -eq 0 ]; then
        echo "No dangling commits found that modified '$FILE_PATH'."
    fi
fi


# --- Method 2: Search The Reflog ---
echo ""
echo "---"
echo "🔎 Searching reflog..."
echo "---"
REFLOG_COMMITS=$(git reflog | awk '{print $1}')

FOUND_IN_REFLOG=0
for commit in $REFLOG_COMMITS; do
    if [ -n "$FILE_PATH" ]; then
        # If a file path is provided, check if the commit modified it
        if git show --name-only --pretty="" "$commit" 2>/dev/null | grep -q "^${FILE_PATH}$"; then
            echo "✅ Found reflog commit [$commit] that modified '$FILE_PATH':"
            git log -n 1 --oneline --stat "$commit"
            echo "------------------------------------------------"
            FOUND_IN_REFLOG=1
        fi
    else
        # If no file path, just show all reflog commits
        echo "✅ Found reflog commit [$commit]:"
        git log -n 1 --oneline --stat "$commit"
        echo "------------------------------------------------"
        FOUND_IN_REFLOG=1
    fi
done

if [ "$FOUND_IN_REFLOG" -eq 0 ]; then
    echo "No commits found in reflog that modified '$FILE_PATH'."
fi

echo ""
echo "✨ Search complete."
echo ""
echo "💡 To recover a commit you found:"
echo "   - Cherry-pick it: git cherry-pick <commit-hash>"
echo "   - Create a branch: git checkout -b recovery-branch <commit-hash>"
echo "   - View the changes: git show <commit-hash>"

How to use

  1. Save the script to a file (e.g., git-find-lost-code.sh)
  2. Make it executable: chmod +x git-find-lost-code.sh
  3. Run it in your Git repository:
    • Find all lost commits: ./git-find-lost-code.sh
    • Find commits that modified a specific file: ./git-find-lost-code.sh path/to/file.txt

Recovering your data

Once you've found the commit you're looking for, you can recover it using:

  • Cherry-pick the changes: git cherry-pick <commit-hash>
  • Create a new branch from it: git checkout -b recovery-branch <commit-hash>
  • View the full changes: git show <commit-hash>
  • Apply as a patch: git show <commit-hash> | git apply