我如何“怪罪”一个删除的行?

git blame非常适合修改和添加代码行,但是我怎样才能找到之前特定提交中存在的代码行最终被删除的时间呢。我在考虑 bisect,但我希望是更方便的东西。

(在你问之前: 在这种情况下,我只是做了一个 git log -p和搜索的代码行和(a)一些白痴 只是删除了重要的行在上一次提交和(b)我是那个白痴。)

97793 次浏览

如果你知道这一行的内容,这是一个理想的用例:

git log -S <string> path/to/file

它向您展示了引入或删除该字符串实例的提交。还有-G<regex>,它对正则表达式做同样的事情!查看man git-log并搜索-G-S选项,或pickaxe(这些功能的友好名称)以获取更多信息。

-S选项实际上也在git-blame manpage的标题中提到,在描述部分,它给出了一个使用git log -S...的示例。

我觉得你真正想要的是

git blame --reverse START..END filename

从# EYZ0:

引领历史前进,而不是倒退。这将显示该行存在的最后一个修订,而不是显示该行出现的修订。这需要一系列修订,如START..END,在START中存在责备路径。

使用git blame reverse,您可以找到该行出现的最后一次提交。您仍然需要获得随后的提交。

您可以使用以下命令来显示反向的git日志。显示的第一次提交将是该行最后一次出现,下一次提交将是该行被更改或删除时。

git log --reverse --ancestry-path COMMIT^..master

Git责备——反向可以让你关闭到行被删除的地方。但实际上指向的是被删除的行。它指向的是最后的版本,而这一行是现在。然后如果修订后是一个普通的提交,你很幸运,你得到了删除修订。哦,如果下面的版本是合并提交,那么事情可能会变得有点疯狂。

作为创建difflame的努力的一部分,我解决了这个问题,所以如果你已经在你的盒子上安装了Python,并且你愿意尝试一下,那么不要再等待了,让我知道它的进展。

https://github.com/eantoranz/difflame

完成响尾蛇的回答:

git log --full-history -S <string> path/to/file

我遇到了和这里提到的相同的问题,,原来这一行是缺失的,因为一个合并提交从一个分支得到了恢复,然后合并回它,有效地删除了有问题的行。--full-history标志防止跳过这些提交。

用于隐藏在合并提交中的更改

合并提交会自动将其更改隐藏在Git日志输出中。鹤嘴锄reverse-blame都没有发现变化。所以我想要的行被添加了,后来又被删除了,我想要找到删除它的归并。文件git log -p -- path/file历史只显示它被添加。以下是我找到它的最佳方法:

# EYZ0

搜索更改,然后向后搜索“^commit”——第一个“^commit”是文件最后有这一行的提交。第二个“^commit”是在它消失之后。第二个提交可能就是删除它的那个提交。-U9999意味着显示整个文件内容(在每次更改文件之后),假设您的文件最多都是9999行。

通过蛮力找到任何相关的合并(将每个可能的合并提交与它的第一个父文件进行区分,对大量的提交进行运行)

# EYZ0

(我试着限制更多的修订过滤器,但我遇到了问题,不建议这样做。我正在寻找的添加/删除更改是在不同的分支上,这些分支在不同的时间合并在一起,A…B没有包括更改实际合并到主线的时间。)

用这两次提交显示一个Git树(删除了很多复杂的Git历史):

< p > # EYZ0 (A是上面的第一个提交,B是上面的第二个提交)

显示A和B的历史减去A和B的历史。

替代版本(似乎显示路径更线性,而不是常规的Git历史树-但我更喜欢常规的Git历史树):

git log --graph --oneline A...B

三个点,不是两个点,三个点表示“r1 r2 -不是$(git merge-base -all r1 r2)”。它是一组可以从r1(左边)或r2(右边)中的任何一个访问的提交,但不能从两个都访问。”-来源:"man gitrevisions"

如果你更喜欢GUI,免费软件DeepGit似乎很适合。在文件旧版本的Blame视图中,通过拖动左边的空白来选择感兴趣的行。文件顶部的日志被过滤,只显示与这些行相关的提交。最上面的提交就是删除它们。