Git'te Commit Boyutları ve Etkisi: Ne Kadar Büyük Olabilir?

Git'te Commit Boyutları ve Etkisi: Ne Kadar Büyük Olabilir?
audio-thumbnail
Git'te Commit Boyutları ve Etkisi: Ne Kadar Büyük Olabilir?
0:00
/0

Git'te Commit Boyutları ve Etkisi: Ne Kadar Büyük Olabilir?

Git, geliştiricilerin kodlarını sürümlemesinde kullanılan en yaygın versiyon kontrol sistemlerinden biridir. Ancak birçok geliştirici, Git commit'lerinin boyutu hakkında sadece “çok küçük” diye düşünür. Ancak gerçek şu ki, bir commit’in boyutu ne kadar büyük olabilir ve bu durum projenizin performansına ne kadar etki edebilir?

Git’in İçinde Ne Oluyor?

Git, dosyaları "nesneler" (objects) olarak saklar. Bu nesneler, zlib ile sıkıştırılmış bir biçimde depolanır. Yani, bir commit’in boyutu sadece dosya boyutundan değil, aynı zamanda dosyaların sıkıştırılabilirliğinden de etkilenir. Yani, tekrar eden verileri taşıyan dosyalar daha küçük boyutta kaydedilirken, tekrar eden veri içermeyen dosyalar daha fazla yer kaplar.

Git ayrıca, bu nesneleri depo içinde birleştirerek daha verimli depolama alanları olan packfiles oluşturur. Bu sayede, aynı dosyaları birden fazla commit'te paylaşan projelerde, depo boyutu önemli ölçüde azalır.

Küçük Commit'lerde Ne Olur?

İlk olarak, bir boş Git deposu oluşturalım:

git init

Bu işlem, .git dizini oluşturur. Boyutu sadece 64.828 baytdir.

Şimdi, 250 tane küçük dosya oluşturup bir commit yapalım:

for d in {1..5}; do mkdir $d; for f in {1..50}; do echo foo > $d/$f; done; done
git add .
git commit -m 'initial commit'

Bu işlem sonrası .git dizininin boyutu 112.468 bayt’a ulaşıyor. Yani, 250 dosyayı içeren bir commit, depoda 47.640 bayt ekler.

Ama burada önemli bir nokta var: Birçok küçük dosya biriktirildiğinde, her commit için git, bu dosyaların ağaç yapısını (tree), dosya içeriklerini (blob) ve commit bilgisini (commit) depolamak zorunda kalır. Bu nedenle, çok sayıda küçük dosya varsa, her değişiklik için büyük bir boyut eklenir.

Tek Bir Dosyaya Değişiklik Yapıldığında Ne Olur?

Şimdi, sadece bir dosyaya küçük bir değişiklik yapalım:

echo bar > 1/1
git commit -am 'changed 1/1'

Bu işlem sonrası .git dizininin boyutu 129.613 bayt’a çıkar. Yani, 17.145 bayt eklenmiş olur. Ancak bu, sadece 3 baytlık bir değişikliktir.

Bu durumda, Git’in depolama mekanizması, bu küçük değişikliği saklamak için bir sürü nesne oluşturur:

  • Bir commit nesnesi
  • Bir ağac (tree) nesnesi (dosyaların hiyerarşik yapısı)
  • Dosya içeriği (blob) nesnesi

Bu yüzden, küçük değişiklikler bile büyük bir boyut ekleyebilir, çünkü her değişiklik için yeni nesneler yaratılır.

Tek Dosyalı Bir Repo İçin Durum Nedir?

Şimdi, sadece bir dosya olan bir repo oluşturalım:

git init
echo foo > foo
git add foo
git commit -m 'initial'

Bu durumda .git boyutu 94.208 bayt olur. Şimdi bir değişiklik yapalım:

echo bar > foo
git commit -am 'change1'

Bu işlem sonrası .git boyutu 102.917 bayt’a çıkar. Yani, 8.709 bayt eklenir.

Bu sonuç, çok sayıda dosya içeren bir projeye göre daha küçük bir eklenme miktarı olduğunu gösterir. Çünkü burada bir ağaç yapısı, çok sayıda dosya değil, sadece bir dosya var. Bu da git’in kaydetmesi gereken nesnelerin sayısını azaltır.

Büyük Dosyaların Etkisi

Şimdi, bir 583.840 baytlık ikili dosya (örneğin bir uygulama binası) ekleyelim:

cp /usr/bin/librewolf .
git add .
git commit -m 'added librewolf'

Bu işlem sonrası .git boyutu 400.790 bayt olur. Yani, 583.840 bayt’lık bir dosya, 297.873 bayt eklemiştir.

Burada dikkat edilmesi gereken şey, ikili dosyaların sıkıştırılabilirliğinin düşük olmasıdır. Ancak, yine de git, zlib ile sıkıştırma yaparak dosyayı daha küçük boyutta saklar.

Şimdi ise 16.415.223 baytlık (16.2 MB) bir kaynak dosyası deneyelim:

cp /usr/src/linux…mask.h .
git add .
git commit -m 'huge source'

Bu işlem sonrası .git boyutu 2.022.978 bayt’a çıkar. Yani, 1.622.188 bayt eklenir.

Bu sonuç, metin dosyalarının çok iyi sıkıştırılabilir olduğunu gösterir. Çünkü aynı dosya, 16.2 MB’lık bir uzunlukta iken, git bunu 1.6 MB civarında bir boyuta sıkıştırır.

Sonuç: Commit Boyutu Ne Kadar Olabilir?

Git’te bir commitin boyutu, dosya boyutuna, sıkıştırılabilirliğe ve projenin yapıya bağlı olarak değişir. Ancak en önemlisi:

  • Küçük dosyalar ve çok sayıda dosya varsa, her commit için büyük bir boyut eklenir, çünkü her değişiklik için yeni nesneler oluşturulur.
  • Büyük dosyalar için, git zlib ile sıkıştırma yaparak depo boyutunu azaltır, ancak büyük dosyaların eklenmesi halinde, depo boyutunda önemli bir artış olabilir.
  • Tek dosyalı projelerde, commit boyutları daha küçük olur çünkü nesne sayısı azalır.

Peki Bu Ne Anlama Gelir?

Bir Git deposunda çok sayıda küçük dosya varsa ve her değişiklikte bu dosyalardan biri değiştirilirse, depo boyutu hızla artar. Bu durum, projenin performansını düşürür – özellikle büyük bir depo ile çalışırken, git clone, git fetch, git status gibi komutlar daha yavaş çalışır.

Bu nedenle:

  • Büyük dosyaları git'e eklememek (örneğin large.bin, video, image dosyaları) en iyi uygulamadır.
  • Git LFS (Large File Storage) gibi araçları kullanarak büyük dosyaları depolayabilirsiniz.
  • Küçük dosyaları bir araya getirerek (örneğin bir config dosyası içinde birden fazla ayar) depo boyutunu kontrol edebilirsiniz.

Sonuç

Git, verimli bir depolama sistemi olarak tasarlanmıştır. Ancak commit boyutu, projenin yapısına ve dosyaların içeriğine göre değişir. Küçük değişiklikler bile, çok sayıda dosya varsa, depo boyutunda önemli artışlar oluşturabilir. Bu nedenle, Git depolarının boyutunu yönetmek için doğru stratejiler geliştirilmesi gerekir.

Bir commit ne kadar büyük olursa olsun, Git’in sıkıştırma mekanizması, veri kaybı olmadan depo boyutunu optimize eder. Ancak, büyük dosyaların eklenmesi ve çok sayıda küçük dosya kullanımı, uzun vadede projenin performansını etkileyebilir. Bu yüzden, Git’te boyut yönetimi, geliştirme sürecinin önemli bir parçasıdır.