如何在Git历史记录中找到包含特定文件的提交?
问题的出现原因:
假设您想恢复一个名为`MyFile`的文件,但您不确定它的路径(或其扩展名):
- 非常复杂的项目可能有多个具有相似或相同文件名的目录。
解决方法:
0. 准备工作:切换到git根目录以避免混淆。
> cd
1. 找到完整路径:
> git log --diff-filter=D --summary | grep delete | grep MyFile
`full/path/to/MyFile.js`是您要寻找的路径和文件。
2. 确定影响该文件的所有提交:
> git log --oneline --follow -- full/path/to/MyFile.js
列出所有影响该文件的提交。
3. 检出文件:
如果选择第一个列出的提交(最后一个按时间顺序,例如bd8374c),则无法找到该文件,因为它在该提交中被删除。
> git checkout bd8374c -- full/path/to/MyFile.js
选择前一个提交:
> git checkout bd8374c^ -- full/path/to/MyFile.js
这比被接受的答案更清晰。
对于Windows控制台(cmd),在步骤2中使用`find`替代`grep`:
> git log --diff-filter=D --summary | find "delete" | find "MyFile"
在步骤3中,注意引号包围哈希值:
> git checkout "bd8374c^" -- full/path/to/MyFile.js
根据用户对此答案的反馈,对于使用PowerShell而不是cmd的Windows用户,请使用`Select-String`替代`find`:
> git log --diff-filter=D --summary | Select-String "delete" | Select-String "MyFile"
如何找到包含特定文件的提交?
如果你不知道确切的路径,你可以使用命令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>
提交时,该文件被删除了,所以我们需要查看前一个提交来获取被删除文件的内容。
如果你不知道确切的路径,只知道文件名怎么办?
当你在一个文件从未存在的分支上使用命令git log -- <path>
时,将没有输出。你应该始终使用git log --all -- <path>
命令,以确保不会错过在其他分支上发生的更改。命令git log -- <path>
在你有多个分支并且容易忘记路径和分支的情况下是非常危险的(就像我一样),同时与其他开发人员一起工作也是危险的。
如果你的git log
答案中没有加上--all
选项(感谢Philip的建议),那么请考虑添加,以确保不会错过其他分支上的更改和文件。这将为像我这样健忘的人节省很多困扰。
如下面的答案所述,在恢复文件时应使用git checkout <SHA>^ -- <path-to-file>
命令(注意符号^),因为在<SHA>
提交时,该文件被删除了,所以我们需要查看前一个提交来获取被删除文件的内容。
当使用**/thefile.*
时,最好将其加上引号,例如'**/thefile.*'
,以保护通配符*
免受shell的影响。我不熟悉Windows的shell以及它们何时会吃掉*
,但如果在bash中从当前工作目录中意外匹配到文件,可能会引发问题。