如何在git历史中grep(搜索)提交的代码?

我过去曾在某个文件中删除过一个文件或一些代码。 我可以在内容中grep(不在提交消息中)吗?

一个非常糟糕的解决方案是grep日志:

git log -p | grep <pattern>

但是,这不会立即返回提交散列。 我玩弄git grep无济于事。


要搜索提交内容(即实际的源代码行,而不是提交消息等),您需要做的是:

git grep <regexp> $(git rev-list --all)

更新git rev-list --all | xargs git grep expression 如果遇到“参数列表太长”的错误, git rev-list --all | xargs git grep expression将起作用

如果你想限制搜索某个子树(例如“lib / util”),你需要将它传递给rev-list子命令和grep

git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util

这将grep通过所有提交文本的正则表达式。

在两个命令中传递路径的原因是因为rev-list将返回所有对lib/util的更改发生的修订列表,但是您还需要传递给grep以便它仅在lib/util上进行搜索。

试想一下以下情况: grep可能会在rev-list返回的同一版本中包含的其他文件上找到相同的<regexp> (即使该版本上的该文件没有更改)。

以下是一些其他搜索源的有用方法:

搜索工作树以查找正则表达式正则表达式的文本:

git grep <regexp>

搜索与正则表达式regexp1或regexp2匹配的文本行的工作树:

git grep -e <regexp1> [--or] -e <regexp2>

搜索工作树中与正则表达式regexp1和regexp2匹配的文本行,仅报告文件路径:

git grep -e <regexp1> --and -e <regexp2>

搜索工作树以查找具有匹配正则表达式regexp1的文本行和匹配正则表达式regexp2的文本行的文件:

git grep -l --all-match -e <regexp1> -e <regexp2>

搜索工作树以更改文本匹配模式的行:

git diff --unified=0 | grep <pattern>

搜索文本匹配正则表达式正则表达式的所有修订:

git grep <regexp> $(git rev-list --all)

搜索文本匹配正则表达式regexp的rev1和rev2之间的所有修订:

git grep <regexp> $(git rev-list <rev1>..<rev2>)

你应该使用git log的镐( -S )选项

搜索Foo

git log -SFoo -- path_containing_change 
git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_change

查看Git历史记录 - 通过关键字查找丢失的行数。


正如JakubNarębski所评论的那样:

  • 这会查找引入或移除<string>实例的差异
    它通常意味着“修改你添加或删除行'Foo'”。

  • --pickaxe-regex选项允许您使用扩展的POSIX正则表达式而不是搜索字符串。


  • 正如Rob评论的那样,这个搜索是区分大小写的 - 他提出了一个关于如何搜索不区分大小写的后续问题。


    我最喜欢的方式是使用git log-G选项(在版本1.7.4中添加)。

    -G<regex>
           Look for differences whose added or removed line matches the given <regex>.
    

    -G-S选项确定提交是否匹配的方式之间存在细微差别:

  • -S选项主要计算在提交之前和之后您的搜索在文件中匹配的次数。 如果前后计数不同,提交会显示在日志中。 例如,这不会显示提交,其中与您的搜索匹配的行已被移动。
  • 使用-G选项,如果您的搜索与添加,删除或更改的任何行匹配,则日志中会显示提交。
  • 以此提交为例:

    diff --git a/test b/test
    index dddc242..60a8ba6 100644
    --- a/test
    +++ b/test
    @@ -1 +1 @@
    -hello hello
    +hello goodbye hello
    

    由于文件中出现“hello”的次数在提交之前和之后都是相同的,所以它将不匹配使用-Shello 。 但是,由于对匹配hello的行进行了更改,因此将使用-Ghello显示提交。

    链接地址: http://www.djcxy.com/p/3313.html

    上一篇: How to grep (search) committed code in the git history?

    下一篇: How do I grep recursively?