How do I find and restore a deleted file in a Git repository?
Say I’m in a Git repository. I delete a file and commit that change. I continue working and make some more commits. Then, I discover that I need to restore that file after deleting it.
I know I can checkout a file using git checkout <commit> -- filename.txt, but I don’t know when that file was deleted.
- How do I find the commit that deleted a given filename?
- How do I restore that file back into my working copy?
To find and restore a deleted file in Git, you can use git log --diff-filter=D --summary | grep filename to locate the commit that deleted the file, then restore it using git checkout <commit> -- filename.txt or the newer git restore <commit>:filename.txt command. This approach allows you to pinpoint exactly when the file was deleted and recover it from that point in the repository’s history.
Contents
- How to Find the Commit That Deleted a File
- How to Restore the Deleted File
- Alternative Methods and Best Practices
- Common Scenarios and Troubleshooting
- Advanced Techniques for Complex Cases
How to Find the Commit That Deleted a File
When you delete a file and commit that change, Git doesn’t actually remove the file from the repository history—it simply marks it as deleted in that specific commit. Here are several effective methods to locate the commit that deleted your file:
Method 1: Using git log with --diff-filter=D
The most straightforward approach is to use Git’s log filtering capabilities to show only commits that performed deletions:
git log --diff-filter=D --summary | grep "filename.txt"
This command filters the commit history to show only commits with deletions (D), displays a summary of changes, and then searches for your specific filename. The output will show you the commit hash and details about when the file was deleted.
Method 2: Using --full-history for Complete History
For a more comprehensive search that includes all references to the file, even those across branch merges:
git log --full-history -- filename.txt
This command shows the complete history of the file, including deletions. The commit where the file disappears from the history is the one that deleted it.
Method 3: Searching Across All Branches
If you’re not sure which branch contained the file before deletion:
git log --all --full-history "filename.txt"
This searches across all branches in your repository to find the complete history of the file.
Method 4: Using --name-status for More Details
For a cleaner view of deleted files:
git log --name-status | grep "^D.*filename.txt"
This shows only deleted files (^D) and helps you quickly identify the relevant commit.
How to Restore the Deleted File
Once you’ve identified the commit that deleted the file, you can restore it using several methods:
Method 1: Using git checkout (Traditional Approach)
The classic method uses the git checkout command to extract the file from a specific commit:
git checkout <commit-hash> -- filename.txt
Where <commit-hash> is the hash of the commit that deleted the file (or more precisely, the commit before the deletion). This command will restore the file to your working directory while keeping your current branch position unchanged.
Pro Tip: You can use a partial commit hash if it’s unique enough. Git will automatically find the full hash.
Method 2: Using git restore (Modern Approach)
Git 2.23+ introduced the git restore command, which is more explicit and user-friendly:
git restore --source=<commit-hash> filename.txt
Or the shorter version:
git restore <commit-hash>:filename.txt
Method 3: Restoring to a Specific Branch
If you want to restore the file to a specific branch while keeping your current branch unchanged:
git checkout <source-branch> -- filename.txt
This is useful when you know the file existed in a particular branch.
Method 4: Adding the Restored File to Index
After restoring the file, you’ll need to stage it if you want to commit it back:
git add filename.txt
git commit -m "Restored deleted file filename.txt"
Alternative Methods and Best Practices
Using git rev-list for More Control
For more advanced filtering, you can use git rev-list combined with other commands:
git rev-list --all --full-history -- filename.txt | head -1
This gives you the most recent commit where the file existed.
Creating an Alias for Common Operations
You can create a Git alias to make finding deleted files easier:
git config --global alias.find-deleted '!f() { git log --diff-filter=D --summary | grep "$1"; }; f'
Then use it like:
git find-deleted filename.txt
Working with Renamed Files
If the file was renamed rather than deleted, use:
git log --follow -- filename.txt
This will show the complete history including renames.
Common Scenarios and Troubleshooting
Scenario: File Was Deleted in a Merge Commit
When a file is deleted in a merge commit, you might need to exclude merge commits from your search:
git log --no-merges --diff-filter=D --summary | grep filename.txt
Scenario: File Exists in Remote Repository but Not Locally
If the file exists in the remote but was deleted locally:
git fetch origin git checkout origin/main -- filename.txt
Scenario: Multiple Files Deleted at Once
To restore multiple files deleted in the same commit:
git checkout <commit-hash> -- file1.txt file2.txt file3.txt
Troubleshooting: “File not found” Errors
If you get “file not found” errors when trying to restore:
- Verify the file path is correct from the repository root
- Ensure you’re using the right commit hash
- Check if the file was actually deleted in that commit or earlier
Advanced Techniques for Complex Cases
Using git show to Verify Before Restoring
Before restoring, you can preview the file content using:
git show <commit-hash>:filename.txt
This shows you the file content without actually restoring it to your working directory.
Restoring Files from Specific Time Ranges
If you know approximately when the file was deleted:
git log --since="1 month ago" --until="2 weeks ago" --diff-filter=D --summary | grep filename.txt
Using git filter-branch for Mass Restorations
For restoring multiple files across many commits, you might need more advanced tools like git filter-branch, but this is generally not recommended as it rewrites history.
Working with Submodules
If the deleted file is in a submodule:
cd path/to/submodule
git checkout <commit-hash> -- filename.txt
cd ..
git add path/to/submodule
Sources
- How to find a deleted file in the project commit history? - Stack Overflow
- Find When a File Was Deleted in Git - Better Stack Community
- How to Find and Restore a Deleted File in a Git Repository - GeeksforGeeks
- Recovering Deleted Files in GitHub - Rewind
- How to Restore Deleted Files From Your Git Working Tree - Smashing Magazine
- Git find deleted files - Waylon Walker
- How to check when a file was deleted in Git - How.dev
Conclusion
Finding and restoring deleted files in Git is a straightforward process once you understand the available commands. The key steps are:
- Use
git log --diff-filter=D --summary | grep filenameor similar commands to locate the commit that deleted your file - Restore the file using either
git checkout <commit> -- filenameor the newergit restore <commit>:filenamecommand
Remember that Git never truly deletes files from the repository history—it simply marks them as deleted in specific commits. This means you can recover files even years after deletion, as long as you have access to the repository history. For regular use, consider creating Git aliases to streamline the process, and always verify file content before restoring to ensure you’re getting the right version.