Si je comprends bien, lorsque Git attribue un hachage SHA1 à un fichier, ce SHA1 est unique au fichier en fonction de son contenu.
En conséquence, si un fichier passe d'un référentiel à un autre, le SHA1 du fichier reste le même car son contenu n'a pas changé.
Comment Git calcule-t-il le condensé SHA1? Le fait-il sur le contenu complet du fichier non compressé?
Je voudrais émuler l'assignation de SHA1 en dehors de Git.
Réponses:
Voici comment Git calcule le SHA1 pour un fichier (ou, en termes Git, un "blob"):
Vous pouvez donc facilement le calculer vous-même sans avoir installé Git. Notez que "\ 0" est l'octet NULL, pas une chaîne de deux caractères.
Par exemple, le hachage d'un fichier vide:
Un autre exemple:
Voici une implémentation Python:
la source
TypeError: Unicode-objects must be encoded before hashing
exception sur la premières.update()
ligne.s.update(("blob %u\0" % filesize).encode('utf-8'))
pour éviter leTypeError
.Un petit goodie: en coquille
la source
echo -en "blob ${#CONTENTS}\0$CONTENTS" | sha1sum
à la sortie degit hash-object path-to-file
et ils produisent des résultats différents. Cependant,echo -e ...
produit les résultats corrects, sauf qu'il y a une fin-
( negit hash-object
produit aucun caractère de fin). Est-ce quelque chose dont je devrais m'inquiéter?-
est utilisée parsha1sum
si elle a calculé le hachage à partir de stdin et non à partir d'un fichier. Rien à craindre. Chose étrange à propos du-n
, qui devrait supprimer la nouvelle ligne normalement ajoutée par echo. Votre fichier a-t-il par hasard une dernière ligne vide, que vous avez oublié d'ajouter dans votreCONTENTS
variable?cat file | sha1sum
place desha1sum file
(plus de processus et de tuyauterie cependant)Vous pouvez créer une fonction shell bash pour le calculer assez facilement si vous n'avez pas installé git.
la source
(stat --printf="blob %s\0" "$1"; cat "$1") | sha1sum -b | cut -d" " -f1
.Jetez un œil à la page de manuel de git-hash-object . Vous pouvez l'utiliser pour calculer le hachage git de n'importe quel fichier particulier. Je pense que git alimente plus que le contenu du fichier dans l'algorithme de hachage, mais je ne sais pas avec certitude, et s'il alimente des données supplémentaires, je ne sais pas ce que c'est.
la source
C'est une solution en F #.
la source
Implémentation complète de Python3:
la source
En Perl:
En tant que commande shell:
la source
Et en Perl (voir aussi Git :: PurePerl sur http://search.cpan.org/dist/Git-PurePerl/ )
la source
En utilisant Ruby, vous pouvez faire quelque chose comme ceci:
la source
Un petit script Bash qui devrait produire une sortie identique à
git hash-object
:la source
En JavaScript
la source
Il est intéressant de noter qu'évidemment, Git ajoute un caractère de nouvelle ligne à la fin des données avant qu'elles ne soient hachées. Un fichier ne contenant rien que "Hello World!" obtient un hachage blob de 980a0d5 ..., identique à celui-ci:
la source
git hash-object
. Notez que faireecho "Hello World!" | git hash-object --stdin
donne980a0d5...
, tandis que utiliserecho -n
donne un hachage de à lac57eff5...
place.