git grep
を使用してgitリポジトリを検索する方法はありますが、特定のパス/ディレクトリ/ファイルを検索から除外しますか?通常のgrepコマンドの--exclude
オプションと同様です。
好奇心が強い場合:gitリポジトリのサイズが大きい場合、git grep
よりもはるかに遅いため、通常のgrepは使用しません。
それは不可能ですが、 最近議論されました 。リンクで提案された回避策:
*.dll
to .gitignore file thengit grep --exclude-standard
。
編集 onlynone's answer を参照してください。git1.9.0以降は可能です。
Git 1.9.0では、「マジックワード」exclude
がpathspec
sに追加されました。したがって、一致する_*.Java
_を除くすべてのファイルでfoobar
を検索する場合は、次のようにします。
_git grep foobar -- './*' ':(exclude)*.Java'
_
または、除外に_!
_「短縮形」を使用します。
_git grep foobar -- './*' ':!*.Java'
_
V2.12までのgitバージョンでは、exclude pathspec
を使用する場合、少なくとも1つの「包括的」pathspec
が必要であることに注意してください。上記の例では、これは_./*
_です(再帰的に現在のディレクトリの下にすべてを含めます)。 git v2.13ではこの制限が解除され、_git grep foobar -- ':!*.Java'
_は_./*
_なしで機能します。
:(top)
(短縮形:_:/
_)のようなものを使用して、リポジトリの先頭からすべてを含めることもできます。ただし、除外pathspec
を調整して、先頭から開始することもできます:_:/!*.Java
_(それ以外の場合は、現在のディレクトリの下から_*.Java
_ファイルのみを除外します)。
git-scm.com (または単に_git help glossary
_)のpathspec
で許可されているすべての「マジックワード」に関する適切なリファレンスがあります。何らかの理由で、 kernel.org のドキュメントは、Google検索で頻繁に最初に表示される場合でも、本当に古くなっています。
更新:git> = 1.9の場合、除外パターンのネイティブサポートがあります。 one's answer を参照してください。
これは逆に思えるかもしれませんが、次のように、除外パターンに一致しないファイルのリストをgit grep
に渡すことができます。
git grep <pattern> -- `git ls-files | grep -v <exclude-pattern>`
grep -v
はすべてのパスを返しますnot一致する<exclude-pattern>
。 git ls-files
も--exclude
パラメーターを使用しますが、これは未追跡ファイルにのみ適用されることに注意してください。
リポジトリに属性ファイルを作成することにより、ファイルまたはディレクトリをバイナリとしてマークできます。
$ cat .git/info/attributes
directory/to/ignore/*.* binary
directory/to/ignore/*/*.* binary
another_directory/to/also/ignore/*.* binary
バイナリファイル内の一致は、インクルード行なしでリストされます。
$ git grep "bar"
Binary file directory/to/ignore/filename matches
other_directory/other_filename: foo << bar - bazz[:whatnot]
@kynanの例をベースにして、このスクリプトを作成し、gg
としてパス(~/bin/
)に入れました。 git grep
を使用しますが、一部の指定されたファイルタイプを回避します。
リポジトリには多数の画像があるため、画像ファイルを除外しました。これにより、リポジトリ全体を検索すると、検索時間が1/3に短縮されます。ただし、他のファイルタイプまたは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
this によると、モノにgit-gg
という名前を付けて、次のような通常のgitコマンドとして呼び出すことができるはずです。
$ git gg searchstring
しかし、私はこれを機能させることはできません。 ~/bin/
でスクリプトを作成し、git-gg
で/usr/lib/git-core/
シンボリックリンクを作成しました。
注2
コマンドは通常のsh
git-aliasにすることはできません。これは、リポジトリのルートで呼び出されるためです。そして、それは私が欲しいものではありません!