webentwicklung-frage-antwort-db.com.de

Wie Sie bestimmte Verzeichnisse/Dateien von git grep search ausschließen

Gibt es eine Möglichkeit, git-Repository mit git grep zu durchsuchen, aber bestimmte Pfade/Verzeichnisse/Dateien von der Suche auszuschließen? Wie die --exclude-Option im normalen grep-Befehl. 

Wenn Sie neugierig sind: Ich möchte kein normales grep verwenden, da es viel langsamer ist als git grep, wenn das git-Repository groß ist. 

111

Es ist nicht möglich, aber wurde kürzlich diskutiert . Vorgeschlagene Problemumgehung im Link:

Sie können *.dll in die .gitignore-Datei und dann git grep --exclude-standard einfügen. 

EDIT siehe onlynone's answer , seit git 1.9.0 ist das möglich. 

16
CharlesB

In git 1.9.0 wurde das "Zauberwort" exclude zu pathspecs hinzugefügt. Wenn Sie also in jeder Datei nach foobar suchen möchten, mit Ausnahme derjenigen, die *.Java entsprechen, können Sie Folgendes tun:

git grep foobar -- './*' ':(exclude)*.Java'

Oder verwenden Sie das ! "Kurzformular" zum Ausschließen:

git grep foobar -- './*' ':!*.Java'

Beachten Sie, dass Sie bei Verwendung einer Ausschlussvariable pathspec mindestens eine "inklusive" pathspec haben müssen. In den obigen Beispielen ist dies der ./* (schließt rekursiv alles unter dem aktuellen Verzeichnis ein).

Sie können auch etwas wie :(top) (Kurzform: :/) verwenden, um alles von oben in das Repo aufzunehmen. Aber dann möchten Sie wahrscheinlich auch die Option pathspec ausschließen, um von oben zu beginnen: :/!*.Java (andernfalls würden nur *.Java-Dateien aus Ihrem aktuellen Verzeichnis ausgeschlossen).

Es gibt eine gute Referenz für alle "magischen Wörter", die in einer pathspec unter git-scm.com (oder einfach nur git help glossary) zulässig sind. Aus irgendeinem Grund sind die Dokumente unter kernel.org wirklich veraltet, auch wenn sie bei Google-Suchen oft an erster Stelle stehen.

154
onlynone

Update: Für git> = 1.9 gibt es native Unterstützung für Ausschlussmuster, siehe onlyone's answer .

Dies mag nach hinten scheinen, aber Sie können eine Liste von Dateien, die nicht mit Ihrem Ausschlussmuster übereinstimmen, wie folgt an git grep übergeben:

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

grep -v gibt jeden Pfad nicht zurück, der <exclude-pattern> entspricht. Beachten Sie, dass git ls-files auch einen --exclude-Parameter benötigt, der jedoch nur auf nicht aufgespürte Dateien angewendet wird.

59
kynan

Mit dem Beispiel von @kynan als Basis habe ich dieses Skript erstellt und es als gg in meinen Pfad (~/bin/) gestellt. Es verwendet zwar git grep, vermeidet jedoch einige angegebene Dateitypen.

In unserem Repo gibt es eine Menge Bilder, also habe ich die Imagefiles ausgeschlossen, und dies führt dazu, dass die Serienzeit auf 1/3 sinkt, wenn ich das gesamte Repo suche. Das Skript kann jedoch leicht modifiziert werden, um andere Dateitypen oder gelierte Muster auszuschließen.

#!/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 "[email protected]" -- `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 "[email protected]"; 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                                                                      

Anmerkung 1

Gemäß this sollte es möglich sein, das Ding git-gg zu benennen und es als regulären Git-Befehl aufzurufen, wie:

$ git gg searchstring

Aber ich kann das nicht zum Laufen bringen. Ich habe das Skript in meinem ~/bin/ erstellt und den git-gg-Symlink in /usr/lib/git-core/ erstellt.

Anmerkung 2

Der Befehl kann nicht in einen regulären sh git-Alias ​​umgewandelt werden, da er dann im Stammverzeichnis des Repos aufgerufen wird. Und das will ich nicht!

2
UlfR

Sie können Dateien oder Verzeichnisse als binär markieren, indem Sie in Ihrem Repository eine Attributdatei erstellen, z.

$ cat .git/info/attributes 
directory/to/ignore/*.* binary
directory/to/ignore/*/*.* binary
another_directory/to/also/ignore/*.* binary

Übereinstimmungen in binären Dateien werden ohne die einschließende Zeile aufgelistet, z.

$ git grep "bar"
Binary file directory/to/ignore/filename matches
other_directory/other_filename:      foo << bar - bazz[:whatnot]
1
coberlin