を使用してgitリポジトリを検索するときに特定のパス/ディレクトリ/ファイルを除外する方法はありますgit grep
か?--exclude
通常のgrep
コマンドのオプションに似ていますか?
大規模なgitリポジトリで直接git grep
使用grep
すると動作が遅すぎるため、使用する必要があります。
を使用してgitリポジトリを検索するときに特定のパス/ディレクトリ/ファイルを除外する方法はありますgit grep
か?--exclude
通常のgrep
コマンドのオプションに似ていますか?
大規模なgitリポジトリで直接git grep
使用grep
すると動作が遅すぎるため、使用する必要があります。
回答:
それは不可能ですが、最近議論されました。リンクの提案された回避策:
あなたは置くことができ
*.dll
、その後.gitignoreファイルにgit grep --exclude-standard
。
EDITは見onlynoneの答えを gitの1.9.0は、それが可能なので、。
git 1.9.0では、「魔法の言葉」exclude
がpathspec
s に追加されました。したがって、foobar
一致*.java
するものを除くすべてのファイルを検索する場合は、次のようにできます。
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(または)pathspec
で許可されているすべての「魔法の言葉」についての適切なリファレンスがあります。何らかの理由で、kernel.orgのドキュメントは、Google検索で最初に表示されることが多いにもかかわらず、実際には古くなっています。git help glossary
git grep clock.gettime -- './*' ':!arch/**' ':!drivers/**'
複数のディレクトリ全体を除外します。再帰を防ぐことはできないと思います。
git config alias.mygrep '!git grep "$@" -- "${GIT_PREFIX}/*" ":!*.java*" #'
。その後だけgit mygrep foobar
です。(エイリアスシェル#トリックと現在のディレクトリを使用します。)
git grep
とgit ls-files
、カレントディレクトリからの相対サブディレクトリとの両方のレポートのファイル名から(あなたが使用している場合でも、':(top)'
PATHSPEC含まれます)。どちらのコマンドにも、--full-name
ルートに関連する名前を報告するオプションがありますが、デフォルトではオフになっています。
更新: git> = 1.9の場合、除外パターンのネイティブサポートがあります。1人だけの回答を参照してください。
これは逆に見えるかもしれませんが、除外パターンに一致しないファイルのリストを次のように渡すことができますgit grep
:
git grep <pattern> -- `git ls-files | grep -v <exclude-pattern>`
grep -v
一致しないすべてのパスを返します<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の例をベースにして、このスクリプトを作成し、パス(~/bin/
)にとして配置しました gg
。git grep
特定のファイルタイプを使用しますが、回避します。
私たちのレポには画像がたくさんあるので、画像ファイルを除外しました。これにより、レポ全体を検索すると、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/.*/\\\.\\\(\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/
、でgit-gg
シンボリックリンクを作成しました/usr/lib/git-core/
。
注2
コマンドsh
はレポのルートで呼び出されるため、通常のgit-alias にすることはできません。そして、それは私が望むものではありません!