Hash SHA1 yang disimpan di objek pohon (seperti yang dikembalikan oleh git ls-tree
) tidak cocok dengan hash SHA1 dari konten file (seperti yang dikembalikan oleh sha1sum
)
$ git cat-file blob 4716ca912495c805b94a88ef6dc3fb4aff46bf3c | sha1sum
de20247992af0f949ae8df4fa9a37e4a03d7063e -
Bagaimana cara git menghitung hash file? Apakah itu memampatkan konten sebelum menghitung hash?
Jawaban:
$ echo -e 'blob 14\0Hello, World!' | shasum 8ab686eafeb1f44702738c8b0f24f2567c36da6d
Sumber: http://alblue.bandlem.com/2011/08/git-tip-of-week-objects.html
sumber
echo 'Hello, World!' | git hash-object --stdin
. Secara opsional, Anda dapat menentukan--no-filters
untuk memastikan tidak ada konversi crlf yang terjadi, atau menetapkan--path=somethi.ng
untuk membiarkan git menggunakan filter yang ditentukan melaluigitattributes
(juga @ user420667). Dan-w
untuk benar-benar mengirimkan blob ke.git/objects
(jika Anda berada dalam git repo).echo -e 'blob 16\0Hello, \r\nWorld!' | shasum
==echo -e 'Hello, \r\nWorld!' | git hash-object --stdin --no-filters
dan itu juga akan setara dengan\n
dan 15.echo
menambahkan baris baru ke keluaran, yang juga diteruskan ke git. Itulah mengapa 14 karakternya. Untuk menggunakan gema tanpa baris baru, tulisecho -n 'Hello, World!'
Saya hanya memperluas jawaban dengan
@Leif Gruenwoldt
dan merinci apa yang ada dalam referensi yang disediakan oleh@Leif Gruenwoldt
Lakukan sendiri..
Bagaimana GIT menghitung hash komitnya
Teks
blob⎵
adalah awalan konstan dan\0
juga konstan dan merupakanNULL
karakter. The<size_of_file>
dan<contents_of_file>
bervariasi tergantung pada file.Lihat: Apa format file dari objek git commit?
Dan itu semua!
Tapi tunggu!, apakah Anda memperhatikan bahwa
<filename>
bukan merupakan parameter yang digunakan untuk komputasi hash? Dua file berpotensi memiliki hash yang sama jika isinya sama pada tanggal dan waktu pembuatan dan namanya. Inilah salah satu alasan Git menangani pemindahan dan mengganti nama dengan lebih baik daripada sistem kontrol versi lain.Lakukan Sendiri (Ext)
catatan:
Tautan tidak menyebutkan bagaimana
tree
objek di-hash. Saya tidak yakin dengan algoritme dan parameternya namun dari pengamatan saya mungkin menghitung hash berdasarkan semuablobs
dantrees
(hash mereka mungkin) yang dikandungnyasumber
SHA1("blob" + <size_of_file>
- apakah ada karakter spasi tambahan antara gumpalan dan ukuran? Apakah ukuran desimal? Apakah ini diawali nol?git hash-object
Ini adalah cara cepat untuk memverifikasi metode pengujian Anda:
Keluaran:
di mana
sha1sum
di GNU Coreutils.Kemudian turun untuk memahami format setiap jenis objek. Kami telah membahas yang sepele
blob
, berikut ini yang lainnya:sumber
$(printf "\0$s" | wc -c)
. Perhatikan karakter kosong yang ditambahkan. Artinya, jika string adalah 'abc' dengan karakter kosong yang ditambahkan di depan panjangnya akan menghasilkan 4, bukan 3. Kemudian hasil dengan sha1sum cocok dengan git hash-object.Berdasarkan jawaban Leif Gruenwoldt , berikut adalah fungsi shell pengganti
git hash-object
:Uji:
sumber
Saya membutuhkan ini untuk beberapa pengujian unit di Python 3 jadi saya pikir saya akan meninggalkannya di sini.
Saya tetap menggunakan
\n
akhiran baris di mana-mana tetapi dalam beberapa situasi Git mungkin juga mengubah akhir baris Anda sebelum menghitung hash ini sehingga Anda mungkin perlu.replace('\r\n', '\n')
di sana juga.sumber