git责备是伟大的修改和添加的行,但我怎么能找到当存在于特定的前一次提交最终被删除的行。我想用二分法,但我希望用更方便的方法。

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


当前回答

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

其他回答

Git blame -reverse可以让你接近被删除的行。但它实际上并没有指向该行被删除的修订。它指向这一行出现的最后一次修订。然后,如果下面的修订是一个普通提交,你很幸运,你得到了删除修订。OTOH,如果下面的修订是一个合并提交,那么事情可能会变得有点疯狂。

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

https://github.com/eantoranz/difflame

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

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

git log -p -U9999——path/文件

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

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

Git log——merged——pretty=format:" Git diff %h^…"%h | grep target_text" HEAD ^$(git merge-base A B) | sh -v 2>&1 | less

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

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

git log——graph——oneline A B ^$(git merge-base A B) (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"

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

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

从手册中:

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

用git责备反向,可以找到最后提交的行中出现的内容。您仍然需要获得随后的提交。

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

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

为了完成Cascabel的回答:

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

我遇到了与这里提到的相同的问题,但结果是该行不见了,因为来自分支的合并提交被还原,然后合并回分支,有效地删除了有问题的行。——full-history标志可以防止跳过这些提交。