Seperti yang saya pahami ketika Git memberikan hash SHA1 ke sebuah file, SHA1 ini unik untuk file berdasarkan isinya.
Akibatnya jika file bergerak dari satu repositori ke yang lain SHA1 untuk file tetap sama karena isinya tidak berubah.
Bagaimana cara Git menghitung intisari SHA1? Apakah itu melakukannya pada konten file terkompresi penuh?
Saya ingin meniru menugaskan SHA1 di luar Git.
Jawaban:
Ini adalah bagaimana Git menghitung SHA1 untuk file (atau, dalam istilah Git, "gumpalan"):
Jadi Anda dapat dengan mudah menghitungnya sendiri tanpa menginstal Git. Perhatikan bahwa "\ 0" adalah byte-NULL, bukan string dua karakter.
Misalnya, hash file kosong:
Contoh lain:
Berikut ini adalah implementasi Python:
sumber
TypeError: Unicode-objects must be encoded before hashing
pengecualian dis.update()
baris pertama .s.update(("blob %u\0" % filesize).encode('utf-8'))
untuk menghindariTypeError
.Goodie kecil: dalam cangkang
sumber
echo -en "blob ${#CONTENTS}\0$CONTENTS" | sha1sum
dengan outputgit hash-object path-to-file
dan mereka menghasilkan hasil yang berbeda. Namun,echo -e ...
menghasilkan hasil yang benar, kecuali ada trailing-
( tidakgit hash-object
menghasilkan karakter trailing). Apakah ini sesuatu yang harus saya khawatirkan?-
digunakan olehsha1sum
jika ia menghitung hash dari stdin dan bukan dari file. Tidak ada yang perlu dikhawatirkan. Namun aneh tentang-n
, yang seharusnya menekan baris baru yang biasanya ditambahkan oleh gema. Apakah file Anda kebetulan memiliki baris terakhir yang kosong, yang Anda lupa tambahkan dalamCONTENTS
variabel Anda ?cat file | sha1sum
alih-alihsha1sum file
(lebih banyak proses dan perpipaan)Anda dapat membuat fungsi bash shell untuk menghitungnya dengan mudah jika Anda tidak menginstal git.
sumber
(stat --printf="blob %s\0" "$1"; cat "$1") | sha1sum -b | cut -d" " -f1
.Lihatlah halaman manual untuk git-hash-object . Anda dapat menggunakannya untuk menghitung hash git dari file tertentu. Saya pikir git memberi makan lebih dari sekedar isi file ke dalam algoritma hash, tapi saya tidak tahu pasti, dan jika itu memberi makan dalam data tambahan, saya tidak tahu apa itu.
sumber
Ini adalah solusi dalam F #.
sumber
Implementasi Python3 lengkap:
sumber
Dalam Perl:
Sebagai perintah shell:
sumber
Dan di Perl (lihat juga Git :: PurePerl di http://search.cpan.org/dist/Git-PurePerl/ )
sumber
Menggunakan Ruby, Anda dapat melakukan sesuatu seperti ini:
sumber
Script Bash kecil yang harus menghasilkan output identik dengan
git hash-object
:sumber
Dalam JavaScript
sumber
Sangat menarik untuk dicatat bahwa jelas Git menambahkan karakter baris baru ke akhir data sebelum hash. File yang berisi tidak lebih dari "Hello World!" mendapat hash gumpalan 980a0d5 ..., yang sama seperti ini:
sumber
git hash-object
. Perhatikan bahwa melakukanecho "Hello World!" | git hash-object --stdin
memberi980a0d5...
, saat menggunakanecho -n
memberi hashc57eff5...
sebagai gantinya.