168

を使用してgitリポジトリを検索するときに特定のパス/ディレクトリ/ファイルを除外する方法はありますgit grepか?--exclude通常のgrepコマンドのオプションに似たものはありますか?

大規模なgitリポジトリで直接使用すると実行が遅すぎるgit grepため、使用する必要があります。grep

4

5 に答える 5

256

git 1.9.0では、「魔法の言葉」excludeがsに追加されましたpathspec。したがって、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'なしで機能し./*ます。

git-scm.com(または単に)pathspecで許可されているすべての「魔法の言葉」についての良いリファレンスがあります。git help glossary

于 2015-05-06T18:18:41.640 に答える
64

更新: git> = 1.9の場合、除外パターンがネイティブでサポートされています。1人の回答のみを参照してください。

これは逆に見えるかもしれませんが、除外パターンに一致しないファイルのリストを次のように渡すことができますgit grep

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

grep -v一致しないすべてのパスを返します<exclude-pattern>。これgit ls-filesもパラメータを取りますが、これは追跡されていないファイル--excludeにのみ適用されることに注意してください。

于 2013-01-09T00:47:59.123 に答える
18

それは不可能ですが、最近議論されました。リンクで提案された回避策:

*.dll次に、.gitignoreファイルに配置できますgit grep --exclude-standard

git 1.9.0以降、編集はnoneの回答のみを参照してください。

于 2012-05-02T23:37:17.257 に答える
13

リポジトリに属性ファイルを作成することで、ファイルまたはディレクトリをバイナリとしてマークできます。

$ 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]
于 2018-07-27T19:52:25.370 に答える
2

@kynanの例をベースにして、このスクリプトを作成し、パス(~/bin/)にとして 配置しましggた。使用しますgit grepが、一部の指定されたファイルタイプを回避します。

私たちのリポジトリでは画像がたくさんあるので、画像ファイルを除外しました。これにより、リポジトリ全体を検索すると、検索時間が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

これによると、Thingに名前を付けて、git-gg次のような通常のgitコマンドとして呼び出すことができるはずです。

$ git gg searchstring

しかし、私はこれを機能させることができません。でスクリプトを作成し、~/bin/git-ggシンボリックリンクを作成しました/usr/lib/git-core/

注2

shコマンドはリポジトリのルートで呼び出されるため、通常のgit-aliasにすることはできません。そして、それは私が望むものではありません!

于 2014-02-20T12:23:12.087 に答える