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.
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 puisgit grep --exclude-standard
.
MODIFIER voir onlynone la réponse de , depuis git 1.9.0 c'est possible.
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.
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 .
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!
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]