如何在项目提交历史中找到已删除的文件?

曾几何时,我的项目中有一个文件,我现在希望能够获得。

问题是:我不知道我什么时候删除了它,以及它在哪条路径上。

如何找到此文件存在时的提交?

457147 次浏览

如果您不知道您可以使用的确切路径

git log --all --full-history -- "**/thefile.*"

如果您知道文件所在的路径,您可以这样做:

git log --all --full-history -- <path-to-file>

这应该显示触及该文件的所有分支中的提交列表。然后,您可以找到所需文件的版本,并使用…

git show <SHA> -- <path-to-file>

或者将其恢复到您的工作副本中:

git checkout <SHA>^ -- <path-to-file>

注意插入符号(^),它将签出事先获取到标识的那个,因为在<SHA>提交文件被删除的时刻,我们需要查看之前的提交以获取已删除文件的内容

尝试使用其中一个查看器,例如gitk,以便您可以浏览历史记录以找到记住一半的文件。(如果需要所有分支,请使用gitk --all

无法编辑已接受的响应,因此在此处将其添加为答案,

要在git中恢复文件,请使用以下命令(注意SHA后面的“^”符号)

git checkout <SHA>^ -- /path/to/file

获取已删除文件的列表并复制已删除文件的完整路径

git log --diff-filter=D --summary | grep delete

执行下一个命令找到该提交的提交ID并复制提交ID

git log --all -- FILEPATH

显示已删除文件的差异

git show COMMIT_ID -- FILE_PATH

请记住,您可以使用>将输出写入文件,例如

git show COMMIT_ID -- FILE_PATH > deleted.diff

下面是一个简单的命令,开发人员或git用户可以从存储库根目录传递已删除的文件名并获取历史记录:

git log --diff-filter=D --summary | grep filename | awk '{print $4; exit}' | xargs git log --all --

如果有人,能改进指挥,请做。

@Amber给出了正确的答案!还有一个补充,如果您不知道文件的确切路径,您可以使用通配符!这对我很有效。

git log --all -- **/thefile.*

假设您想恢复一个名为MyFile的文件,但不确定其路径(或其扩展名):

初步:通过跳转到git根来避免混淆

一个重要的项目可能有多个具有相似或相同文件名的目录。

> cd <project-root>
  1. 找到完整路径

    git log--diff-filter=D--摘要|grep删除|grep MyFile

    delete mode 100644 full/path/to/MyFile.js

full/path/to/MyFile.js是您要查找的路径和文件。

  1. 确定影响该文件的所有提交

    #MyFile.js

    bd8374c Some helpful commit message

    ba8d20e Another prior commit message affecting that file

    cfea812 The first message for a commit in which that file appeared.

  2. 检查文件

如果您选择第一个列出的提交(按时间顺序排列的最后一个,此处为bd8374c),将找不到该文件,因为它已在该提交中被删除。

> git checkout bd8374c -- full/path/to/MyFile.js
`error: pathspec 'full/path/to/MyFile.js' did not match any file(s) known to git.`

只需选择前面的(附加一个插入符号)提交:

> git checkout bd8374c^ -- full/path/to/MyFile.js

总结:

  1. 步骤1

您在已删除文件的历史记录中搜索文件完整路径git log --diff-filter=D --summary | grep filename

  1. 步骤2

您在文件被删除之前从提交中恢复文件

restore () {filepath="$@"last_commit=$(git log --all --full-history -- $filepath | grep commit | head -1 | awk '{print $2; exit}')echo "Restoring file from commit before $last_commit"git checkout $last_commit^ -- $filepath}
restore my/file_path

以下是我的解决方案:

git log --all --full-history --oneline -- <RELATIVE_FILE_PATH>git checkout <COMMIT_SHA>^ -- <RELATIVE_FILE_PATH>

如果您希望查看所有已删除文件的size

以及相关的SHA

git log --all --stat --diff-filter=D --oneline

添加-p|--patch以查看内容

git log --all --stat --diff-filter=D -p

要缩小到任何文件,您有两个简单的选项,您可以使用路径规范,也可以通过管道访问grep并搜索文件名。

使用grep:

git log --all --stat --diff-filter=D --oneline | grep foo

使用路径规范:

git log --all --stat --diff-filter=D --oneline -- '*foo*'

如果您想查看内容,路径规范可以与-p|--patch很好地配合使用:

git log --all --stat --diff-filter=D --oneline --patch -- '*foo*'

你可能也会喜欢这个如果你知道文件在哪里

git log --all --full-history -- someFileName

我发生了这种情况,我甚至不知道文件的名称是什么,所以我想看到所有删除的文件……

总的来说,我强烈建议熟悉git-filter-repo开发完成。它在重写历史记录方面有很多用途,但它的分析功能之一包括非常快速地识别存储库中所有已删除的文件,并显示它们的大小和删除日期。(在非Windows操作系统上使用它相当于直接以下是专门针对Windows的安装说明。)

一旦你在你的路径中运行它,你只需运行:

git filter-repo --analyze

这将在您的. git文件夹中输出一些文件,您要查看此问题的文件称为:

.git\filter-repo\analysis\path-deleted-sizes.txt

此文件显示存储库中所有已删除的文件,按大小反向排序,以及删除日期。这是一个示例输出:

=== Deleted paths by reverse accumulated size ===Format: unpacked size, packed size, date deleted, path name(s)57151421   44898377 2022-07-22 somdirectory/somefileA46034619   42929136 2022-01-18 somdirectory/somefileB65332368   29102439 2020-09-28 somdirectory/somefileC23686432   21681498 2022-07-22 somdirectory/somefileD23681272   21678818 2022-07-22 somdirectory/somefileE23676153   21670502 2022-07-22 somdirectory/somefileF43232768   21439037 2020-07-10 somdirectory/somefileG18714315   14299243 2019-01-10 somdirectory/somefileH16788104   13035176 2019-01-10 somdirectory/somefileI

显然,您可以使用它来查找您要查找的文件,或者,在重写历史记录的上下文中,基于第二列大小,我知道如果我从历史记录中删除这9个已删除的文件,我将回收大约220 MB。

确定要查找的文件后,您可以使用它来查找提交:

git log --all --full-history -- <filename>