如何在项目提交历史中找到已删除的文件?
Posted
技术标签:
【中文标题】如何在项目提交历史中找到已删除的文件?【英文标题】:How to find a deleted file in the project commit history? 【发布时间】:2011-11-04 10:25:34 【问题描述】:曾几何时,我的项目中有一个文件,我现在希望能够得到它。
问题是:我不知道我什么时候删除它以及它在哪个路径上。
如果该文件存在,我如何找到它的提交?
【问题讨论】:
这里的答案对我来说比duplicates中的答案更有用。 同意...不管有没有重复...他们没有出现在 Google 搜索中...这个有...我希望我们不要再浪费时间追逐重复。 ..只有时间和谷歌的算法会告诉你哪个问题是最好的。 【参考方案1】:如果您不知道可以使用的确切路径
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>
提交的那一刻文件被删除,我们需要查看上一次提交以获取已删除文件的内容
【讨论】:
如果您不知道确切的路径怎么办?你只知道文件名? @PedroMorteRologit log -- <path>
在文件从未存在的分支上时将没有输出。您应该始终使用git log --all -- <path>
,以确保您不会错过其他分支上发生的更改。如果你有多个分支并且容易忘记路径和分支(像我一样),命令git log -- <path>
可能会非常危险,如果你与其他开发人员一起工作也会很危险。
@Amber,考虑将--all
(感谢Philip)添加到您的git log
答案中,这样人们就不会错过其他分支上的更改和文件。它会让像我这样健忘的人免去很多悲伤。
如下面的回答所说,恢复文件应该是git checkout <SHA>^ -- <path-to-file>
(注意^符号),因为在**/thefile.*
时,引用它通常是个好主意,例如 '**/thefile.*'
,以保护 glob *
免受 shell 的影响。 (我不熟悉 WIndows shell 以及当它们吃 *
s 时,但如果 bash 中的当前工作目录有意外匹配,那可能会造成麻烦。)【参考方案2】:
获取已删除文件的列表并复制已删除文件的完整路径
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
【讨论】:
虽然在第一步的帮助下找到了路径,但是第二步却抛出了这个错误:unknown revision or path not in the working tree
。
要查看提交哈希和删除,您可以使用git log --diff-filter=D --summary | grep -E 'delete|^commit\s+\S+'
第 2 步不返回任何内容。关于为什么会发生的任何想法?我的文件名是正确的。
要找到三合一功能,请将其添加到您的 .bashrc 或 .zshrc 中:git-grep-latest() result_path=$(git log --diff-filter=D --summary | grep $1 | head -1 | awk 'print $4;'); latest_commit=$(git log --all -- $result_path | head -1 | awk 'print $2;'); git show $latest_commit -- $result_path;
,现在您可以这样做:git-grep-latest some_text
@TylerJones 你可以使用管道将任何东西用 linux 提供给任何东西 - google linux pipes
.. 你会喜欢的。【参考方案3】:
假设您想恢复一个名为 MyFile
的文件,但不确定它的路径(或它的扩展名):
初步:通过进入 git 根目录避免混淆
一个重要的项目可能有多个目录具有相似或相同的文件名。
> cd <project-root>
查找完整路径
git log --diff-filter=D --summary | grep 删除 | grep 我的文件
delete mode 100644 full/path/to/MyFile.js
full/path/to/MyFile.js
是您要查找的路径和文件。
确定影响该文件的所有提交
git log --oneline --follow -- full/path/to/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.
签出文件
如果您选择列出的第一个提交(按时间顺序排列的最后一个,此处为 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
【讨论】:
这比公认的答案要清楚得多 对于 windows 控制台 (cmd),在第 2 步中使用 find 而不是 grep:git log --diff-filter=D --summary | find "delete" | find "MyFile"
和第 3 步,注意哈希周围的引号:git checkout "bd8374c^" -- full/path/to/MyFile.js
【参考方案4】:
无法编辑已接受的回复,因此在此处将其添加为答案,
要在 git 中恢复文件,请使用以下命令(注意 SHA 后面的 '^' 符号)
git checkout <SHA>^ -- /path/to/file
【讨论】:
我不明白你为什么想要 ^。该文件在该 SHA 的提交中...为什么要从那里退回另一个提交? 它在提交中,该 sha 为“已删除”,这意味着它仍然不存在。您必须在此之前进行提交才能真正取回它。 @tandrewnichols 这只是意味着您使用了错误的提交 SHA - 您想要提交您想要的文件版本......这可能不是文件被删除的版本。 @Amber 并且您想要的提交可能是它被删除之前的最新提交,因此这个答案。 @AlexR:<SHA>~1
应该可以正常工作,而无需用引号括起来。【参考方案5】:
@Amber 给出了正确答案!再补充一点,如果您不知道文件的确切路径,您可以使用通配符!这对我有用。
git log --all -- **/thefile.*
【讨论】:
@PedroMorteRolo 嗯。我不知道将现有答案复制到投票最多的答案中感觉如何:/ 这个答案本身也很有用;一个upvote可能就足够了? 如果文件在项目根目录下(在 Cygwin 中测试),则找不到该文件。【参考方案6】:下面是一个简单的命令,开发者或 git 用户可以从存储库根目录传递已删除的文件名并获取历史记录:
git log --diff-filter=D --summary | grep filename | awk 'print $4; exit' | xargs git log --all --
如果有人可以改进命令,请做。
【讨论】:
太棒了,谢谢!看起来我的文件根本不存在,但这是一个单独且更棘手的问题…… 如果您的文件似乎“丢失”,请确保从存储库根目录运行此文件【参考方案7】:尝试使用其中一个查看器,例如gitk
,这样您就可以浏览历史记录以找到那个被记住了一半的文件。 (如果所有分支都需要,请使用gitk --all
)
【讨论】:
--all
选项对于您的答案和接受的答案都至关重要。
对于大多数项目来说,浏览历史将花费大量时间。【参考方案8】:
总结:
-
步骤 1
您在已删除文件的历史记录中搜索您的文件完整路径git log --diff-filter=D --summary | grep filename
-
第二步
在文件被删除之前从提交中恢复文件
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
【讨论】:
【参考方案9】:如果您希望查看所有已删除文件的size
以及关联的SHA
git log --all --stat --diff-filter=D --oneline
添加 -p 也可以查看内容
git log --all --stat --diff-filter=D -p
要缩小到任何文件,只需管道到 grep 并搜索文件名
git log --all --stat --diff-filter=D --oneline | grep someFileName
如果你知道文件在哪里,你可能也会喜欢这个
git log --all --full-history -- someFileName
【讨论】:
【参考方案10】:这是我的解决方案:
git log --all --full-history --oneline -- <RELATIVE_FILE_PATH>
git checkout <COMMIT_SHA>^ -- <RELATIVE_FILE_PATH>
【讨论】:
以上是关于如何在项目提交历史中找到已删除的文件?的主要内容,如果未能解决你的问题,请参考以下文章