Comment exclure certains répertoires / fichiers de la recherche git grep

Existe-t-il un moyen de rechercher un dépôt git en utilisant git grep mais en excluant certains chemins/répertoires/fichiers de la recherche? Comme l'option --exclude dans la commande grep normale.

si vous êtes curieux: Je ne veux pas utiliser le grep normal car il est beaucoup plus lent que git grep quand la taille du dépôt git est grande.

105
demandé sur Sklivvz 2012-05-03 03:31:46

5 réponses

ce n'est pas possible, mais a été discuté récemment . Contournement proposé dans le lien:

Vous pouvez mettre *.dll .dossier gitignore puis git grep --exclude-standard .

MODIFIER voir onlynone la réponse de , depuis git 1.9.0 c'est possible.

15
répondu CharlesB 2018-09-24 17:20:55

Dans git 1.9.0 le "mot magique", exclude a été ajouté à pathspec . Donc, si vous voulez la recherche pour foobar dans tous les fichiers à l'exception de ceux correspondant *.java vous pouvez le faire:

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

ou en utilisant la ! " forme abrégée "pour exclure:

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

notez que lorsque vous utilisez une exclusion pathspec , vous devez avoir au moins un" inclusif " pathspec . Dans les exemples ci-dessus, il s'agit du ./* (incluez récursivement tout dans le répertoire courant).

vous pouvez également utiliser quelque chose comme :(top) (raccourci: :/ ) pour inclure tout du haut de la pension. Mais alors vous voudriez probablement aussi ajuster votre exclure pathspec pour commencer du haut aussi bien: :/!*.java (autrement il exclurait seulement *.java des dossiers de sous votre répertoire courant).

il y a une bonne référence pour toute la magie mots "autorisé dans un pathspec à git-scm.com (ou tout simplement git help glossary ). Pour une raison inconnue, le docs à kernel.org sont vraiment obsolètes, même si elles apparaissent souvent en premier dans les recherches google.

144
répondu onlynone 2015-05-06 20:01:18

mise à Jour: Pour git >= 1.9 il y a un support natif pour les exclure des modèles, voir seule la réponse de .

cela peut sembler à l'envers, mais vous pouvez passer une liste de fichiers ne correspondant pas à votre motif d'exclusion à git grep comme ceci:

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

grep -v renvoie tous chemin pas matching <exclude-pattern> . Notez que git ls-files prend également un --exclude paramètre, mais c'est seulement appliqué à sans traces de fichiers .

59
répondu kynan 2017-05-23 12:18:23

Avec l'exemple de @kynan comme base j'ai fait ce script et le mettre dans mon chemin ( ~/bin/ ) comme gg . Il utilise git grep mais évite certains types de fichiers.

dans notre rapport il y a beaucoup d'images donc j'ai exclu les imagefiles, et cela prend le serchtime à 1/3 si je cherche le rapport entier. Mais le script pourrait facilement être modifié pour exclure d'autres types de fichiers ou des 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/.*/\\.\\("151900920"\\)/'`      

# 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

selon ce il devrait être possible de nommer la chose git-gg et être en mesure de l'appeler comme une commande git régulière comme:

$ git gg searchstring

mais je n'y arrive pas. J'ai créé le script dans mon ~/bin/ et fait un git-gg symlink dans /usr/lib/git-core/ .

Note 2

la commande peut ne pas être transformé en un sh git-alias régulier puisqu'il sera alors invoqué à la racine du repo. Et ce n'est pas ce que je veux!

2
répondu UlfR 2017-05-23 12:26:27

vous pouvez marquer des fichiers ou des répertoires en tant que fichiers binaires en créant un fichier d'attributs dans votre dépôt, par exemple

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

dans les fichiers binaires sont listées sans la ligne including, p.ex.

$ git grep "bar"
Binary file directory/to/ignore/filename matches
other_directory/other_filename:      foo << bar - bazz[:whatnot]
0
répondu coberlin 2018-07-27 19:52:25