Git 恢复在本地分支中删除的文件

Git restore file deleted in local branch

我总是在构建功能时创建一个新分支。这次我这样做了,把我的工作交给了新的分支机构。但是,我注意到我以某种方式删除了一个文件并且该文件也已提交。所以现在我的功能分支缺少一个仍在 master 中的文件。

如何恢复文件?

我得到了删除文件的提交的哈希值,并尝试了:

git checkout 1f1d3f76bac0bf6e13ceee5bb3df69f8389fc73f -- /path/to/MyMissingFile

但 git 说 pathspec did not match any files known to git。我确认文件名和提交都是正确的,使用 git log --diff-filter=D --summary 打印发生删除的提交和文件名。

我可以通过简单地从 master 分支检出文件,然后将它们提交到我的功能分支来解决这个问题:

git checkout master -- /path/to/MyMissingFile

最简单的方法是使用 git 还原。

  1. 找到你犯错的提交散列
  2. 运行 git revert [commit-hash]

然后您将取回您的文件

Git 2.23+ 的正确命令是使用 git restore, which replaces the confusing git checkout command.

 git restore -s master -- /path/to/MyMissingFile

这将仅在工作树上恢复存在于 "source" (-s) 分支 master.

中的文件

同时恢复工作树和索引:

git restore -s master -SW -- /path/to/MyMissingFile

(-SW: --staged --worktree的缩写)

如果您只恢复工作树,那么 git diff,如 illustrated here,索引(仍然反映正在删除的文件)和工作树之间会有差异。
通过恢复工作树 索引,您可以直接添加恢复的文件,然后提交。

的问题
git checkout 1f1d3f76bac0bf6e13ceee5bb3df69f8389fc73f -- /path/to/MyMissingFile

大概是根据您所说的,它是删除文件的提交的哈希值 - 因此该文件不存在。但该文件位于该提交的父级中。顺便说一句,您可以使用缩写的散列,然后将 ^~ 添加到末尾将获得提交的父项。所以

git checkout 1f1d3f76ba^ -- /path/to/MyMissingFile

应该可以。 (如果有问题的提交是合并,那么这里可能会有一些错误的余地,因为您需要确保您到达了正确的父级;但这听起来不适用于此处。)

切换到较新的 restore 命令也是一个选项(并且可能不是一个坏主意),正如其他人提到的那样;但这不是真正的问题。

正如您似乎已经发现的那样,您还可以进入 master(或文件仍然存在的任何其他分支)并从那里获取文件。不过,我不推荐这样做(尤其是如果您已经费尽心思找到文件被删除的提交),因为 (a) 在删除文件之前对分支上的文件所做的任何更改都将丢失,并且 ( b) 对 master 上文件的任何更改都可能会在您的分支上过早地获取。也许你知道这些问题这次不适用,但这是一个坏习惯。下次也许有一个你忘记的改变。