2 puan yazan GN⁺ 2025-06-05 | 1 yorum | WhatsApp'ta paylaş
  • Mevcut Unified Diff formatı, geliştirme ortamlarının gereksinimlerini yeterince yansıtamama gibi sınırlamalara sahip
  • DiffX, mevcut formatla tam uyumludur ve geleceği gözeten bir yapı ile metadata genişletilebilirliği sunar
  • Birden fazla commit bilgisi, binary dosya, karakter kodlaması ve metadata yapılandırılmış bir şekilde saklanabilir
  • Standartlaştırılmış parsing kuralları sayesinde çeşitli araçlarla (patch, code review vb.) kolay entegrasyon mümkündür
  • Mevcut araçlar ve workflow'lar içinde sorunsuz kullanılabilir; yalnızca yeni özellikler için ilgili araç desteği gerekir

Geliştiriciler ve Diff dosyaları

  • Yazılım geliştiriciler genellikle Git, Subversion, CVS gibi sistemlerde diff dosyalarıyla kod değişikliklerini inceler
  • Diff dosyaları, metin ekleme(+)·silme(-) ile dosya adı, yol, zaman damgası ve bazı metadata'ları içeren bir yapıya sahiptir
  • Çoğu araç ve kullanıcı Unified Diff formatını kullanır; bu yöntem farkları görece basit biçimde görselleştirir

Unified Diff'in sınırları

  • Unified Diff, yalnızca dosya tanımlama, değişiklik kapsamı ve eklenen·silinen satırları standartlaştırır; encoding, revision, genişletilmiş metadata gibi alanları standartlaştırmaz
  • Farklı source control system desteği, güvenilir parsing ve zengin bilgi çıkarımı zordur
  • Aşağıdaki sorunlar sürekli ortaya çıkar
    • Birden fazla commit aynı anda ifade edilemez
    • Binary dosyalar için özel bir standart format yoktur
    • Karakter kodlaması bilinmediği için bilgi kaybı ve karışıklık oluşur
    • Keyfi metadata için standardizasyon eksik olduğundan her araç farklı bir biçim kullanır

İyileştirme yönü

  • Mevcut Unified Diff, yapı ve standart açısından eksik olsa da esnekliği sayesinde çok çeşitli ortamlarda zaten yaygın biçimde kullanılmaktadır
  • Git Diff fiilen bir standart rolü oynasa da formatın resmi spesifikasyonu ve genel amaçlı genişletilebilirliği hâlâ yetersizdir
  • Mevcut Unified Diff'in güçlü yönlerini korurken, genişletilebilirlik ve standart yapı ekleyen yeni bir formata duyulan ihtiyaç artmaktadır

DiffX nedir

  • DiffX, mevcut araçlarla tam uyumlu olan genişletilebilir bir diff formatıdır; insan tarafından okunabilirliği korurken metadata ve yapıyı düzenli biçimde taşıyabilir
  • Sözdizimi örneği:
    • Dosya, commit ve tüm diff için metadata ile gövde içeriği, yapısal ve genişletilebilir bir yaklaşımla saklanır
    • Örnek çıktıda #diffx: gibi sözdizimiyle birlikte section'lar, metadata(JSON), dosya yolları ve commit bilgileri yer alır

DiffX'in başlıca avantajları

  • Standartlaştırılmış parsing kuralları sunar; araçlar bilgiyi güvenilir şekilde okuyup yazabilir
  • Metadata saklama ve yönetimini resmileştirir: tüm diff, commit ve dosya düzeyinde kullanılabilir
  • Mevcut parser, patcher, code review gibi tüm araçlarla uyumludur (yeni özellikler destek gerektirse de mevcut özelliklerde uyumluluk korunur)
  • Tek bir dosyada birden fazla commit, binary diff, metin encoding bilgisi gibi birden çok içerik verimli bir yapıyla ifade edilebilir
  • Araçların diff'i açıp gerekli bilgileri kaydetmesi, düzenlemesi ve yeniden saklaması için değiştirilebilirlik (mutability) desteği sunar

DiffX'in hedefleri ve hedeflemedikleri

  • Tüm araçlara bu formatı zorunlu kılmaz ve uyumluluk sorunları yaratmaz
  • Vendor lock-in oluşturmaz, mevcut workflow'ları bozmaz
  • Mevcut diff dosyalarının sorunlarını gidererek geliştirme, review ve analiz araçlarında tutarlı ve güvenilir bir kullanım deneyimi sağlar

1 yorum

 
GN⁺ 2025-06-05
Hacker News görüşleri
  • Ben ..meta ve ...meta gibi hiyerarşik olarak karmaşık formatları sevmiyorum. İfadenin açıklığı için yalnızca üç seviye ayırmak daha anlaşılır olurdu diye düşünüyorum: diff’in tamamı, dosya ve chunk; bunlara da ayrı adlar verilmesi formatı daha kolay okunur kılardı. Meta blok olmasa bile hedefi bir bakışta ayırt etmek mümkün olur, böylece hata ve yanlışlar da azalır. Diff’in tamamının metaverisi ile dosya düzeyindeki metaverinin aynı alanlardan oluşması da mantıksız görünüyor. Ayrıca neden hem JSON hem de key=value olmak üzere iki format gerektiğini anlamıyorum; yönetilecek şey azsa tek bir format kullanmak, uygulama ve mevcut araçlarla entegrasyon açısından çok daha faydalı olur (grep, sed ya da jq içinden biri yeter). Ek olarak listelerde trailing comma desteği iyi olurdu ve diff zaten doğası gereği parça parça uygulanabilen bir yapı olduğu için bu formatın buna nasıl etki ettiğini merak ediyorum (örneğin diff’in sadece bir kısmını uygulamak için preamble’ı da kopyalamak ve blokları ayrıca taşımak gerektiğinden zahmetli görünüyor). revision dosya özelliği mi yoksa commit checksum’ı mı, bunu da merak ediyorum.

    • Yapı için çeşitli yaklaşımlar denedikten sonra, sonunda parse etme açısından sadelik için #<section_level><section_type> biçiminde karar kıldık. Her meta blokta yalnızca dikey olarak seviyeyi kontrol etmek yeterli oluyor ve nokta sayısını sayınca hangi seviyedeki meta olduğu doğal olarak ayırt edilebiliyor. Anahtar/değer başlık formatı, parser’ın önceden bildiği basit özellikleri taşımak içindi; serbest metaveri ise ayrı bir meta bloğa konacak şekilde tasarlandı. Sadece mevcut JSON için değil, zamanla başka serileştirme yöntemleri gerekirse genişletilebilir olsun diye başlıkta format da belirtilebiliyor. Bu, sadelik ile esneklik arasında denge kurma çabasının sonucu. Trailing comma’yı kişisel olarak ben de isterdim ama temel seviye JSON uyumluluğu yüzünden JSON5 parser’ını zorunlu tutmak zor. Diff hâlâ bölünebilir; Unified Diff’in görmezden geldiği alanlara bilgi yerleştirdiğimiz için GNU patch gibi araçlarda bu bilgiler yok sayılıyor ve sorun çıkmıyor. Yine de iki DiffX dosyasına bölmek isterseniz başlığı yeniden eklemek gerekir, bu yüzden biraz daha karmaşık olabilir. Bazı SCM’lerde diff bölündüğünde kimi metaveriler (örneğin parent commit bilgisi) kaybolabilir ya da uygulama hedefine göre bilgi kaybı yaşanabilir. revision ise SCM’e göre değişir; commit ID, dosya başına ID veya bunların birleşimi, ek bilgiler gibi çok farklı ihtiyaçlar var. Yapı da SCM’lerin bu farklı gereksinimlerini karşılamak düşünülerek tasarlandı.
  • Bana göre aşağıdaki dört eleştiri arasında, diff dosyasının genelleştirilmesi açısından gerçekten makul olan tek nokta ikili yama gösterimi. Geri kalanlar belirli sürüm kontrol sistemlerinin (SCM) iç verileri ya da protokol sorunları; her birinin kendi istemcisi, sunucusu veya yedekleme sistemi içinde anlamlı şeyler. Diğerlerinin hepsi gereksiz görünüyor.

    • Tek bir diff içinde birden fazla commit sıralanamıyor

    • İkili patch için standart yok

    • Metin kodlaması algılanamıyor (beklenmedik derecede sorun oluyor)

    • Keyfi metaveri için standart bir format yok

    • Biz 20 yıldır 12’den fazla SCM ile entegre çalışan bir code review ürünü geliştiriyoruz ve hayal bile edemeyeceğiniz kadar çok diff formatı ve SCM’ye özgü sorunla karşılaştık. Son kullanıcının doğrudan ilgilenmesi gereken şeyler değiller ama araç geliştirme tarafında mutlaka çözülmesi gereken pain point’lerdi. Bazı SCM’lerin kendi diff formatı yok ya da eksik bilgi içeriyor (örneğin silinen dosyayı işaretleyemiyor), bu da diğer araçların dosyaları doğru tanımlayamamasına yol açıyor; o yüzden böyle iyileştirmelere ihtiyaç olduğunu düşündük.

    • Bugünlerde daha az yaygın olabilir ama ben de hâlâ zaman zaman patch(1) benzeri araçlar kullanıyorum. Farklı platformlardaki geliştiriciler birlikte çalışırken dosya adı büyük/küçük harf duyarlılığı, karakter kodlaması gibi nedenlerle çeşitli sorunlar hâlâ çıkabiliyor.

  • JSON’u uzunluk bilgisiyle birlikte self-delimitered bir format olarak gömmek demek, JSON içindeki tek bir boşluğu bile değiştirseniz JSON geçerli kalsa da DiffX’in bütün olarak bozulma riski taşıması demek. Yapısal olarak hantal ve dağınık bir birleşim gibi geliyor (kendi başlıklarıyla JSON payload’ının karışması, nokta saymadan farklı meta blokların ayırt edilememesi, iki ayrı parser gerektiren yapı vb.). Metaveri için genişletilebilir bir diff’i standartlaştırma fikri iyi ama bu uygulama deneme yanılma ürünü gibi duruyor.

  • Bence patch formatı zaten bütün bu sorunları çözüyor. git format-patch açıklama bağlantısı

    • Böyle bir format olduğunu bugün ilk kez öğrendim, not ettim (ben sıradan bir internet kullanıcısıyım, yazar değilim).

    • Git tarafında çözülebilir ama Review Board gibi bir ürün SVN, CVS, Perforce gibi birçok VCS ile entegre olmak zorunda; bu formatın çıkış nedeni de sanırım bu. Ben de Review Board ve SVN kullandım; birçok geliştirici git-svn ile svn’i karışık kullandığında review sırasında diff yüklemelerinde sık sık sorun yaşanıyordu. Her iki tarafın da desteklediği standart bir diff formatı olsaydı araç kullanımı çok daha kolay olurdu.

  • Açıkçası sunulan sorunların gerçekten var olduğunu pek hissetmiyorum (ikili dosyalar hariç).

    • Kodlama farklı olsa da patch algoritması aynı, o yüzden önemsemeye gerek yok (karakterlerin geçerli UTF-8 olması bile şart değil)

    • Tek bir diff içine birden fazla commit koyma ihtiyacı da yok; birkaç diff’e bölmek daha sezgisel

    • Metaveri zaten yalnızca sistem içinde geçerli değil mi diye düşünüyorum

    • Kodlama konusunda da patch verisi zaten ASCII tabanlı ikili veri gibi ele alınmalı. Karışık kodlamalarda dosya düzenlemek de mümkün olduğundan, kodlamayı sabitlemenin pek anlamı yok.

    • Bunun hiç sorun olmadığını düşünüyorum; diff’i gerçekten çok kullanan insanların gerçek deneyimlerini dinlemek daha iyi olur. Zaten çalışan bir formatı gereksiz yere overengineering etmemek lazım.

    • İkili veri sorununun ise kesinlikle var olduğunu düşünüyorum.

    • Genelde bu sorunlarla ancak doğrudan araç geliştirirken ya da belirli bir SCM ile arayüz kurarken karşılaşıyorsunuz.

      1. Kodlama sorunu hem dosya adlarında hem gövdede var. Git dosya adı kodlamasına dikkat ediyor ama çoğu SCM etmiyor; bu yüzden bir ortamda otomatik üretilen diff başka bir ortamda dosya adını bulamayabiliyor (Perforce, Subversion vb. ile gördüm). Gövde tarafında da SCM’ye bağlı yerel kodlama yüzünden diff bozulabiliyor. Windows ile Linux arasında gidip gelirken satır sonları karışıp patch uygulanamadığı ya da BOM yüzünden GNU patch’in bozulduğu durumlar yaşadım.
      2. Birden fazla commit’i aynı anda işlerken veya araçlara aktarırken eksik dosya, tutarlılık sorunu gibi çeşitli problemler çıkabiliyor ve diff’ler arasında tek tek sanity check yapmak zahmetli. Araçların desteklediği formatlar da farklı olduğundan iş zorlaşıyor.
      3. Depoda dosya bulmak için sistemden sisteme commit düzeyi, dosya düzeyi, bunların birleşimi ya da ilişki bilgileri gibi çeşitli tanımlayıcılar gerekiyor. Sembolik bağlantılar, dosya modu veya SCM’ye özgü özellikler gibi Unified diff’te yer almayan veriler de zorunlu olabiliyor.
  • Belgenin tamamı okunması zor geliyor. Benim için ‘diff’, iki öğe (dosya, dizin vb.) arasındaki fark demek ama TFA’daki diff benim bildiğim anlamda bir ‘patch’. Burada tartışılan şey diff değil, patch metaverisinin yönetimi. Metaveriyi JSON gibi zorunlu bir biçimde standartlaştırmak fena olmazdı ama muğlak bir self-describing, length-delimited yapı sanki sorunu gizliyor gibi. Standartlaştırma fikri iyi ama daha net düzenlenmiş bir çözüme ihtiyaç var gibi geliyor. Bana ilginç gelen bir başka şey de git diff tarzının fiili standarda daha yakın görünmesi.

    • Son cümleye tamamen katılıyorum; diff’i birkaç parçaya bölüp kullanmak yeterli.
  • Böyle bir formatın tam olarak hangi sorunu çözmeye çalıştığını merak ediyorum. Patch/diff formatlarının yeterince iyi olmadığı söyleniyor ama bunun kimin için bir iyileştirme olduğu, GNU Patch topluluğunda gerçekten artan bir memnuniyetsizlik mi bulunduğu, gerekçenin ne olduğu daha somut anlatılmalı. Gerçekten neden daha iyi bir patch formatına ihtiyaç duyulduğu konusunda soru işareti kalıyor.

    • Buraya sığmayacak kadar uzun bir yazıyı ayrıca derledim ama özeti şu: Bu, doğrudan SCM geliştirenler ya da SCM ile entegre araçlar yazanlar için bir mesele. Sıradan kullanıcıların ilgilenmesine gerek yok. Diff formatları da SCM’den SCM’ye tamamen farklı; gerçekten iyi tasarlanmış olanlar da var, ciddi biçimde yetersiz olanlar ya da hiç format sunmayanlar da. Review Board gibi birçok SCM’yi kapsaması gereken ürünler için böyle bir ortak standart pratikte gerçekten gerekli. Bu da SCM üreticileriyle çalışırken gelen geri bildirimleri yansıtan bir iyileştirme denemesi.

    • Daha çok Review Board çevresinde kullanılan bir format gibi görünüyor; bu ürün birçok VCS’yi destekliyor ve source review’da diff merkezi önemde olduğu için böyle bir yaklaşım benimsenmiş olmalı.

  • En genel ve açık diff gösterimi, iki dosyanın kendisini doğrudan içeren yöntemdir. Artık veri boyutu büyük mesele değil; diff a b | patch c yerine apply a b c gibi bir şey yapılsa, iç temsili ne olursa olsun fark etmez. Diff insanın okuması için zor, renkli yan yana görünüm çok daha iyi; bu yüzden baştan iki dosyanın da alınması daha sezgisel. Bu kadar standart dışı bir diff’in taşınmasına gerek olmadığını düşünüyorum.

    • İki dosyadan üretilen diff tek bir şey değil; farklı amaçlara uygun birden çok diff türü olabilir. Bir diff formatı olduğunda diff üretme mantığı ile uygulama mantığını ayırıp n*m problemini n+m problemine indirebilirsiniz.

    • Program güncellemelerinde her seferinde 130GB’nin tamamını yeniden indirmek sinir bozucu olurdu ama neredeyse aynı dosyalar kolay sıkıştırılabildiği için iki sürüm arasındaki farkı göndermek de gayet anlamlı. Sadece orijinal dosyanın hash’ini gönderip sıkıştırılmış veri gövdesini iletmek gibi daha verimli yöntemler de mümkün olabilir.

    • İki dosya çiftini taşımak ve yönetmek, özel bir kapsayıcı olmadan zordur; birden çok değişikliği (10 dosya değişikliği + silme + ekleme gibi) e-posta üzerinden paylaşırsanız, VCS öncesi dönemdeki gibi tar/zip benzeri karmaşık yapılara geri dönmüş gibi olursunuz.

    • Tam dosyaları göndermek daha sezgisel olsa bile, gerçek kullanım ve ortam koşullarına göre diff hâlâ çok önemli. Özellikle bugünlerde LLM ile kod düzenleme gibi çıktılar üretilirken istekleri diff olarak vermek token kullanımını ciddi biçimde azaltıyor, yanıt gecikmesini 5-10 kat düşürüyor ve belirgin verimlilik sağlıyor. Her iki dosyayı da göndermek token israfı ve ek maliyet demek. Kod sandbox’ına ya da uzak makineye hızlı uygulama için diff ciddi bir optimizasyon avantajı sunuyor. Elinizde A dosyası, A2 dosyası ve AxA2 diff’i varsa A2’yi yeniden kurmak da kolaylaşıyor, depo optimizasyonu da mümkün oluyor. Birleştirme sırasında çakışma çıkarsa ancak o zaman doğrudan müdahale etmek gerekir. Kısacası diff harika.

  • Diff araçlarının satır sonuna fazla bağımlı olmasından hâlâ rahatsızım. Bir satır çok uzun olduğunda (ör. JSON, uzun diziler vb.) inceleme yapmak zorlaşıyor.

    • Ben de katılıyorum. Yapılandırılmış veri için (ör. AST diff gibi) daha iyi diff gösterimlerini araştırmak için alan var. Bu formatın (DiffX) odak noktası, mevcut Unified Diff formatını genişletmekti; eğer AST gibi daha özel formatlar yaygınlaşırsa, onları da kolayca gömecek ve destekleyecek şekilde tasarlandı.

    • Yaygın biçim, insan okunabilirliği ile araçların parse edebilmesi arasında bir uzlaşma olduğu için biraz yarım kalmış bir yapı. Bu kez metaveri genişletmesiyle sorunun bir kısmı çözülmeye çalışılmış gibi ama gerçekten iyi bir çözüm, düz metin yerine hem okunabilir hem de parse edilebilir yeni bir format tanımlamak olabilir. Uzun satırlar ya da yapısal veri için mevcutlardan daha iyi diff algoritmaları geliştirmek zor bir iş ama bence gayet çözülebilir.

    • Git, satır diff’inden daha ayrıntılı word diff’i de destekliyor ve varsayılan ayırıcı boşluk karakteri.

  • JSON’un desteklenen tek metaveri formatı olması bana garip geliyor. Genel amaçlı bir metaveri standardı için JSON aslında gereksiz derecede karmaşık.

    • JSON’un neden gereksiz derecede karmaşık olduğunu düşündüğünü biraz daha somut anlatmanı merak ediyorum.