如何从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的根目录下被调用。 这不是我想要的!