2011-03-09 24 views
26

Me encanta git grep para buscar en todos los archivos registrados en un repositorio. Es genial. Pero, ¿es posible usarlo (o algún otro comando git) para usarlo solo para buscar archivos (independientemente del contenido)?¿Cómo grep archivos en git repo?

En el momento en que haga esto:

$ find . | grep middleware 

que funciona pero no está utilizando el índice git lo que significa que va a través de cada archivo encontrado y se informa sobre los archivos que se cumplan el criterio de .gitignore.

¿Alguna idea para trucos ingeniosos?

Respuesta

38

Tal vez quiera git ls-files que enumera los archivos en el índice? (y se ajusta automáticamente para su directorio actual dentro del directorio de trabajo de git)

+0

Esta es la respuesta correcta. Haría git ls-files | grep 'nombre que estás buscando' para filtrar en la gran lista de archivos que devolverá git ls-files. (También alias ls-files a ls porque lo uso con frecuencia) – I82Much

+3

Podemos hacerlo con el comando '' git ls-files "* .sh" '' o '' git ls-files | grep .sh'' –

+0

Hace mucho que tengo el alias: 'find =! git ls-files | grep', pero a veces me gustaría limitar la búsqueda a una ruta particular, por ejemplo, 'git find foo bar/baz'. ¿Alguna idea de cómo implementar eso? – JFlo

19

Creo que git ls-files hará el truco para usted.

Así:

git ls-files "*middleware*" 
+0

+1 para eso. Siempre hice 'git ls-tree -r HEAD | grep "toSearchFor"' –

+0

Eso también es genial, pero con 'git ls-files | grep ... 'Obtengo el poder de grep justo en la punta de mis dedos y dado que tengo el resaltado de color por defecto en grep, se muestra mejor. –

4

Usted podría considerar una solución no git en este caso.

find sí mismo tiene la capacidad de hacer lo que quiere de una manera más eficiente que las tuberías sus resultados en grep:

find . -name 'middleware*' 

Usted tendrá que citar el patrón para que el * no está desplegado por el caparazón antes de pasar al find.

Hay un programa de gran alcance llamada ack es decir, bueno, better than grep, y uno de mis favoritos utiliza para ack es exactamente lo que usted ha mencionado - la búsqueda de archivos que coinciden con un patrón dentro de un árbol. ack usa perl regexps, no shell fileglobs, though.

ack -g middleware 

Si desea buscar dentro esos archivos, ack le permite hacer eso más fácil que escribir un bucle de cáscara en los resultados de find que grep s dentro de cada archivo. Comparar los dos y ver cuál prefiere:

for f in $(find . -name 'middleware*') 
do 
    grep 'pattern in file' $f 
done 

frente

ack -G 'middleware' 'pattern in file' 

le recomiendo ack como algo que añadir a su caja de herramientas.

+0

¡Esto es genial! Gracias por presentarme a 'ack'! Solo quiero señalar: "La opción' -G' ha sido eliminada. Dos expresiones regulares en la línea de comando se consideraron demasiado confusas: para simular la funcionalidad de '-G', puedes usar la nueva opción' -x' para canalizar nombres de archivos de una invocación de ack a otra ". de ['ack (1)'] (https://beyondgrep.com/documentation/ack-2.22-man.html). Si descubro la solución, editaré esta respuesta. – askewchan

-2

solución git puro

git grep ha incorporado soporte para limitar el grep a un pegote de archivos. Las otras respuestas usan todas las herramientas externas para hacer la desgrapación real, lo que pasa por alto el punto.

Ejemplo del git grepman page.

git grep 'time_t' -- '*.[ch]' 

busca time_t en toda .c rastreado y los archivos .h en el directorio de trabajo y sus subdirectorios.

De las descripciones de las opciones.

-- Señala el final de las opciones; el resto de los parámetros son limitadores.

<pathspec>…​ Si se proporciona, limite la búsqueda a las rutas que coincidan con al menos un patrón. Ambos caminos principales coinciden y los patrones glob (7) son compatibles.

Así traducir su ejemplo (que no incluía algo para limitar la búsqueda, sin embargo por lo que añade aquí):

$ find . -name '*.txt' | grep middleware 

puede hacer:

$ git grep middleware -- '*.txt' 
+1

esto no responde la pregunta. OP está pidiendo un sabor limitado a git de 'encontrar' en el mismo sentido en que' git grep' es un sabor limitado a git de 'grep'. es decir, OP desea buscar archivos git-tracked por nombre, no por contenido. –

0

tengo el mismo problema regularmente, y acabo de ir y hackear git find - si no usa Debian package, puede copiar el script git-find en /usr/lib/git-core/ (o similar) y enj oy eso.

Se puede utilizar en varios modos, el más fácil de lo que es, en efecto:

git find \*middleware\*  # or 
git find '*middleware*'  # which is short for 
git find -name '*middleware*' 

La combinación también es posible (y casi tan flexible como regulares find, sólo hay que escribir el -a explícitamente):

git find \(-name \*.java -o -name \*.js \) -a ! -ipath \*/test/\* 

tiene un par de opciones más, la mayoría de los cuales se encargan de filtrar el nombre o (es decir, por debajo del directorio de trabajo actual parcial) ruta completa, algunos de ellos mayúsculas y minúsculas (-iname y amigo s), y dos opciones globales, una para alternar expresiones regulares entre POSIX Basic (predeterminado) y POSIX Extended, la otra alterna enlaces simbólicos (valor predeterminado activado); esto solo busca archivos (y enlaces simbólicos), no directorios o submódulos ("gitlinks") por diseño.

También puede pasar la lista de archivos para regular de find(1) si no es demasiado largo (hay que pasar en la línea de comandos), lo que permite cosas como ...

git find -- -mtime -100 

... en ligero costo del sistema de archivos (find accede al sistema de archivos), pero, por otro lado, funciona casi la totalidad (no material de profundidad de búsqueda) de find, y solo se puede operar en archivos "en el índice", es decir, conocido por git (presente en el compromiso HEAD o git add ed).

Sin embargo, es un poco exigente con los conflictos no resueltos. Si nota algún problema, simplemente envíeme una nota (aquí, o a través de IRC).

PD: Siéntete libre de cabildear con la gente oficial de git para subárbol-fusionar el repositorio git-find, estaría más que feliz de tenerlo integrado en git adecuada (la licencia es aún más liberal, solo necesitas la mksh shell en una versión algo reciente (50 debería ser suficiente), pero es el shell Unix más extendido hoy en día, así que está bien).