如何从git grep搜索中排除某些目录/文件

Yog*_*rma 121 git grep

有没有办法搜索git存储库,git grep但从搜索中排除某些路径/目录/文件?像--exclude普通grep命令中的选项一样.

如果你很好奇:我不想使用普通的grep,因为它比git grepgit存储库的大小要慢得多.

onl*_*one 177

在git 1.9.0中,"魔术词" exclude被添加到pathspecs中.因此,如果您想foobar在每个文件中搜索除了匹配的文件,*.java您可以执行以下操作:

git grep foobar -- './*' ':(exclude)*.java'
Run Code Online (Sandbox Code Playgroud)

或者使用!"简短形式"进行排除:

git grep foobar -- './*' ':!*.java'
Run Code Online (Sandbox Code Playgroud)

请注意,使用排除时pathspec,您必须至少有一个"包含" pathspec.在上面的例子中,这是./*(递归地包括当前目录下的所有内容).

您还可以使用类似git grep foobar -- ':!*.java'(简短形式./*:)的内容来包含回购顶部的所有内容.但是你可能也想调整你的排除:(top)从顶部开始:( :/否则它只会排除pathspec你当前目录下的文件).

有在一个允许所有的"咒语"一个很好的参考:/!*.java,在git-scm.com(或只*.java).出于某种原因,kernel.org上的文档确实已经过时了,即使它们经常出现在谷歌搜索中.

  • `git grep clock.gettime - './*'':!arch/**'':! drivers/**'`排除多个整个目录.我认为它不会阻止递归. (3认同)
  • 对于频繁使用,你可以使用exclusions来创建一个git别名:`git config alias.mygrep'!git grep"$ @" - "$ {GIT_PREFIX}/*"":!*.java*"#'`.然后只是`git mygrep foobar`.(使用别名[shell#trick](http://stackoverflow.com/a/39523506/647002)和[current dir](http://stackoverflow.com/a/22039008/647002).) (2认同)
  • @elonderin 此解决方案与匹配文件的报告方式无关。但我只是从子目录中尝试了一个 `git grep` 和 `git ls-files`,并且都报告了相对于当前目录的文件名(即使你使用了 `':(top)'` 包含路径规范)。这两个命令都有 `--full-name` 选项来报告相对于根的名称,但默认情况下是关闭的。 (2认同)

kyn*_*nan 60

更新:对于git> = 1.9,对排除模式有本机支持,请参阅onlyone的答案.

这似乎是倒退,但您可以传递与您的排除模式不匹配的文件列表,git grep如下所示:

git grep <pattern> -- `git ls-files | grep -v <exclude-pattern>`
Run Code Online (Sandbox Code Playgroud)

grep -v返回每个匹配的路径<exclude-pattern>.请注意,它git ls-files也接受一个--exclude参数,但这仅适用于未跟踪的文件.

  • 不幸的是,我的仓库有很多文件。当我尝试@kynan 的方法时,我得到:“-bash:/usr/bin/git:参数列表太长” (2认同)
  • 这应解决Benissimo的"Argument list too long"问题和我用bash解释的文件名caracters(如[])或存储库中包含空格的文件名的问题:git ls-files | grep -v <exclue-pattern> | xargs -d'\n'git grep <pattern> - (2认同)
  • 只检查一个人的答案,它可能完全在(现代版本的)git中完成. (2认同)

Cha*_*esB 16

这是不可能的,但最近已经讨论过了.链接中提议的解决方法:

然后你可以把*.dll.gitignore文件git grep --exclude-standard.

编辑只看到了没人的答案,因为git 1.9.0是可能的.

  • @ mustafa.0x看到最受欢迎的答案,有可能 (3认同)
  • 这曾经是正确的,但现在不再是这样,现在可以在 git 中使用。看看下面的真正答案应该是什么:http://stackoverflow.com/a/30084612/1391445 (2认同)

小智 11

您可以通过在存储库中创建属性文件来将文件或目录标记为二进制文件,例如

$ cat .git/info/attributes 
directory/to/ignore/*.* binary
directory/to/ignore/*/*.* binary
another_directory/to/also/ignore/*.* binary
Run Code Online (Sandbox Code Playgroud)

二进制文件中的匹配项不带包含行列出,例如

$ git grep "bar"
Binary file directory/to/ignore/filename matches
other_directory/other_filename:      foo << bar - bazz[:whatnot]
Run Code Online (Sandbox Code Playgroud)