git log -G<regex> -p
es una herramienta maravillosa para buscar cambios en el historial de una base de código que coincidan con el patrón especificado. Sin embargo, puede ser abrumador localizar el trozo relevante en la salida diff / patch en un mar de trozos en su mayoría irrelevantes.
Por supuesto, es posible buscar la salida de git log
la cadena / expresión regular original, pero eso hace poco para reducir el ruido visual y la distracción de muchos cambios no relacionados.
Leyendo git log
, veo que está el --pickaxe-all
, que es exactamente lo contrario de lo que quiero: amplía la salida (a todo el conjunto de cambios), mientras que quiero limitarlo (al trozo específico).
Esencialmente, estoy buscando una manera de analizar "inteligentemente" el diff / patch en trozos individuales y luego ejecutar una búsqueda contra cada trozo (apuntando solo a las líneas cambiadas), descartar los trozos que no coinciden y generar los Esto hace.
¿Existe una herramienta como la que describo? ¿Existe un mejor enfoque para obtener los trozos emparejados / afectados?
Algunas investigaciones iniciales que he hecho ...
Si fuera posible
grep
la salida diff / patch y hacer que los valores de las opciones de contexto sean dinámicos, digamos, a través de expresiones regulares en lugar de recuentos de líneas, eso podría ser suficiente. Perogrep
no está exactamente construido de esa manera (ni necesariamente estoy solicitando esa función).Encontré la suite patchutils , que inicialmente sonaba como si pudiera satisfacer mis necesidades. Pero después de leer sus
man
páginas, las herramientas no parecen manejar trozos coincidentes basados en expresiones regulares. (Sin embargo, pueden aceptar una lista de trozos ...)Finalmente me encontré con splitpatch.rb , que parece manejar bien el análisis del parche, pero necesitaría un aumento significativo para manejar parches de lectura
stdin
, emparejar los trozos deseados y luego generar los trozos.
Respuestas:
aquí /programming//a/35434714/5305907 se describe una forma de hacer lo que está buscando. efectivamente:
git diff -U1 | grepdiff 'console' --output-matching=hunk
Muestra solo los trozos que coinciden con la cadena dada "consola".
fuente
grepdiff
es básicamente lo que quiero; Debo haber perdido su opción de coincidencia de trozos! sin embargo ... la información de confirmación de git se eliminagrepdiff
, por lo que una vez que localice el trozo relevante, debe adivinar el sha de confirmación del objeto / blob sha en el encabezado diff, una operación bastante costosa. (ver stackoverflow.com/a/223890/2284440 ) sería algo así comogit find-object SHA --reverse | head -1 | cut -c 1-7 | { read sha ; git log -1 $sha; }
grepdiff
que es más básica en términos de argumentos aceptados. tenga en cuenta que cuando el trozo coincidente es el último trozo en un diff, incluye incorrectamente el encabezado git commit del siguiente commit, ¡algo que me confundió por completo hasta que me di cuenta de lo que está sucediendo!No es exactamente lo que está pidiendo, pero una forma de lidiar con los trozos es el modo de adición interactiva. Esto requiere que revises el commit después del parche que te interesa
luego retroceda un paso más en el VCS, pero no en el directorio de trabajo
(En este punto, la diferencia entre el índice y el directorio de trabajo corresponderá al parche que le interese).
Ahora puedes ejecutar
git add -p
. Esto lanzará una sesión interactiva que tiene una/
opción, que le permite localizar trozos en los que alguna línea coincide con una expresión regular. Particularmente útil si realmente desea procesar aún más esos parches (como, preparar una selección parcial de cereza).Desafortunadamente, al menos en este momento, el
/
comandoadd -p
solo funciona dentro de un solo archivo, por lo que es posible que deba omitir varios archivos no relevantes.fuente
Sobre la base de la respuesta anterior de @nagu, y las otras respuestas vinculadas, pude llegar
git log -G
a mostrar solo los tíos relevantes.Primero cree un script en algún lugar de su $ PATH con este contenido:
Llame
git log -G
y dígale a Git que use elpickaxe-diff
script como un controlador de diferencias externo:Esto usará el script pickaxe-diff solo para generar los diffs, por lo que el resto de la
git log
salida (commit hash, mensaje, etc.) no se tocará.Advertencia
La forma en que funciona el pico Git es que limita la salida a los archivos cuyos trozos cambian la cadena / expresión regular dada. Esto significa que si otro trozo en estos archivos también contiene la cadena de búsqueda / expresión regular, pero no la cambia, todavía se mostrará con el script anterior. Esta es una limitación de grepdiff. Hay una solicitud de extracción abierta en el proyecto patchutils para agregar un
--only-matching
indicador a grepdiff, que proporcionaría la funcionalidad necesaria para filtrar correctamente estos trozos.Hice una reseña de mi solución en esta esencia .
fuente