如何从 git grep 搜索中排除某些目录/文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10423143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to exclude certain directories/files from git grep search
提问by Yogeshwer Sharma
Is there a way to exclude certain paths/directories/files when searching a git repository using git grep
? Something similar to the --exclude
option in the normal grep
command?
在使用 搜索 git 存储库时,有没有办法排除某些路径/目录/文件git grep
?类似于--exclude
普通grep
命令中的选项?
I need to use git grep
because using grep
directly runs too slowly on large git repositories.
我需要使用,git grep
因为grep
在大型 git 存储库上直接使用运行速度太慢。
采纳答案by CharlesB
It's not possible, but has been discussed recently. Proposed workaround in link:
这是不可能的,但最近已经讨论过了。链接中建议的解决方法:
You can put
*.dll
to .gitignore file thengit grep --exclude-standard
.
您可以将
*.dll
.gitignore 文件放入.gitignore 文件中git grep --exclude-standard
。
EDIT see onlynone's answer, since git 1.9.0 it's possible.
编辑看到onlynone's answer,因为 git 1.9.0 是可能的。
回答by onlynone
In git 1.9.0 the "magic word" exclude
was added to pathspec
s. So if you want to search for foobar
in every file except for those matching *.java
you can do:
在 git 1.9.0 中,“魔法词”exclude
被添加到pathspec
s 中。因此,如果您想foobar
在除匹配文件之外的每个文件中进行搜索,*.java
您可以执行以下操作:
git grep foobar -- './*' ':(exclude)*.java'
Or using the !
"short form" for exclude:
或使用!
“简短形式”排除:
git grep foobar -- './*' ':!*.java'
Note that in git versions up to v2.12, when using an exclude pathspec
, you must have at least one "inclusive" pathspec
. In the above examples this is the ./*
(recursively include everything under the current directory). In git v2.13 this restriction was lifted and git grep foobar -- ':!*.java'
works without the ./*
.
请注意,在 v2.12 之前的 git 版本中,使用 exclude 时pathspec
,您必须至少有一个 "inclusive" pathspec
。在上面的例子中,这是./*
(递归地包括当前目录下的所有内容)。在 git v2.13 中,此限制被取消并且git grep foobar -- ':!*.java'
无需./*
.
You could also use something like :(top)
(short form: :/
) to include everything from the top of the repo. But then you'd probably also want to adjust your exclude pathspec
to start from the top as well: :/!*.java
(otherwise it would only exclude *.java
files from under your current directory).
您还可以使用类似:(top)
(short form: :/
) 的内容来包含 repo 顶部的所有内容。但是,您可能还想调整排除pathspec
以从顶部开始:(:/!*.java
否则它只会排除*.java
当前目录下的文件)。
There's a good reference for all the "magic words" allowed in a pathspec
at git-scm.com(or just git help glossary
). For some reason, the docs at kernel.orgare really out of date even though they often come up first in google searches.
有在一个允许所有的“咒语”一个很好的参考pathspec
,在git-scm.com(或只git help glossary
)。出于某种原因,kernel.org上的文档确实已经过时了,尽管它们经常出现在谷歌搜索中。
回答by kynan
Update:For git >= 1.9 there is native support for exclude patterns, see onlyone's answer.
更新:对于 git >= 1.9 有对排除模式的本机支持,请参阅onlyone's answer。
This may seem backwards, but you can pass a list of files not matching your exclude pattern to git grep
like this:
这可能看起来倒退,但您可以传递与排除模式不匹配的文件列表,git grep
如下所示:
git grep <pattern> -- `git ls-files | grep -v <exclude-pattern>`
grep -v
returns every path notmatching <exclude-pattern>
. Note that git ls-files
also takes a --exclude
parameter, but that is only applied to untracked files.
grep -v
返回每个不匹配的路径<exclude-pattern>
。请注意,它git ls-files
也需要一个--exclude
参数,但这仅适用于未跟踪的文件。
回答by coberlin
You can mark files or directories as binary by creating an attributes file in your repository, e.g.
您可以通过在存储库中创建属性文件来将文件或目录标记为二进制文件,例如
$ cat .git/info/attributes
directory/to/ignore/*.* binary
directory/to/ignore/*/*.* binary
another_directory/to/also/ignore/*.* binary
Matches in binary files are listed without the including line, e.g.
二进制文件中的匹配项不带包含行列出,例如
$ git grep "bar"
Binary file directory/to/ignore/filename matches
other_directory/other_filename: foo << bar - bazz[:whatnot]
回答by UlfR
With the example by @kynan as base I made this script and put it in my path (~/bin/
) as gg
. It does use git grep
but avoids some specified filetypes.
以@kynan 的示例为基础,我制作了这个脚本并将其放在我的路径 ( ~/bin/
) 中作为 gg
. 它确实使用git grep
但避免了某些指定的文件类型。
In our repo its a lot of images so I have excluded the imagefiles, and this takes the serchtime down to 1/3 if I search the whole repo. But the script could easily be modified to exclude other filestypes or geleralpatterns.
在我们的 repo 中有很多图像,所以我排除了图像文件,如果我搜索整个 repo,这会将 serchtime 降低到 1/3。但是可以轻松修改脚本以排除其他文件类型或凝胶模式。
#!/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/.*/\\.\\($ git gg searchstring
\\)/'`
# 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
Note 1
注 1
According to thisit should be possible to name the thing git-gg
and be able to call it as a regular git command like:
根据这个应该可以说出的东西git-gg
,并能称其为像一个普通的git命令:
But I can not get this working. I created the script in my ~/bin/
and made a the git-gg
symlink in /usr/lib/git-core/
.
但我不能让它工作。我在 my 中创建了脚本~/bin/
并git-gg
在/usr/lib/git-core/
.
Note 2
笔记2
The command can not be made into an regular sh
git-alias since it will then be invoked at the root of the repo. And that is not what I want!
该命令不能成为常规的sh
git-alias,因为它将在 repo 的根目录中被调用。这不是我想要的!