当一行被删除/移除时如何找到提交记录?

153

我在Git仓库的一个文件中有一行被删除了。我知道缺失文本的一部分,以及它所在的文件,因此我使用git log -S'missingtext' /path/to/file命令。

然而,返回的结果只有添加缺失文本的那次提交记录。这个文本在HEAD中没有出现,添加该文本的提交记录位于我的分支中,所以我知道我的分支历史记录中的其中一次提交已将其删除,但是它没有显示出来。

经过一些手动搜索,发现这行文本是在解决合并冲突时被意外删除的。因此,我的问题是:

  1. 这是pickaxe无法找到删除行的提交记录的原因吗?
  2. 我如何找到“missingtext”被删除的位置,而不需要手动查找历史记录?

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


14
less中使用git log -p/missingtext是一种快速而简单的方法,可以实现这一点。 - nneonneo
4
可能是如何“blame”一个已删除的行的重复问题。 - hypehuman
3个回答

199

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

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

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

从git-log文档中得知:

-c 使用此选项,合并提交的差异显示每个父提交到合并结果的差异,而不是一次显示一个父提交与结果之间的差异。此外,它仅列出了所有父提交都修改过的文件。

--cc 此标志意味着-c选项,并通过省略在父提交中只有两种变体内容且合并结果选择其中一种变体而没有修改的不重要的hunk来进一步压缩补丁输出。


3
如果您想查找已删除文件中的某一行何时被删除,可以使用 git log -c -S'missingtext' -- /path/to/file 命令。 - Jonathan
6
如果您不知道哪个文件包含了缺失的文本,可以省略“/path/to/file”,只需运行“git log -c -S'missingtext'”。 - Aryeh Beitz
6
在Windows系统中,我需要执行以下命令来查看文件的修改历史:git log -c -S "missingtext" /path/to/file。请注意,双引号是必需的。 - SpeedOfSpin
4
这显示了在/path/to/file中甚至不包含“missingtext”的提交。 - Philip Rego
1
@PhilipRego,-c标志也会给我带来误报结果。所以只需要使用git log -S'missingtext'就可以了。 - victorlin
如果在更改后重新命名文件,这个方法还能正常工作吗? - undefined

25

在Super User上有一个很好的答案:Git:我如何找到删除一行的提交?

git blame --reverse START.. file.ext

这将显示每一行最后存在的提交 - 比如哈希值为0123456789。接下来要查找的提交是删除该行的那个提交。使用git log并搜索哈希值0123456789及其后继提交。


2
下一个提交将是删除它的提交,但这并不总是正确的。blame --reverse 将显示包含该行的最新提交(按时间戳排序),但它可能已经被来自不同分支的早期提交删除。 - Superole
你有任何搜索“missingtext”的方法吗? - Philip Rego

8
快速而简单的方法#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命令中指定文件路径时,它跳过了我要查找的提交。
由于这可能需要一段时间,您可以在git log命令上指定-n,或者在循环末尾放置&& break,如果您只需要1个结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接