Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: February 6, 2024
Commands like git stash and git stash pop are used to Shelve (stash) and restore changes in our working directory. In this tutorial, we’ll learn how to recover a dropped stash in Git.
For our example, let’s say that we’ve forked and cloned a Git Repository. Now, let’s make some changes to the README.md file by simply adding a new line at the end and checking the status of our working directory:
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
From here, we can use the git stash command to shelve our changes temporarily.
$ git stash
Saved working directory and index state WIP on master: a8088442db Updated pom.xml
Now, if do a git status again, we will see that our working directory is clean.
$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
Let’s see how we can restore the stashed changes and find the hash associated with the stash commit.
We can bring the stashed changes back into our working directory like this:
$ git stash pop
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (59861637f7b599d87cb7a1ff003f1b0212e8908e)
As we can see in the last line git stash pop not only restores the stashed changes but also removes the reference to its associated commit.
If our terminal is still open, we can easily locate the hash generated after the execution of git stash pop. In our example, the hash, displayed in the last line is 59861637f7b599d87cb7a1ff003f1b0212e8908e.
Even if we have closed the terminal we can still find our hash in the following manner:
$ git fsck --no-reflog
Checking object directories: 100% (256/256), done.
Checking objects: 100% (302901/302901), done.
dangling commit 59861637f7b599d87cb7a1ff003f1b0212e8908e
The commit hash for the dropped stash is now visible to us.
We would not normally need a stash entry once we’ve applied it. However, there may be a situation where we wish to go back to a stash entry after we’ve dropped it. For example, if using git reset –hard HEAD will throw away all the uncommitted changes from our working directory. In this situation, we may wish to recall some earlier stashed changes, even though they were dropped.
Using the hash for a dangling commit, it’s still possible for us to recover those changes:
$ git stash apply 59861637f7b599d87cb7a1ff003f1b0212e8908e
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
We can see that our working directory is restored with the changes that were stashed earlier.
If we don’t have the hash readily available, we can find it:
git fsck --no-reflog | awk '/dangling commit/ {print $3}'
Here, we combine our –no-reflog option with awk to filter out only the hash for us.
In this article, we saw how git stash works and how it drops an entry when we use it. Then we saw how we can still use a dropped entry when we know its hash, and how the hash of a stash commit can be found.