删除/删除行时如何查找提交?

我在 Git 存储库中的一个文件中有一行已删除的代码。我知道一些丢失的文本和它所在的文件,所以我使用了 git log -S'missingtext' /path/to/file

但是,唯一返回的是提交,我在其中添加了包含缺失文本的行。文本不在 HEAD 中,添加它的提交在我的分支中,所以我知道分支历史记录中一定有一个提交删除了它,但是它没有显示出来。

经过一些手动搜索后,发现在解决合并冲突时,该行被意外删除。所以我在想:

  1. 这就是为什么鹤嘴锄找不到删除行的提交的原因吗?
  2. 如果不手动查看历史记录,我怎么可能找到“丢失的文本”被删除的位置?

关于 # 1的任何见解都将是伟大的(我认为 git log -S会给我答案) ,但我真正的问题是 # 2,因为我希望在未来能够避免这种情况。

39226 次浏览

git log -c -S'missingtext' /path/to/file

在默认情况下,git log不显示合并提交的差异。请尝试使用 -c--cc标志。

更多讨论/解释:
Https://git-scm.com/docs/git-log
Nabble.com

来自 git-log 文档:

- c 使用此选项,合并提交的 diff 输出将显示每个父级对合并结果的差异 同时,而不是显示成对的差异之间的父和 此外,它只列出一些文件 改良自所有父母。

- cc 此标志暗示了-c 选项,并通过省略其内容位于 父母只有两个变体,合并结果选择其中一个 不做任何修改。

快速和肮脏的方法 # 2-使用 for 循环。

for commit in $(git log --pretty='%H'); do
git diff -U0 --ignore-space-change "$commit^" "$commit" | grep '^-.*missingtext' > /dev/null && echo "$commit"
done

这将包括所有合并更改,因为它显式指定了 diff 的基提交。我想出这个是因为 git log -c -S...给了我一堆假阳性。另外,当我在初始 git log命令中指定文件路径时,它跳过了我正在寻找的提交。

由于这可能会运行一段时间,您可以在 git log命令上指定 -n,或者如果您只需要1个结果,则在循环的末尾放置一个 && break

在超级用户上有一个很好的答案: Git: 我如何找到哪一个提交删除了一行?

git blame --reverse START.. file.ext

对于每一行,这将显示该行出现的最后一次提交——比如散列0123456789。下一个要执行的提交将是删除它的提交。使用 git log并搜索散列0123456789,然后后续提交。