tag - git ver archivos modificados




Cómo excluir ciertos directorios/archivos de git grep search (3)

¿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 "[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                                                                      

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.


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 .







grep