2012-02-10 12 views
10

La situación: Tengo un tar.gz de un lanzamiento de un proyecto github pero me gustaría averiguar de qué compromiso se tomó esto. No parece haber sido etiquetado o es obvio desde el mensaje de confirmación.encontrar el primer commit de un archivo en git

Así que puedo calcular sha1 de los archivos, pero me gustaría saber a qué compromiso pertenecen?

¡Llamando a los magos de git!

+2

¿Por qué los votos a favor? Este es un problema interesante. Tiene archivos que se originaron en un repositorio de Git, pero actualmente no están bajo control de versión, y quiere saber a qué versión corresponden. Es una buena pregunta. – eykanal

+0

Votación máxima. Es una excelente pregunta que expone la increíble manera en que Git almacena la historia. –

+0

gracias por las dos excelentes respuestas. Al momento de hacer la pregunta, asumí que el tar.gz es una exportación exacta del repositorio, pero al probar ambos métodos, parece que solo hay una confirmación muy cercana, la diferencia está en los archivos README que parecen haber sido manualmente editado para el lanzamiento. Así que dar el crédito a la respuesta basada en diferencias, pero eso no quiere decir que el otro tampoco fue una respuesta excelente. Gracias de nuevo. – bee

Respuesta

2

Dado que el hash almacenado en git no solo incluye el contenido del archivo (y, en teoría, las colisiones hash suceden de todos modos), para estar realmente seguro de que tiene la versión correcta del archivo que necesita comparar los contenidos.

for rev in $(git log --format=%H -- /path/to/file); do 
    git diff --quiet $x:/path/to/file my-current-file; 
    if [[ $? -eq 0 ]]; then 
     echo $x; 
    fi 
done 

En inglés: itere sobre las revisiones que cambiaron el archivo, en orden inverso. Para cada revisión, difiera la versión del archivo allí con el archivo externo al árbol. Si los dos archivos son idénticos, imprima el hash de revisión.

Si usted quiere hacer esto para el toda tar, puede hacer lo mismo pero diff todo el árbol en lugar de un solo archivo (y omitir la ruta del archivo como argumento para git log) - utilizat opciones diff tolerantes te gusta.

+0

Necesita hacer coincidir todos los archivos en el alquitrán para averiguar de dónde vino el alquitrán. –

+0

@ AdamDymitruk Agregué una nota al final de la respuesta sobre esto. – Borealid

+0

En este caso, puede llevar mucho tiempo encontrarlo. Pero se deshace de la ambigüedad de los atributos del archivo. –

2

Este método puede ser complicado debido a los atributos del archivo. Suponiendo que no se modifiquen o mire lo que almacena el repositorio, asegúrese de que sean iguales. Comprométalo con el repositorio y luego eche un vistazo al hash del árbol.

git show -s --pretty=format:%T HEAD 

Ahora camina todos los envíos en el repositorio y ver si alguno de ellos tiene un árbol del mismo hash.

git log --all --format=%H 

le dará todas las hashes de confirmación. Ahora tubería de esto para mostrar el hash árbol

git log --all --format=%H \ 
    | xargs -n 1 git show -s --pretty='format:%H %T' \ 
    | gerp <hash of your tree> 

Si el alquitrán contenía exactamente la misma estructura que incluye permisos, la salida mostrará los SHA1s de las confirmaciones que tienen el mismo árbol.

La búsqueda del árbol de nivel superior SHA1 será RÁPIDA.