Pemeriksa Perbedaan Teks
Bandingkan dua teks dan temukan perbedaan secara seketika.
Tentang perbandingan teks
Alat diff ini menggunakan algoritma Longest Common Subsequence (LCS) untuk membandingkan dua teks baris demi baris. Penambahan disorot dengan warna hijau dan penghapusan dengan warna merah. Pilih tampilan "Inline" untuk melihat semua perubahan dalam satu kolom, atau "Berdampingan" untuk membandingkan teks asli dan modifikasi secara paralel.
Penggunaan umum
- Bandingkan perubahan kode sebelum committing
- Tinjau dokumen atau kontrak yang dimodifikasi
- Periksa perbedaan terjemahan
- Validasi perubahan file konfigurasi
- Bandingkan respons API
Pertanyaan umum
Apakah membandingkan karakter demi karakter?
Alat ini membandingkan baris demi baris. Jika sebuah baris memiliki perubahan sekecil apa pun (bahkan satu karakter saja), seluruh baris ditandai sebagai dimodifikasi. Ini adalah pendekatan yang sama yang digunakan oleh Git dan kebanyakan alat diff.
Apakah ada batas ukuran?
Tidak ada batas tegas, tetapi teks yang sangat besar (lebih dari 10.000 baris) mungkin perlu waktu sejenak untuk diproses, karena perbandingan dijalankan sepenuhnya di browser Anda.
Apa yang dimaksud «diff» sebenarnya
Sebuah diff menggambarkan cara mengubah satu teks menjadi teks lain menggunakan sekumpulan penyisipan dan penghapusan terkecil. Ada tak terhitung cara untuk melakukannya, yang sepele adalah «hapus setiap karakter dari A lalu sisipkan setiap karakter dari B.» Diff yang berguna adalah skrip pengeditan terpendek, yang merupakan kebalikan dari masalah Longest Common Subsequence: temukan urutan baris terpanjang yang muncul (secara berurutan) di kedua teks, dan segala hal lainnya adalah penambahan atau penghapusan. Sebagian besar algoritma diff adalah algoritma LCS dengan nama yang berbeda.
Poin halus: subsequence umum terpanjang bukan substring umum terpanjang. Subsequence mempertahankan urutan tetapi tidak ketetanggaan, sehingga «ABCDE» dan «AXBYCZD» berbagi subsequence «ABCD» meskipun tidak ada rangkaian tiga karakter berurutan yang muncul di keduanya.
Sejarah singkat algoritma diff
Program perbandingan file yang pertama kali digunakan secara luas adalah Unix diff yang ditulis oleh Douglas McIlroy di Bell Labs, dengan algoritma yang mendasarinya diterbitkan oleh James W. Hunt dan McIlroy sebagai Bell Labs Computing Science Technical Report #41 pada Juni 1976. McIlroy sendiri menggambarkan pengembangan empat bulan itu sebagai «upaya yang penuh keputusasaan.» Pendekatan Hunt-McIlroy melakukan hash setiap baris file B, mengindeks di mana setiap baris unik muncul, dan mencari rantai kecocokan monoton menaik yang terpanjang. Program ini dikirimkan di Version 6 Unix dan tetap menjadi algoritma yang sama di /usr/bin/diff pada sebagian besar sistem Unix selama beberapa dekade.
Eugene W. Myers menerbitkan standar industri modern pada tahun 1986, «An O(ND) Difference Algorithm and Its Variations» dalam Algorithmica Vol. 1, No. 2. Myers memformulasikan ulang LCS sebagai masalah jalur terpendek melalui graf pengeditan: tempatkan A di sumbu atas dan B di sisi kiri, gambar diagonal setiap kali dua baris cocok, dan cari jalur dari kiri-atas ke kanan-bawah dengan jumlah tepi non-diagonal paling sedikit. Setiap tepi non-diagonal adalah satu penyisipan atau penghapusan; setiap diagonal gratis. Yang krusial, algoritma ini berjalan dalam waktu O((N+M)·D) di mana D adalah ukuran skrip pengeditan, artinya semakin mirip file-filenya, semakin cepat algoritmanya. Untuk diff kontrol versi yang tipikal, D sangat kecil dibandingkan N+M, sehingga Myers secara dramatis lebih cepat dari kasus terburuk O(N·M) dalam praktiknya. Makalahnya juga mencakup penyempurnaan ruang linear menggunakan trik divide-and-conquer «middle snake». Algoritma Myers adalah default yang mendukung GNU diff, git diff, Mercurial, Subversion, jsdiff, difflib Python, dan sebagian besar penampil diff GUI.
Bram Cohen (yang kemudian lebih dikenal sebagai penemu BitTorrent) merancang patience diff untuk sistem kontrol versi Bazaar sekitar tahun 2002. Masalah yang memotivasi: Myers diff menyelaraskan baris mana pun yang cocok, termasuk yang sangat umum, sehingga memindahkan fungsi dalam C dapat menghasilkan diff yang berisik di mana kurung kurawal penutup dari fungsi yang dipindahkan sejajar dengan kurung kurawal penutup dari fungsi yang tidak terkait. Patience diff menjangkarkan diff pada baris yang muncul tepat sekali di setiap file (biasanya tanda tangan fungsi, header komentar, pesan log yang khas), menghitung LCS hanya dari jangkar tersebut menggunakan patience sort, dan melakukan rekursi pada celahnya. Hasilnya sejajar pada baris yang bermakna dan lebih mudah dibaca untuk kode sumber. Git mendukungnya melalui git diff --patience. Histogram diff adalah penyempurnaan yang ditambahkan ke git sekitar tahun 2010 yang membangun histogram kemunculan baris dan lebih menyukai jangkar berfrekuensi rendah daripada yang benar-benar unik; sejak git 2.45 dan seterusnya, ini adalah default untuk banyak konfigurasi.
Levenshtein vs LCS
Konsep terkait yang perlu dibedakan. Jarak Levenshtein (Vladimir Levenshtein, 1965) menghitung jumlah minimum penyisipan, penghapusan, dan substitusi satu karakter untuk mengubah satu string menjadi string lain. Diff berbasis LCS sangat terkait tetapi sedikit berbeda: diff klasik memperlakukan «perubahan» sebagai pasangan hapus-lalu-sisipkan daripada substitusi tunggal, karena itu lebih baik dipetakan ke file berorientasi baris. Levenshtein menjawab «seberapa berbeda string-string ini?» dan memberi Anda angka; LCS menjawab «apa yang berubah secara spesifik?» dan memberi Anda skrip pengeditan yang sebenarnya. Pemeriksa ejaan dan fitur «apakah maksud Anda?» menginginkan yang pertama; alat diff menginginkan yang kedua. Varian Damerau-Levenshtein (1964) memperluas Levenshtein dengan operator transposisi untuk deteksi kesalahan ketik.
Granularitas: baris, kata, dan karakter
Diff dapat dihitung pada granularitas yang berbeda, masing-masing dengan trade-off:
- Tingkat baris: setiap baris adalah satu token; dua baris entah cocok persis atau tidak. Cepat, cocok secara alami dengan cara programmer mengedit kode, menghasilkan patch ringkas yang dapat diterapkan oleh
patch(1). Kerugian: memformat ulang satu karakter dalam baris 200 karakter menandai seluruh baris sebagai berubah. Default untukdiff, git, SVN, dan alat ini. - Tingkat kata: setiap token yang dibatasi spasi adalah unit, sehingga baris yang mengubah satu kata hanya menampilkan kata itu yang disorot. Sangat baik untuk prosa, kontrak, draf blog. Digunakan oleh
git diff --word-diff, mode «Suggesting» Google Docs, «Track Changes» Microsoft Word, mode perbandingan-kata Diffchecker. - Tingkat karakter: setiap code point Unicode adalah unit. Menangkap kesalahan ketik satu karakter, ideal untuk redlining hukum di mana satu kata dapat mengubah makna. Lambat pada input besar dan terkadang tidak terbaca untuk pengeditan panjang.
Pola umum dalam UI diff modern adalah menghitung diff pada tingkat baris terlebih dahulu, lalu untuk setiap pasang «tetangga yang dihapus/ditambahkan» jalankan diff tingkat kata sekunder hanya pada dua baris tersebut dan sorot perubahan intra-baris. Itulah tepatnya cara kerja tampilan PR GitHub dan pustaka diff-match-patch.
Tiga mode tampilan diff yang akan Anda lihat
- Unified diff (format setiap file
.patch), hunk yang diperkenalkan oleh@@ -oldStart,oldLen +newStart,newLen @@dengan tiga baris konteks di atas dan bawah secara default. Berasal dari flag GNU diff-ubuatan Wayne Davison sekitar tahun 1990. Ringkas dan dapat dibaca mesin olehpatch(1), itulah mengapa git, patch email gaya kernel, dan SVN semuanya menggunakannya. - Side-by-side: asli di kiri, yang dimodifikasi di kanan, disejajarkan baris per baris.
diff -ymenghasilkan versi ASCII primitif; Beyond Compare, Meld, WinMerge, dan tampilan «Side by Side» di atas semuanya menggunakan format ini. Terbaik untuk tinjauan visual dan proofreading prosa. - Inline (bertumpuk): kolom tunggal di mana baris yang dihapus dan ditambahkan disatukan. Tampilan PR GitHub menggunakan ini secara default. Format paling hemat ruang untuk layar sempit dan pengeditan kecil.
Varian git diff yang berguna
git diff: index vs working tree.git diff --staged: HEAD vs index.git diff main..feature: ujung branch.main...featuremembandingkan terhadap merge base, apa yang akan di-landing oleh PR.git diff --word-diffdan--color-words: diff tingkat kata yang ramah markup dengan pewarnaan.git diff --no-index a.txt b.txt: bekerja pada file di luar repo git mana pun. Berguna sebagai diff mandiri dengan algoritma patience atau histogram.git diff -w: abaikan semua spasi (sesuai dengan kotak centang «Ignore whitespace» di atas).git diff --histogram: ganti algoritma per perintah.
Kapan Anda akan menggunakan diff di browser
- Tinjauan kode. Tempel dua versi file, periksa apa yang berubah, putuskan apakah perubahannya masuk akal.
- Meninjau kode yang diedit AI. Diff original Anda terhadap versi refaktored LLM untuk menemukan penyimpangan atau halusinasi.
- Redlining kontrak hukum. Konfirmasi bahwa hanya klausul yang disepakati yang berubah antara versi 3 dan versi 4.
- QA terjemahan. Bandingkan dua terjemahan Prancis dari paragraf yang sama, atau diff file lokalisasi sebelumnya dan yang diperbarui ketika hanya sejumlah kecil string yang seharusnya berubah.
- Penyimpangan konfigurasi. Bandingkan
nginx.confdari prod dengan staging. - Perbandingan skema SQL. Dump pernyataan
CREATE TABLEdari dua database dan diff untuk menemukan indeks yang hilang atau penyimpangan tipe kolom. - Penyimpangan spesifikasi. Diff dua versi OpenAPI / Swagger YAML untuk memverifikasi perubahan yang melanggar telah didokumentasikan.
- Draf blog Markdown. Temukan apa yang diedit oleh penulis bersama.
- Audit kepatuhan. Diff kebijakan privasi dari bulan ke bulan untuk regulator.
- Forensik file lock. Diff
package-lock.jsonatauyarn.lockuntuk memahami peningkatan dependensi.
Keterbatasan yang jujur
- Diff teks biasa tidak memiliki kesadaran semantik. Mengganti nama
foomenjadibardi seluruh file terlihat identik biayanya dengan penulisan ulang yang sama sekali tidak terkait. Alat seperti difftastic mengurai AST bahasa dan menghasilkan diff struktural («function added», «argument reordered»). Halaman ini tidak demikian, ini adalah diff baris LCS biasa. - Spasi dan akhir baris menyebabkan diff palsu. CRLF vs LF, spasi trailing, tab vs spasi. Toggle «Ignore whitespace» di atas dipetakan ke
-wmilik git. - File biner tidak cocok. Diff adalah konsep teks. Untuk diff biner ada alat seperti
bsdiff,xdelta, atau VBinDiff. - Sensitivitas urutan. Diff baris mengasumsikan dokumen diedit baris per baris. Untuk CSV tidak tersortir atau pengurutan ulang kunci objek JSON, Anda perlu mengurutkan atau menganonikalisasi terlebih dahulu.
- Deteksi pemindahan. Diff LCS klasik tidak mengenali bahwa sebuah fungsi dipindahkan di dalam file, ia menampilkan pemindahan sebagai penghapusan ditambah penyisipan. Beyond Compare, Meld, dan difftastic mencoba deteksi pemindahan; halaman ini tidak.
Pertanyaan lainnya
Mengapa halaman ini tidak menampilkan sorotan tingkat karakter di dalam baris yang berubah?
Karena pass tingkat baris sudah cukup untuk sebagian besar kasus penggunaan dan berjalan jauh lebih cepat pada input panjang. Untuk penyorotan kata-per-kata intra-baris, penyempurnaan dua langkah adalah praktik standar tetapi menambah latensi. Jika perbedaan seluruh baris penting bagi Anda (redlining hukum, proofreading prosa), alat tingkat kata khusus (termasuk git diff --word-diff di baris perintah) lebih sesuai.
Apa perbedaan antara unified diff dan side-by-side?
Unified diff adalah format ringkas yang dapat dibaca mesin yang digunakan setiap file .patch, tiga baris konteks, hunk ditandai dengan @@. Side-by-side menampilkan dua versi dalam kolom paralel, yang lebih nyaman secara visual untuk tinjauan tetapi membutuhkan lebih banyak ruang horizontal. Unified adalah yang Anda kirim melalui email atau commit; side-by-side adalah yang Anda baca di monitor lebar.
Apakah ada algoritma yang lebih baik dari Myers untuk kode sumber?
Untuk kode sumber dengan fungsi yang dipindahkan atau penataan ulang besar, ya, patience diff (Bram Cohen, 2002) dan histogram diff (git, sekitar 2010) dirancang untuk menyelaraskan pada baris unik yang bermakna daripada yang umum, menghasilkan output yang lebih mudah dibaca. Keduanya tersedia melalui git diff --patience dan git diff --histogram. Alat yang sadar AST seperti difftastic melangkah lebih jauh dan mengurai struktur bahasa yang sebenarnya.
Apakah aman menempel teks rahasia di sini?
Ya, diff berjalan sepenuhnya di browser Anda menggunakan implementasi LCS JavaScript. Tidak ada yang diunggah, tidak ada analitik pada input, tidak ada log teks di sisi server. Ini adalah satu-satunya kategori alat diff yang aman untuk NDA, kode sumber internal, atau klausul kontrak yang belum dirilis; layanan diff berbasis cloud melihat apa pun yang Anda tempel.