Recovering Deleted Git Stashes
A dropped Git stash remains recoverable until garbage collection removes it. Learn how to find it as a dangling commit and restore its changes.
A Git stash is implemented internally as a commit. Consequently, dropping a stash does not delete the underlying object immediately; it persists in the repository as a “dangling” commit until garbage collection runs. This makes recovery possible in most cases.
List Dangling Commits
Use the following command to identify dangling commits in the repository:
git fsck | awk '/dangling commit/ {print $3}' >> commit_list.txtThe output will look something like this:
dangling commit bfebf68feeebf07a86d7e3e4da77962de67c14eedangling commit 86f4aec78bd51c80b0fd2d5d83963a2259dc72b4dangling commit 48fd9f8f97a577bc8a87b133f6e1dd789a692bd0dangling commit 64ff8c33fb878afb8bf5c99c1b8d8fdfaa1b1f3cdangling commit bdff88e13803e6c7737691aa1fb6f1e038321966Review Candidate Commits
To review the details of each candidate commit, run the following script:
#!/bin/bash
while read linedo git show $linedone < ./commit_list.txtThis will display summaries of the dangling commits:
commit bfebf68feeebf07a86d7e3e4da77962de67c14eeMerge: b046240 5ee731aAuthor: Takahiro Iwasa <iwasa.takahiro@wasabee.dev>Date: Fri Feb 12 22:01:47 2016 +0900
On develop: 0212Restore Selected Commits
Review the commit summaries and use the date, time, and commit message to identify the commits to be restored.
The identified commits can then be restored using git cherry-pick:
git cherry-pick -n -m1 <YOUR_COMMIT_ID>Conclusion
To recover a dropped stash, list the dangling commits, review each candidate, and cherry-pick the correct one. The git fsck | awk '/dangling commit/ {print $3}' command produces a short list of commit IDs because dropping a stash removes its ref but does not immediately delete the underlying objects.
Use git show to inspect the author, date, and message of each candidate. After identifying the correct commit, git cherry-pick -n -m1 reapplies its changes to the working tree without creating a new commit.
This method works only until garbage collection removes the unreachable objects, so recovery is not guaranteed.
Related posts
Dependency Injection for Maintainable, Testable Code
Refactor a tightly coupled TypeScript class by injecting its salary calculator, system clock, and Amazon SES mailer.
Monitoring OPC UA Variable Nodes with Python
Subscribing to OPC UA variable node changes with opcua-asyncio so the client reacts to pushed updates instead of polling.
Performing OCR on Japanese PDFs Using Tesseract and Pytesseract
Extracting Japanese text from a PDF with Tesseract OCR v4 and pytesseract, including the normalization step needed to clean up the output.
Installing Python Packages Without Internet Access
Download Python packages on a connected machine, transfer them, and install them in an environment without internet access.
Spying on Mock Object Properties in Jasmine
Working around Jasmine's "already been spied upon" error when spying on a mocked object's property with Object.getOwnPropertyDescriptor.
