webentwicklung-frage-antwort-db.com.de

Wie ordne ich Git SHA1 einer Datei ohne Git zu?

So wie ich es verstehe, wenn Git einer Datei einen SHA1-Hash zuweist, ist dieser SHA1 für die Datei aufgrund ihres Inhalts eindeutig. 

Wenn eine Datei von einem Repository in ein anderes verschoben wird, bleibt der SHA1 für die Datei derselbe, da der Inhalt nicht geändert wurde. 

Wie berechnet Git den SHA1-Verdau? Macht es den vollen Inhalt der unkomprimierten Datei? 

Ich möchte die Zuweisung von SHA1s außerhalb von Git nacheifern.

137
git-noob

So berechnet Git den SHA1 für eine Datei (oder, in Git ausgedrückt, einen "Blob"):

sha1("blob " + filesize + "\0" + data)

Sie können es also problemlos selbst berechnen, ohne dass Git installiert ist. Beachten Sie, dass "\ 0" das NULL-Byte ist, keine aus zwei Zeichen bestehende Zeichenfolge.

Zum Beispiel der Hash einer leeren Datei:

sha1("blob 0\0") = "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"

$ touch empty
$ git hash-object empty
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391

Ein anderes Beispiel:

sha1("blob 7\0foobar\n") = "323fae03f4606ea9991df8befbb2fca795e648fa"

$ echo "foobar" > foo.txt
$ git hash-object foo.txt 
323fae03f4606ea9991df8befbb2fca795e648fa

Hier ist eine Python-Implementierung:

from hashlib import sha1
def githash(data):
    s = sha1()
    s.update("blob %u\0" % len(data))
    s.update(data)
    return s.hexdigest()
248
Ferdinand Beyer

Ein kleines Bonbon: in Shell

echo -en "blob ${#CONTENTS}\0$CONTENTS" | sha1sum
18
knittl

Sie können eine bash-Shell-Funktion erstellen, um diese ganz einfach zu berechnen, wenn Sie git nicht installiert haben.

git_id () { printf 'blob %s\0' "$(ls -l "$1" | awk '{print $5;}')" | cat - "$1" | sha1sum | awk '{print $1}'; }
8
CB Bailey

Schauen Sie sich die Manpage für git-hash-object 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 ob es einspeist In zusätzlichen Daten weiß ich nicht, was es ist.

4
Dale Hagglund

Vollständige Python3-Implementierung:

import os
from hashlib import sha1

def hashfile(filepath):
    filesize_bytes = os.path.getsize(filepath)

    s = sha1()
    s.update(("blob %u\0" % filesize_bytes).encode('utf-8'))

    with open(filepath, 'rb') as f:
        s.update(f.read())

    return s.hexdigest() 
2
Tomer
/// Calculates the SHA1 for a given string
let calcSHA1 (text:string) =
    text 
      |> System.Text.Encoding.ASCII.GetBytes
      |> (new System.Security.Cryptography.SHA1CryptoServiceProvider()).ComputeHash
      |> Array.fold (fun acc e -> 
           let t = System.Convert.ToString(e, 16)
           if t.Length = 1 then acc + "0" + t else acc + t) 
           ""
/// Calculates the SHA1 like git
let calcGitSHA1 (text:string) =
    let s = text.Replace("\r\n","\n")
    sprintf "blob %d%c%s" (s.Length) (char 0) s
      |> calcSHA1

Dies ist eine Lösung in F #.

2
forki23

Und in Perl (siehe auch Git :: PurePerl unter http://search.cpan.org/dist/Git-PurePerl/ )

use strict;
use warnings;
use Digest::SHA1;

my @input = <>;

my $content = join("", @input);

my $git_blob = 'blob' . ' ' . length($content) . "\0" . $content;

my $sha1 = Digest::SHA1->new();

$sha1->add($git_blob);

print $sha1->hexdigest();
1
Alec the Geek

Ein kleines Bash-Skript, das eine identische Ausgabe zu git hash-object erzeugen sollte:

#!/bin/sh
( 
    echo -en 'blob '"$(stat -c%s "$1")"'\0';
    cat "$1" 
) | sha1sum | cut -d\  -f 1
1
Fordi

In Perl:

#!/usr/bin/env Perl
use Digest::SHA1;

my $content = do { local $/ = undef; <> };
print Digest::SHA1->new->add('blob '.length($content)."\0".$content)->hexdigest(), "\n";

Als Shell-Befehl:

Perl -MDigest::SHA1 -E '$/=undef;$_=<>;say Digest::SHA1->new->add("blob ".length()."\0".$_)->hexdigest' < file
1
dolmen

Mit Ruby können Sie so etwas tun:

require 'digest/sha1'

def git_hash(file)
  data = File.read(file)
  size = data.bytesize.to_s
  Digest::SHA1.hexdigest('blob ' + size + "\0" + data)
end
1
Leif

In JavaScript

const crypto = require('crypto')
const bytes = require('utf8-bytes')

function sha1(data) {
    const shasum = crypto.createHash('sha1')
    shasum.update(data)
    return shasum.digest('hex')
}

function shaGit(data) {
    const total_bytes = bytes(data).length
    return sha1(`blob ${total_bytes}\0${data}`)
}
0
EnZo