111

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

但是,唯一回来的是我在其中添加了包含缺失文本的行的提交。该文本不存在于 HEAD 中,并且添加它的提交存在于我的分支中,因此我知道我的分支历史记录中的一个提交必须已将其删除,但它没有出现。

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

  1. 这就是镐找不到删除该行的提交的原因吗?
  2. 如果不手动挖掘历史记录,我怎么能找到删除“missingtext”的位置?

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

4

3 回答 3

148

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

git log默认情况下不显示合并提交的差异。试试-cor--cc标志。

更多讨论/解释:
https:
//git-scm.com/docs/git-log nabble.com

来自 git-log 文档:

-c使用此选项,合并提交的差异输出同时显示每个父级与合并结果的差异,而不是一次显示父级与结果之间的成对差异。此外,它仅列出从所有父项修改的文件。

--cc该标志暗示了 -c 选项,并通过省略无趣的大块来进一步压缩补丁输出,这些小块的父项中的内容只有两个变体,并且合并结果选择其中一个而无需修改。

于 2012-09-25T21:47:56.123 回答
22

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

git blame --reverse START.. file.ext

对于每一行,这将显示该行所在的最后一次提交——比如哈希 0123456789。接下来的下一个提交将是删除它的那个。使用git log并搜索哈希 0123456789,然后是它的后续提交。

于 2017-04-18T04:37:34.127 回答
6

快速而肮脏的方式#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

这将包括所有合并更改,因为它明确指定了差异的基本提交。我想出这个是因为git log -c -S...给了我一堆误报。此外,当我在初始命令中指定文件路径时git log,它跳过了我正在寻找的提交。

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

于 2015-04-07T01:55:02.237 回答