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

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

技术背景

在项目开发过程中,有时会不小心删除文件,或者由于历史清理等原因文件被删除。为了恢复这些文件,需要从项目的提交历史中查找它们。Git作为一个强大的版本控制系统,提供了多种方法来实现这一目的。

实现步骤

1. 不知道文件确切路径

如果不知道文件的确切路径,可以使用以下命令查找涉及该文件的所有提交:

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

2. 知道文件路径

若知道文件的路径,可以使用以下命令查看所有分支中涉及该文件的提交:

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

3. 显示指定版本的文件

找到想要的文件版本后,使用以下命令显示该版本的文件内容:

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

4. 恢复文件到工作副本

使用以下命令将文件恢复到工作副本:

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

注意,这里的^符号表示获取指定提交之前的版本,因为在<SHA>提交时文件已被删除,所以需要查看前一个提交来获取已删除文件的内容。

5. 获取已删除文件列表

使用以下命令获取已删除文件的列表,并复制已删除文件的完整路径:

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

6. 查找提交ID

使用以下命令查找涉及该文件的提交ID:

1
git log --all -- FILEPATH

7. 显示已删除文件的差异

使用以下命令显示已删除文件的差异:

1
git show COMMIT_ID -- FILE_PATH

可选地,可以使用>将输出写入文件:

1
git show COMMIT_ID -- FILE_PATH > deleted.diff

8. 不确定文件路径或扩展名

如果不确定文件的路径或扩展名,可以按以下步骤操作:

步骤0:进入Git项目根目录

1
cd <project-root>

步骤1:查找完整路径

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

步骤2:确定影响该文件的所有提交

1
git log --oneline --follow -- full/path/to/MyFile.js

步骤3:检出文件

如果选择列出的第一个提交(按时间顺序最后一个),由于文件在该提交中已被删除,将找不到该文件。需要选择前一个提交:

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

9. 查看所有已删除文件的大小和SHA

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

添加-p|--patch参数可以查看文件内容:

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

10. 缩小搜索范围

可以使用路径规范或grep命令缩小搜索范围:

使用grep

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

使用路径规范

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

如果想查看文件内容,可以将路径规范与-p|--patch参数一起使用:

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

11. 知道文件位置

如果知道文件的位置,可以使用以下命令:

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

12. 总结步骤

步骤1:在已删除文件的历史记录中搜索文件的完整路径

1
git log --diff-filter=D --summary | grep filename

步骤2:从文件被删除之前的提交中恢复文件

1
2
3
4
5
6
7
8
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

13. 使用git-filter-repo

如果甚至不知道文件的名称,可以使用git-filter-repo快速识别仓库中所有已删除的文件,并显示它们的大小和删除日期:

1
git filter-repo --analyze

结果会输出到.git\filter-repo\analysis\path-deleted-sizes.txt文件中。找到想要的文件后,可以使用以下命令查找涉及该文件的提交:

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

核心代码

恢复文件函数

1
2
3
4
5
6
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
}

最佳实践

  • 在进行文件恢复操作之前,建议先备份当前的工作副本,以防意外覆盖。
  • 使用gitk等可视化工具可以更方便地浏览提交历史,找到想要的文件版本。

常见问题

1. git checkout时提示文件未找到

如果在执行git checkout <SHA> -- <path-to-file>时提示文件未找到,可能是因为该提交中文件已被删除。可以尝试使用git checkout <SHA>^ -- <path-to-file>来获取前一个提交中的文件内容。

2. git-filter-repo在Windows上安装问题

在Windows上安装git-filter-repo可能会遇到一些问题,可以参考这里的安装说明。


如何在项目提交历史中查找已删除的文件
https://119291.xyz/posts/how-to-find-deleted-file-in-project-commit-history/
作者
ww
发布于
2025年5月23日
许可协议