ChatGPT解决这个技术问题 Extra ChatGPT

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

git

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

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

当它存在时,如何找到该文件的提交?

这里的答案对我来说比副本中的答案更有用。
同意...不管重复...他们没有出现在谷歌搜索中......这个确实......我希望我们不会浪费时间追逐重复......只有时间和谷歌的算法会告诉哪个问题是最好的。
哪些重复@FelipeAlvarez?望向地平线,却没有找到。也许从前有一个副本。

J
John Clements

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

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> 提交时文件被删除,我们需要查看上一次提交获取已删除文件的内容


如果你不知道确切的路径怎么办?你只知道文件名?
@PedroMorteRolo git log -- <path> 在您位于文件从未存在的分支上时将没有输出。您应该始终使用 git log --all -- <path>,以确保您不会错过其他分支上发生的更改。如果您有多个分支并且容易忘记路径和分支(如我),命令 git log -- <path> 可能非常危险,如果您与其他开发人员一起工作,它也很危险。
@Amber,请考虑将 --all(感谢 Philip)添加到您的 git log 答案中,这样人们就不会错过其他分支上的更改和文件。它会为像我这样健忘的人省去很多悲伤。
如以下答案所述,恢复文件应为 git checkout <SHA>^ -- <path-to-file>(注意 ^ 符号),因为在 <SHA> commit 文件被删除了,我们需要查看之前的commit来获取被删除文件的内容
使用 **/thefile.* 时,通常最好引用它,例如 '**/thefile.*',以保护 glob * 免受 shell 的影响。 (我不熟悉 WIndows shell 以及它们何时吃 *,但如果 bash 中的当前工作目录意外匹配,那可能会造成麻烦。)
F
Fatih Acet

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

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 .. 您会喜欢的。
C
Calaf

假设您要恢复一个名为 MyFile 的文件,但不确定它的路径(或它的扩展名,就此而言):

初步:通过进入 git root 来避免混淆

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

> cd <project-root>

找到完整路径 git log --diff-filter=D --summary | grep 删除 | grep MyFile 删除模式 100644 full/path/to/MyFile.js

full/path/to/MyFile.js 是路径 &您正在寻找的文件。

确定影响该文件的所有提交 git log --oneline --follow --full/path/to/MyFile.js bd8374c 一些有用的提交消息 ba8d20e 另一个影响该文件的先前提交消息 cfea812 提交的第一条消息文件出现。签出文件

如果您选择列出的第一个提交(按时间顺序排列的最后一个,此处为 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
我和@pouyan021 一起讨论这个问题。这个答案很快让我找到了删除文件的提交。
A
Akshay Agarwal

无法编辑接受的回复,因此在此处将其添加为答案,

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

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

我不明白你为什么想要^。该文件在该 SHA 的提交中......为什么要从那里退回另一个提交?
它在该 sha 作为“已删除”的提交中,这意味着它仍然不存在。您必须在此之前进行提交才能真正取回它。
@tandrewnichols 这只是意味着您使用了错误的提交 SHA - 您想要提交您想要的文件版本......这可能不是文件被删除的版本。
@Amber 并且您想要的提交可能是它被删除之前的最新提交,因此这个答案。
@AlexR:<SHA>~1 应该可以正常工作,而无需用引号括起来。
P
Petur Subev

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

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

@PedroMorteRolo 嗯。我不知道将现有答案复制到投票最多的答案中有何感受:/ 这个答案本身也很有用;一个upvote可能就足够了?
如果文件位于项目根目录中(在 Cygwin 中测试),则找不到该文件。
J
Jason

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

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

如果有人可以改进命令,请做。


太好了,谢谢!看起来我的文件根本不存在,但这是一个单独且更棘手的问题......
如果您的文件似乎“丢失”,请确保从存储库根目录运行它
P
Philip Oakley

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


--all 选项对于您的答案和接受的答案都至关重要。
对于大多数项目来说,浏览历史将花费大量时间。
m
m_floer

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

以及相关的 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*'

如果您想查看内容,pathspec 可以与 -p|--patch 一起很好地工作:

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

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

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

这是我发现找到删除特定文件的提交的最有效方法。非常感谢。
s
srghma

概括:

步骤1

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

第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

A
Antonio Petricca

这是我的解决方案:

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

请阅读 How to Answeredit 您的问题,以解释为什么此代码实际上可以解决手头的问题。永远记住,您不仅在解决问题,而且还在教育 OP 和这篇文章的任何未来读者。