Git Hash (git hash-object) berechnen...

braegler

NGBler
Registriert
14 Juli 2013
Beiträge
873
Guten Abend zusammen,

ich hab da mal wieder ein kleines Problem, für das ich Eure Hilfe bräuchte.
Eigentlich möchte ich das ganze final in php umsetzen, da es mit aber zuerst mal nur um die Funktionsweise und nicht die Implementierung geht, hab ich das mal hier platziert.

Background (für Gelangweilte)
Möchte mir in php ein Update Skript basteln, das mir Änderungen von GitHub via "auto-update" ermöglicht.

Git ermöglicht es ja über
[src=c]git hash-object MeineSuperDatei[/src]
den git-Hash einer Datei zu bestimmen.

Ich hab nun 2 Dateien (testfile1.php und testfile2.php), und folgendes in der Konsole:
[src=bash]

HomePC@HomePC-PC /phpDEV/installer (main)
$ git hash-object testfile1.php
1b632cfba7d215ebdc1dae12367b3aa2170f14f1

HomePC@HomePC-PC /phpDEV/installer (main)
$ git hash-object testfile2.php
1b632cfba7d215ebdc1dae12367b3aa2170f14f1

HomePC@HomePC-PC /phpDEV/installer (main)
$ md5sum.exe testfile*
1415c25569a5431e432a4305d8939a73 *testfile1.php
61fbca1a2418bd005a6db649cb4cbcc1 *testfile2.php

[/src]

wie Ihr sehen könnt, haben beide Dateien unterschiedliche MD5-Summen, jedoch identische git Objekt Hashes.
Jetzt suche ich eine Möglichkeit, diese auch ohne installiertes Git zu berechnen.

Leider sind meine C-Kenntnisse nicht gut genug, um den Git-Quellcode zu kapieren.

Bin Euch für jede Hilfe dankbar.

Vielen Dank schonmal
 
Heyyo.
Im Prinzip sind Object-Hashes in Git einfach nur ein String, an dessen Anfang der Typ steht(bei Dateien blob), woraurf ein Leerzeichen folgt, darauf dann die Dateigröße in Bytes, und darauf dann ein NUL(\x00)-Byte, und *dann* der Inhalt der Datei. Der gesamte String wird dann mit SHA1 beschmissen, woraus der Hash resultiert.

Im Prinzip ist der String also(Pseudocode):
Code:
Expand Collapse Copy
String = "blob " + FileSizeBytes + '\0' + FileContents;
Hash = sha1(String);

Daher kommst Du mit MD5 nicht zum Ziel, und würdest es auch nicht mit SHA1 alleine. :D
Du kannst das nachvollziehen, indem Du z.B. folgst.

EDITH:// Und, soweit ich mich erinnere, nimmt md5sum den Timestamp und Dateinamen mit in den Hash.. jenachdem wie die Implementation ist, vermutlich. Hab kein Windows. Kann nicht nachsehen D:
 
Zuletzt bearbeitet:
  • Thread Starter Thread Starter
  • #4
Vielen Dank für Euren Input.

@drfuture: Leider braucht das Projekt git-php einen installierten Client und wrapped den nur

@darksider3:
So hab ich mir das zuerst auch vorgestellt. Hatte aber trotzdem unterschiedliche Hashs.
Bin vor wenigen Minuten zur Lösung gekommen:
Jage ich beide Dateien zuvor über
[src=bash]sed '/\r$//' [/src] um die lästigen "CR" Steuerzeichen loszuwerden und wurschte sie danach nach dem von Dir geposteten Prinzip zusammen, komm ich auf die selben Hashes wie git hash-object :beer:

Ich sag Euch vielen Dank :D

Remark:
md5sum nimmt nur den Inhalt,wie auch SHA1.
[src=bash]
md5sum.exe test.*
915edf14d6d450bbd204d9d6132a2f7e *test.1
915edf14d6d450bbd204d9d6132a2f7e *test.2
[/src]
 
  • Thread Starter Thread Starter
  • #6
Kein Problem, bin für jeden Versuch dankbar.

--- [2020-10-12 12:35 CEST] Automatisch zusammengeführter Beitrag ---

Scheinbar ist mein Ansatz
[src=php]
function GitFileHash($file2check){
$cont=file_get_contents($file2check);
$cont = str_replace("\r","" ,$cont);
$len = mb_strlen($cont,'8bit');
$toc ="blob " . $len . chr(0) . $cont ;
$tmp = sha1($toc);
return $tmp;
}
[/src]

wohl doch noch Mangelhaft.....
Für kleinere Dateien stimmt mein Hash und der durch git hash-object Erstellte überein. Bei grösseren Dateien (18kB in meinem Fall), schlägt das ganze fehl......

Also nochmal über die Bücher... falls jemand noch eine Idee hat: Nur her damit
 
  • Thread Starter Thread Starter
  • #8
Vielen Dank.
Werde mich mal drin umschauen. Hab noch ein wenig gewürgt, und zumindest eine "einigermassen" funktionierende Hässlichkeit zusammen gebaut (Wer einen stabilen Magen hat darf es sich gerne anschauen: )
 
Würde das str_replace \r durch \r\n, "\n" ersetzen, weil Git alleinstehende \r's stehen lässt. Es wandelt nur eben die Zeilenumbrüche um.
Abgesehen davon habe ich tatsächlich mit Random >500MB-Dateien(mit dd /dev/urandom gebaut) keine Probleme dabei gefunden :unknown:
Hast Du Beispieldateien, an denen man rumbasteln kann? :)
 
  • Thread Starter Thread Starter
  • #10
Hab es zum Testen einfach mal rekursiv durch mein Home-Drive laufen lassen,
dazu jede Datei mit "git hash-object" und dem php Code beworfen. Bei knapp 14GB an Dateien hatte ich nur bei einer Grossen Probleme, die mein php Memory Limit sprengte.
 
Zurück
Oben