Según tengo entendido, cuando Git asigna un hash SHA1 a un archivo, este SHA1 es único para el archivo en función de su contenido.
Como resultado, si un archivo se mueve de un repositorio a otro, el SHA1 para el archivo permanece igual ya que su contenido no ha cambiado.
¿Cómo calcula Git el resumen de SHA1? ¿Lo hace en el contenido completo del archivo sin comprimir?
Me gustaría emular la asignación de SHA1 fuera de Git.
Respuestas:
Así es como Git calcula el SHA1 para un archivo (o, en términos de Git, un "blob"):
Por lo tanto, puede calcularlo usted mismo sin tener que instalar Git. Tenga en cuenta que "\ 0" es el byte NULL, no una cadena de dos caracteres.
Por ejemplo, el hash de un archivo vacío:
Otro ejemplo:
Aquí hay una implementación de Python:
fuente
TypeError: Unicode-objects must be encoded before hashing
excepción en la primeras.update()
línea.s.update(("blob %u\0" % filesize).encode('utf-8'))
para evitar elTypeError
.Un pequeño regalo: con cáscara
fuente
echo -en "blob ${#CONTENTS}\0$CONTENTS" | sha1sum
con la salida degit hash-object path-to-file
y producen resultados diferentes. Sin embargo,echo -e ...
produce los resultados correctos, excepto que hay un final-
( nogit hash-object
produce caracteres finales). ¿Es esto algo de lo que debería preocuparme?-
se usasha1sum
si calcula el hash desde stdin y no desde un archivo. Nada de que preocuparse. Sin embargo, hay algo extraño en el-n
, que debería suprimir la nueva línea normalmente agregada por echo. ¿Su archivo tiene una última línea vacía, que olvidó agregar en suCONTENTS
variable?cat file | sha1sum
lugar desha1sum file
(aunque más procesos y tuberías)Puede hacer que bash shell funcione para calcularlo con bastante facilidad si no tiene instalado git.
fuente
(stat --printf="blob %s\0" "$1"; cat "$1") | sha1sum -b | cut -d" " -f1
.Eche un vistazo a la página de manual de git-hash-object . Puede usarlo para calcular el hash git de cualquier archivo en particular. Yo creo que alimenta git algo más que el contenido del archivo en el algoritmo de hash, pero no sé a ciencia cierta, y si no se alimentan de datos adicionales, no sé lo que es.
fuente
Esta es una solución en F #.
fuente
Implementación completa de Python3:
fuente
En perl:
Como un comando de shell:
fuente
Y en Perl (ver también Git :: PurePerl en http://search.cpan.org/dist/Git-PurePerl/ )
fuente
Usando Ruby, podrías hacer algo como esto:
fuente
Un pequeño script de Bash que debería producir resultados idénticos para
git hash-object
:fuente
En JavaScript
fuente
Es interesante notar que, obviamente, Git agrega un carácter de nueva línea al final de los datos antes de que se mezcle. Un archivo que no contiene nada más que "Hello World!" obtiene un hash blob de 980a0d5 ..., que es el mismo que este:
fuente
git hash-object
. Tenga en cuenta que hacerecho "Hello World!" | git hash-object --stdin
da980a0d5...
, mientras que el usoecho -n
da un hash de en suc57eff5...
lugar.