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

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 &lt;SHA&gt;^ -- &lt;path-to-file&gt;

注意插入符号 (^),它使结帐先于识别出,因为在&lt;SHA&gt; 提交的那一刻文件被删除,我们需要查看上一次提交以获取已删除文件的内容

【讨论】:

如果您不知道确切的路径怎么办?你只知道文件名? @PedroMorteRolo git log -- &lt;path&gt; 在文件从未存在的分支上时将没有输出。您应该始终使用git log --all -- &lt;path&gt;,以确保您不会错过其他分支上发生的更改。如果你有多个分支并且容易忘记路径和分支(像我一样),命令git log -- &lt;path&gt; 可能会非常危险,如果你与其他开发人员一起工作也会很危险。 @Amber,考虑将--all(感谢Philip)添加到您的git log 答案中,这样人们就不会错过其他分支上的更改和文件。它会让像我这样健忘的人免去很多悲伤。 如下面的回答所说,恢复文件应该是git checkout &lt;SHA&gt;^ -- &lt;path-to-file&gt;(注意^符号),因为在提交的那一刻文件被删除了,我们需要看一下上一次提交以获取已删除文件的内容 当使用 **/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

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

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: &lt;SHA&gt;~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>

【讨论】:

以上是关于如何在项目提交历史中找到已删除的文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Git 历史记录中永久删除提交?

Git 清除历史已提交文件永久删除文件

Git:恢复一个已经在提交中被删除的文件

怎么查看svn的提交记录

Git 如何从特定的提交中创建一个新的分支

如何在 SVN 中查找文件被删除/移动的所有提交(修订号)