Los hash SHA1 almacenados en los objetos del árbol (tal como los devuelve git ls-tree
) no coinciden con los hashes SHA1 del contenido del archivo (tal como los devuelve sha1sum
)
$ git cat-file blob 4716ca912495c805b94a88ef6dc3fb4aff46bf3c | sha1sum
de20247992af0f949ae8df4fa9a37e4a03d7063e -
¿Cómo funciona git calcular los hashes de archivos? ¿Comprime el contenido antes de calcular el hash?
Respuestas:
$ echo -e 'blob 14\0Hello, World!' | shasum 8ab686eafeb1f44702738c8b0f24f2567c36da6d
Fuente: http://alblue.bandlem.com/2011/08/git-tip-of-week-objects.html
fuente
echo 'Hello, World!' | git hash-object --stdin
. Opcionalmente, puede especificar--no-filters
para asegurarse de que no se produzca la conversión de crlf, o especificar--path=somethi.ng
que deje que git use el filtro especificado a través degitattributes
(también @ user420667). Y-w
para enviar realmente el blob a.git/objects
(si está en un repositorio de git).echo -e 'blob 16\0Hello, \r\nWorld!' | shasum
==echo -e 'Hello, \r\nWorld!' | git hash-object --stdin --no-filters
y también será equivalente con\n
y 15.echo
agrega una nueva línea a la salida, que también se pasa a git. Por eso son 14 personajes. Para utilizar eco sin un salto de línea, escrituraecho -n 'Hello, World!'
Solo estoy ampliando la respuesta
@Leif Gruenwoldt
y detallando lo que está en la referencia proporcionada por@Leif Gruenwoldt
Hazlo tu mismo..
¿Cómo calcula GIT sus hashes de confirmación?
El texto
blob⎵
es un prefijo constante y\0
también es constante y es elNULL
carácter. El<size_of_file>
y<contents_of_file>
varían según el archivo.Ver: ¿Cuál es el formato de archivo de un objeto git commit?
Y eso es todo amigos!
¡Pero espera! , ¿notó que
<filename>
no es un parámetro utilizado para el cálculo de hash? Dos archivos podrían tener el mismo hash si su contenido es igual a la fecha y hora en que se crearon y su nombre. Esta es una de las razones por las que Git maneja los movimientos y renombra mejor que otros sistemas de control de versiones.Hágalo usted mismo (Ext)
Nota:
El enlace no menciona cómo
tree
se hashiza el objeto. No estoy seguro del algoritmo y los parámetros, sin embargo, según mi observación, probablemente calcula un hash basado en todoblobs
ytrees
(sus hashes probablemente) contienefuente
SHA1("blob" + <size_of_file>
- ¿hay espacio adicional entre blob y tamaño? ¿El tamaño es decimal? ¿Tiene el prefijo cero?git hash-object
Esta es una forma rápida de verificar su método de prueba:
Salida:
donde
sha1sum
está en GNU Coreutils.Luego se trata de comprender el formato de cada tipo de objeto. Ya hemos cubierto lo trivial
blob
, aquí están los otros:fuente
$(printf "\0$s" | wc -c)
. Tenga en cuenta el carácter vacío agregado. Es decir, si la cadena es 'abc' con el carácter vacío agregado al frente, la longitud arrojará 4, no 3. Luego, los resultados con sha1sum coinciden con git hash-object.Basado en la respuesta de Leif Gruenwoldt , aquí hay un sustituto de la función de shell para
git hash-object
:Prueba:
fuente
Necesitaba esto para algunas pruebas unitarias en Python 3, así que pensé en dejarlo aquí.
Me apego a los
\n
finales de línea en todas partes, pero en algunas circunstancias Git también podría estar cambiando los finales de línea antes de calcular este hash, por lo que es posible que también necesites uno.replace('\r\n', '\n')
allí.fuente