2010-12-10 7 views
353

git blame es ideal para líneas modificadas y agregadas, pero ¿cómo puedo saber cuándo una línea que existía en una confirmación previa específica fue finalmente eliminada? Estoy pensando en bisect pero esperaba algo más práctico.¿Cómo puedo "echarle la culpa" a una línea eliminada?

[antes de preguntar: en el caso, que acabo de hacer un git log -p y buscado a través de la línea de código y (a) algún idiota había simplemente borrado la línea vital en la confirmación anterior y (b) que fue que idiota]

+3

Hay una [seguimiento] (http: // stackoverflow.com/q/12591247/923794) con una respuesta que aclara que 'git log -S /path/to/file' también quiere un' -c' o '-cc' para mostrar las eliminaciones durante la fusión (conflictos) – cfi

+2

Debería be '-c' y' --cc'. @Steen: ¡Correcto, gracias por señalar! Estúpida supervisión. Desearía poder editar el comentario. Agregar una nueva, luego eliminar la mía, y luego eliminar la tuya es demasiado engorrosa, supongo :) – cfi

+3

Me gustaría que 'git culpa' tuviera una opción para mostrar líneas borradas (con quizás [tachado] (http://stackoverflow.com)/q/8357203/60075) o texto rojo) con la revisión en la que se eliminaron. –

Respuesta

436

Si conoce el contenido de la línea, se trata de un caso de uso ideal para:

git log -S <string> path/to/file 

lo que demuestra que se compromete la que introducir o quitar una instancia de esa cadena. ¡También está el -G<regex> que hace lo mismo con expresiones regulares! Consulte man git-log y busque las opciones -G y -S, o pico (el nombre descriptivo de estas características) para obtener más información.

La opción -S también se menciona en el encabezado de la página de manual git-blame, en la sección de descripción, donde muestra un ejemplo con git log -S....

+0

Brillante ... justo lo que necesitaba en este trabajo de portabilidad Estoy trabajando en +1 – jkp

+19

Después de usar Git por 1+ año, todavía me sorprende ver que Git * siempre * tiene un comando/opción en algún lugar para abordar casi cualquier escenario de uso que tengo. ¡Gracias por compartir este, es exactamente lo que necesito ahora! –

+16

Este método me ha funcionado antes, pero justo ahora vi un caso en el que no se encontró el compromiso donde se eliminó la línea. Resultó que la línea en cuestión se eliminó en una confirmación de fusión. ¿Eso explicaría el error? (Sin embargo, el método 'git blame --reverse' lo encontró) – antinome

100

creo que lo que realmente quiere es

git blame --reverse START..END filename 

De the manpage:

historia Walk adelante en lugar de hacia atrás. En lugar de mostrar la revisión en la que apareció una línea, muestra la última revisión en la que ha existido una línea. Esto requiere un rango de revisión como START..END donde existe el camino a la culpa en START.

Con git blame reverse, puede encontrar la última confirmación en la que apareció la línea. Todavía necesita obtener el compromiso que viene después.

Puede usar el siguiente comando para mostrar un registro de git invertido. La primera confirmación que se muestra será la última vez que aparece esa línea, y la próxima confirmación será cuando se modifique o elimine.

git log --reverse --ancestry-path COMMIT^..master 
+9

Si hay múltiples fusiones de la sucursal donde se agregó la línea en la sucursal donde falta la línea (o en cualquier otro caso en que haya múltiples rutas en el linaje de START a END), 'git culpa --reverse' mostrará la revisión antes de la fusión que fue cronológicamente la última, no la revisión antes de la fusión inicial donde se tomó la decisión de no tomar la línea. ¿Hay alguna forma de encontrar la primera revisión donde la línea dejó de existir en lugar de la más reciente? – rakslice

+1

@rakslice, para eso puedes usar la culpa --reverse --primer padre, es un poco mejor. – max630

5

git culpa --reverse puede conseguir que cerca de donde se elimina la línea. Pero realmente no indica a la revisión donde se borra la línea. Apunta a la última revisión donde la línea era presente. Luego, si el siguiente revisión es una confirmación simple, tiene suerte y obtiene la revisión de eliminación. OTOH, si la siguiente revisión es merge commit, entonces las cosas pueden ponerse un poco salvajes. Como parte del esfuerzo para crear difflame, resolví este problema, así que si ya tienes Python instalado en tu caja y estás dispuesto a intentarlo, entonces no esperes más y cuéntame cómo funciona.

https://github.com/eantoranz/difflame

Cuestiones relacionadas