- Manyana, Bram Cohen tarafından geliştirilen CRDT tabanlı bir sürüm kontrol prototipi olarak, birleştirme çakışmalarını ortadan kaldıran ve geçmişi yapısal olarak koruyan yeni bir yaklaşım sunuyor
- CRDT (Conflict-Free Replicated Data Type) kullanarak birleştirmenin her zaman başarılı olmasını sağlıyor ve çakışmaları basit bir bilgilendirici gösterim olarak ele alarak kullanıcıların değişiklikleri açıkça fark etmesine imkan veriyor
- Satır sırasının kalıcılığı, engellemeyen birleştirme, geçmişin yapının içine gömülmesi temel ilkeleri üzerine kurulu ve rebase sürecinde de mevcut kayıtları bozmaz
- Yaklaşık 470 satırlık Python koduyla yazılmış demo düzeyinde bir uygulama; tüm kod ve tasarım dokümanı public domain olarak GitHub'da yayımlanmış durumda
- Git'in sınırlarını aşarak birleştirme hatası olmayan yeni nesil bir sürüm kontrol modelini deneysel olarak ortaya koyan bir örnek
Manyana: Sürüm kontrolünün geleceği için tutarlı bir vizyon
- Manyana, Bram Cohen'in yayımladığı CRDT tabanlı sürüm kontrol sistemi prototipi; mevcut sistemlerdeki birleştirme çakışması sorununu çözmeye yönelik bir girişim
- CRDT, birleştirmenin her zaman başarılı olmasını garanti eder ve çakışmaları bilgilendirici işaretler olarak ele alarak kullanıcıların gerçek değişiklikleri net biçimde görmesini sağlar
- Bu yaklaşımın üç temel özelliği var: satır sırasının kalıcılığı, engellemeyen çakışma işleme, geçmişin yapının içine gömülmesi
- Rebase sürecinde bile mevcut geçmiş korunur; tek bir ortak atası olmayan karmaşık birleştirme yapıları da kararlı biçimde işlenebilir
- Manyana, yaklaşık 470 satırlık Python koduyla yazılmış bir demo uygulama ve tasarım dokümanı ile kod public domain olarak GitHub'da yayımlanmış durumda
CRDT tabanlı yaklaşımın özü
- CRDT, birleştirmenin her zaman başarılı olmasını sağlar ve birleştirme sırasından bağımsız olarak aynı sonucu garanti eden eventual consistency sunar
- Birden fazla kullanıcının bağımsız çalıştığı branch'ler hangi sırayla birleştirilirse birleştirilsin sonuç aynı kalır
- Satır sırasının kalıcılığı sayesinde, aynı konuma eklenen kodun sırası bir kez belirlendiğinde sonrasında da korunur
- Bu, farklı branch'lerde çakışmalı bölümlerin farklı şekillerde çözülmesi sorununu önler
- Çakışmalar yalnızca bilgi vermek için işaretlenir ve birleştirmeyi engellemez
- Birleştirme sonucu her zaman üretilir; çakışmalar ise “yakın konumda aynı anda değiştirilmiş bölümler” olarak işaretlenir
- Her değişikliğin sahibi ve yapılan işlem izlenerek yararlı çakışma göstergeleri sağlanır
- Geçmiş yapının içine gömülüdür
- Durum, dosyanın tüm satırlarını içeren bir 'weave' yapısı ile ifade edilir ve her satır eklenme/silinme zamanına dair metadata taşır
- Birleştirme sırasında ortak ata bulmaya veya DAG üzerinde gezinmeye gerek kalmadan, iki durum girdi olarak verildiğinde her zaman doğru sonuç üretilir
Geliştirilmiş çakışma gösterimi
- Mevcut sürüm kontrol sistemleri çakışma olduğunda genelde sadece iki kod bloğunu yan yana gösterir; kullanıcı farkları kendisi çıkarmak zorunda kalır
- Manyana ise her çakışmalı bölgeyi “silindi”, “eklendi” gibi ifadelerle açıkça belirtir ve değişikliği kimin yaptığını gösterir
- Örneğin bir kullanıcı bir fonksiyonu silerken başka bir kullanıcı fonksiyonun içine bir satır eklediyse, Manyana bu değişikliklerin yapısını net biçimde ayırarak gösterir
- Böylece kullanıcı iki bloğu karşılaştırmak yerine, değişikliğin anlamını ve bağlamını hemen kavrayabilir
Rebase'in yeniden tanımlanması
- CRDT tabanlı sistemlerde rebase, geçmişi tahrip etmez
- Geleneksel rebase, commit'leri yeni bir temel üzerine yeniden dizer ve kurgusal bir geçmiş üretir
- Manyana'da ise aynı etki elde edilirken tüm özgün geçmiş korunur
- Bunun için DAG'e yalnızca “primary ancestor” açıklaması eklemek yeterlidir
- Bu yöntem, ortak atası olmayan birleştirme yapılarında da kararlı çalışır ve geleneksel 3-way merge'in başarısızlıklarından kaçınabilir
Projenin mevcut durumu
- Manyana, tam teşekküllü bir sürüm kontrol sistemi değil, bir demo uygulama ve dosya bazında çalışıyor
- Yaklaşık 470 satırlık Python kodundan oluşuyor
- Cherry-pick ve yerel undo işlevleri henüz uygulanmış değil; ancak README'de gelecekteki yön belirtiliyor
- Proje, CRDT tabanlı sürüm kontrolünün UX sorunlarını çözebileceğini gösteriyor ve mevcut araçlardan daha iyi sonuçlar sunuyor
- Tüm kod public domain olarak dağıtılıyor ve tasarım dokümanının tamamı GitHub README içinde yer alıyor
Topluluk tepkilerinin özeti
- Bir kullanıcı, Git'in 10 yılı aşkın süredir kullanıldığını ancak yeni bir sürüm kontrol paradigmasına ihtiyaç olduğunu söyleyerek Manyana'nın yaklaşımını olumlu değerlendirdi
- Birleştirmenin her zaman başarılı olması fikrinin sezgisel gelmediğini belirterek ek örnekler ve açıklama istedi
- Rebase'i iyileştirme fikrine ilgi gösterdi ve kişisel projelerinde ara branch'ler üzerinden birleştirme yönetimi kullandığını söyledi
- Git'in sınırlamaları olarak binary dosya işleme, sağ/sol branch ayrımındaki kafa karışıklığı, büyük kod değişiklikleri için özet eksikliği gibi noktaları vurguladı
- Gelecekte sürüm kontrolünün token-aware özellikler veya dil/dosya biçimine özel eklentiler desteklemesinin iyi olacağını önerdi
- Başka bir kullanıcı ise Manyana'nın Pijul ya da Darcs ile benzer bir temele sahip olup olmadığını sordu ve Darcs'ın performans sorunlarıyla Pijul'ün mevcut durumunun karşılaştırılmasını istedi
Sonuç
- Manyana, CRDT'yi sürüm kontrolüne uygulayan somut bir demo olarak, çakışma yönetimi ve rebase sorunlarını kökten yeniden tasarlıyor
- Birleştirme hatası olmayan yapı, çakışmaların bilgilendirici hale getirilmesi ve geçmişin yapısal olarak içselleştirilmesi gibi unsurlar, mevcut Git modelinin sınırlarını aşan bir tasarım yönü ortaya koyuyor
- Tam bir sistem olmasa da, yeni nesil sürüm kontrol sistemleri için anlamlı bir tasarım planı olarak önem taşıyor
1 yorum
Hacker News görüşleri
Merge gösterim biçiminin, geçmişin nasıl temsil edildiğinden ayrı bir mesele olduğunu düşünüyorum
Ben de Git’in varsayılan merge arayüzünü sevmiyorum; bu yüzden p4merge kullanıyorum. Sol, sağ, ortak taban ve sonuç olmak üzere dört panel gösteren bir araç; bu sayede çakışmanın nedenini ve çözüm yolunu tek bakışta görmek mümkün
Sırf bunun için VCS’in kendisini değiştirmeye gerek olmadığını düşünüyorum
merge.conflictStyleayarını"diff3"ya da"zdiff3"olarak değiştirirseniz taban sürüm de gösterilirBöylece yalnızca çakışma işaretlerine bakarak bile hangi tarafın yeni kod eklediğini çıkarabilirsiniz
Bir zamanlar bir podcast’te yeni bir VCS yapan bir konuğun Git’in diff saklama biçimini yanlış anladığını duyunca şaşırmıştım. Yıllarca proje yürütüp de temel kavramlara bile bakmamış olması, NIH (yeniden icat etme) ruhunun hâlâ yaşadığını gösteriyor
Ama bunu SCM düzeyinde yapmak, kullanıcının merge geçmişini hatırlayabilme avantajı sağlıyor. Git’in burada bazı uç durumları var
Merge’ün asla başarısız olmamasının iyi bir şey olduğundan emin değilim
Merge başarısızlığı çoğu zaman basit bir konum çakışmasından ziyade anlamsal çakışmanın işaretidir. Böyle durumlarda elle müdahale etmek gerekir
CRDT’lerin sürüm kontrolü için uygun olmadığını düşünüyorum
Çakışma, sürüm kontrolünün özüdür. İki geliştirici kodu farklı yönlere çektiğinde, sonunda anlamsal bir seçim yapmak gerekir. CRDT bu gibi durumlarda saçma kod üretmeye daha yatkın olabilir
Git üzerinde daha iyi bir merge UX’i sunan zaten birçok araç var; ayrıca cherry-pick ve revert’in kolay olması da Git’in avantajlarından biri
Örneğin bir branch’te bir sabit silinirken, diğer branch’te o sabit kullanılıyorsa kod bozulur
Git’in çakışmaları çoğunlukla sözdizimsel olduğundan, daha akıllı bir semantic merge ya da CRDT yaklaşımı yardımcı olabilir
Örneğin dosya adlarını, özellikleri ve hash’leri izlerken OR-set kullanılabilir (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type).
Ama çakışma çözümü yine dış arayüzde ele alınmalıdır
Neden CRDT’ye bu kadar odaklanıldığını pek anlamıyorum
Çakışmaların anlamsal boyutu hâlâ var. Hatta değişiklikler iç içe geçmiş (interleave) biçimde görünebileceği için daha da kafa karıştırıcı olabilir
Ben bir rebase merkezciyim. Merge commit’lerden kaçınılmalı ve her commit bağımsız bir birim olmalı. Gitflow’nun bir anti-pattern olduğunu düşünüyorum
Jujutsu ya da Gerrit, Git’in asıl problemi olan “inceleme geri bildirimine dayalı commit zinciri yönetimi” meselesini daha iyi çözüyor
Git snapshot’ları yeniden uyguladığı için aynı iş iki kez varmış gibi oluyor. Buna karşılık Pijul patch düzeyinde çalışıyor ve sıradan bağımsız olarak aynı sonucu veriyor. Bana göre gerçek bağımsız iş birimi bu
Çakışmalı bir durumda bile belirli commit’leri geri alma (undo) mümkün olabilir. Bu da Git’ten daha esnek bir yapı sağlayabilir
Pratikte çoğu zaman yalnızca nihai sonuç önemlidir. squash merge ile bunu dengeli biçimde kullanmak daha gerçekçi
Ama bazı sorunlar doğası gereği çakışma gerektirir. Örneğin eşzamanlı editörde karakterlerin birbirine karışması gibi durumlarda sonuç daha da kötü olabilir
Bu proje sanki Bram’in eskiden yaptığı Codeville fikirlerini genişletiyor gibi
Codeville, 2000’lerin başındaki DVCS patlaması döneminde çıkmıştı ve weave tabanlı depolama ile merge kullanıyordu. CRDT’den 10 yıl daha eski olsa da doğal bir devam fikri gibi duruyor
Bram’in hâlâ bu problemle uğraşıp yeni denemeler yapıyor olması sevindirici
arxiv:2002.09511
“CRDT tabanlı bir VCS hâlâ yok” sözüne katılmıyorum
Pijul zaten var ve uzmanların binlerce saat harcadığı bir proje
6 yıldır deneysel durumda ve 4 yıl önce bizzat bir issue açmış olmama rağmen hâlâ yansıtılmadı
Pijul, kendi kendisiyle geliştirilen bir VCS olduğu için GitHub kullanmıyor
pijul pull -ayaptığımda çakışma oluyor ve ben de doğrudan yeniden clone alıyorum. İzlenen güncellemeler için bir pull seçeneği var mı diye merak ediyorummanana.py 473 satırlık, bağımlılığı olmayan bir Python kodu
Asıl uygulama yaklaşık 240 satır; geri kalanı test kodu. Basit ama etkileyici
JS ekosistemindeki left-pad olayını düşününce, Python dünyasında da böyle küçük ama sorumluluk sahibi paketlerin daha fazla olması gerektiğini düşünüyorum
Bu tür sistemler, takım büyüklüğüne göre merge çakışmalarının yapısını analiz ederek tasarlanmalı
1, 10, 100, 1000 kişilik ekiplerin hangi sorunları yaşadığına ve ajan tabanlı geliştirmenin bunu nasıl değiştireceğine bakmak gerekir
Benim deneyimimde 1–100 kişi aralığında ekipler kod alt ağaçlarını bölüştürdüğü için neredeyse hiç çakışma olmuyor.
Ajanlar artarsa 100 kişi 1000 kişi gibi davranabilir ama şimdilik gerçek bir problemden çok önce çözüm üretilmiş gibi geliyor
Bugünlerde zaten merge çakışmasını Codex’e bırakıp geçiyorsunuz; bu yüzden yeni bir VCS kullanma gerekçesi daha da azalıyor
Git büyük ekipler için tasarlandı ve ajan çağında süreç otomasyonu ile yeterince başa çıkılabilir
Asıl sorun daha çok paylaşılan kütüphanelerdeki darboğazlar ya da erişim kısıtı politikalarından doğar
Çakışmalardan daha büyük sorun Git’in ölçeklenebilirliği (scalability)
Depo boyutu ve değişim hızı sınıra dayanıyor. Sunucu, istemci ve protokol genelinde yeniden tasarım gerekiyor
Açıkçası bu sistemin hangi sorunu çözdüğünü pek anlamıyorum
Soyut düzeyde ilginç ama pratikte jj, Git’ten çok daha kullanışlı
Bir sonraki adımın dosya düzeyi değil, AST düzeyinde sürüm kontrolü yapan sistemler olduğunu düşünüyorum.
LightTable ya da Dark gibi denemeler vardı; böyle ağaç tabanlı VCS yaklaşımlarını denemek ilginç olabilir