Bagaimana git menyimpan file?

225

Saya baru saja mulai belajar git dan untuk itu saya mulai membaca Buku Komunitas Git , dan dalam buku ini mereka mengatakan bahwa SVN dan CVS menyimpan perbedaan antara file dan bahwa git menyimpan snapshot dari semua file.

Tapi saya tidak benar-benar mendapatkan apa yang mereka maksudkan dengan snapshot. Apakah git benar-benar membuat salinan dari semua file di setiap commit karena itulah yang saya mengerti dari penjelasan mereka.

PS: Kalau ada yang punya sumber yang lebih baik untuk belajar git saya akan sangat menghargainya.

mffffaha
sumber
20
Inilah postingan cemerlang yang menjelaskan secara detail bagaimana git bekerja. Apa yang Anda cari mungkin adalah § tentang objek database.
greg0ire
Artikel luar biasa yang berisi tautan ke sumber daya hebat lainnya. Saya sudah bersenang-senang dengan ini selama beberapa jam.
mihai
2
Saya menemukan artikel yang sangat bagus ini menggambarkan git dari dalam ke luar: maryrosecook.com/blog/post/git-from-the-inside-out
Sumudu

Jawaban:

275

Git memang menyertakan untuk setiap komit salinan lengkap dari semua file, kecuali bahwa, untuk konten yang sudah ada di repo Git, snapshot hanya akan menunjuk ke konten yang dikatakan daripada menduplikatnya.
Itu juga berarti bahwa beberapa file dengan konten yang sama disimpan hanya sekali.

Jadi snapshot pada dasarnya adalah komit, merujuk pada isi struktur direktori.

Beberapa referensi yang bagus adalah:

Anda memberi tahu Git bahwa Anda ingin menyimpan snapshot dari proyek Anda dengan perintah git commit dan pada dasarnya merekam manifes apa yang terlihat dari semua file dalam proyek Anda pada saat itu

Lab 12 menggambarkan cara mendapatkan foto sebelumnya


The book progit memiliki gambaran yang lebih komprehensif snapshot:

Perbedaan utama antara Git dan VCS lainnya (termasuk Subversion dan teman-temannya) adalah cara Git berpikir tentang datanya.
Secara konseptual, sebagian besar sistem lain menyimpan informasi sebagai daftar perubahan berbasis file. Sistem ini (CVS, Subversion, Perforce, Bazaar, dan sebagainya) memikirkan informasi yang mereka simpan sebagai satu set file dan perubahan yang dibuat untuk setiap file dari waktu ke waktu

VCS berbasis delta

Git tidak memikirkan atau menyimpan datanya dengan cara ini. Sebagai gantinya, Git berpikir tentang datanya lebih seperti sekumpulan snapshot dari sistem file mini.
Setiap kali Anda berkomitmen, atau menyimpan status proyek Anda di Git, pada dasarnya ia mengambil gambar seperti apa semua file Anda pada saat itu dan menyimpan referensi ke snapshot itu.
Agar efisien, jika file tidak berubah, Git tidak menyimpan file lagi — hanya tautan ke file identik sebelumnya yang telah disimpannya.
Git berpikir tentang datanya seperti di bawah ini:

VCS berbasis snapshot

Ini adalah perbedaan penting antara Git dan hampir semua VCS lainnya. Itu membuat Git mempertimbangkan kembali hampir setiap aspek kontrol versi yang sebagian besar sistem lain disalin dari generasi sebelumnya. Ini membuat Git lebih seperti sistem file mini dengan beberapa alat yang sangat kuat yang dibangun di atasnya, bukan hanya VCS.


Jan Hudec menambahkan ini komentar penting :

Walaupun itu benar dan penting pada tingkat konseptual, itu TIDAK benar pada tingkat penyimpanan.
Git memang menggunakan delta untuk penyimpanan .
Tidak hanya itu, tetapi lebih efisien di dalamnya daripada sistem lainnya. Karena itu tidak menyimpan riwayat per file, ketika itu ingin melakukan kompresi delta, dibutuhkan setiap gumpalan, memilih beberapa gumpalan yang cenderung serupa (menggunakan heuristik yang mencakup perkiraan terdekat dari versi sebelumnya dan beberapa lainnya), mencoba untuk menghasilkan delta dan memilih yang terkecil. Cara ini dapat (seringkali, tergantung pada heuristik) memanfaatkan file serupa lainnya atau versi yang lebih lama yang lebih mirip dari sebelumnya. Parameter "paket jendela" memungkinkan kinerja perdagangan untuk kualitas kompresi delta. Default (10) umumnya memberikan hasil yang layak, tetapi ketika ruang terbatas atau untuk mempercepat transfer jaringan, git gc --aggressivemenggunakan nilai 250, yang membuatnya berjalan sangat lambat, tetapi memberikan kompresi tambahan untuk data histori.

VONC
sumber
4
@JanHudec poin bagus. Saya telah memasukkan komentar Anda dalam jawaban untuk lebih banyak visibilitas.
VonC
1
Adakah yang tahu istilah ilmu komputer untuk pola penyimpanan mirip Git, alias toko nilai berbasis hash? (atau yang serupa)
Joannes Vermorel
34
Dalam konteks pertanyaan aktual OP, paragraf pertama tampaknya sangat menyesatkan. Ini tidak sampai Anda mendapatkan ke paragraf akhir yang kita belajar bahwa, oh ya, sebenarnya Git melakukan "toko [...] perbedaan antara file. Benar-benar berharap info yang ditandai di bagian atas dan tidak terkubur begitu dalam. Yang mengatakan, terima kasih pada paling tidak memasukkan kisah nyata di suatu tempat dalam jawaban Anda;)
Josh O'Brien
1
@NickVolynkin Hebat! Saya senang jawaban itu menemukan audiens yang lebih besar.
VonC
1
Buku bagus lainnya: Git From The Bottom Up: ftp.newartisans.com/pub/git.from.bottom.up.pdf
Jonas Berlin
46

Git secara logis menyimpan setiap file di bawah SHA1-nya. Artinya adalah jika Anda memiliki dua file dengan konten yang persis sama di repositori (atau jika Anda mengganti nama file), hanya satu salinan yang disimpan.

Tetapi ini juga berarti bahwa ketika Anda memodifikasi sebagian kecil file dan melakukan, salinan lain dari file tersebut disimpan. Cara git memecahkan ini menggunakan file paket. Kadang-kadang, semua file "longgar" (sebenarnya, bukan hanya file, tetapi objek yang mengandung komit dan informasi direktori juga) dari repo dikumpulkan dan dikompresi menjadi file paket. File paket dikompres menggunakan zlib. Dan file serupa juga dikompresi delta.

Format yang sama juga digunakan ketika menarik atau mendorong (setidaknya dengan beberapa protokol), sehingga file-file tersebut tidak perlu dikompres lagi.

Hasil dari hal ini adalah repositori git, yang berisi seluruh copy pekerjaan yang tidak dikompresi, file terbaru yang tidak dikompresi, dan file yang lebih lama dikompres biasanya relatif kecil, dua kali lebih kecil dari ukuran copy pekerjaan. Dan ini berarti lebih kecil dari repo SVN dengan file yang sama, meskipun SVN tidak menyimpan sejarah secara lokal.

svick
sumber
1
ah begitu lincah lebih efisien ruang
Ben