1. 概述

在 Git 中,git stashgit stash pop 命令用于临时保存并恢复工作目录中的更改。本文将介绍如何在误删除暂存项后找回它们,具体操作步骤见Git 教程

2. 工作目录中暂存更改

以一个例子来说,我们已经克隆了一个 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")

然后,我们可以使用 git stash 命令暂时保存这些更改:

$ git stash
Saved working directory and index state WIP on master: a8088442db Updated pom.xml

再次执行 git status,我们会看到工作目录已变得干净:

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

nothing to commit, working tree clean

3. 恢复暂存更改及查找哈希值

接下来,我们将学习如何恢复暂存的更改以及找到与暂存提交关联的哈希值。

3.1. 将暂存更改恢复到工作目录

可以这样将暂存更改带回工作目录:

$ 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)

如最后一行所示,git stash pop 不仅恢复了暂存更改,还移除了与之关联的提交引用。

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

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

3.3. 关闭终端后找回哈希值

即使关闭了终端,我们也可以通过以下方式找到哈希值:

$ git fsck --no-reflog
Checking object directories: 100% (256/256), done.
Checking objects: 100% (302901/302901), done.
dangling commit 59861637f7b599d87cb7a1ff003f1b0212e8908e

现在,丢失的暂存项的哈希值已可见。

4. 恢复丢失的暂存项

通常情况下,应用暂存项后我们不再需要它。但有时可能希望在误删后找回暂存项,例如,使用 git reset --hard HEAD 可能会丢弃所有未提交的工作目录更改。在这种情况下,我们可能希望召回先前暂存的更改。

4.1. 使用哈希值恢复暂存项

即使哈希值对应的是一个悬而未决的提交,我们仍可通过哈希值找回这些更改:

$ 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")

可以看到,工作目录已恢复为之前暂存的更改状态。

4.2. 查找所有哈希提交

如果我们没有立即可用的哈希值,可以查找它:

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

这里,我们将 --no-reflog 选项与 awk 结合,筛选出我们需要的哈希值。

5. 总结

本文介绍了 git stash 的工作原理,以及在误删除暂存项后如何利用其哈希值找回更改。我们学会了如何使用哈希值恢复被丢弃的暂存项,并了解了如何查找暂存提交的哈希值。