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 还原。
- 找到你犯错的提交散列
- 运行
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 上文件的任何更改都可能会在您的分支上过早地获取。也许你知道这些问题这次不适用,但这是一个坏习惯。下次也许有一个你忘记的改变。
我总是在构建功能时创建一个新分支。这次我这样做了,把我的工作交给了新的分支机构。但是,我注意到我以某种方式删除了一个文件并且该文件也已提交。所以现在我的功能分支缺少一个仍在 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 还原。
- 找到你犯错的提交散列
- 运行
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 上文件的任何更改都可能会在您的分支上过早地获取。也许你知道这些问题这次不适用,但这是一个坏习惯。下次也许有一个你忘记的改变。