git blame非常适合修改和添加的行,但是如何最终删除特定先前提交中存在的行.我在想,bisect但我希望有更方便的东西.
[在你问之前:在这种情况下,我只是做了一个git log -p并搜索了代码行和(a)一些白痴刚刚删除了前一次提交中的重要行和(b)我是那个白痴]
Cas*_*bel 598
如果您知道该行的内容,这是一个理想的用例:
git log -S <string> path/to/file
Run Code Online (Sandbox Code Playgroud)
它显示了提交或删除该字符串实例的提交.还有-G<regex>正则表达式做同样的事情!有关详细man git-log信息,请参阅并搜索-G和-S选项或pickaxe(这些功能的友好名称).
该-S选项实际上也在手册git-blame页的标题中提到,在描述部分中,它给出了一个使用示例git log -S....
Chr*_*ial 132
我想你真正想要的是
git blame --reverse START..END filename
Run Code Online (Sandbox Code Playgroud)
从联机帮助页:
走向历史而不是落后.这不显示出现一行的修订,而是显示一行存在的最后修订版.这需要一系列的修订,如START..END,其中指责路径存在于START中.
使用git blame reverse,您可以找到该行出现的最后一次提交.您仍然需要获得之后的提交.
您可以使用以下命令显示反转的git日志.显示的第一个提交将是该行的最后一次出现,下一次提交将在更改或删除时进行.
git log --reverse --ancestry-path COMMIT^..master
Run Code Online (Sandbox Code Playgroud)
est*_*ani 14
刚刚完成Cascabel的回答
git log --full-history -S <string> path/to/file
Run Code Online (Sandbox Code Playgroud)
我这里提到了同样的问题,但事实证明,在一行丢失,因为合并提交一个分支得到了恢复,然后合并到它,有效去除有问题的线路.该--full-history标志可防止跳过这些提交.
git blame --reverse可以让你接近删除行的位置.但它实际上并没有指向删除行的修订版.它指向存在该行的最后修订版.然后,如果以下修订版是一个普通提交,那么您很幸运,并且您获得了删除修订版.OTOH,如果以下修订版是合并提交,那么事情就会变得有点疯狂.作为创建difflame的努力的一部分,我解决了这个问题,所以如果你已经在你的盒子上安装了python并且你愿意尝试一下,那么不要再等了,让我知道它是怎么回事.
https://github.com/eantoranz/difflame
对于隐藏在合并提交中的更改
合并提交会自动将其更改隐藏在 Git 日志输出中。镐和反向责怪都没有发现变化。因此,我想要的行已被添加,后来被删除,我想找到删除它的合并。文件git log -p -- path/file历史记录仅显示它被添加。这是我发现找到它的最佳方法:
git log -p -U9999 -- path/file
搜索更改,然后向后搜索“^commit” - 第一个“^commit”是文件最后包含该行的提交。第二个“^commit”是在它消失之后。第二次提交可能是删除它的那次提交。它的-U9999目的是显示整个文件内容(每次更改文件后),假设您的文件最多有 9999 行。
通过暴力查找任何相关的合并(将每个可能的合并提交与其第一个父级进行比较,针对大量提交运行)
git log --merges --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
Run Code Online (Sandbox Code Playgroud)
三个,而不是两个点 - 三个点表示“r1 r2 --not $(git merge-base --all r1 r2)。它是可从 r1(左侧)或 r2(右侧)之一访问的提交集侧),但不是来自双方。” - 来源:“man gitrevisions”