modificados - git ver commits pendientes
¿Cómo grep(buscar) código comprometido en el historial de git? (13)
Buscar en cualquier revisión, cualquier archivo :
git rev-list --all | xargs git grep <regexp>
Buscar solo en algunos archivos dados, por ejemplo archivos xml:
git rev-list --all | xargs -I{} git grep <regexp> {} -- "*.xml"
Las líneas de resultados deberían verse así: 6988bec26b1503d45eb0b2e8a4364afb87dde7af: bla.xml: texto de la línea que encontró ...
Luego puede obtener más información como autor, fecha, diff usando git show:
git show 6988bec26b1503d45eb0b2e8a4364afb87dde7af
He eliminado un archivo o un código en un archivo en el pasado. ¿Puedo grep en el contenido (no en los mensajes de confirmación)?
Una solución muy mala es grep el registro:
git log -p | grep <pattern>
Sin embargo, esto no devuelve el hash de confirmación de inmediato. git grep
con git grep
en vano.
Deberías usar la opción pickaxe ( -S
) del git log
de git log
Para 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: encuentre la línea perdida por palabra clave para obtener más información.
Como comentó Jakub Narębski :
esto busca diferencias que introducen o eliminan una instancia de
<string>
.
Por lo general, significa "revisiones donde agregó o quitó la línea con ''Foo''".La opción
--pickaxe-regex
permite utilizar--pickaxe-regex
POSIX extendidas en lugar de buscar una cadena.
Como comentó Rob , esta búsqueda distingue entre mayúsculas y minúsculas: abrió una pregunta de seguimiento sobre cómo realizar una búsqueda sin distinción de mayúsculas y minúsculas.
En mi caso, necesitaba buscar un Compromiso corto y las soluciones enumeradas no funcionaban.
Logré hacerlo con: (reemplazar el token REGEX )
for commit in $(git rev-list --all --abbrev-commit)
do
if [[ $commit =~ __REGEX__ ]]; then
git --no-pager show -s --format=''%h %an - %s'' $commit
fi
done
Entonces, ¿estás tratando de pasar grep a través de versiones anteriores del código para ver dónde existe algo último?
Si estuviera haciendo esto, probablemente usaría git bisect . Usando bisect, puede especificar una versión buena conocida, una versión mala conocida y un script simple que verifique si la versión es buena o mala (en este caso, un grep para ver si el código que busca está presente) ). Ejecutando esto encontrará cuando el código fue eliminado.
La respuesta de @Jeet funciona en PowerShell.
git grep -n <regex> $(git rev-list --all)
A continuación se muestran todos los archivos, en cualquier confirmación, que contienen una password
.
# store intermediate result
$result = git grep -n "password" $(git rev-list --all)
# display unique file names
$result | select -unique { $_ -replace "(^.*?:)|(:.*)", "" }
Mi forma favorita de hacerlo es con la opción -G
git log
(agregada en la versión 1.7.4).
-G<regex>
Look for differences whose added or removed line matches the given <regex>.
Hay una diferencia sutil entre la forma en que las opciones -G
y -S
determinan si una confirmación coincide:
- La opción
-S
esencialmente cuenta la cantidad de veces que su búsqueda coincide en un archivo antes y después de una confirmación. La confirmación se muestra en el registro si los recuentos anteriores y posteriores son diferentes. Esto no mostrará, por ejemplo, confirmaciones donde se movió una línea que coincide con su búsqueda. - Con la opción
-G
, la confirmación se muestra en el registro si su búsqueda coincide con cualquier línea que se haya agregado, eliminado o cambiado.
Tome este compromiso como ejemplo:
diff --git a/test b/test
index dddc242..60a8ba6 100644
--- a/test
+++ b/test
@@ -1 +1 @@
-hello hello
+hello goodbye hello
Debido a que el número de veces que aparece "hola" en el archivo es el mismo antes y después de esta confirmación, no coincidirá con el uso de -Shello
. Sin embargo, dado que hubo un cambio en una línea que coincide con hello
, la confirmación se mostrará usando -Ghello
.
Para buscar contenido de confirmación (es decir, líneas de origen reales, en lugar de mensajes de confirmación y similares), lo que debe hacer es:
git grep <regexp> $(git rev-list --all)
Actualizaciones : git rev-list --all | xargs git grep <expression>
git rev-list --all | xargs git grep <expression>
funcionará si te encuentras con un error "Lista de argumentos demasiado larga"
Si desea limitar la búsqueda a algún subárbol (por ejemplo, "lib / util"), también deberá pasarlo al subcomando rev-list
y grep
:
git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util
Esto hará grep a través de todo su texto de confirmación para la expresión regular.
La razón para pasar la ruta en ambos comandos es porque rev-list
devolverá la lista de revisiones donde ocurrieron todos los cambios a lib/util
, pero también debe pasar a grep
para que solo busque en lib/util
.
Imagínese el siguiente escenario: grep
puede encontrar el mismo <regexp>
en otros archivos que se encuentran en la misma revisión devuelta por rev-list
(incluso si no hubo cambios en ese archivo en esa revisión).
Aquí hay algunas otras formas útiles de buscar su fuente:
Busque en el árbol de trabajo el texto que coincida con la expresión regular regexp:
git grep <regexp>
Busque en el árbol de trabajo las 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 las líneas de texto que coincidan con las expresiones regulares regexp1 y regexp2, que solo reporten rutas de archivos:
git grep -e <regexp1> --and -e <regexp2>
Busque en el árbol de trabajo los 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 las líneas cambiadas de patrón de coincidencia de texto:
git diff --unified=0 | grep <pattern>
Busque en todas las revisiones el texto que coincida con expresiones regulares regexp:
git grep <regexp> $(git rev-list --all)
Busque en todas las revisiones entre rev1 y rev2 el texto que coincida con expresiones regulares regexp:
git grep <regexp> $(git rev-list <rev1>..<rev2>)
Para cualquier otra persona que intente hacer esto en SourceTree , no hay un comando directo en la IU para ello (a partir de la versión 1.6.21.0). Sin embargo, puede usar los comandos especificados en la respuesta aceptada abriendo la ventana de Terminal (botón disponible en la barra de herramientas principal) y copiándolos / pegándolos en la misma.
Nota: la vista de búsqueda de SourceTree puede realizar búsquedas de texto en parte. Presione Ctrl + 3 para ir a la vista Buscar (o haga clic en la pestaña Buscar disponible en la parte inferior). Desde el extremo derecho, establezca Tipo de búsqueda en Cambios de archivo y luego escriba la cadena que desea buscar. Este método tiene las siguientes limitaciones en comparación con el comando anterior:
- SourceTree solo muestra las confirmaciones que contienen la palabra de búsqueda en uno de los archivos modificados. Encontrar el archivo exacto que contiene el texto de búsqueda es nuevamente una tarea manual.
- RegEx no es compatible.
Para simplificar, sugiero usar GUI: gitk - El navegador de repositorio Git , es bastante flexible
y puedes navegar a través de los resultados usando la flecha arriba / abajo
Si desea buscar cambios en el código (vea lo que realmente se ha cambiado con la palabra dada en todo el historial) opte por el modo de patch
: encontré una combinación muy útil de hacer:
git log -p
# hit ''/'' for search mode
# type in the word you are searching
# if the first search is not relevant hit ''n'' for next (like in vim ;) )
Tomé la respuesta de @ Jeet y la adapté a Windows (gracias a esta respuesta ):
FOR /F %x IN (''"git rev-list --all"'') DO @git grep <regex> %x > out.txt
Tenga en cuenta que para mí, por algún motivo, el compromiso real que eliminó esta expresión regular no apareció en la salida del comando, sino más bien un compromiso anterior.
git log
puede ser una forma más efectiva de buscar texto en todas las ramas, especialmente si hay muchas coincidencias y desea ver los cambios más recientes (relevantes) primero.
git log -p --all -S ''search string''
git log -p --all -G ''match regular expression''
Esta lista de comandos de registro confirma que agrega o elimina la cadena de búsqueda / expresión regular dada, (generalmente) más reciente primero. La opción -p
hace que se muestre la diferencia relevante donde se agregó o eliminó el patrón, para que pueda verlo en contexto.
Tras encontrar un compromiso relevante que agrega el texto que estaba buscando (por ejemplo, 8beeff00d), encuentre las ramas que contienen el compromiso:
git branch -a --contains 8beeff00d
git rev-list --all | xargs -n 5 git grep EXPRESSION
es una modificación para la solución de @ Jeet, por lo que muestra resultados mientras se busca y no solo al final (lo que puede llevar mucho tiempo en un gran repositorio).