tag - Cómo excluir ciertos directorios/archivos de git grep search
git ignorar archivos (4)
¿Hay alguna forma de buscar el repositorio de git usando git grep
pero excluir ciertas rutas / directorios / archivos de la búsqueda? Como la opción --exclude
en el comando grep normal.
Si tiene curiosidad: no quiero usar grep normal ya que es mucho más lento que git grep
cuando el tamaño del repositorio de git es grande.
Con el ejemplo de @kynan como base hice este script y lo puse en mi camino ( ~/bin/
) como gg
. Utiliza git grep
pero evita algunos tipos de archivos especificados.
En nuestro repositorio hay muchas imágenes, por lo que he excluido los archivos de imagen, y esto lleva el tiempo de búsqueda a 1/3 si busco todo el repositorio. Pero la secuencia de comandos podría modificarse fácilmente para excluir otros tipos de archivos o 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://.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
Nota 1
De acuerdo con this , debería ser posible nombrar el objeto git-gg
y poder llamarlo como un comando regular de git como:
$ git gg searchstring
Pero no puedo hacer que esto funcione. Creé el script en mi ~/bin/
e hice un enlace simbólico de git-gg
en /usr/lib/git-core/
.
Nota 2
El comando no se puede convertir en un shit-alias regular ya que se invocará en la raíz del repositorio. ¡Y eso no es lo que quiero!
En git 1.9.0, la exclude
"palabra mágica" se agregó a pathspec
s. Por lo tanto, si desea buscar foobar
en cada archivo, excepto aquellos que coincidan con *.java
, puede hacer lo siguiente:
git grep foobar -- ''./*'' '':(exclude)*.java''
O usando el !
"forma corta" para excluir:
git grep foobar -- ''./*'' '':!*.java''
Tenga en cuenta que al usar una pathspec
exclusión, debe tener al menos una pathspec
"inclusiva". En los ejemplos anteriores, este es el ./*
(recursivamente incluye todo en el directorio actual).
También podría usar algo como :(top)
(forma abreviada :/
) para incluir todo desde la parte superior del repositorio. Pero también es probable que desee ajustar su pathspec
exclusión pathspec
para comenzar desde la parte superior también :/!*.java
(de lo contrario, solo excluiría los archivos *.java
de su directorio actual).
Hay una buena referencia para todas las "palabras mágicas" permitidas en una pathspec
de git-scm.com en git-scm.com (o simplemente en el git help glossary
). Por alguna razón, los documentos en kernel.org están realmente desactualizados a pesar de que a menudo aparecen primero en las búsquedas de Google.
No es posible, pero ha sido discutido recientemente . Solución propuesta en el enlace:
Puede poner
*.dll
en .gitignore file y luegogit grep --exclude-standard
.
EDITAR no ve ninguna respuesta, ya que git 1.9.0 es posible.
Actualización: para git> = 1.9 hay soporte nativo para patrones de exclusión, vea la respuesta de oneone .
Esto puede parecer al revés, pero puede pasar una lista de archivos que no coinciden con su patrón de exclusión a git grep
como este:
git grep <pattern> -- `git ls-files | grep -v <exclude-pattern>`
grep -v
devuelve todas las rutas que no coinciden con <exclude-pattern>
. Tenga en cuenta que git ls-files
también toma un parámetro --exclude
, pero que solo se aplica a los archivos sin seguimiento .