我过去的某个时候删除了文件或某些代码。我可以在内容中进行 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
这将通过 regexp 的所有提交文本进行 grep。
在两个命令中传递路径的原因是因为rev-list
将返回修订列表,其中发生了对lib/util
所有更改,但是您还需要传递给grep
以便它只搜索lib/util
。
想象一下下面的场景: grep
可能会在rev-list
返回的同一版本中包含的其他文件中找到相同的<regexp>
(即使该版本上没有对该文件进行任何更改)。
以下是搜索源代码的其他一些有用方法:
在工作树中搜索匹配正则表达式 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>
搜索与正则表达式 regexp 匹配的文本的所有修订:
git grep <regexp> $(git rev-list --all)
搜索 rev1 和 rev2 之间的所有修订版本,以匹配正则表达式 regexp 的文本:
git grep <regexp> $(git rev-list <rev1>..<rev2>)
你应该使用git log
的pickaxe( -S
)选项
要搜索Foo
:
git log -SFoo -- path_containing_change
git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_change
正如JakubNarębski评论的那样:
这会查找引入或删除<string>
实例的差异 。
它通常意味着 “你在'Foo'添加或删除行的修订版”。
--pickaxe-regex
选项允许您使用扩展的 POSIX 正则表达式而不是搜索字符串。
我最喜欢的方法是使用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
显示提交。