git grep
在 git 存储库中,使用over good old有什么区别/好处grep
吗?
一个例子是?
5 回答
两者非常相似。主要区别在于git grep
默认搜索由 git 跟踪的文件。
例子
如果我想foo
在我的项目中找到我可以使用git grep
或很好的独立grep
:
git grep foo
grep -R foo .
该git grep
版本将仅搜索 git 跟踪的文件,而该grep
版本将搜索目录中的所有内容。到目前为止很相似;根据您想要实现的目标,任何一个都可能更好。
如果我们想将搜索限制为仅.rb
文件怎么办?
git grep foo -- *.rb
grep -R --include=*.rb foo .
普通的旧grep
版本变得有点罗嗦,但如果你习惯使用grep
它可能不是问题。他们仍然不会搜索完全相同的文件,但这再次取决于您想要实现的目标。
在项目的以前版本中搜索呢?
git grep foo HEAD^
git checkout HEAD^; grep -R foo .; git checkout -
这就是git grep
真正不同的地方:您可以在项目的另一个修订版中搜索,而无需先检查它。不过,这对我来说并不是经常出现的情况。我通常想在我签出的项目版本中进行搜索。
配置 git grep
有一些git config
变量可以修改行为git grep
并避免需要传递几个命令行参数:
grep.lineNumber
:总是显示匹配的行号(你可以传递-n
给两者grep
并git grep
获得这种行为)grep.extendedRegexp
:始终使用扩展的正则表达式(您可以传递-E
给两者grep
并git grep
获得此行为)
在实践中
在实践中,我使用了gg
别名git grep -En
,这几乎总是可以满足我的要求。
的主要优点git grep
是它可以在 git 存储库中找到模式,即也可以在源的当前版本之外的其他版本中找到模式。这当然不能使用标准来完成grep
。在git grep
类似的模式算术(比如git grep -e pattern1 --and --not \( -e pattern2 -e pattern3 \)
)、使用 glob 的树搜索(比如git grep pattern -- '*.[ch]'
只在.c
和.h
文件中搜索的东西)还有更多的功能。
这是在旧版本中搜索的示例会话:
$ mkdir git-test # create fresh repository
$ cd git-test/
$ git init .
Initialized empty Git repository in /home/alfe/git-test/.git/
$ echo eins zwei drei > bla # create example file
$ git add bla # add and commit it
$ git commit bla
[master (root-commit) 7494515] .
1 file changed, 1 insertion(+)
create mode 100644 bla
$ echo vier fuenf sechs > bla # perform a change on that file
$ git commit -m 'increase' bla # commit it
[master 062488e] increase
1 file changed, 1 insertion(+), 1 deletion(-)
$ git grep eins | cat # grep for outdated pattern in current version
# (finds nothing)
$ git grep eins master^ | cat # grep for outdated pattern on former version
# finds it:
master^:bla:eins zwei drei
git grep
仅在 repo 中的跟踪文件中搜索。
grep
您必须传递要搜索的文件列表,并且您自己会过滤掉任何未跟踪的文件。
因此,如果您正在搜索您知道在 repo 中的东西,git grep
可以节省您的时间,因为您所要做的就是提供模式。它对于不必搜索 repo 中未跟踪的任何内容也很有用。
如果您在 git 存储库中搜索模式/字符串(即在已跟踪的文件中),那么是的,git grep 通常应该比常规 grep 快得多,因为它被索引了。(您可以手动尝试,git-grep 应该更快)
如果您在 Git 存储库中搜索,git grep
速度会更快。
并且使用 Git 2.20(2018 年第四季度),它在选项方面也与常规grep
.
正如这个git grep
“愿望清单”中所讨论的:
我经常使用 "
grep -r $pattern
" 递归地 grep 源代码树。
如果这花费的时间太长,我会在命令行前面打上^C
“”标签git
并重新运行它。
然后 Git 抱怨“error: unknown switch
r'" because "
git grep`”是自然递归的。我们可以让“
git grep -r
”接受兼容性的论点吗?
其他重要的 grep 开关如“-i
”是兼容的,添加-r
将提高可用性。
现在(Git 2.20,2018 年第四季度)已完成:
请参阅René Scharfe ( ) 的提交 0a09e5e(2018 年 10 月 1 日)。
推荐人:Junio C Hamano ( )。(由Junio C Hamano 合并——在提交 9822b8f中,2018 年 10 月 19 日)rscharfe
gitster
gitster
grep
: 添加-r/--[no-]recursive
识别
-r
并--recursive
作为--max-depth=-1
与 GNU grep 兼容的同义词;它仍然是git grep
.这也添加了免费
--no-recursive
的同义词--max-depth=0
,这是为了完整性和一致性而受到欢迎。修正.
--max-depth
_--max-depth=0
请注意,在工作树文件中查找匹配项时,“ git grep --untracked
” (man)旨在让 ALSO 在文件系统上的这些文件中查找”,如果针对索引或树进行主搜索,则没有任何意义“
”--cached
和“ --untracked
”选项已被标记为与 Git 2.31(2021 年第一季度)相互不兼容。
请参阅Matheus Tavares ( ) 的提交 0c5d83b(2021 年 2 月 8 日)。(由Junio C Hamano 合并 -- --在提交 f712632中,2021 年 2 月 17 日)matheustavares
gitster
grep
: 错误输出,如果--untracked
与--cached
签字人:Matheus Tavares
审核人:Elijah Newren
选项
--untracked
和--cached
不兼容,但如果它们一起使用,grep 只是默默地忽略--cached
并搜索工作树。
相反,出错是为了避免任何潜在的混淆。
--untracked cannot be used with --cached