How to Recover a Dropped Stash in Git – 如何在Git中恢复掉落的存储空间

最后修改: 2022年 2月 7日

1. Overview

1.概述

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.

git stashgit stash pop这样的命令被用来搁置(stash)和恢复我们工作目录中的变化。在本教程中,我们将学习如何在Git中恢复丢失的藏书。

2. Stashing the Changes in Working Directory

2.在工作目录中存储变化

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 仓库。现在,让我们对README.md文件做一些修改,只需在最后添加一行,并检查我们工作目录的状态。

$ 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命令来暂时搁置我们的修改。

$ 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,我们会看到我们的工作目录是干净的。

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

3. Restoring Stashed Changes and Finding the Hash

3.恢复隐藏的变化并找到哈希值

Let’s see how we can restore the stashed changes and find the hash associated with the stash commit.

让我们看看如何恢复存储的修改,并找到与存储提交相关的哈希值。

3.1. Restoring Stashed Changes into the Working Directory

3.1.将存储的变化恢复到工作目录中

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.

正如我们在最后一行看到的,git stash pop不仅恢复了存储的修改,还删除了对其相关提交的引用

3.2. Locating the Hash When the Terminal Is Open

3.2.终端打开时定位哈希值

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.

如果我们的终端仍然打开,我们可以很容易地找到执行git stash pop后产生的哈希值。在我们的例子中,最后一行显示的哈希值是59861637f7b599d87cb7a1ff003f1b0212e8908e.

3.3. Recovering the Hash After the Terminal Is Closed

3.3.在终端关闭后恢复哈希值

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.

现在我们可以看到被丢弃的储藏室的提交哈希值了。

4. Recovering the Dropped Stash

4.收回掉落的藏品

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.

通常情况下,一旦我们应用了一个贮藏室条目,我们就不需要它了。然而,在某些情况下,我们可能希望在丢弃一个储藏库条目之后再回到它。例如,如果使用git reset -hard HEAD 将丢弃我们工作目录中所有未提交的修改。在这种情况下,我们可能希望召回一些早期的存储修改,尽管它们被丢弃了。

4.1. Use the Hash to Restore the Stash

4.1.使用哈希值来恢复藏品

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.

我们可以看到,我们的工作目录已经恢复了先前所隐藏的变化。

4.2. Finding All the Hash Commits

4.2.找到所有的哈希承诺

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.

在这里,我们将我们的-no-reflog选项与awk结合起来,只为我们过滤出哈希值。

5. Conclusion

5.总结

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.

在这篇文章中,我们看到了git stash是如何工作的,以及当我们使用它时,它是如何丢弃一个条目。然后我们看到,当我们知道一个被丢弃的条目的哈希值时,我们仍然可以使用它,以及如何找到一个储藏室提交的哈希值。