İçeriğe geç
edumintsBlog
Yazılım3 dk okuma

Git Bir Fark Takipçisi Değildir: Blob, Tree, DAG Commit ve Index Mimarisi

Kaynak: dev.to

Paylaş
İçindekiler 3 başlık

Çoğu yazılımcıya Git'in nasıl çalıştığını sorduğunuzda tanıdık bir yanıt alırsınız: "Git değişiklikleri takip eder; dosyayı düzenleyip commit ettiğinizde eski ve yeni dosya arasındaki farkı hesaplar ve yamayı kaydeder." git diff veya git show çalıştırdığınızda terminalde yeşil eklemeler ve kırmızı silmeler gördüğünüz için bu mantıklı bir zihinsel modeldir. CVS ve Subversion (SVN) tam olarak böyle çalışıyordu: bir ana dosyayı saklayıp zaman içindeki delta yamalarını eklerlerdi.

Ancak Git kesinlikle böyle çalışmaz. Git dosya farklarını takip etmez, yamaları saklamaz ve dahili bir "dosya yeniden adlandırma" kavramına dahi sahip değildir. Porselen komut satırının altında Git çok daha zariftir: anlık görüntü (snapshot) ağaçlarından oluşan Yönlendirilmiş Asiklik Grafik (DAG) yapısının altında yer alan, değiştirilemez (immutable) ve içerik-adresli bir anahtar-değer nesne deposudur. Geliştiriciler Git'i sihirli bir kutu gibi gördüklerinde git rebase veya detached HEAD durumları korkutucu gelebilir. Ancak .git klasörünün veri modelini anladığınızda bu gizem çözülür.

1. .git Klasörünün İçine Bakış: İçerik-Adresli Nesne Deposu#

Boş bir klasörde git init çalıştırdığınızda Git bir sunucu kurmaz; yalnızca .git adında gizli bir dizin oluşturur. En kritik bölüm Git'in veritabanı olan .git/objects klasörüdür. Projenizdeki her dosya, dizin ve commit burada dört temel nesne türünden biri olarak saklanır:

  • Blob: Dosyanın ham içeriğini sıkıştırılmamış bayt akışı olarak saklar. Dosya adını, yolunu veya izinlerini tutmaz.
  • Tree: Dizinleri temsil eder. Dosya adlarını ve izinlerini blob'ların veya alt ağaçların kriptografik özetlerine (hash) eşler.
  • Commit: Kök ağacı, üst commit özetlerini, yazarı ve commit mesajını işaret eden anlık görüntü göstergesidir.
  • Annotated Tag: Bir commit'i kalıcı olarak işaret eden; etiketleyen, tarih ve mesaj içeren göstergedir.

Kriptografik Özetleme (İçerik-Adresleme)#

Git her nesneyi kriptografik özetiyle (40 karakterlik SHA-1 veya SHA-256) tanımlar. Düşük seviyeli tesisat komutunu inceleyelim:

echo "hello world" | git hash-object -w --stdin
3b18e512dba79e4c8300dd08aeb37f8e728b8dad

-w bayrağı nesneyi doğrudan .git/objects içine yazar. Git ham verinin başına nesne türünü (blob), boşluk, bayt uzunluğu ve boş baytı (\0) ekler:

  • header = "blob 12\0"
  • content = "hello world\n"
  • sha1("blob 12\0hello world\n") = 3b18e512dba79e4c8300dd08aeb37f8e728b8dad

Bu hesaplamada dosya adının bulunmadığına dikkat edin. Dosyayı README.md veya main.py yapsanız da içerik aynı kaldığı sürece üretilen nesne özeti aynıdır.

Yazılım Geliştirme Açısından Pratik Çıkarımlar#

  • Veri Tekilleştirme (Deduplication): İçerik-adresleme sayesinde aynı içeriğe sahip dosyalar farklı isimlerde olsa dahi depoda tek bir blob olarak tutulur.
  • Veri Değişmezliği: Kriptografik özetleme sayesinde geçmişteki verilerin gizlice bozulması veya değiştirilmesi imkansızdır.
  • Zihinsel Model Netliği: Git'i farklar yerine anlık durum ağaçları olarak modellemek, rebase ve reset işlemlerini güvenli kılar.

Kaynak ve atıf

Bu yazı, dev.to üzerinde yayımlanan içerikten yararlanılarak Edumints tarafından yapay zekâ desteğiyle Türkçe hazırlandı. Ayrıntılar ve yazarların kendi anlatımı için orijinaline bakabilirsin:

  • dev.to/smtahosin/git-isnt-a-diff-tracker-how-blobs-trees-dag-commits-and-the-index-actually-work-under-the-hood-19eo