Soweit ich weiß, wenn Git einer Datei einen SHA1-Hash zuweist, ist dieser SHA1 aufgrund seines Inhalts für die Datei eindeutig.
Wenn eine Datei von einem Repository in ein anderes verschoben wird, bleibt der SHA1 für die Datei unverändert, da sich der Inhalt nicht geändert hat.
Wie berechnet Git den SHA1-Digest? Tut es das mit dem vollständigen unkomprimierten Dateiinhalt?
Ich möchte die Zuweisung von SHA1s außerhalb von Git emulieren.
Antworten:
So berechnet Git den SHA1 für eine Datei (oder, in Git-Begriffen, einen "Blob"):
So können Sie es einfach selbst berechnen, ohne Git installiert zu haben. Beachten Sie, dass "\ 0" das NULL-Byte ist und keine zweistellige Zeichenfolge.
Zum Beispiel der Hash einer leeren Datei:
Ein anderes Beispiel:
Hier ist eine Python-Implementierung:
quelle
TypeError: Unicode-objects must be encoded before hashing
in der erstens.update()
Zeile eine Ausnahme angezeigt.s.update(("blob %u\0" % filesize).encode('utf-8'))
um das zu vermeidenTypeError
.Ein kleiner Leckerbissen: in der Schale
quelle
echo -en "blob ${#CONTENTS}\0$CONTENTS" | sha1sum
mit der Ausgabe vongit hash-object path-to-file
und sie produzieren unterschiedliche Ergebnisse. Allerdingsecho -e ...
erzeugt die richtigen Ergebnisse, außer es gibt eine Hinter ist-
(git hash-object
erzeugt keine nachlauf Zeichen). Sollte ich mir darüber Sorgen machen?-
wird verwendet,sha1sum
wenn der Hash aus stdin und nicht aus einer Datei berechnet wird. Nichts, über das man sich sorgen sollte. Seltsame Sache an der-n
, die die normalerweise durch Echo angehängte Newline unterdrücken sollte. Hat Ihre Datei zufällig eine leere letzte Zeile, die Sie vergessen haben, in IhreCONTENTS
Variable aufzunehmen?cat file | sha1sum
anstelle vonsha1sum file
(mehr Prozesse und Rohrleitungen allerdings) verwendenSie können eine Bash-Shell-Funktion erstellen, um sie ganz einfach zu berechnen, wenn Sie kein Git installiert haben.
quelle
(stat --printf="blob %s\0" "$1"; cat "$1") | sha1sum -b | cut -d" " -f1
.Schauen Sie sich die Manpage für Git-Hash-Objekt an . Sie können es verwenden, um den Git-Hash einer bestimmten Datei zu berechnen. Ich denke, dass git mehr als nur den Inhalt der Datei in den Hash-Algorithmus einspeist, aber ich weiß es nicht genau, und wenn es zusätzliche Daten einspeist, weiß ich nicht, was es ist.
quelle
Dies ist eine Lösung in F #.
quelle
Vollständige Python3-Implementierung:
quelle
In Perl:
Als Shell-Befehl:
quelle
Und in Perl (siehe auch Git :: PurePerl unter http://search.cpan.org/dist/Git-PurePerl/ )
quelle
Mit Ruby können Sie Folgendes tun:
quelle
Ein kleines Bash-Skript, das identische Ausgaben erzeugen sollte wie
git hash-object
:quelle
In JavaScript
quelle
Es ist interessant festzustellen, dass Git offensichtlich am Ende der Daten ein Zeilenumbruchzeichen hinzufügt, bevor sie gehasht werden. Eine Datei, die nichts als "Hallo Welt!" bekommt einen Blob-Hash von 980a0d5 ..., der der gleiche ist wie dieser:
quelle
git hash-object
. Beachten Sie, dass das Geben vonecho "Hello World!" | git hash-object --stdin
gibt980a0d5...
, während das Verwenden stattdessenecho -n
einen Hash von gibtc57eff5...
.