Cómo buscar (buscar) código comprometido en el historial de Git

Resuelto Ortwin Gentz asked hace 14 años • 22 respuestas

Eliminé un archivo o algún código en un archivo en algún momento del pasado. ¿Puedo buscar en el contenido (no solo en los mensajes de confirmación)?

Una solución muy pobre es recuperar el registro:

git log -p | grep <pattern>

Sin embargo, esto no devuelve el hash de confirmación de inmediato. Jugué git grepsin éxito.

Ortwin Gentz avatar May 28 '10 18:05 Ortwin Gentz
Aceptado

Para buscar contenido de confirmación (es decir, líneas de fuente reales, a diferencia de mensajes de confirmación y similares), debe hacer:

git grep <regexp> $(git rev-list --all)

git rev-list --all | xargs git grep <expression>funcionará si se encuentra con el error "Lista de argumentos demasiado larga".

Si desea limitar la búsqueda a algún subárbol (por ejemplo, "lib/util"), deberá pasarlo al rev-listsubcomando y greptambién:

git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util

Esto revisará todo el texto de confirmación de regexp.

La razón para pasar la ruta en ambos comandos es porque rev-listdevolverá la lista de revisiones donde lib/utilocurrieron todos los cambios, pero también debe pasar greppara que solo busque en lib/util.

Imagínese el siguiente escenario: greppodría encontrar lo mismo <regexp>en otros archivos contenidos en la misma revisión devuelta rev-list(incluso si no hubo ningún cambio en ese archivo en esa revisión).

A continuación se muestran otras formas útiles de buscar su fuente:

Busque en el árbol de trabajo texto que coincida con expresiones regulares regexp:

git grep <regexp>

Busque en el árbol de trabajo líneas de texto que coincidan con la expresión regular regexp1 o regexp2:

git grep -e <regexp1> [--or] -e <regexp2>

Busque en el árbol de trabajo líneas de texto que coincidan con las expresiones regulares regexp1 y regexp2, informando únicamente las rutas de los archivos:

git grep -l -e <regexp1> --and -e <regexp2>

Busque en el árbol de trabajo archivos que tengan líneas de texto que coincidan con la expresión regular regexp1 y líneas de texto que coincidan con la expresión regular regexp2:

git grep -l --all-match -e <regexp1> -e <regexp2>

Busque en el árbol de trabajo líneas modificadas de patrón de coincidencia de texto:

git diff --unified=0 | grep <pattern>

Busque en todas las revisiones texto que coincida con expresiones regulares regexp:

git grep <regexp> $(git rev-list --all)

Busque en todas las revisiones entre rev1 y rev2 texto que coincida con expresión regular regexp:

git grep <regexp> $(git rev-list <rev1>..<rev2>)
Jeet avatar May 28 '2010 13:05 Jeet

Debes utilizar la opción pico ( -S) de git log.

Buscar Foo:

git log -SFoo -- path_containing_change
git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_change

Consulte el historial de Git: busque líneas perdidas por palabra clave para obtener más información.

-S(llamado pickaxe) proviene originalmente de una git diffopción (Git v0.99, mayo de 2005). Luego -S( pickaxe) fue portadogit log en mayo de 2006 con Git 1.4.0-rc1.


Como comentó Jakub Narębski :

  • esto busca diferencias que introducen o eliminan una instancia de<string> . Por lo general, significa "revisiones en las que agregó o eliminó una línea con 'Foo'".

  • la --pickaxe-regexopción le permite utilizar expresiones regulares POSIX extendidas en lugar de buscar una cadena. Ejemplo (de git log):git log -S"frotz\(nitfol" --pickaxe-regex


Como comentó Rob , esta búsqueda distingue entre mayúsculas y minúsculas; abrió una pregunta de seguimiento sobre cómo realizar búsquedas que no distinguen entre mayúsculas y minúsculas.


Hola Angel señala en los comentarios :

Ejecutar a git log -G<regexp> --branches --all( -Ges lo mismo -Spero para expresiones regulares) hace lo mismo que el aceptado ( git grep <regexp> $(git rev-list --all)), ¡pero es muchísimo más rápido!

La respuesta aceptada seguía buscando texto después de ≈10 minutos de ejecutarlo, mientras que esta da resultados después de ≈4 segundos 🤷‍♂️. El resultado aquí también es más útil.

VonC avatar May 28 '2010 11:05 VonC