如何从git grepsearch中排除某些目录/文件

有没有办法使用git grep来searchgit存储库,但排除search中的某些path/目录/文件? 像普通的grep命令中的--exclude选项一样。

如果您好奇:我不想使用正常的grep,因为当git存储库的大小很大时,它比git grep慢得多。

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

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

编辑看到唯一的答案,因为Git 1.9.0是可能的。

在git 1.9.0中,“magic word” exclude被添加到pathspec 。 所以如果你想在每个文件中searchfoobar ,除了匹配*.java文件,你可以这样做:

 git grep foobar -- './*' ':(exclude)*.java' 

或者使用! 排除的“简表”:

 git grep foobar -- './*' ':!*.java' 

请注意,使用排除pathspec ,您必须至less有一个“包容性” pathspec 。 在上面的例子中,这是./* (recursion地包含当前目录下的所有东西)。

您也可以使用像:(top) (简写:/ )来包含回购顶部的所有内容。 但是,你可能还想调整排除pathspec指定从顶部开始:/!*.java (否则它只会排除当前目录下的*.java文件)。

在git-scm.com (或者仅仅是git help glossary )中,对一个pathspec允许的所有“魔术字”都有很好的参考。 出于某种原因, kernel.org上的文档实际上是过时的,即使它们经常在谷歌search中首先出现。

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

这可能看起来倒退,但你可以传递一个不匹配你的排除模式的文件列表,像这样的git grep

 git grep <pattern> -- `git ls-files | grep -v <exclude-pattern>` 

grep -v返回每个匹配<exclude-pattern>path。 请注意, git ls-files也需要一个--exclude参数,但是这只适用于未跟踪的文件

用@kynan作为基础的例子,我制作了这个脚本,并把它放在我的path( ~/bin/ )中作为gg 。 它确实使用git grep但避免了一些指定的文件types。

在我们的repo中有很多的图片,所以我排除了imagefiles,如果我search整个回购,这将serchtime降到1/3。 但是,脚本可以很容易地修改,以排除其他文件types或geleralpatterns。

 #!/bin/bash # # Wrapper of git-grep that excludes certain filetypes. # NOTE: The filetypes to exclude is hardcoded for my specific needs. # # The basic setup of this script is from here: # https://stackoverflow.com/a/14226610/42580 # But there is issues with giving extra path information to the script # therefor I crafted the while-thing that moves path-parts to the other side # of the '--'. # Declare the filetypes to ignore here EXCLUDES="png xcf jpg jpeg pdf ps" # Rebuild the list of fileendings to a good regexp EXCLUDES=`echo $EXCLUDES | sed -e 's/ /\\\|/g' -e 's/.*/\\\.\\\(\0\\\)/'` # Store the stuff that is moved from the arguments. moved= # If git-grep returns this "fatal..." then move the last element of the # arg-list to the list of files to search. err="fatal: bad flag '--' used after filename" while [ "$err" = "fatal: bad flag '--' used after filename" ]; do { err=$(git grep "$@" -- `git ls-files $moved | grep -iv "$EXCLUDES"` \ 2>&1 1>&3-) } 3>&1 # The rest of the code in this loop is here to move the last argument in # the arglist to a separate list $moved. I had issues with whitespace in # the search-string, so this is loosely based on: # http://www.linuxjournal.com/content/bash-preserving-whitespace-using-set-and-eval x=1 items= for i in "$@"; do if [ $x -lt $# ]; then items="$items \"$i\"" else moved="$i $moved" fi x=$(($x+1)) done eval set -- $items done # Show the error if there was any echo $err 

注1

根据这个 ,应该可以将这个东西命名为git-gg并且可以将其称为一个常规的git命令,如:

 $ git gg searchstring 

但我无法得到这个工作。 我在~/bin/创build了脚本,并在/usr/lib/git-core/创build了git-gg符号链接。

笔记2

该命令不能成为常规的sh -git-alias,因为它会在repo的根目录下被调用。 这不是我想要的!