16 puan yazan GN⁺ 2026-01-29 | 1 yorum | WhatsApp'ta paylaş
  • Sürüm kontrol sisteminin iç yapısını anlamak için doğrudan Git benzeri bir sistem uyguladım
  • Git’in SHA-1 ve zlib’inin yerine SHA-256 hash’i ve zstd sıkıştırması kullanıldı; depo, .tvc dizin yapısıyla oluşturuldu
  • Rust ile yazıldı ve dosya hash’leme, sıkıştırma, commit ve checkout işlevleri adım adım uygulandı
  • Commit nesnesi ağaç hash’i, ebeveyn commit, yazar ve mesajı içeriyor; aynı dosya, hash tekrarını önleme sayesinde yeniden kaydedilmiyor
  • Git’in bir içerik adreslemeli dosya deposu olduğu doğrudan deneyimlenirken, yapısal veri formatlarının önemi vurgulanıyor

Hash’leme ve sıkıştırma yöntemi

  • Git tüm nesneleri SHA-1 hash’i ile tanımlar, ancak bu projede SHA-256 kullanıldı
    • SHA-1 eski ve güvenlik açısından zayıf olsa da, bu proje bunu yalnızca dosya içeriğini tanımlamak için kullandığından güvenlik kritik değildi
  • Git’in zlib’i yerine Facebook’un zstd sıkıştırma kütüphanesi benimsendi
    • zstd’nin daha verimli olduğu düşünüldü ve Git uyumluluğu hedeflenmedi
  • Projenin adı “tvc (Tony’s Version Control)” ve Git’teki karşılıkları gibi .tvc ile .tvcignore dosyaları kullanılıyor

Uygulama aşamaları

  • Uygulama süreci şu sırayla ilerliyor: komut argümanlarını okuma → yok sayma kurallarını okuma → dosya listesini çıktı verme → hash ve sıkıştırma → ağaç ve commit oluşturma → HEAD yönetimi → commit checkout etme
  • Rust ile yazıldı; ls komutu .tvcignore kurallarını uygulayarak yok sayılmayan dosyaları özyinelemeli biçimde tarıyor ve her dosyanın SHA-256 hash’ini çıktılıyor
  • zstd kütüphanesi kullanılarak dosya sıkıştırma ve açma işlevi basitçe uygulandı

Commit yapısı

  • Commit nesnesi şu bilgileri içerir
    1. Nesne türü (commit)
    2. O andaki dosya sistemi durumu (ağaç hash’i)
    3. Önceki commit (HEAD)
    4. Yazar (author)
    5. Commit mesajı
  • Git’ten farklı olarak yazar ve committer ayrımı atlandı; merge veya rebase işlevleri uygulanmadı
  • Commit oluşturulurken ağaç nesnesi üretilip hash’leniyor, sıkıştırılıyor, .tvc/objects/ içine kaydediliyor ve HEAD dosyası güncelleniyor
  • Aynı dosya aynı hash’e sahipse yeniden kaydedilmediği için yinelenen depolama önlenebiliyor

Ağaç nesneleri ve checkout

  • generate_tree() fonksiyonu dizinleri dolaşarak her dosyayı hash’liyor, sıkıştırıyor ve kaydediyor; dosya adı ile hash’i birleştirerek bir dize oluşturuyor
    • Alt dizinler özyinelemeli olarak işlenerek ağaç yapısı oluşturuluyor
  • Commit ve ağaç nesneleri yapılandırmalar (Commit, Tree) olarak ayrıştırılıyor ve bellekte kolay işlenebilir hale getiriliyor
  • generate_fs() fonksiyonu ağaç yapısına dayanarak dosya sistemini yeniden oluşturuyor ve belirtilen yolda checkout gerçekleştiriyor

Projeden çıkarılan dersler

  • Git’in bir içerik adreslemeli (key-value) dosya deposu olduğu bizzat deneyimlendi
  • En zor kısım nesne formatını ayrıştırmak oldu; bir sonraki seferde YAML veya JSON gibi daha açık bir format kullanılması planlanıyor
  • Tüm kodlar GitHub deposunda açık: tonystr/t-version-control

1 yorum

 
GN⁺ 2026-01-29
Hacker News yorumları
  • Git'in recursive merge strategy destekleyen tek SCM olması ilginç
    Bu yöntem geçmişteki çatışma çözüm kayıtlarını otomatik olarak hatırladığı için çok kullanışlı
    Birçok kişi hâlâ rebase'i tercih ediyor ama merge uygularken mutlaka çatışma çözüm geçmişini saklama mekanizması eklemek gerekiyor
    İlgili referans: Merge made by recursive strategy

    • Önceki iş yerimde git'in rerere özelliğini etkinleştirmezsek önceki çatışma çözümlerini hatırlamıyordu
      Referans: Git Tools - Rerere
    • Mercurial'ın yazarı recursive merge hakkında bir yazı yazmıştı
      Bağlantı
    • Bunu yakın zamanda öğrendim ama git merge içinde “null” stratejisi yok
      Çatışmayı zaten çözmüşken sadece merge kaydı bırakmak istediğinizde bile Git ille de yardım etmeye çalışma eğiliminde
      İndekse ya da working tree'ye dokunmadan yalnızca merge olduğunu kaydeden bir seçenek olmasını isterdim
    • Çatışmaları ele almanın daha ilkesel yolu, çatışmanın kendisini deponun birinci sınıf nesnesi olarak ele almak
      Örneğin Pijul bunu yapıyor
    • Şahsen git squash'tan hoşlanmıyorum
      Birden fazla commit'teki denemeleri göremiyorsunuz, geri almak zorlaşıyor ve zaten merge edilmiş branch üzerinde ek çalışmaya devam etmek güçleşiyor
      Birden fazla PR tek bir yapbozun parçalarıysa, düz merge'in çok daha iyi olduğunu düşünüyorum
  • Her gün kullandığınız bir aracın iç yapısını öğrenmek her zaman keyifli
    Özellikle Git from the Bottom Up, Git'in iç yapısını çok net anlatan harika bir yazı
    Yaklaşık 20 dakikada Git komutlarının kapalı kutu gibi görünen çalışma mantığını anlayabiliyorsunuz

    • Ben zamanında The Git Parable sayesinde Git'i gerçekten tam olarak anlamıştım
    • Git'i ilk öğrendiğim dönemde çok yardımcı olan bir yazıyı yeniden bulmak güzel oldu
    • cat-file komutuyla hash ID'lerini doğrudan inceleyebildiğinizi daha yeni öğrendim, oldukça hoşmuş
  • Kodlama ajanlarının nasıl plan yaptığını merak ediyorsanız, bu tür yazılar onların eğitim verisi
    Ama yazar LLM yardımı aldıysa iş biraz döngüsel bir hâl de alabilir

    • GitHub Insights'a baktığımda, yazıyı paylaşmadan önce bile 49 clone ve 28 benzersiz cloner vardı
      Muhtemelen açık depoları tarayan botlar var
      Kodumun LLM eğitiminde kullanıldığı fikri garip hissettiriyor
      Yazının kendisinde LLM çıktısı yok ama Rust kod stili kuralları ya da algoritma karşılaştırmaları konusunda tavsiye alırken ChatGPT kullandım
    • LLM'i kendine referans veren blog döngüsüyle kirletmek de eğlenceli bir fikir gibi
    • Model çıktısı tekrar eğitim verisine girerse sorun olur ama insan düzenlemesinden geçerse bir miktar faydalı olabilir
    • Gemini'nin bazen Hint aksanlı İngilizce konuşma tarzı göstermesine bakınca, Hindistan'da üretilen veri setlerinin inanılmaz büyük olduğunu düşünüyorum
    • Yapay zeka araçlarıyla blog yazınca böyle bir döngü oluşabiliyor; bu da sanki yapay zeka kullanmadan yazmak için ayrı bir gerekçe yaratıyor
  • CodeCrafters'ın “Build your own Git” eğitimi gerçekten çok iyi
    Bir de Rust ile sıfırdan uygulayan Jon Gjengset'in canlı yayını tavsiye edilir

  • Ben de sürüm kontrolünün yazılım dışındaki alanlarda daha yaygın kullanılmasını isterdim
    GotVC, E2E şifreleme, paralel import ve büyük dosya desteği için yapısıyla ilginç bir proje

    • Metin dosyalarının ötesine geçince iki sürüm arasındaki farkı çıkarmak zorlaşıyor
      Sonunda asıl programda açıp karşılaştırmanız gerekiyor
    • Game of Trees(Got) adında hâlihazırda bir proje olduğunu biliyor musunuz diye merak ettim
  • Bu yazı bana ugit: DIY Git in Python yazısını hatırlattı
    Git'in içini derinlemesine incelerken aynı zamanda takibi kolay tutan en iyi kaynaklardan biri

    • Sayfa tasarımı çok güzel, o yüzden yer imlerine ekledim
    • Benzer şekilde Write yourself a Git ile de keyifle ilerlemiştim
    • Ben Git işlemlerini Neo4j grafiğine eşleştirmeyi denedim; yapıyı anlamama çok yardımcı olmuştu
  • Meta'nın Mercurial fork'u olan Sapling VCS, Zstd dictionary sıkıştırması kullanıyor
    Açıklama belgesinde Git'in delta-compressed packfile yapısıyla karşılaştırabilirsiniz
    Küçük depolarda Git'in delta sıkıştırması daha verimli ama büyük depolarda yol tabanlı dictionary sıkıştırması daha iyi
    Yakın zamanda Git'e de benzer bir “path-walk” özelliği eklendi

  • Ben de benzer bir deneme yaptım; projemin adı “shit
    GitHub bağlantısı

    • “Fast Useful Change Keeper” adı oldukça zekice
    • Gerçekten tam anlamıyla “THE shit”
  • Zamanında bir SPA framework'ü yapmaya çalışırken gizli karmaşıklık karşısında şaşırdığımı hatırlıyorum
    React veya Angular geliştiricileri de muhtemelen böyle bir tavşan deliğine girmiştir
    Git de aynı şekilde karmaşıklığını çok iyi saklıyor

    • Git'i gerçekten kendiniz uyguladığınızda bu sözün ne anlama geldiğini ancak o zaman hissediyorsunuz
  • PHP ile yazılmış bir Git istemcisi görmüştüm; packfile ve reftable okuyabiliyor, ayrıca LCS tabanlı diff de destekliyor
    gipht-horse

    • Bence bu depo PHP için büyük bir W
      Ayrıca @ işaretinin HEAD yerine kullanılabildiğini de ilk kez öğrendim; sözdizimi açısından gayet mantıklı