如何从 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 13:36:15  来源:igfitidea点击:

How to exclude certain directories/files from git grep search

gitgrep

提问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 --excludeoption in the normal grepcommand?

在使用 搜索 git 存储库时,有没有办法排除某些路径/目录/文件git grep?类似于--exclude普通grep命令中的选项?

I need to use git grepbecause using grepdirectly 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 *.dllto .gitignore file then git 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" excludewas added to pathspecs. So if you want to search for foobarin every file except for those matching *.javayou can do:

在 git 1.9.0 中,“魔法词”exclude被添加到pathspecs 中。因此,如果您想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 pathspecto start from the top as well: :/!*.java(otherwise it would only exclude *.javafiles 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 pathspecat 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 greplike this:

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

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

grep -vreturns every path notmatching <exclude-pattern>. Note that git ls-filesalso takes a --excludeparameter, 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 grepbut 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-ggand 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-ggsymlink 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 shgit-alias since it will then be invoked at the root of the repo. And that is not what I want!

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