2012-09-25 19 views
33

Hoy temprano descubrí que faltaba algún código de mi repositorio de git. Sabía algo del texto que faltaba, y el archivo en el que estaba, así que usé git log -S'missingtext' /path/to/file. Sin embargo, lo único que regresó fue la confirmación en la que agregué la línea que contenía el texto faltante. El texto no estaba presente en HEAD, y la confirmación que lo agregaba estaba presente en mi rama, así que sabía que uno de los commits en el historial de mi sucursal debía haberlo eliminado, pero no aparecía.Buscar cuando se borró la línea

Después de algunas búsquedas manuales, resultó que la línea se eliminó accidentalmente mientras se resolvía un conflicto para una combinación. Así que me pregunto:

  1. ¿Es este el motivo por el cual el pico no pudo encontrar el compromiso que borró la línea?
  2. ¿Cómo pude haber encontrado donde se eliminó "missingtext" sin buscar el historial manualmente?

Cualquier penetración en el # 1 sería genial (I supone que git log -S me daría mi respuesta), pero mi verdadera pregunta es # 2, ya que me gustaría ser capaz de evitar esto en el futuro.

+6

'-p' git log y'/missingtext' mientras que en 'less' es una 'n' manera sucia rápida de hacer esto. – nneonneo

+1

Posible duplicado de [¿Cómo "culpo" a una línea eliminada] (http://stackoverflow.com/questions/4404444/how-do-i-blame-a-deleted-line) – hypehuman

Respuesta

44

git log no muestra un diff para fusiones por defecto. Los -c o --cc banderas debe hacer el truco:

git log -c -S'missingtext' /path/to/file

Más discusión/explicación here.

+0

Si quiere saber cuándo se eliminó la línea de un archivo eliminado, puede usar 'git log -c -S'missingtext '-/path/to/file'. – Jonathan

+0

si no sabe qué archivo contiene el texto faltante, puede omitir '/ ruta/a/archivo' y simplemente ejecutar' git log -c -S'missingtext'' –

0

Manera rápida y sucia # 2 - utilice un bucle for.

for commit in $(git log --pretty='%H'); do 
    git diff -U0 --ignore-space-change "$commit^" "$commit" | grep '^-.*missingtext' > /dev/null && echo "$commit" 
done 

Esto incluirá todos los cambios se funden porque especifica explícitamente la base de cometer el diff. Se me ocurrió esto porque git log -c -S... me estaba dando un montón de falsos positivos. Además, cuando especifiqué una ruta de archivo en el comando inicial git log, omití la confirmación que estaba buscando.

Como esto puede funcionar por un tiempo, puede especificar -n en el comando git log o poner && break al final del ciclo si solo necesita 1 resultado.

Cuestiones relacionadas