如何使用git grep搜索主仓库及其所有子模块?

16

我在一篇博客中找到了以下内容,用于在项目和子模块中进行grep:

[alias]
  sgrep = "!f() { git grep \"$1\"; git submodule foreach \"git grep '$1'; true\" | grep -B 1 \"$1\"; }; f"

我更新了~/.gitconfig文件并添加了这个别名,但是当我使用这个别名时,它会显示:

fatal: bad config file line 9 in /home/myname/.gitconfig

我做错了什么?

2个回答

30
使用 Git 2.12(2017年第一季度),您将不需要任何“git submodule foreach”技巧。
只需:
 git grep -e "bar" --recurse-submodules

请查看以下提交记录:commit e6fac7fcommit 74ed437commit 0281e48commit 4538eefcommit 9ebf689commit f9f4256commit 5688c28(2016年12月16日),以及commit 4ac9006commit 7241764commit a1ae484commit 05b458c(2016年12月12日),作者为Brandon Williams (mbrandonw)
请查看commit e9a379c(2016年12月21日),作者为Johannes Sixt (j6t)
以上内容已被Junio C Hamano -- gitster --合并至commit 55d128a中(2017年1月18日)。

grep:可选择递归进入子模块

允许grep识别子模块并递归搜索每个子模块中的模式。
这是通过派生一个进程来递归调用每个子模块上的grep来完成的。

递归仅发生在已由父项目初始化和检出的子模块中。如果子模块尚未初始化和检出,则将其简单地跳过。

为了支持grep中现有的多线程基础设施,从每个子进程输出被捕获在strbuf中,以便稍后以有序方式打印到控制台。

为了限制创建的线程数,每个子进程的线程数量为其父进程的一半(最小值为1),否则可能会导致fork-bomb。

git grep man page现在包括:

--recurse-submodules

递归搜索已在仓库中初始化和检出的每个子模块。与<tree>选项结合使用时,所有子模块输出的前缀都将是父项目的<tree>对象的名称。
在Git 2.14.x/2.15 (2017年第三季度)中,"git grep --recurse-submodules"已经重新设计,以在子模块边界上提供更一致的输出(并且不需要分叉一个单独的进程来完成其任务)。

请参阅 提交 f9ee2fc, 提交 2184d4b, 提交 34e2ba0, 提交 91b8348, 提交 8fa2915, 提交 f20e7c1, 提交 b22e51c, 提交 4c0eeaf (2017年8月2日),以及 提交 ba43964, 提交 3f13877 (2017年7月18日),提交者为 Brandon Williams (mbrandonw)
(由Junio C Hamano -- gitster --合并于提交 5aa0b6c,2017年8月22日)

这意味着 git grep 的内部--parent-basename <basename>选项已不存在。


请确保使用Git 2.21(2019年第一季度),因为已修复了与cygwin路径相关的错误:请参见“Cygwin uses relative and absolute path for environment variables”。


实际上,在 Git 2.23.1/2.24(2019年第四季度)之前,"git grep --recurse-submodules" 命令查看工作树文件时会查看子模块中索引的内容,而不是工作树中的文件。

这个问题已经得到解决。

请参见 commit 6a289d4(由 Matheus Tavares (matheustavares) 于 2019 年 7 月 30 日提交)
(由 Junio C Hamano -- gitster -- 合并于 commit 3071797,2019 年 8 月 22 日)

grep: 修复子模块中的工作树大小写问题

使用 --recurse-submodules 参数运行 git-grep,即使没有使用 --cached 参数,也会导致对子模块进行缓存的 grep
这将使得所有子模块跟踪文件中的修改在 grepping 时总是被忽略。

解决方法是让 git grep 在调用 grep_submodule() 中的 grep_cache() 时尊重缓存选项。
此外,添加测试以确保执行所需的行为。


"git grep --no-index" 不应受到 .gitmodules 文件内容的影响,但是当给出 "--recurse-submodules" 或设置 "submodule.recurse" 变量时,它确实会受到影响。
现在,在 Git 2.25.1(2020年2月)中不再如此。现在这些设置在 "--no-index" 模式下被忽略。

查看提交记录 c56c48d(2020年1月30日),作者为Philippe Blain(phil-blain
(由Junio C Hamano -- gitster --提交记录 556ccd4中合并,于2020年2月12日)
查看讨论

grep: ignore --recurse-submodules if --no-index is given

Helped-by: Junio C Hamano
Signed-off-by: Philippe Blain

Since grep learned to recurse into submodules in 0281e487fd ("grep: optionally recurse into submodules", 2016-12-16, Git v2.12.0-rc0 -- merge listed in batch #6), using --recurse-submodules along with --no-index makes Git die().

This is unfortunate because if submodule.recurse is set in a user's ~/.gitconfig, invoking git grep --no-index either inside or outside a Git repository results in:

fatal: option not supported with --recurse-submodules

Let's allow using these options together, so that setting submodule.recurse globally does not prevent using git grep --no-index.

Using --recurse-submodules should not have any effect if --no-index is used inside a repository, as Git will recurse into the checked out submodule directories just like into regular directories.


请参阅 https://dev59.com/iaTia4cB1Zd3GeqP_Ef9#54298834,自从2016年12月Git v2.12.0-rc0的提交05b458c引入了Cygwin用户的回归问题,“real_path:手动解析符号链接”。 - VonC

3
一般来说,类似于“GitConfig: bad config for shell command”的问题可能是因为 '\' 字符在执行shell命令之前被git解释了。但在您的情况下,由于周围有双引号,这应该按预期工作。在我的Ubuntu上,我的git 1.8.4确实可以工作。因此,请简化您的.gitconfig文件,并检查是否包含您的别名(以及nothing)可以更好地工作。如果可以工作,则问题在您的配置文件中的其他位置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接