4 puan yazan GN⁺ 2023-08-02 | 2 yorum | WhatsApp'ta paylaş
  • Jujutsu, yazılım projelerinde kod kopyalama, değişiklikleri izleme ve değişiklikleri yayımlamak için kullanılan bir sürüm kontrol sistemidir; yeni kullanıcılar ve deneyimli kullanıcılar ile bireysel yeni projeler ve büyük geçmişlerekipler göz önünde bulundurularak kullanımı kolay olacak şekilde tasarlanmıştır
  • Kullanıcı arayüzü ile sürüm kontrol algoritmalarını, içeriği sağlayan depolama sisteminden dahili olarak ayırır; şu anda Git deposunu depolama katmanı olarak kullanır ve bu sayede Git tabanlı araçlarla uyumludur
  • Git'te yalnızca commit'ler ve dosyalar saklanır; bookmark(branch) ve diğer üst seviye meta veriler ise Git dışındaki özel bir depoda tutulur
  • Varsayılan Git backend'i gitoxide Rust kütüphanesini kullanır; Git uzak depolarından branch çekebilir ve uzağa push yapabilir, ayrıca normal Git commit'leri gibi görünen commit'ler oluşturur
  • Gerçek commit olarak çalışma kopyasını temsil eden working-copy-as-a-commit modelini kullanır; dosya değişiklikleri otomatik olarak normal commit'ler olarak kaydedilir ve sonraki her değişiklikte amend edilir
    • dirty working copy nedeniyle komutlar başarısız olmaz
    • git stash gerekmez
    • İş bitmeden önce bile çalışma kopyası commit'ine commit mesajı atanabilir
  • Depodaki tüm işlemler, işlem sonrasındaki depo durumu anlık görüntüsüyle birlikte kaydedilir; önceki depo durumunu geri yüklemek, işlem bazında undo yapmak ve en son işlem olmayan belirli bir işlemi revert etmek mümkündür
  • Çatışmaları commit'ler gibi birinci sınıf nesneler olarak kaydeder; çatışma oluşturan işlemler de başarılı olur ve sonrasında tek bir çatışma çözümleme iş akışıyla ele alınabilir
  • Bir commit değiştirildiğinde, mevcut commit'in tüm descendant'ları otomatik olarak yeni commit'in üzerine rebase edilir; çatışma çözüm sonuçları descendant'lara da aktarılır ve rebased commit'i gösteren bookmark ile çalışma kopyası da güncellenir
  • Açık bir index veya staging area yoktur; commit seçimi için revset dili kullanılır ve çıktı biçimi kullanıcı tarafından yapılandırılabilen bir template diliyle işlenir
  • Geçmiş yeniden yazma özellikleri olarak, herhangi bir commit'in mesajını düzenlemek için jj describe, checkout yapmadan commit değişikliklerini düzenlemek için jj diffedit, commit bölmek için jj split, değişikliklerin bir kısmını başka bir commit'e taşımak için jj squash -i --from X --into Y sunulur
  • Güvenli eşzamanlı çoğaltma özelliği deneysel durumdadır; Dropbox ve rsync gibi dağıtık dosya sistemleri veya yedekleme araçları kullanıldığında deponun bozuk duruma gelmemesi için tasarlanmıştır ve en kötü durumda yerel ile uzak durumlar arasındaki çatışmaları görünür kılmayı hedefler
  • jj deneysel bir sürüm kontrol sistemidir; Git uyumluluğu kararlıdır ancak üzerinde çalışılan özellikler, ideal olmayan UX ve belirli kullanım biçimlerinde iş akışı boşlukları olabilir
  • Özellikler büyük ölçüde tamamlanmış durumdadır ancak Git submodule desteği henüz bitmemiştir, çeşitli performans hataları vardır ve e-posta tabanlı iş akışları için yerel destek yoktur
  • 1.0.0 öncesinde iş akışında değişiklikler ve disk üzerindeki biçimde geriye dönük uyumlu olmayan değişiklikler beklenmektedir; biçim değişiklikleri için şeffaf yükseltme veya istek üzerine yükseltme komutu ya da betiği sağlanmaya çalışılır
  • Apache 2.0 lisanslı bir açık kaynak yazılımdır; Google tarafından desteklenen bir ürün değildir ve destek topluluk tarafından sağlanır

2 yorum

 
xguru 2023-08-03

Jujutsu - basit ve güçlü, Git uyumlu bir DVCS

Bunu bir buçuk yıl önce paylaşmıştım, şimdi yine HN'de gündem olmuş.

 
GN⁺ 2023-08-02
Hacker News görüşleri
  • Burada görmek sevindirici. Yaklaşık 2–3 hafta önce jj’ye geçtim ve geri dönmeyi düşünmüyorum. Kafamdaki çalışma biçimini epey değiştirmem gerekti ama jj’nin sunduğu akışı oldukça sevdim.
    Neyi commit edeceğimi ayrıca düşünmeye ayırdığım zaman ortadan kalktı; tüm dosya değişiklikleri otomatik olarak çalışma kopyası commit’ine yansıyor. Elbette bunu istemediğiniz zamanlar da oluyor; bu yüzden commit’i ikiye bölme veya değişiklikleri taşıma özellikleri var ve tüm işlemlerin commit’ler üzerinde çalışması hoşuma gidiyor.
    jj log, birden çok branch’in tüm haritasını görmek için harika; çakışmaları kısmen çözüp başka bir branch’e geçebiliyorsunuz ve kısaltılmış changeset ID’leri de kullanışlı. Örneğin jj log içinde rebase edeceğiniz changeset’i görüp jj rebase -s qr -d master gibi çalıştırabiliyorsunuz; bu, branch adını tamamen yazmaktan daha hızlı.

    • Yanlışlıkla gizli değerler içeren bir dosya kaydedip otomatik olarak içeri alınırsa ne olacağını merak ediyorum.
    • Bunu sadece GitHub deposu ile birlikte mi kullanıyoruz, merak ediyorum.
      Dropbox gibi backend’lerle kullanılabildiği söyleniyor ama IPFS ile kolayca kullanılabilecek bir sistem çıksa iyi olurdu. Büyük verilerde GitHub’da 1 TB saklayamazsınız; LFS de ücretli olduğu için onu dışarıda tutuyorum.
      Veri kümesini kullanmak isteyen kişi zaten onu yerelinde bulunduracağından, indirme kaynağının tek bir yer değil binlerce yer olduğu IPFS doğal bir çözüm. Veri deposu için IPFS kullanıyorsa hemen geçerim; değilse incelemeye çok da değmeyeceğini düşünüyorum.
    • Bir ekipte başarıyla kullanıldığı örnekler var mı, merak ediyorum. İki kişi aynı branch üzerinde çalışınca nasıl hissettirdiğini bilmek isterim.
  • Jujutsu, yazarının kişisel projesi olarak başladı ve şimdi Google’da yazarının tam zamanlı projesi hâline geldi. Git Merge 2022’de sunulmuştu.
    Jujutsu: A Git-Compatible VCS - Git Merge 2022:
    Video:
    https://youtu.be/bx_LGilOuE4
    Slides:
    https://docs.google.com/presentation/d/1F8j9_UOOSGUN9MvHxPZX...

    • Kişisel bir projenin Google’da tam zamanlı proje hâline gelmesi epey gurur verici olmalı.
  • Neredeyse 1 yıldır jj’yi her gün kullanıyorum ve Git kullanıcı deneyiminden kesinlikle çok daha iyi olduğunu düşünüyorum. Değişiklikleri atomik commit’lere ayırma konusunda hassas olduğum için otomatik rebase temel özellik benim için.
    Çakışmalar commit’e kaydedilebildiğinden, Git veya Mercurial’da olduğu gibi rebase’in ortasında durup çakışmaları düzeltmek gerekmiyor. Bir commit’i değiştirseniz veya silseniz bile jj tüm alt commit’leri otomatik olarak rebase ediyor; Git rebase’in aksine Mercurial evolve gibi birden fazla çocuğu da işleyebiliyor.
    Commit geçmişini ele alan temel komutlar da iyi. jj move|restore ile bir commit’teki değişikliği başka bir commit’e taşıyor veya kopyalıyorsunuz, jj split ile commit’i bölüyorsunuz, jj rebase ile commit’i taşıyorsunuz. Çalışma ağacı veya index olmadan her şey commit geçmişinin içinde olduğu için aynı komutlar ve flag’lerle yönetilebiliyor.
    İşlem günlüğü de harika; çoğu işlemi sorunsuz geri alabiliyorsunuz. Bu, Git’te kötü bir rebase’i veya commit --amend işlemini düzeltmek için reflog’da doğru commit’i arayıp ref’i elle düzeltmek zorunda kalmanızla tezat oluşturuyor.
    En rahatsız edici yanı, otomatik çalışma kopyası commit’inin bazen istenmeyen dosyaları da commit etmeye çalışması ve ad değişikliği algılama olmadığı için merge’leri Git kadar zarif yönetememesi. Yine de bozuk commit’ler jj split|restore ile nispeten kolay düzeltilebiliyor ve jj geliştiricileri de ad değişikliği meselesi üzerine düşünüyor.

  • Çalışmanın sonucunda çakışma çıksa bile bu bilgiyi commit’e kaydedip işlemi başarılı sayması ve çakışmayı daha sonra çözebilmek sevindirici. Son yaklaşık 10 yıldır işbirlikli düzenleme algoritmalarıyla uğraşıyorum ve idealde Git gibi araçların sonunda CRDT tabanlı bir yaklaşımla yer değiştirmesini isterim.
    CRDT kullanırsanız aynı araçla pair programming yapabilirsiniz ve Git’te ortaya çıkabilecek kendiyle çakışma gibi karmaşık merge durumlarını da daha iyi yönetir. Ayrıca daha güçlü bir modeldir.
    Ancak modern metin CRDT’leri eşzamanlı düzenlemeyi otomatik olarak çakışmasız çözüyor; oysa kod üzerinde çevrimdışı işbirliği yaparken genellikle çakışmaların görünür olmasını ve bir insan tarafından elle çözülmesini isteriz. CRDT, Git’ten daha fazla düzenleme geçmişi bilgisi taşıdığı için teorik olarak bu mümkün; ama düzgün yapmak için çakışmanın kendisini metin dosyasının veri modeline koymak gerekecek gibi görünüyor ve bunun modern editörlerle nasıl örtüşeceğini pek bilmiyorum.
    jj’nin aynı püf noktasını bulmuş gibi gelmesi, pratikte ne kadar iyi çalışacağını merak ettiriyor. CRDT tabanlı kod deposu hayaline bir adım daha yaklaşılmış gibi.

    • Pijul’a bakmak iyi olabilir. Burada söylenenlerin çoğunu fiilen uyguluyor. Pijul, bir CRDT olan patch’ler üzerinde çalışıyor ve çakışmayı birinci sınıf bir kavram olarak ele alıyor.
    • git bisect’ten hiç değer görmediniz mi, merak ediyorum.
      Yeniden üretilebilir bir bug varsa ve nedeni karmaşıksa, hangi commit’in bug’ı getirdiğini bulup hangi değişikliğin sebep olduğuna bakmak faydalı olmaz mı? En azından neyin düzeltilmesi gerektiğine dair ilk sezgiyi verir.
      Mevcut git bisect, tüm commit’ler derlenebilir ve çalıştırılabilir olduğunda en iyi şekilde çalışıyor. İçinde çakışma işaretleri olduğu için derlenemeyen veya çalıştırılamayan commit’ler varsa çok daha fazla manuel müdahale gerekiyor.
      Böyle bir senaryoda git bisect’e karşılık gelen özelliğin nasıl uyarlanabileceğini merak ediyorum. Sadece çakışma işareti dizgilerini taramak uygun olmayabilir; çünkü belgelerde çakışma işaretleri anlatılıyor olabilir veya bazı markup dillerinde ======= yasal olarak alt çizgi için kullanılabilir.
    • Gerçekte nasıl gelişeceğini merak ediyorum.
      Kaynak kontrol geçmişinin anlamlı bir çıktı olduğu ve patch demetinin geliştirme makinesinden ayrılmadan önce kademeli, atomik değişiklikler dizisi olarak düzenlenmesi gerektiği fikriyle çelişiyor gibi görünüyor.
      Öte yandan çevremdeki geliştiricilerin çoğu zaten Git geçmişini sonsuz bir editör geri alma geçmişi gibi kullanıyor; bu yaklaşım da bunu iyice yerleştirecek gibi.
      Uzun vadeli geçmişin nasıl çalışacağını düşündüklerini, bugünkünden daha mı faydalı yoksa daha mı az faydalı olacağını merak ediyorum.
  • Çalışma kopyasının otomatik commit edilmesi ilk başta iyi görünüyor, ama bunun kötü olduğu çok durum var
    Yeni bir çıktı dosyası oluştuğunda henüz .gitignore’a eklemeden otomatik commit edilir; bir branch’te yok sayılacak dosyayı ekleyip sonra başka bir branch’e geçerseniz dosya çalışma kopyasında kalır ama .gitignore’da olmadığı için otomatik commit edilebilir
    Ayrıca sonradan commit’i bölmektense yalnızca bazı dosyaları stage edip commit etmek çok daha kolaydır

    • Bu projenin, yalnızca bazı dosyaları stage edip commit etmenin sonradan commit’i bölmekten daha kolay olduğu yönündeki yaygın kabule meydan okuduğunu düşünüyorum
      Benim de aklıma yerleşmiş fikir bu, ama gerçekten doğru mu bilmiyorum. Pratikte indeksi düzeltip sonradan commit’i amend etmek oldukça sık oluyor; bunu önceden de yapmak mümkün
      Sonradan düzenlemeyi tamamen kaçınılmaz olarak yapacaksak, bu tür düzenlemeler için tek bir iş akışı daha iyi olmaz mı diye düşünüyorum. Henüz denemedim, ama kanıksadığımız bir alışkanlığın aslında yardımcı olmayabileceği noktasına oldukça ikna edici biçimde dokunan bir yaklaşım gibi görünüyor
    • Aynı fikirdeyim. Genelde proje dizinimde çıktı dosyaları, notlar, tek seferlik script’ler gibi 10’dan fazla ek dosya oluyor. Commit’e dosya eklerken her zaman dosya adına göre seçiyorum; yeni oluşan ya da değişen her şeyi eklemiyorum
      Oluşturulan veya değiştirilen tüm dosyaların her zaman commit’e girdiği bir kullanım senaryom yok
      Başka bir branch’e geçtiğinizde dosyanın çalışma kopyasında kalması ama .gitignore’da olmaması bence Git’in bir başarısızlığı. .gitignore’a ek olarak .local.gitignore gibi bir şey olmalı. Yalnızca bana gereken yok sayma dosyaları çok yaygın ve projenin .gitignore’ına girecek nitelikte değil. Yöntemler var ama hepsi tuhaf; bu yüzden varsayılan olarak basitçe sunulmalı
    • İlk sorun, zaten izlenen dosyalarla yeni dosyaları kolayca karşılaştırarak çözülebilir gibi geliyor
      Yine de ilginç. Git’in staging’ini hiç sevmedim, ama burada sözü edilen durumu yaşamadığım için dosya sistemi ile commit arasında bir ara aşama gerektiğini ancak şimdi anlıyorum
    • Yalnızca README’den anladığım kadarıyla, böyle bir dosyayı .gitignore’a eklediğinizde sonraki otomatik commit’te anonim çalışma kopyası commit’inden tekrar çıkarılıyor
      Dosyanın en başta eklenmemesi yerine anonim çalışma kopyası commit’ine girip sonra çıkması sezgisel değil; ama bu anonim commit çoğu kullanıcıya görünmüyorsa fark olmayabilir
    • Bunların jj tasarımında neden sorun olduğunu pek anlamıyorum; bazı dosyaları stage etmenin sonradan commit’i bölmekten neden daha kolay olduğunu da pek anlamıyorum
      Belgelere bakınca, endişe edilen birçok durumun açıkça ele alındığı görülüyor:
      https://github.com/martinvonz/jj/blob/main/docs/git-comparis...
  • Birkaç özel durum dışında yıllardır komut satırında Git’i neredeyse hiç kullanmıyorum. Günlük kullanımda IntelliJ gibi IDE’nin yerleşik entegrasyonuna dayanıyorum ve bunu neden özellikle elle göğüslediklerini anlamakta zorlanıyorum
    Editör içinde satır bazında seçip kısmi commit yapabiliyor; tüm branch’leri görüp merge ve cherry-pick yapabiliyor; commit veya amend edebiliyor; güncellemeleri pull edebiliyor ve tag’leri tek bir kısayolla düzenleyebiliyorum
    Yine de burada azınlıkta gibiyim. Git’in zorunlu bir beceri olduğu, gerçek programcıların komutları gözü kapalı yazabilmesi gerektiği yönündeki havayı da düşününce bu daha da belirgin; nedenini merak ediyorum

    • Sürüm kontrol sistemini komut satırından kullanmayı her zaman tercih ettim ve etmeye devam edeceğim
      Bu beceri ortamdan bağımsızdır; uzak bir makineye bağlanıp depoya bakmak yereldekiyle aynıdır, her editörün VCS entegrasyonunu ayrıca öğrenmek gerekmez ve alıştığınız araçları aynen kullanabilirsiniz
      Verilen örneklerdeki işler komut satırında da aynı derecede kolay yapılabildiğinden editör entegrasyonunu özel görmüyorum. reflog ile oynamak gibi tuhaf ve ileri seviye bir iş gerektiğinde eninde sonunda komut satırını açmanız büyük olasılık
      Elbette GUI kullananlara itirazım yok. Araçla üretkenseniz yargılanacak bir şey değil; sadece neden diye sorduğunuz için yanıtlıyorum, yoksa benim yöntemimin daha iyi olduğunu iddia etmiyorum
    • Deneyimime göre IDE entegrasyonları genellikle Git CLI’nin tüm işlevlerini uygulamıyor. İyileşmiş olabilir, ama temel clone/branch/commit/merge’in ötesine geçip geliştirici ve branch sayısı biraz artınca sorun çözmek için sonunda Git CLI’ye dönmek zorunda kaldım
    • Gerçek programcı mıyım bilmiyorum, ama Git GUI’nin yanlış bir şey yapabileceğine dair irrasyonel bir korkum var. IntelliJ’de bile Git’i yerleşik CLI’yi açarak kullanıyorum. Eski alışkanlıklar kolay ölmüyor
    • Git’i yeni kullanmaya başlayan birçok kişi Git’in nasıl çalıştığını, yani commit ve branch’in ne olduğunu ve neler yapılabileceğini anlamıyor. Sonra CLI aracını suçlayıp GitHub Desktop kullanırsa her şeyin anlaşılacağını umuyor
      İnsanların “Git CLI öğrenmelisin” demesinin en yaygın bağlamı bu
      Birkaç gün önce de Git komutlarını öğrenmemek için GitHub Desktop kullanmayı öneren bir örnek vardı: https://www.reddit.com/r/learnprogramming/comments/15b7pra/s...
    • Ekipte Git’i anlayan insanlar yalnızca iki türdür: CLI kullananlar ve Git’i anlamadan sadece düğmelere basmaya başlayanlar
  • Git uyumluluğunu öne alan yaklaşımı sayesinde Jujutsu, şimdiye kadar gördüklerim arasında Git’e alternatif aday olarak daha güçlü görünüyor
    Git uyumluluğu açıklamasını okurken merak ettiğim şey, Jujutsu kullanıcılarının GitHub gibi yerlerde barındırılan Git depolarına jj ile erişmesi kullanım senaryosuna ağırlık verilmiş gibi görünmesiydi. Tersine, yerel Jujutsu depolarına Git ile erişme biçiminin de desteklenip desteklenmediğini merak ediyorum
    Çoğu geliştirici zaten Git CLI’a alışkın olduğundan, gerçek operasyonlarda aynı kod tabanında jj ve Git’i birlikte kullanan geliştiriciler çıkacak gibi. Yoksa pratik işletim senaryosu, iki taraftan da CLI erişimi için her zaman yerel Jujutsu veritabanı değil, backend depo olarak Git’i kullanmak mı, onu merak ediyorum

    • README dipnotuna göre, şu anda yerel backend kullanmak için neredeyse hiçbir pratik neden yok
      Bu backend esas olarak, ileride Git backend’ine kolayca eklenemeyecek özelliklerin eklenebilmesini garanti altına almak için var
    • Jujutsu’yu her zaman bir Git deposunun frontend’i olarak kullanmak ya da tamamen Jujutsu tabanlı bir uzak depo kullanmak beklentisi olacak gibi
      Zaten Jujutsu kullanan bir projede çalışıp katkı vermek istiyorsam, projenin benim iş akışıma uyması yerine benim projeye uymam daha makul
  • Önce Git uyumluluğu yaklaşımı sayesinde Jujutsu, şimdiye kadar gördüğüm Git alternatif adayları arasında daha güçlü görünüyor
    Çakışma yönetimini merak ediyorum. pmeunier’in Pijul için patch teorisini biçimsel olarak düzenlemeye çok özen gösterdiğini biliyorum; sağlam olmayan ya da sorunlu patch/çakışma kavramları büyük sorunlara yol açabilir. Darcs’ın performans sorunları da böyle ortaya çıkmıştı diye hatırlıyorum
    Depo wiki’sindeki karşılaştırma sayfası, Pijul’un çakışma işlemesini “benzer” demekten biraz daha ayrıntılı açıklasa iyi olurdu

    • Burada biraz daha ayrıntılı açıklama var: https://github.com/martinvonz/jj/blob/main/docs/technical/co...
      Çakışmaları bu şekilde sembolik olarak saklamak, daha sonra çakışmaları yeniden üretmeyi ve bazı çakışmaları otomatik çözmeyi mümkün kılabilir; ancak gerçek çakışma içeriğinin kendisini çözme sorununu ele almaz
      Biri uygularsa, her iki tarafın avantajlarını almak için jj backend’i olarak Pijul’u kullanmak da mümkün olabilir gibi
  • rsync, Dropbox ve dağıtık dosya sistemleri üzerinden güvenli klonlama güzelmiş. Son zamanlarda giderek basit senkronizasyon dostu sistemlere daha çok eğiliyorum
    Çünkü nereye, hangi araçla bırakırsan bırak, çalışıyor. Yeni bir aracın bu yönde ilerlemesi her zaman sevindirici

    • Bu kısmı biraz daha açıklayabilirseniz iyi olur
      Böyle bir sorun olduğunu duydum ama bizzat yaşamadım. Git ile rsync/Dropbox gibi araçlar arasında ne tür race condition’lar oluşup sorun çıkarıyor, merak ediyorum
  • Çalışma kopyasının otomatik olarak commit edilmesi iyi olmuş. Uzun zamandır ihtiyaç duyulan bir özellikti
    Zarif bir araç ortaya koymak için emek veren Martin’i alkışlıyorum