2 poin oleh GN⁺ 2025-06-05 | 1 komentar | Bagikan ke WhatsApp
  • Format Unified Diff yang ada saat ini memiliki keterbatasan karena belum cukup mencerminkan kebutuhan lingkungan pengembangan modern
  • DiffX sepenuhnya kompatibel dengan format yang ada, sekaligus menawarkan struktur yang siap untuk masa depan dan kemampuan perluasan metadata
  • Berbagai informasi commit, file biner, encoding karakter, dan metadata dapat disimpan dengan cara yang terstruktur
  • Dengan diperkenalkannya aturan parsing yang terstandarisasi, beragam alat (patch, code review, dll.) dapat terintegrasi dengan mudah
  • Tetap dapat digunakan tanpa masalah pada alat dan workflow yang ada, dan hanya fitur baru yang memerlukan dukungan alat terkait

Pengembang dan file Diff

  • Pengembang perangkat lunak biasanya memeriksa riwayat perubahan kode melalui file diff di Git, Subversion, CVS, dan lainnya
  • File diff memiliki struktur yang mencakup penambahan teks (+)·penghapusan (-), serta nama file, path, timestamp, dan sebagian metadata
  • Sebagian besar alat dan pengguna memakai format Unified Diff, dan pendekatan ini memvisualisasikan perbedaan dengan relatif sederhana

Keterbatasan Unified Diff

  • Unified Diff hanya menstandarkan identifikasi file, cakupan perubahan, dan baris yang ditambahkan atau dihapus, tetapi tidak menstandarkan encoding, revisi, atau metadata tambahan
  • Akibatnya, dukungan untuk berbagai sistem manajemen sumber kode, parsing yang andal, dan ekstraksi informasi yang kaya menjadi sulit
  • Masalah berikut terus muncul
    • Tidak bisa merepresentasikan beberapa commit sekaligus
    • Kurangnya format standar khusus untuk file biner
    • Karena encoding karakter tidak diketahui, dapat terjadi kehilangan informasi dan kebingungan
    • Karena standardisasi metadata arbitrer belum memadai, bentuknya berbeda-beda di tiap alat

Arah perbaikan

  • Unified Diff yang ada saat ini kekurangan struktur dan standardisasi, tetapi tetap fleksibel dan sudah telanjur tersebar luas di berbagai lingkungan
  • Git Diff pada praktiknya berperan sebagai standar, tetapi masih kurang dalam hal spesifikasi format resmi dan perluasan yang benar-benar umum
  • Karena itu, kebutuhan akan format baru yang mempertahankan kelebihan Unified Diff sekaligus menambahkan kemampuan perluasan dan struktur standar semakin besar

Apa itu DiffX

  • DiffX adalah format diff yang dapat diperluas, sepenuhnya kompatibel dengan alat yang sudah ada, tetap mudah dibaca manusia, dan pada saat yang sama dapat menyimpan metadata dan susunan konten secara terstruktur
  • Contoh sintaks:
    • Metadata dan isi untuk file, commit, maupun seluruh diff disimpan secara terstruktur dengan pendekatan yang dapat diperluas
    • Dalam contoh output, terdapat sintaks seperti #diffx:, beserta section, metadata (JSON), path file, informasi commit, dan lainnya

Fitur utama DiffX

  • Menyediakan aturan parsing yang terstandarisasi, sehingga alat dapat membaca dan menulis informasi dengan andal
  • Memformalkan penyimpanan dan pengelolaan metadata: dapat digunakan pada tingkat seluruh diff, commit, maupun file
  • Kompatibel dengan semua alat yang ada seperti parser, patcher, code review, dan lainnya (fitur baru memang memerlukan dukungan, tetapi kompatibilitas fitur lama tetap terjaga)
  • Dalam satu file, dapat merepresentasikan beberapa jenis konten seperti beberapa commit, diff biner, dan informasi encoding teks dengan struktur yang efisien
  • Mendukung mutability: alat dapat membuka diff, mencatat atau mengubah informasi yang diperlukan, lalu menyimpannya kembali

Arah yang dituju dan yang tidak dituju oleh DiffX

  • Tidak memaksa semua alat untuk mendukung format ini dan tidak menciptakan masalah kompatibilitas
  • Tidak menimbulkan vendor lock-in dan tidak merusak workflow yang ada
  • Bertujuan mengatasi masalah pada file diff yang ada dan memberikan pengalaman penggunaan yang konsisten serta andal pada alat pengembangan, review, dan analisis

1 komentar

 
GN⁺ 2025-06-05
Opini Hacker News
  • Saya tidak suka format yang rumit secara hierarkis seperti ..meta dan ...meta. Demi kejelasan ekspresi, menurut saya akan lebih mudah dipahami jika hanya dibagi menjadi tiga tingkat—seluruh diff, file, dan chunk—lalu masing-masing diberi nama yang berbeda. Bahkan tanpa blok meta, targetnya bisa dibedakan sekilas sehingga kesalahan atau error juga bisa berkurang. Metadata untuk keseluruhan diff dan metadata tingkat file yang memakai field yang sama juga terasa tidak masuk akal. Dan saya juga tidak paham kenapa perlu dua format, yaitu JSON dan key=value; kalau objek yang dikelola sedikit, memakai satu format saja jauh lebih menguntungkan untuk implementasi maupun integrasi dengan tool yang sudah ada (cukup pakai salah satu dari grep, sed, atau jq). Selain itu, akan bagus kalau trailing comma diizinkan dalam daftar. Saya juga penasaran bagaimana format ini memengaruhi sifat asli diff yang bisa diterapkan secara terpisah (misalnya, kalau ingin menerapkan hanya sebagian diff, rasanya merepotkan karena harus menyalin preamble dan blok secara terpisah). Saya juga bertanya-tanya apakah revision itu atribut file atau checksum commit.

    • Kami bereksperimen dengan berbagai pendekatan untuk struktur, dan pada akhirnya merapikannya menjadi bentuk #<section_level><section_type> demi kesederhanaan dari sudut pandang parsing. Untuk setiap blok meta, parser cukup memeriksa level secara vertikal, dan dengan menghitung jumlah titik, level metadata-nya bisa langsung dibedakan. Format header key/value dimaksudkan untuk hanya memuat properti sederhana yang sudah diketahui parser sebelumnya, sedangkan metadata bebas dirancang untuk dimasukkan ke blok meta terpisah. Selain JSON yang ada sekarang, format di header juga bisa menyatakan cara serialisasi lain bila suatu saat dibutuhkan, sehingga tetap punya ekstensibilitas. Ini hasil upaya menyeimbangkan kesederhanaan dan fleksibilitas. Secara pribadi saya ingin menambahkan trailing comma, tetapi sulit menjadikan parser JSON5 sebagai syarat wajib karena masalah kompatibilitas dengan JSON level dasar. Diff tetap bisa dipisah-pisah, dan karena informasinya ditempatkan di area yang diabaikan Unified Diff, tool seperti GNU patch juga akan mengabaikannya tanpa masalah. Namun, jika satu file DiffX dipecah menjadi dua file DiffX, header memang harus ditambahkan lagi sehingga bisa sedikit lebih rumit. Pada beberapa SCM, diff yang dipecah bisa kehilangan sebagian metadata (misalnya informasi parent commit), atau bisa terjadi kehilangan informasi tergantung target penerapannya. Revision berbeda-beda di tiap SCM; kebutuhannya sangat beragam, bisa berupa commit ID, ID per file, kombinasi keduanya, atau informasi tambahan lain. Strukturnya dirancang dengan mempertimbangkan beragam kebutuhan lintas SCM.
  • Menurut saya, dari empat poin kritik di bawah ini, satu-satunya yang benar-benar masuk akal sebagai generalisasi file diff hanyalah notasi patch biner. Sisanya adalah persoalan data internal atau protokol milik sistem version control (SCM) tertentu, jadi isinya hanya berlaku di client, server, atau sistem backup masing-masing. Yang lain tampak tidak perlu.

    • Tidak bisa mencantumkan banyak commit dalam satu diff

    • Tidak ada standar untuk patch biner

    • Tidak bisa mengenali encoding teks (ternyata ini cukup bermasalah)

    • Tidak ada format standar untuk metadata arbitrer

    • Selama 20 tahun kami mengembangkan produk code review yang mengintegrasikan lebih dari 12 SCM, dan kami sudah menghadapi tak terhitung banyaknya masalah format diff serta persoalan spesifik tiap SCM yang tak pernah terpikir sebelumnya. Memang ini bukan hal yang biasanya perlu diperhatikan end user secara langsung, tetapi dari sisi pengembangan tool, ini adalah pain point yang memang harus diselesaikan. Beberapa SCM bahkan tidak punya format diff sendiri, atau informasinya banyak yang hilang (misalnya tidak bisa menandai file yang dihapus), sehingga tool lain sering gagal mengidentifikasi file dengan benar. Karena itu kami merasa perbaikan seperti ini memang diperlukan.

    • Sekarang memang lebih jarang, tetapi saya sendiri masih cukup sering memakai tool mirip patch(1). Saat developer dari berbagai platform berkolaborasi, masalah seperti huruf besar/kecil pada nama file dan encoding karakter masih sering muncul.

  • Jika JSON dimasukkan sebagai format self-delimited bersama informasi panjangnya, maka walaupun JSON tetap valid hanya dengan mengubah satu spasi kosong di dalam isinya, DiffX secara keseluruhan bisa berisiko rusak. Kombinasi ini terasa clunky dan messy secara struktural (campuran header khusus dan payload JSON, tidak bisa membedakan blok meta tanpa menghitung jumlah titik, dan struktur yang butuh dua parser). Gagasan untuk menstandarkan diff yang bisa diperluas untuk metadata itu bagus, tetapi implementasi kali ini terlihat seperti hasil trial and error.

  • Saya rasa format patch sudah menyelesaikan semua masalah ini: tautan penjelasan git format-patch

    • Baru hari ini saya tahu ada format seperti itu, terima kasih referensinya (saya cuma pengguna internet biasa, bukan penulis artikel).

    • Di git ini memang bisa diselesaikan, tetapi untuk produk seperti Review Board yang harus terintegrasi dengan banyak VCS seperti SVN, CVS, dan Perforce, tampaknya inilah latar belakang munculnya format seperti ini. Saya juga pernah memakai Review Board dan SVN, dan ketika beberapa developer mencampur git-svn dan svn, upload diff untuk review cukup sering bermasalah. Kalau ada format diff standar yang didukung kedua belah pihak, tool seperti ini pasti akan jauh lebih terbantu.

  • Saya sendiri tidak terlalu merasa bahwa masalah-masalah yang diajukan itu benar-benar ada (kecuali file biner).

    • Walaupun encoding berbeda, algoritma patch tetap sama jadi tidak perlu dipikirkan (karakternya juga tidak harus berupa utf-8 yang valid)

    • Saya juga tidak pernah merasa perlu menaruh banyak commit dalam satu diff; membaginya menjadi beberapa diff lebih intuitif

    • Saya menduga metadata hanya valid di dalam sistem masing-masing saja

    • Soal encoding juga, data patch pada akhirnya memang harus diperlakukan seperti data biner berbasis ascii. File dengan mixed encoding pun bisa saja dimodifikasi, jadi menetapkan satu encoding terasa tidak terlalu bermakna.

    • Menurut saya ini sama sekali bukan masalah. Lebih baik mendengar pengalaman nyata dari pengguna yang benar-benar sering memakai diff. Tidak perlu meng-overengineering format yang sejauh ini sudah bekerja dengan baik.

    • Menurut saya persoalan data biner memang jelas nyata.

    • Biasanya masalah seperti ini benar-benar muncul saat Anda membuat tool sendiri atau harus berinteraksi dengan SCM tertentu.

      1. Masalah encoding ada baik di nama file maupun isi. Git memperhatikan encoding nama file, tetapi kebanyakan SCM tidak, sehingga diff yang dibuat otomatis di satu lingkungan kadang tidak bisa menemukan nama file di lingkungan lain (saya melihat ini di Perforce dan Subversion). Isi file juga bisa membuat diff rusak tergantung encoding lokal tiap SCM. Saat bolak-balik antara Windows dan Linux, campuran karakter newline bisa membuat patch gagal diterapkan, atau masalah BOM pernah membuat GNU patch rusak.
      2. Saat banyak commit ditangani sekaligus atau diteruskan ke tool, berbagai masalah bisa muncul seperti file yang hilang atau inkonsistensi, dan merepotkan untuk melakukan sanity check satu per satu antar diff. Format yang didukung tiap tool juga berbeda-beda, jadi tidak nyaman.
      3. Untuk menemukan file di repositori, tiap sistem memerlukan berbagai identifier seperti tingkat commit, tingkat file, kombinasinya, atau informasi relasi. Data seperti symbolic link, mode file, atau informasi khas SCM yang tidak masuk ke Unified diff juga sering penting.
  • Dokumen keseluruhan terasa sulit dibaca. Bagi saya, ‘diff’ berarti perbedaan antara dua item (file, direktori, dan sebagainya), tetapi diff yang dibicarakan TFA sebenarnya adalah ‘patch’ yang saya kenal. Yang dibahas di sini bukan diff, melainkan pengelolaan metadata patch. Kalau metadata itu distandardisasi sebagai format wajib seperti JSON, mungkin tidak masalah, tetapi struktur self-describing length-delimited yang ambigu ini terasa seperti menyembunyikan masalah. Upaya standarisasinya sendiri bagus, tetapi menurut saya perlu solusi yang disusun lebih jelas. Menarik juga bahwa menurut saya gaya git diff justru terasa lebih dekat ke standar de facto.

    • Saya sepenuhnya setuju dengan kalimat terakhir itu, cukup bagi diff menjadi beberapa bagian.
  • Saya penasaran masalah apa sebenarnya yang ingin diselesaikan format ini. Katanya format patch/diff yang ada sekarang kurang memadai, tetapi untuk siapa perbaikannya, apakah komunitas GNU Patch memang makin sering mengeluh, atau apa alasannya, itu perlu dijelaskan lebih konkret. Saya masih penasaran kenapa format patch yang lebih baik benar-benar dibutuhkan.

    • Saya pernah menulis penjelasan yang terlalu panjang untuk dimasukkan di sini, tetapi ringkasnya ini adalah pertimbangan untuk para pengembang yang membuat SCM sendiri atau tool yang terintegrasi dengan SCM. Pengguna umum tidak perlu memikirkannya. Format diff juga berbeda-beda di tiap SCM; ada yang sangat bagus, ada yang sangat kurang, bahkan ada yang sama sekali tidak punya format. Dari sudut pandang produk seperti Review Board yang harus mencakup banyak SCM, standar terpadu seperti ini benar-benar diperlukan secara praktis. Ini adalah upaya perbaikan yang juga mencerminkan masukan dari kolaborasi dengan vendor SCM.

    • Ini tampak seperti format yang terutama dipakai untuk Review Board; karena produk ini mendukung berbagai VCS dan diff adalah inti dari source review, masuk akal kalau mereka mengadopsinya.

  • Representasi diff yang paling umum dan paling jelas adalah dengan langsung menyertakan dua file. Sekarang ukuran data bukan lagi masalah besar, jadi daripada diff a b | patch c, bisa saja dibuat seperti apply a b c, dan representasi internalnya bebas apa pun. Diff sulit dibaca manusia, dan tampilan side-by-side berwarna jauh lebih baik, jadi dari awal lebih intuitif untuk menerima kedua file lalu memprosesnya. Saya rasa tidak perlu bersikeras mengirim diff yang tidak distandardisasi.

    • Diff yang dibuat dari dua file tidak hanya satu macam; bisa ada banyak versi untuk tujuan yang berbeda. Dengan adanya format diff, logika pembuatan diff dan penerapannya bisa dipisahkan sehingga masalah n*m dapat dikurangi menjadi n+m.

    • Untuk hal seperti update program, menerima ulang seluruh file 130GB setiap kali tentu menjengkelkan. Karena file yang hampir sama juga mudah dikompresi, mengirim hanya perbedaan antara dua versi file tetap punya manfaat nyata. Bahkan mungkin ada cara yang lebih efisien, seperti hanya mengirim hash file asli lalu mentransfer arsip terkompresi utamanya.

    • Mengirim dan mengelola dua pasang file itu sulit tanpa kontainer khusus. Jika banyak perubahan (misalnya 10 file diubah + dihapus + ditambahkan) harus dipertukarkan lewat email dan semacamnya, rasanya malah mundur ke era pra-VCS yang bergantung pada struktur rumit seperti tar/zip.

    • Walaupun mengirim seluruh file mungkin lebih intuitif daripada diff, dalam penggunaan dan lingkungan nyata diff tetap sangat penting. Sekarang saat LLM dipakai untuk menghasilkan hasil seperti edit kode, meminta dalam bentuk diff bisa sangat menghemat token dan mengurangi latensi respons sampai 5–10 kali, sehingga efisiensinya meningkat drastis. Mengirim kedua file sekaligus boros token dan mahal. Untuk penerapan cepat di code sandbox atau mesin jarak jauh, diff memberi keuntungan optimasi yang besar. Jika ada file A, A2, dan diff AxA2, merekonstruksi A2 juga mudah dan optimasi penyimpanan pun memungkinkan. Jika muncul konflik merge, baru saat itu campur tangan manual diperlukan. Singkatnya, diff itu hebat.

  • Saya masih kesal karena tool diff terlalu bergantung pada unit baris. Kalau satu baris terlalu panjang (misalnya JSON, array panjang, dan sebagainya), review jadi sulit.

    • Saya juga setuju. Dalam data terstruktur (misalnya AST diff), masih banyak ruang untuk mengeksplorasi cara representasi diff yang lebih baik. Format ini (DiffX) berfokus sebagai perluasan dari format Unified Diff yang ada sekarang, dan jika nanti format yang lebih spesifik seperti AST dipakai luas, format ini juga dirancang agar bisa dengan mudah disematkan dan didukung.

    • Bentuk yang umum dipakai memang kompromi antara keterbacaan manusia dan kemudahan parsing tool, jadi strukturnya terasa serba tanggung. Kali ini tampaknya mereka mencoba menyelesaikan sebagian masalah lewat perluasan metadata, tetapi solusi yang benar-benar bagus mungkin justru menetapkan format baru yang bukan plain text, namun tetap mudah dibaca dan diparse. Membuat algoritma diff yang lebih baik untuk baris panjang atau data terstruktur memang tantangan sulit, tetapi menurut saya sangat mungkin untuk dipecahkan.

    • git juga mendukung word diff yang lebih rinci daripada line diff, dan pemisah bawaan yang dipakai adalah spasi.

  • Saya ragu dengan fakta bahwa JSON adalah satu-satunya format metadata yang didukung. Untuk standar metadata yang dirancang untuk tujuan umum, JSON justru terasa terlalu rumit.

    • Saya ingin mendengar penjelasan lebih spesifik kenapa Anda menganggap JSON terlalu rumit.