git 搜索文件名

git grepping on filenames

如何通过管道传输到 git grep 我要搜索特定模式的文件列表?
具体来说,我这样做:

git grep -l 'string to search' 

我想对之前搜索的结果文件再做一次 git grep

正在尝试

git grep -l -e 'string to search' --and -e 'another string'  

没有给出任何结果,但我知道有匹配项

正在做

git grep -l 'string to search' | git grep -l 'another string'

给出与 git grep -l 'another string'

相同的结果

你的第二个 git grep 没有将第一个的结果作为参数,它只输出它应该输出的内容,而不考虑第一个命令。

用一个简单的 bash grep 替换它,它应该可以

git grep -l 'string to search' | grep 'another string'

TL;DR

您不能管道名称,但您可以提供名称(作为路径规范)到两个git grep 命令。

(奇怪的是,--and 一开始就应该完成你想要的——我只是回答没有 --and 如何做到的问题。)

中等长度

不清楚您想要什么结果,但假设您想要的是:

  • 对于(一些提交 | 一些提交集 | 索引 | 工作树)中的每个文件

    • 如果文件包含模式 1

    • and 文件包含,同一文件中的其他任何地方(不一定在同一行)模式 2

    • 然后列出文件名

有两种比较明显的方法可以尝试实现这一点,但其中一种不起作用,因为 Git 无法跨换行匹配。1所以我们剩下另一个明显的方法:

  • 首先,使用 git grep -l 生成与第一个表达式匹配的 文件列表
  • 然后,使用 git grep -l 生成匹配第二个表达式的 文件列表 ,可选地,仅从第一个 git grep 生成的文件开始.

要将它们组合为 操作,您有一个相当明显的选择,即使用两个 git grep -l 输出中的一个作为另一个的一系列路径名参数git grep。但是请注意,git grep 在分隔它们的 -- 之后采用 pathspec 参数,而不是路径 name 参数(有关详细信息,请参阅 the documentation)。这意味着如果您的任何文件名中包含路径规范元字符,这个简单的 shell 扩展可能会失败。验证第一个 grep 实际上列出了一些文件,但将它们组合成一个 bash 样式命令可能也是一个好主意:

git grep -l pattern2 -- $(git grep -l pattern1)

通常就足够了。

要将以上两者组合为 操作(列出包含任一模式的文件),最简单的方法是只使用一个 git grep 和多个模式。但是请注意,您可以 运行 多次 git grep -l 操作,将生成的文件名定向到一个临时文件,然后使用 comm 之类的程序来报告每组文件的共同点和独特点结果。 (假设您的命令行解释器工具箱中有 comm。)使用 comm 还可以解决特殊文件名(如 (top)file.cgot*you.sh 或其他名称)的路径规范问题.


1如果 Git did 跨换行匹配,您可以使用扩展或 Perl 模式:(foo(.|\n)*bar)|(bar(.|\n)*foo) 以允许在其他两个模式 foobar 之间的任意文本,其中任一模式的顺序都可以。