Git Nasıl Çalışır?

Bu flood’da sizlere Git versiyon kontrol sisteminin akıllara durgunluk veren basit ve usta işi mimarisi anlatacağım.

Git, Linus Torvalds’ın Linux Kernel’i yönetecek adamakıllı bir versiyon kontrol sistemi bulamaması ve “İki haftada SVN ve CVS’den daha kullanılabilir bir sistem yazabilirim” demesi ve sonunda gerçekten de iki haftada yazması sonucu ortaya çıktı.

Git, kısaca tanıyacağımız bu mimarinin sağladığı esneklik ve optimizasyonlar sayesinde 2–3 yıl gibi kısa bir sürede önce açık kaynaklı projeler tarafından benimsendi. Daha sonra ise en kurumsal olanımızın bile ana versiyon kontrol sistemi oldu :-)

Linus’un OS deneyiminden olsa gerek ki Git, yönettiği repo ile ilgili bilgileri dosya sisteminde (repo altındaki .git adlı klasörde) tutmakta ve bir veritabanı kullanmamaktadır. Hepimizin bildiği dağıtık yapıda olma özelliği bu sayede çok kolay bir şekilde sağlanmıştır.

Commit’ler, kaynak dosya içerikleri (blob), dosya/klasör yapısı (tree) ve tag'ler Git tarafından birer obje olarak değerlendirir.

Git, bu objelerin SHA1 hash’ini alarak dosya sisteminde oluşan SHA1'i dosyanın ismi olarak kullanıp bir dosya yaratır ve içeriği kaydeder.

Şimdi örnek bir Git repo üzerinden Git’in nasıl çalıştığına detaylı olarak bakalım. Öncelikle basit bir repo yaratalım.

Git’in her şeyi dosya sistemindeki git klasöründe tuttuğunu söylemiştik. İlk olarak bu klasörün içeriğine bakalım.

Git’in objelerin SHA1 hash’ini kullandığını söylemiştik, o zaman bu hex karakterli dosyalar objeleri tutuyor olmalı.

Dosyalar sıkıştırılarak saklansa da içeriklerini ekrana dökmek için git cat-file -p <hash-of-object> komutunu kullanabiliriz.

Şimdi README dosyasında küçük bir değişiklik yapalım.

Ve şimdi de .git klasöründe az önce yaptığımız commit'in sonucu meydana gelen değişiklikleri gözlemleyelim.

Yukarıda görebileceğiniz üzere dosyamızın (obje) içeriğinde bir değişiklik yaptık. Yapılan commit'le birlikte dosyadaki değişiklik kendi hash'ini değiştirdiği için Git, yeni bir blob (dosya içeriği) ile yeni commit'ten gösterilebilmek için yeni bir tree yarattı.

Buraya kadar Git’in en güçlü özelliklerinden biri olan branch’lerden hiç bahsetmedik. Branch’ler refs/heads klasörü içerisinde tutulur.

Şimdi yeni bir branch yaratalım. .git/refs/heads klasöründe oluşturulan dosya içeriği mevcut commit'i gösterecektir.

Gördüğünüz gibi bir branch açmak diğer versiyon kontrol sistemlerinin aksine tek bir dosya yaratmak kadar basit ve maliyetsizdir.

Son olarak repo’da hangi branch/commit’in aktif olduğunu gösteren HEAD'e bakalım. .git/HEAD dosyasının içeriği repo'da o anda görünen (genellikle) branch ya da commit'i gösterecektir. Aşağıda .git/HEAD dosyası değiştirilerek Git CLI kullanılmadan branch değiştirilmiştir.

Gördüğünüz gibi Git basit ancak çok akılcı bir mimari ile tasarlanmıştır. Bu flood’daki bilgilerle bir haftasonu projesi olarak çok basit işlevleri yerine getirebilecek şekilde kendi basit Git istemcinizi yazabilirsiniz.

Konu ile ilgili detaylı bilgi almak isteyenler bu linki https://git-scm.com/book/en/v2/Git-Internals-Git-Objects kullanabilirler.