Tools Review

OmniDiff: Difftool Git Content-Aware di Rust dengan Klaim 99,95 Persen

OmniDiff: Difftool Git Content-Aware di Rust dengan Klaim 99,95 Persen

OmniDiff adalah difftool berbasis Rust yang membaca tipe berkas sebelum membandingkannya, jadi PDF, font, gambar, dan arsip tidak lagi muncul sebagai "binary file differs". Menurut README-nya, alat ini bisa mem-diff 99,95 persen perubahan kode, dan 98,8 persen perubahan diproses dengan algoritma yang khusus untuk jenis kontennya. Waktu proses diklaim di bawah 100 milidetik, diukur pada ThinkPad T14s dengan Intel Core i7-1370P dan RAM 32 GB. Repo ivankovic/omnidiff saat ini punya 167 bintang dan riwayat 1.514 commit.

TL;DR

  • OmniDiff memilih algoritma diff berdasarkan tipe berkas: kode memakai parser tree-sitter, gambar dan font dibandingkan secara visual, arsip dibandingkan per entri.
  • Klaim utamanya tiga: 99,95 persen perubahan bisa di-diff, 98,8 persen lewat algoritma spesifik konten, dan waktu proses di bawah 100 ms.
  • Bisa dipasang lewat cargo, Homebrew, repo apt resmi untuk Debian dan Ubuntu, Nix, serta resep Arch dan Gentoo.
  • Untuk CI dan skrip, ada mode headless dan output JSON, dengan konvensi exit code yang mengikuti diff(1).

Apa bedanya OmniDiff dengan git diff biasa?

git diff membandingkan baris teks dan menyerah pada berkas biner, sementara OmniDiff memilih cara pembandingan sesuai jenis berkas. Untuk kode sumber, ia memakai grammar tree-sitter yang dikompilasi dari C, sehingga yang dibandingkan adalah struktur, bukan sekadar urutan baris. Untuk PDF, font, dan gambar, ia menghasilkan laporan ringkas tentang apa yang berubah.

Perbedaan ini paling terasa saat review kode sehari-hari. git diff akan menampilkan satu blok besar sebagai "diubah" ketika sebuah fungsi dipindahkan, sedangkan diff yang sadar struktur bisa menandai bahwa isinya sama dan hanya posisinya yang bergeser. Halaman showcase menampilkan 20 perubahan kode nyata yang direkam dari versi command line, dibandingkan berdampingan dengan diff Unix biasa.

AspekOmniDiffgit diff / diff -u
Kesadaran struktur kodeYa, lewat grammar tree-sitterTidak, berbasis baris
Berkas binerLaporan per tipe: gambar, font, arsip, PDF, katalog pesanHanya keterangan "binary files differ"
AntarmukaTUI interaktif, mode headless, output JSONTeks biasa ke pager
Exit code saat berkas berbeda0 secara default, 1 hanya dengan --exit-code1 saat ada perbedaan
Cara pasangcargo, Homebrew, apt, Nix, Arch, GentooSudah ada di sistem

Baris exit code itu bukan detail sepele. OmniDiff sengaja mengembalikan 0 meski berkas berbeda, karena pemanggil non-interaktifnya adalah sistem kontrol versi yang memperlakukan exit code bukan nol sebagai kegagalan alat. README menyebut kasus konkret: git difftool dengan difftool.trustExitCode=true akan membatalkan seluruh proses diff kalau alatnya keluar dengan kode selain nol.

Bagaimana cara memasangnya?

Paling cepat lewat cargo, dengan syarat rustc 1.92 atau lebih baru dan sebuah compiler C di PATH. Build pertama butuh beberapa menit karena semua grammar tree-sitter dikompilasi dari C dan profil rilisnya memakai lto = "fat".

cargo install --locked omnidiff

Untuk yang tidak mau kompilasi sendiri, ada tiga jalur resmi:

  • Homebrew di macOS dan Linux: brew install ivankovic/omnidiff/omnidiff
  • Debian dan Ubuntu: paket .deb untuk amd64 dan arm64 di repo apt bertanda tangan, kuncinya tersedia di situs proyek
  • Nix: nix run github:ivankovic/omnidiff, dengan tambahan flag experimental kalau flake belum aktif

Resep Arch dan Gentoo tersedia di direktori packaging, tapi README menyebut dua distro itu belum menerima paketnya ke repo resmi. Binary prebuilt untuk Linux, macOS Intel, macOS Apple Silicon, dan Windows menempel di setiap rilis GitHub.

Kapan sebaiknya dipakai, dan kapan tidak?

Pakai saat review perubahan besar atau saat harus memeriksa perubahan pada berkas non-teks, karena di situ nilai tambahnya paling jelas. Jangan pakai sebagai pengganti git diff di dalam skrip yang bergantung pada exit code untuk mendeteksi perbedaan, karena defaultnya 0.

Integrasi git-nya sederhana. Jalankan wizard omnidiff git configure, atau set manual:

git config difftool.omnidiff.cmd 'omnidiff "$LOCAL" "$REMOTE"'
git difftool --tool=omnidiff

Untuk menjadikannya default, set git config diff.tool omnidiff. Satu jebakan yang dijelaskan README: git diff dan git log -p tidak akan pernah membuka TUI, karena outputnya dialirkan ke pager dan TUI layar penuh tidak bisa menggambar ke pipe. Kalau ingin viewer interaktif dari git, gunakan git difftool, bukan git diff. Detail konfigurasinya ada di dokumentasi git-difftool.

Ada juga jalur tanpa konfigurasi difftool, lewat variabel GIT_EXTERNAL_DIFF:

GIT_EXTERNAL_DIFF=omnidiff git diff

Jalur ini dipakai README untuk menegaskan satu hal: berkas yang tidak bisa ditampilkan dilaporkan sebagai diff kosong yang sukses, bukan kegagalan. Alasannya sama seperti soal exit code tadi, satu berkas yang gagal tidak boleh membatalkan seluruh tampilan diff.

Apakah cocok untuk CI dan otomasi?

Cocok, dalam batas tertentu. Mode headless aktif otomatis ketika stdout bukan terminal, jadi omnidiff BEFORE AFTER | less langsung berjalan tanpa flag tambahan. Flag --exit-code memberi exit 1 saat berkas berbeda, mengikuti konvensi diff(1), dan itu yang dibutuhkan skrip untuk mengambil keputusan.

Untuk pemrosesan lanjutan, --mode json mencetak satu objek JSON berisi seluruh diff, dengan skema di src/tui/json_output.schema.json. Ini berguna kalau hasilnya mau dimasukkan ke laporan atau diteruskan ke alat lain tanpa mem-parsing teks berwarna.

Ada juga alat pendamping bernama codereview untuk melihat perubahan di browser, tapi README menandainya masih v0.0.0 dan menyuruh memakainya dengan risiko sendiri. Untuk produksi, jangan bergantung pada alat itu dulu.

Seberapa akurat klaim "perfect" di README?

Menariknya, README sendiri tidak mengklaim sempurna untuk semua tipe. Tabel akurasinya memisahkan tingkat "perfect" dan "near-perfect" per jenis konten, dan untuk kode sumber angka perfect-nya 98 persen, sementara untuk PDF turun jauh ke 57 persen dengan kurang dari sepuluh kasus uji yang dinilai. Artinya klaim pemasaran di bagian atas halaman dan tabel detail di bawahnya tidak sama, dan yang kedua lebih jujur.

Ini penting karena PDF adalah format yang paling sulit di-diff secara bermakna: urutan objek di dalamnya bisa berubah total tanpa perubahan visual sama sekali. Kalau pekerjaan kalian banyak berurusan dengan PDF, uji dulu pada berkas nyata sebelum mengandalkannya.

Apa yang perlu diperhatikan sebelum mengadopsi?

Pertama, lisensinya ganda: ada LICENSE dan LICENSE-COMMERCIAL di root repo, jadi pastikan dulu mana yang berlaku untuk pemakaian kalian. Kedua, build dari source butuh rantai alat yang lengkap, bukan sekadar cargo. Ketiga, integrasi editor masih terbatas: ekstensi VS Code ada, tapi README menyatakan API upstream untuk mengganti tampilan diff bawaan belum dirilis, jadi ekstensinya belum bisa mengambil alih sepenuhnya.

Untuk Neovim ada omnidiff.nvim yang terpisah. Untuk Jujutsu, OmniDiff menyediakan wizard omnidiff jj configure, karena jj tidak membaca setelan difftool git meski repo-nya colocated. Ini detail kecil yang biasanya jadi sumber frustrasi di hari pertama pemakaian, dan README menanganinya dengan cukup rapi.

Yang belum jelas dari README adalah performa pada repo besar dengan ribuan berkas berubah. Angka di bawah 100 ms diukur pada mesin tertentu tanpa menyebut ukuran diff-nya, jadi anggap itu batas bawah, bukan jaminan untuk monorepo.

Bagaimana perilakunya di repo besar?

Belum ada data publik soal performa pada repo dengan ribuan berkas berubah. Angka di bawah 100 ms diukur pada mesin tertentu tanpa menyebut ukuran diff, jadi angka itu lebih tepat dibaca sebagai batas bawah pada perubahan kecil dan sedang.

Yang bisa diperkirakan dari desainnya: karena OmniDiff mengompilasi grammar tree-sitter per jenis bahasa, biaya awal saat membuka diff pada repo yang punya banyak bahasa campuran akan lebih tinggi daripada diff berbasis baris. Untuk repo satu bahasa dengan perubahan wajar, biaya itu tidak terasa.

Apa alternatif yang sudah ada?

Sebelum OmniDiff, orang biasanya memakai diff bawaan git yang dipercantik oleh pager, misalnya diff-so-fancy atau delta. Keduanya menyelesaikan masalah estetika, bukan masalah pemahaman struktur: keduanya tetap membandingkan baris, dan tetap menyerah pada berkas biner.

Perbedaan posisinya kira-kira begini. Pager memperbaiki tampilan output git diff, sedangkan OmniDiff mengganti cara diff-nya dihitung. Kalau keluhan utama kalian adalah "sulit dibaca", pager sudah cukup. Kalau keluhannya "perubahan ini tidak terbaca sama sekali karena semua baris dianggap berubah", OmniDiff menawarkan pendekatan yang berbeda.

Yang perlu diuji sendiri sebelum memutuskan memakai alat ini: buka diff pada satu berkas yang paling sering kalian ubah, lalu bandingkan hasilnya dengan git diff biasa. Kalau perbedaannya tidak terasa, berarti masalah utama tim kalian bukan pada cara diff dihitung, dan biaya memasang alat baru tidak akan kembali.

Sebaliknya, kalau review kalian sering macet pada berkas yang "berubah semua padahal isinya sama", alat ini menyerang tepat masalah tersebut. Uji pada dua sampai tiga berkas nyata, bukan pada repo demo, karena nilai OmniDiff baru muncul ketika strukturnya rumit.

Satu catatan soal ekosistem: banyak difftool muncul dan menghilang karena hanya membungkus output git diff. OmniDiff memilih jalur yang lebih sulit, yaitu mem-parsing berkas sebelum membandingkan, dan konsekuensinya ia harus merawat grammar untuk setiap bahasa yang didukung. Itu beban pemeliharaan yang nyata, tapi juga alasan mengapa ia bisa menawarkan hal yang tidak bisa dilakukan pembungkus tampilan.

FAQ

Apakah OmniDiff menggantikan git difftool sepenuhnya?

Bisa, dengan setelan diff.tool omnidiff dan difftool.prompt false. Tapi ia tetap alat tampilan: git diff biasa akan jatuh ke teks karena output dialirkan ke pager, hanya git difftool yang membuka TUI.

Berapa ukuran repo dan seberapa aktif proyeknya?

Repo GitHub-nya mencatat 167 bintang dan 1.514 commit pada saat artikel ini ditulis. Riwayat commit yang panjang dengan 1.514 entri menunjukkan proyek ini bukan eksperimen akhir pekan.

Apakah butuh Rust untuk memakainya?

Tidak, kalau memakai binary prebuilt, Homebrew, atau repo apt. Rust baru dibutuhkan kalau memasang lewat cargo dari source, dan README menyebut minimal rustc 1.92 disertai compiler C.

Bisakah dipakai di CI untuk memutuskan lolos atau gagal?

Bisa, dengan flag --exit-code. Tanpa flag itu, alat ini keluar dengan kode 0 meski ada perbedaan, karena defaultnya dirancang untuk dipanggil sistem kontrol versi sebagai penampil, bukan sebagai pemeriksa.

Apakah PDF benar-benar bisa dibandingkan?

Bisa, tapi akurasinya paling lemah menurut tabel di README sendiri, yaitu 57 persen pada kategori perfect dengan kurang dari sepuluh kasus uji. Untuk dokumen PDF yang kritis, tetap lakukan pemeriksaan visual manual.

💬 Komentar (0)

Belum ada komentar. Jadilah yang pertama! 💬

Komentar yang memuat tautan, bahasa asing, atau aksara non-Latin ditahan dulu buat ditinjau.