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

Existe-t-il un moyen de rechercher dans git repository 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 grep normal car il est beaucoup plus lent que git grep lorsque la taille du repository git est grande.

Ce n’est pas possible, mais a été discuté récemment . Solution proposée dans le lien:

Vous pouvez mettre *.dll dans le fichier .gitignore puis git grep --exclude-standard .

EDIT voir réponse unique, puisque git 1.9.0 est possible.

Dans git 1.9.0, le mot magique ” exclude ” a été ajouté à pathspec s. Donc, si vous voulez rechercher foobar dans chaque fichier, sauf ceux correspondant à *.java vous pouvez le faire:

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

Ou en utilisant le ! “forme courte” pour exclure:

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

Notez que lorsque vous utilisez un pathspec exclure, vous devez avoir au moins une pathspec “inclusive”. Dans les exemples ci-dessus, il s’agit du ./* (inclure de manière récursive tout dans le répertoire actuel).

Vous pouvez également utiliser quelque chose comme :(top) (forme abrégée :/ ) pour inclure tout depuis le haut du repo. Mais vous voudrez probablement également ajuster votre pathspec à exclure pour qu’il démarre également depuis le haut :/!*.java (sinon, cela exclurait uniquement les fichiers *.java de votre répertoire actuel).

Il y a une bonne référence pour tous les “mots magiques” autorisés dans un pathspec sur git-scm.com (ou simplement un git help glossary ). Pour une raison quelconque, les documents de kernel.org sont vraiment obsolètes, même s’ils sont souvent les premiers à être consultés lors des recherches Google.

Mise à jour: pour git> = 1.9, il existe un support natif pour les modèles d’exclusion, voir la réponse de l’unique .

Cela peut sembler rétrograde, mais vous pouvez passer une liste de fichiers ne correspondant pas à votre modèle d’exclusion à git grep comme ceci:

 git grep  -- `git ls-files | grep -v ` 

grep -v renvoie tous les chemins ne correspondant pas à . Notez que git ls-files --exclude également un paramètre --exclude , mais cela s’applique uniquement aux fichiers non suivis .

Avec l’exemple de @kynan en tant que base, j’ai créé ce script et l’a placé dans mon chemin ( ~/bin/ ) en tant que gg . Il utilise git grep mais évite certains types de fichiers spécifiés.

Dans notre repo, il y a beaucoup d’images, j’ai donc exclu les fichiers image, ce qui ramène le serchtime à 1/3 si je recherche l’ensemble du repository. Mais le script pourrait facilement être modifié pour exclure d’autres types de fichiers ou 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-ssortingng, 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 cela, il devrait être possible de nommer la chose git-gg et de pouvoir l’appeler comme une commande git normale comme:

 $ git gg searchssortingng 

Mais je ne peux pas faire fonctionner cela. J’ai créé le script dans mon ~/bin/ et créé le lien symbolique git-gg dans /usr/lib/git-core/ .

Note 2

La commande ne peut pas être transformée en un alias sh git régulier, car il sera alors appelé à la racine du repository. Et ce n’est pas ce que je veux!

Vous pouvez marquer des fichiers ou des répertoires comme binarys en créant un fichier d’atsortingbuts dans votre référentiel, par exemple

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

Les correspondances dans les fichiers binarys sont listées sans la ligne

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