Git dosyaları nasıl saklar?


225

Git'i öğrenmeye başladım ve bunu yapmak için Git Topluluk Kitabı'nı okumaya başladım ve bu kitapta SVN ve CVS'nin dosyalar arasındaki farkı sakladığını ve git'in tüm dosyaların anlık görüntüsünü sakladığını söylüyorlar.

Ama ne demek istediğini anlık olarak anlayamadım. Git gerçekten her komuttaki tüm dosyaların bir kopyasını yapıyor mu çünkü onların açıklamalarından anladığım bu.

Not: Gitmek için daha iyi bir kaynak varsa, bunu takdir ediyorum.


20
İşte git'in nasıl çalıştığını ayrıntılı olarak açıklayan parlak bir yazı . Aradığınız şey muhtemelen nesne veritabanı hakkındaki §.
greg0ire

Diğer büyük kaynaklara bağlantılar içeren mükemmel makale. Birkaç saat boyunca bunlarla eğlendim.
mihai

Yanıtlar:


275

Git her komut için tüm dosyaların tam bir kopyasını içerir, ancak Git deposunda zaten mevcut olan içerik için, anlık görüntü çoğaltmak yerine söz konusu içeriğe işaret eder.
Bu, aynı içeriğe sahip birkaç dosyanın yalnızca bir kez depolandığı anlamına gelir.

Dolayısıyla, anlık görüntü temel olarak bir dizin yapısının içeriğine atıfta bulunarak bir taahhüttür .

Bazı iyi referanslar:

Git'e git taahhüdü komutuyla projenizin anlık görüntüsünü kaydetmek istediğinizi söylersiniz ve temel olarak projenizdeki tüm dosyaların o noktada nasıl göründüğünün bir tezahürünü kaydeder

Lab 12 , önceki anlık görüntülerin nasıl alınacağını gösterir


Progit kitap bir anlık daha kapsamlı açıklama vardır:

Git ve diğer VCS (Subversion ve arkadaşlar dahil) arasındaki en büyük fark Git'in verileri hakkında düşünme şeklidir.
Kavramsal olarak, diğer sistemlerin çoğu bilgileri dosya tabanlı değişikliklerin bir listesi olarak depolar. Bu sistemler (CVS, Subversion, Perforce, Bazaar, vb.) Sakladıkları bilgileri bir dizi dosya olarak ve zaman içinde her dosyada yapılan değişiklikleri düşünürler.

delta tabanlı VCS

Git, verilerini bu şekilde düşünmez veya saklamaz. Bunun yerine Git, verilerini daha çok bir mini dosya sisteminin anlık görüntüleri gibi düşünüyor.
Projenizin durumunu Git'e her kaydettiğinizde veya kaydettiğinizde, temelde o anda tüm dosyalarınızın nasıl göründüğünün bir resmini çeker ve bu anlık görüntüye bir referans depolar.
Verimli olmak için, dosyalar değişmediyse Git dosyayı tekrar saklamaz - sadece önceden depolanmış olan aynı dosyaya bir bağlantı.
Git, verilerini aşağıdaki gibi düşünüyor:

anlık görüntü tabanlı VCS

Bu Git ve neredeyse diğer tüm VCS'ler arasında önemli bir ayrımdır. Git, sürüm denetiminin hemen hemen her yönünü önceki nesilden kopyalanan çoğu sistemin yeniden gözden geçirmesini sağlar. Bu, Git'i sadece bir VCS'den ziyade üzerine inşa edilmiş inanılmaz derecede güçlü araçlarla mini bir dosya sistemi gibi yapar.


Jan Hudec bu önemli yorumu ekliyor :

Kavramsal düzeyde bu doğru ve önemli olsa da, depolama düzeyinde doğru DEĞİLDİR.
Git depolama için delta kullanır .
Sadece bu değil, aynı zamanda diğer tüm sistemlerden daha verimlidir. Delta sıkıştırması yapmak istediğinde dosya başına geçmiş tutmaz., her blob'u alır, benzer olması muhtemel bazı lekeleri seçer (önceki sürümün en yakın yaklaşımını ve bazılarının sezgisel yöntemini kullanarak), deltaları oluşturmaya çalışır ve en küçük olanı alır. Bu şekilde (çoğu zaman sezgisel yöntemlere bağlı olarak) diğer benzer dosyalardan veya öncekinden daha benzer olan eski sürümlerden yararlanabilir. "Paket penceresi" parametresi, delta sıkıştırma kalitesi için işlem performansına izin verir. Varsayılan (10) genellikle iyi sonuçlar verir, ancak alan sınırlı olduğunda veya ağ aktarımlarını hızlandırmak için git gc --aggressive250 değerini kullanır, bu da çok yavaş çalışmasını sağlar, ancak geçmiş verileri için ekstra sıkıştırma sağlar.


4
@JanHudec iyi bir nokta. Daha fazla görünürlük için yorumunuzu cevaba ekledim.
VonC

1
Git benzeri depolama düzeni, yani karma tabanlı değer deposu için bilgisayar bilimi terimini bilen var mı? (veya benzer bir şey)
Joannes Vermorel

34
OP'nin asıl sorusu bağlamında ilk paragraf gerçekten yanıltıcı görünüyor. Eğer biz bu öğrendikleri nihai paragrafa elde edene O değil, ah evet, aslında Git yapar "mağaza [...] dosyaları arasında farklılıklar. Gerçekten bu bilgi o kadar derin gömülü kontör bayraklı ve etmeseydi. Yani, en teşekkürler en azından cevabınızdaki bir yerde gerçek bir hikaye dahil;)
Josh O'Brien

1
@NickVolynkin Harika! Bu cevapların daha geniş bir kitle bulmasından memnunum.
VonC

1
Başka bir iyi kitap: Git Aşağıdan Yukarı: ftp.newartisans.com/pub/git.from.bottom.up.pdf
Jonas Berlin

46

Git, mantıksal olarak SHA1 altında her dosyayı saklar. Bunun anlamı, bir depoda tam olarak aynı içeriğe sahip iki dosyanız varsa (veya bir dosyayı yeniden adlandırırsanız), yalnızca bir kopya saklanır.

Ancak bu aynı zamanda bir dosyanın küçük bir bölümünü değiştirip kaydettiğinizde, dosyanın başka bir kopyasının saklandığı anlamına gelir. Git'in bunu çözme şekli paket dosyalarını kullanmaktır. Arada sırada, bir repodaki tüm "gevşek" dosyalar (aslında yalnızca dosyalar değil, aynı zamanda exec ve dizin bilgilerini içeren nesneler) bir paket dosyasına toplanır ve sıkıştırılır. Paket dosyası zlib kullanılarak sıkıştırılır. Ve benzer dosyalar da delta sıkıştırılmıştır.

Aynı format, çekerken veya iterken de (en azından bazı protokollerde) kullanılır, bu nedenle bu dosyaların tekrar sıkıştırılması gerekmez.

Bunun sonucu, tüm sıkıştırılmamış çalışma kopyasını, sıkıştırılmamış son dosyaları ve sıkıştırılmış eski dosyaları içeren bir git deposunun, genellikle çalışma kopyasının boyutundan iki kat daha küçük, nispeten küçük olmasıdır. SVN, geçmişi yerel olarak depolamasa da, aynı dosyalara sahip SVN deposundan daha küçük olduğu anlamına gelir.


1
ah yani mercurial daha fazla yer verimli
Ben
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.