¿Cómo puedo "culpar" a una línea eliminada?

Resuelto Michael Lorton asked hace 14 años • 6 respuestas

git blamees excelente para líneas modificadas y agregadas, pero ¿cómo puedo saber cuándo finalmente se eliminó una línea que existía en una confirmación anterior específica? estoy pensandobisect , pero esperaba algo más útil.

(Antes de que preguntes: en este caso, simplemente hice git log -py busqué la línea de código y (a) algún idiota acababa de eliminar la línea vital en la confirmación anterior y (b) yo era ese idiota).

Michael Lorton avatar Dec 10 '10 07:12 Michael Lorton
Aceptado

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

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

que muestra confirmaciones que introducen o eliminan una instancia de esa cadena. ¡ También está el -G<regex>que hace lo mismo con las expresiones regulares! Consulte man git-logy busque las opciones -Gy -S, o pico (el nombre descriptivo de estas funciones) para obtener más información.

De hecho, la -Sopción también se menciona en el encabezado de la git-blamepágina de manual, en la sección de descripción, donde se ofrece un ejemplo de uso git log -S....

Cascabel avatar Dec 10 '2010 00:12 Cascabel

Creo que lo que realmente quieres es

git blame --reverse START..END filename

Desde la página de manual :

Hacer avanzar la historia en lugar de retroceder. En lugar de mostrar la revisión en la que apareció una línea, muestra la última revisión en la que existió una línea. Esto requiere una variedad de revisiones como START..END donde el camino a la culpa existe en START.

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

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

git log --reverse --ancestry-path COMMIT^..master
Chronial avatar Jun 28 '2012 12:06 Chronial

Sólo para completar la respuesta de Cascabel :

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

Tuve el mismo problema que se menciona aquí, pero resultó que faltaba la línea, porque una confirmación de fusión de una rama se revirtió y luego se volvió a fusionar, eliminando efectivamente la línea en cuestión. La --full-historybandera evita omitir esas confirmaciones.

estani avatar Dec 20 '2018 14:12 estani

git seek --reverse puede acercarte al lugar donde se elimina la línea. Pero en realidad no apunta a la revisión donde se elimina la línea. Apunta a la última revisión donde estaba presente la línea . Entonces, si la siguiente revisión es una confirmación simple, tiene suerte y obtuvo la revisión eliminada. OTOH, si la siguiente revisión es una confirmación de fusión , entonces las cosas pueden volverse un poco locas.

Como parte del esfuerzo para crear difflame, abordé este mismo problema, así que si ya tienes Python instalado en tu equipo y estás dispuesto a probarlo, no esperes más y cuéntame cómo te va.

https://github.com/eantoranz/difflame

eftshift0 avatar Mar 10 '2017 00:03 eftshift0

Para cambios ocultos en confirmaciones de fusión

Las confirmaciones de fusión automáticamente ocultan sus cambios de la salida del registro de Git. Tanto el pico como la culpa inversa no encontraron el cambio. Entonces, la línea que quería se agregó y luego se eliminó y quería encontrar la combinación que la eliminó. El git log -p -- path/filehistorial del archivo solo mostró que se agregó. Esta es la mejor manera que encontré para encontrarlo:

git log -p -U9999 -- path/file

Busque el cambio, luego busque hacia atrás "^commit"; el primer "^commit" es la confirmación donde el archivo tenía esa línea por última vez. El segundo "^commit" es después de que desapareció. La segunda confirmación podría ser la que lo eliminó. Está -U9999destinado a mostrar el contenido completo del archivo (después de cada cambio del archivo), suponiendo que sus archivos tengan un máximo de 9999 líneas.

Encuentra cualquier fusión relacionada mediante fuerza bruta (diferencia cada posible confirmación de fusión con su primer padre, ejecútala contra toneladas de confirmaciones)

git log --merges --pretty=format:"git diff %h^...%h | grep target_text" HEAD ^$(git merge-base A B) | sh -v 2>&1 | less

(Intenté restringir más el filtro de revisión, pero tuve problemas y no lo recomiendo. Los cambios de agregar/eliminar que estaba buscando estaban en diferentes ramas que se fusionaron en diferentes momentos y A...B no incluía cuando los cambios realmente se fusionaron en la línea principal).

Muestre un árbol de Git con estas dos confirmaciones (y gran parte del complejo historial de Git eliminado):

git log --graph --oneline A B ^$(git merge-base A B) (A es el primer compromiso anterior, B es el segundo compromiso anterior)

Muestra el historial de A y el historial de B menos el historial de A y B.

Versión alternativa (parece mostrar la ruta de manera más lineal en lugar del árbol de historial de Git normal; sin embargo, prefiero el árbol de historial de Git normal):

git log --graph --oneline A...B

Tres, no dos puntos: tres puntos significa "r1 r2 --no $(git merge-base --all r1 r2). Es el conjunto de confirmaciones a las que se puede acceder desde r1 (lado izquierdo) o r2 (lado derecho). lado), pero no de ambos." - fuente: "hombre gitrevisions"

Curtis Yallop avatar Sep 23 '2019 22:09 Curtis Yallop