Mengapa repositori Git / Mercurial menggunakan lebih sedikit ruang?

15

Saya telah membaca beberapa diskusi di sini dan di SO bahwa repositori DVCS menggunakan sekitar ruang yang sama atau kurang dari bagian-bagiannya yang terpusat. Saya mungkin telah melewatkannya, tetapi saya belum menemukan penjelasan yang baik mengapa itu terjadi. Adakah yang tahu

Alex Florescu
sumber
1
Saya belum, terima kasih! Jadi saya mengerti dari mereka bahwa ada dua jawaban: kompresi menggunakan zlib dan menyimpan objek sebagai paket jika memungkinkan. Contoh-contoh dari Mozilla juga luar biasa!
Alex Florescu
1
@ Alex Tidak, itu merindukan alasan utama. SVN menyimpan snapshot lengkap, Git dan Mercurial hanya menyimpan revisi HEAD dan diffs. Menggunakan kompresi konvensional dapat memberi Anda tingkat kasus terbaik kompresi sekitar 60–80%. Menggunakan diffs bisa memberi Anda sebanyak 99%. Angka-angka ini ditarik dari pantat saya - bilangan real mungkin berbeda; yang kecenderungan akan meskipun sama.
Konrad Rudolph
@KonradRudolph, bukankah itu semua tentang packfiles?
Alex Florescu
@ Alex Tidak juga. Sejauh yang saya tahu packfile juga mengemas beberapa file menjadi satu. Ini belum tentu terkait.
Konrad Rudolph

Jawaban:

18

Dari pengalaman saya sendiri, semua pernyataan berikut ini benar:

  • Git sangat efisien dalam menyimpan file teks, dan hanya menyimpan file-file ini yang diubah. jadi ketika melakukan perbandingan SVN dan Git untuk membandingkan ukuran repositori, mereka mungkin serupa, atau bahkan mungkin ada keuntungan kecil untuk Git.
  • Ini sepenuhnya salah jika Anda membandingkan ukuran repositori di mana sejumlah besar file adalah file kantor (seperti kata MS, excel, powerpoint, ...). Di sini Git juga menyimpan salinan lengkap, yang berarti bahwa 10 perubahan kecil pada slide powerpoint menghasilkan 10 salinan lengkap, di mana Subversion hanya menyimpan diff biner, yang mungkin merupakan faktor 100 lebih kecil.

Jika Anda membandingkan lokasi checkout (yang merupakan repositori dengan Git), ceritanya sangat berbeda:

  • Subversion menyimpan setiap file salinan lengkap, sehingga ukuran lokasi checkout Anda biasanya 2 kali ukuran file itu sendiri.
  • Git menyimpan histori lengkap repositori secara lokal, jadi tergantung pada ukuran histori, ini mungkin lebih kecil atau lebih besar dari pada salinan checkout Subversion.

Jika Anda membandingkan jumlah byte yang harus Anda unduh atau unggah, itu berbeda lagi.

  • Subversi biasanya mengirim atau menerima lebih sedikit byte, karena hanya mengirim perbedaan. Itu harus dilakukan pada setiap komit dan pembaruan.
  • Git harus mendapatkan seluruh repositori (awalnya), dan kemudian mengirimkan file lengkap (terkompresi?) Yang tidak berbeda untuk file teks, tetapi mungkin berbeda untuk file biner. Dan ya, Git hanya melakukan itu ketika Anda mendorong atau menarik sesuatu ke repositori jarak jauh.

Jadi pada akhirnya, Anda membandingkan apel dengan jeruk, dan tergantung pada apa yang ingin Anda lakukan dengan Subversion atau Git, hasilnya mungkin berbeda.


@ jk bertanya tentang salinan lengkap atau perbedaan biner, dan saya tidak bisa menjawab pertanyaan itu. Saya bertanya kepada Matthew McCullough yang memberikan lokakarya Git akhir-akhir ini di Jax 2012 (yang saya kunjungi). Dia telah meluangkan waktu (terima kasih banyak untuknya) untuk menjelaskan dengan intis rinci pekerjaan batin Git. Jadi ya, ada kompresi yang bekerja di sana (dan saya akan melakukan percobaan dengan file microsoft office juga dan akan membandingkannya dengan intinya), tetapi tidak, kompresi dilakukan pada seluruh file. Mengutip dari intinya:

Objek yang longgar ditulis dalam format terkompresi, tetapi non-delta pada saat setiap komit.

mliebelt
sumber
1
apakah Anda yakin bahwa git menyimpan salinan lengkap file kantor? Saya pikir itu juga menyimpan diff biner. tentu saja masalah sebenarnya dengan file-file semacam ini adalah mereka sering sudah dikompres sehingga perubahan kecil dapat menyebabkan seluruh file berubah
jk.
2
Tanya seseorang (melalui email) yang tahu lebih banyak dari saya, dan akan memasukkan jawabannya dalam jawaban saya.
mliebelt
6
Git memperlakukan file teks dan biner dengan cara yang persis sama dalam semua hal sehubungan dengan penyimpanan. Objek yang longgar vs dikemas tidak terkait dengan teks vs biner. Alasan file biner sering menghasilkan perbedaan jauh lebih besar daripada file teks adalah bahwa banyak format biner (termasuk semua format kantor baru) sudah dikompresi dan bahkan perubahan kecil dalam konten sering menyebabkan perubahan besar dalam gumpalan biner yang dihasilkan. Ini sama-sama menjadi perhatian git dan subversi, tetapi subversi hanya mengambil penalti di server, sementara git ada di mana-mana.
Jan Hudec
4
Objek longgar vs dikemas tidak ada hubungannya dengan teks vs biner. Ini adalah amortisasi dari pekerjaan sulit untuk menemukan perbedaan biner. Kecepatan adalah fitur penting dari git, jadi selama operasi reguler, git hanya membuka ritsleting data baru dan menamparnya di repositori. Ini benda longgar. Daripada ketika Anda memintanya dengan menelepon git gcatau terlalu banyak benda longgar terakumulasi, ia menemukan kandidat yang baik untuk melakukan kompres-delta terhadap mereka (git dapat berbeda dengan versi lain sebelumnya), menyimpan delta dalam "paket" dan menghapus objek yang longgar.
Jan Hudec
3
Bagi mereka yang tertarik dengan angka dunia nyata: Saya hanya membandingkan dua copy pekerjaan dari repo yang sama persis. Salinan kerja SVN sekitar 2,9 GB, salinan kerja GIT adalah sekitar 0,8 GB.
JensG