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

Ort*_*ntz 1342 git diff grep

我过去的某个时候删除了文件或某些代码.我可以在内容中进行grep(不在提交消息中)吗?

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

git log -p | grep <pattern>
Run Code Online (Sandbox Code Playgroud)

但是,这不会立即返回提交哈希.我一直玩得git grep无济于事.

Jee*_*eet 1769

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

git grep <regexp> $(git rev-list --all)
Run Code Online (Sandbox Code Playgroud)

更新:git rev-list --all | xargs git grep <expression>如果遇到"参数列表太长"错误,将会有效

如果要将搜索限制为某个子树(例如"lib/util"),则需要将其传递给rev-list子命令grep以及:

git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util
Run Code Online (Sandbox Code Playgroud)

这将通过regexp的所有提交文本进行grep.

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

想象一下下面的场景:lib/util可能会grep在返回的同一版本中包含的其他文件中找到相同的内容<regexp>(即使该版本上没有对该文件进行任何更改).

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

在工作树中搜索匹配正则表达式regexp的文本:

git grep <regexp>
Run Code Online (Sandbox Code Playgroud)

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

git grep -e <regexp1> [--or] -e <regexp2>
Run Code Online (Sandbox Code Playgroud)

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

git grep -e <regexp1> --and -e <regexp2>
Run Code Online (Sandbox Code Playgroud)

在工作树中搜索具有匹配正则表达式regexp1的文本行和与正则表达式regexp2匹配的文本行的文件:

git grep -l --all-match -e <regexp1> -e <regexp2>
Run Code Online (Sandbox Code Playgroud)

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

git diff --unified=0 | grep <pattern>
Run Code Online (Sandbox Code Playgroud)

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

git grep <regexp> $(git rev-list --all)
Run Code Online (Sandbox Code Playgroud)

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

git grep <regexp> $(git rev-list <rev1>..<rev2>)
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,效果很好!虽然需要"$(git rev-list --all)"并且没有方便的切换来指定在分支的整个历史中进行搜索,但这很令人遗憾. (59认同)
  • 不幸的是,我无法通过msysgit-1.7.4实现这一目标.它告诉我`sh.exe":/ bin/git:错误的文件号`.VonC的答案也适用于msysgit. (17认同)
  • 是的,这似乎在Windows上也失败了,唉. (7认同)
  • 如果在使用rev-list调用git grep历史记录时出现"无法读取树"错误,则可能需要清理.试试`git gc`或查看:http://stackoverflow.com/questions/1507463/how-to-deal-with-this-git-error (4认同)
  • 优秀.+1.GitBook添加了一些细节(http://book.git-scm.com/4_finding_with_git_grep.html),Junio C Hamano说明了你的一些观点:http://gitster.livejournal.com/27674.html (2认同)
  • 处理`参数列表太长`问题的另一种方法是:`git rev-list --all | (同时读取 rev; do git grep -e &lt;regexp&gt; $rev; done)` (2认同)
  • @Jeet在这种情况下,这是`git log -G`或`git log -S`答案的首选方案吗?它在处理方面似乎要"更重",因为它基本上是获取提交列表,然后搜索每个提交? (2认同)

Von*_*onC 504

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

要搜索Foo:

git log -SFoo -- path_containing_change 
git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_change
Run Code Online (Sandbox Code Playgroud)

请参阅Git历史记录 - 按关键字查找丢失的行.


正如JakubNarębski评论的那样:

  • 这会查找引入或删除实例的差异<string>.
    它通常意味着"你在'Foo'添加或删除行的修订版".

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


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

  • 将它与`-p`标志组合以输出diff. (8认同)
  • 谢谢,我不知道这个选项.如果您对提交消息感兴趣,看起来这是最好的解决方案,如果您需要纯行匹配的传统UNIX grep行为,Jeet的解决方案是最合适的. (3认同)
  • @Anentropic你需要`--branches --all`选项来搜索所有仓库。 (2认同)

Tyl*_*ien 233

我最喜欢的方式做到这一点是git log-G选项(在1.7.4版本中增加).

-G<regex>
       Look for differences whose added or removed line matches the given <regex>.
Run Code Online (Sandbox Code Playgroud)

-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
Run Code Online (Sandbox Code Playgroud)

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

  • @ Thilo-AlexanderGinkel - 我通常只需添加`-p`选项来显示每个提交的差异.然后当我的寻呼机打开日志时,我会搜索我正在寻找的任何内容.如果你的寻呼机是'less`而你是`git log -Ghello -p`,你可以输入`/ hello`,按'Enter`,然后使用`n`和`N`来查找下一个/上一次出现的"你好" ". (10认同)
  • 有没有办法在git日志输出中显示匹配的更改上下文? (2认同)
  • 我发现 `-G` 和正则表达式有一个有趣的问题:如果命令行使用 UTF-8 并且您正在查看的文件使用某些 ISO-Latin(8 位)编码,则 `.*` 会失败。例如,我有一个更改 `Vierter Entwurf` -&gt; `Fünfter Entwurf`,虽然 `'V.*ter Entwurf'` 产生匹配,但 `'F.*ter Entwurf'` 没有。 (2认同)

Bar*_*ira 46

如果你想浏览代码更改(看看实际上已经用整个历史中的给定单词改变了什么)去patch模式 - 我发现了一个非常有用的组合:

git log -p
# hit '/' for search mode
# type in the word you are searching
# if the first search is not relevant hit 'n' for next (like in vim ;) )
Run Code Online (Sandbox Code Playgroud)

  • 加入的解决方案对我来说既不适用于git log -S.这一个做到了! (10认同)

rip*_*234 24

我把@ Jeet的答案拿到了Windows上(感谢这个答案):

FOR /F %x IN ('"git rev-list --all"') DO @git grep <regex> %x > out.txt
Run Code Online (Sandbox Code Playgroud)

请注意,对于我来说,由于某种原因,删除此正则表达式的实际提交没有出现在命令的输出中,而是出现在它之前的一次提交.

  • +1 - 如果你想在每次查找后避免点击"q",最后在git命令中添加`--no-pager` (2认同)
  • 另外,我会注意到附加到文本文件还具有实际显示匹配文本的额外优势.(对于不熟悉Windows管道的人,使用`>> results.txt`附加到文本文件中... (2认同)
  • 而且我认为 bash 的语法很难看:) (2认同)

Edw*_*son 23

git log 可以是跨所有分支搜索文本的更有效方式,特别是如果有许多匹配,并且您希望首先看到更新的(相关)更改.

git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'
Run Code Online (Sandbox Code Playgroud)

这些日志命令列出了添加或删除给定搜索字符串/正则表达式的提交,(通常)最近更新.该-p选项会导致相关差异显示在添加或删除模式的位置,因此您可以在上下文中查看它.

找到一个添加了您正在寻找的文本的相关提交(例如,8beeff00d),找到包含提交的分支:

git branch -a --contains 8beeff00d
Run Code Online (Sandbox Code Playgroud)


Chr*_*ssy 18

搜索任何修订,任何文件:

git rev-list --all | xargs git grep <regexp>
Run Code Online (Sandbox Code Playgroud)

仅在某些给定文件中搜索,例如 xml文件:

git rev-list --all | xargs -I{} git grep <regexp> {} -- "*.xml"
Run Code Online (Sandbox Code Playgroud)

结果行应如下所示:6988bec26b1503d45eb0b2e8a4364afb87dde7af:bla.xml:它找到的行的文本...

然后,您可以使用git show获取更多信息,如作者,日期,差异:

git show 6988bec26b1503d45eb0b2e8a4364afb87dde7af
Run Code Online (Sandbox Code Playgroud)


sur*_*s1n 8

每当我发现自己在您的位置时,我都会使用以下命令行:

git log -S "<words/phrases i am trying to find>" --all --oneline  --graph
Run Code Online (Sandbox Code Playgroud)

解释:

  1. git log- 需要我在这里写更多;它按时间顺序显示日志。
  2. -S "<words/phrases i am trying to find>" - 它显示了所有那些 Git 提交,其中任何文件(添加/修改/删除)都包含我试图在没有“<>”符号的情况下找到的单词/短语。
  3. --all - 在所有分支机构中执行和搜索。
  4. --oneline - 它在一行中压缩 Git 日志。
  5. --graph - 它创建按时间顺序提交的图表。


dot*_*NET 6

对于其他试图在SourceTree中执行此操作的人,UI中没有直接命令(从版本1.6.21.0开始).但是,您可以通过打开终端窗口(主工具栏中的可用按钮)并在其中复制/粘贴它们来使用接受答案中指定的命令.

注意:SourceTree的搜索视图可以部分为您进行文本搜索.按Ctrl+ 3转到"搜索"视图(或单击底部的"搜索"选项卡).从最右侧,将"搜索类型"设置为" 文件更改",然后键入要搜索的字符串.与上述命令相比,此方法具有以下限制:

  1. SourceTree仅显示其中一个已更改文件中包含搜索词的提交.查找包含搜索文本的确切文件也是一项手动任务.
  2. 不支持RegEx.


wat*_*HUN 6

为简单起见,我建议使用GUI:gitk - Git存储库浏览器,它非常灵活

  1. 搜索代码: 在此输入图像描述
  2. 搜索文件: 在此输入图像描述
  3. 因为它也支持正则表达式: 在此输入图像描述

您可以使用向上/向下箭头浏览结果


归档时间:

查看次数:

358795 次

最近记录:

5 年,10 月 前