Perintah diff Linux: bandingkan berkas, direktori, dan buat patch

Perintah diff membandingkan dua berkas teks atau dua pohon direktori dan menunjukkan perbedaannya. Gunakan diff -u untuk membaca perubahan beserta konteksnya, misalnya saat meninjau konfigurasi, kode sumber, atau membuat patch. Pada GNU diff, status keluar 1 berarti ada perbedaan; status ini perlu dibedakan dari kesalahan pelaksanaan.

Apa yang dibandingkan oleh diff?

Diff menghitung perubahan baris yang diperlukan untuk mengubah masukan pertama menjadi masukan kedua. Urutan argumen menentukan arah perubahan: menukar kedua nama berkas akan menukar peran versi lama dan baru. Perintah perbandingannya tidak mengubah isi kedua masukan.

Pada GNU diff, status 0 berarti tidak ada perbedaan menurut opsi yang dipakai, status 1 berarti ada perbedaan, dan status 2 berarti terjadi masalah, misalnya masukan tidak dapat dibaca. Tidak adanya keluaran saja belum cukup untuk memastikan keberhasilan: periksa juga status keluar dan pesan kesalahan pada keluaran standar galat.

Sintaks dasar

diff [OPSI]... BERKAS1 BERKAS2
diff [OPSI]... DIREKTORI1 DIREKTORI2

Ganti penanda dengan jalur yang benar-benar ada. Kutip jalur yang mengandung spasi, misalnya diff -u "konfigurasi lama.conf" "konfigurasi baru.conf". Contoh opsi di sini mengacu pada GNU Diffutils; periksa diff --version, diff --help, dan man diff pada sistem tujuan karena implementasi dan versi bisa berbeda.

Penggunaan dasar diff

Bandingkan dua berkas

Siapkan dua salinan konfigurasi, misalnya old.conf sebagai versi awal dan new.conf sebagai versi yang telah diubah. Format bawaan memakai notasi perubahan tradisional: huruf a menunjukkan penambahan, c penggantian, dan d penghapusan. Nomor di sekitarnya menunjuk baris dalam masukan pertama dan kedua; baris berawalan < berasal dari berkas pertama, sedangkan > berasal dari berkas kedua.

diff old.conf new.conf

Tampilkan perubahan beserta konteksnya

Format unified menggabungkan baris lama, baris baru, dan konteks dalam satu kelompok perubahan. GNU diff menampilkan tiga baris konteks secara bawaan jika tersedia; opsi seperti -U 5 meminta lima baris. Format ini membantu memastikan letak perubahan di antara baris yang tetap sama.

diff -u old.conf new.conf

Bandingkan direktori secara rekursif

Opsi -r melanjutkan perbandingan ke subdirektori yang bersesuaian. Contoh ini menggabungkannya dengan format unified. Nama direktori harus menunjuk dua salinan proyek yang hendak dibandingkan; jalankan dari direktori induk keduanya atau gunakan jalur lengkap.

diff -ru project-old project-new

Berkas yang hanya ada di satu sisi biasanya dilaporkan sebagai Only in .... Perintah ini tidak otomatis menghasilkan patch penambahan atau penghapusan untuk semua berkas tersebut. Perbandingan isi juga bukan pemeriksaan lengkap kepemilikan, izin, atau metadata cadangan.

Membaca tanda perubahan dan status keluar

Untuk mencoba tanpa menyentuh konfigurasi asli, buat direktori latihan kosong dan jalankan contoh berikut di dalamnya. Dua perintah printf membuat berkas latihan before.txt dan after.txt; jika nama tersebut sudah ada, isinya akan ditimpa.

printf 'old\n' > before.txt
printf 'new\n' > after.txt
diff -u before.txt after.txt

Keluaran memuat header --- untuk berkas pertama, header +++ untuk berkas kedua, lalu penanda kelompok seperti @@ -1 +1 @@. Bagian perubahan isinya adalah:

-old
+new

Awalan - menandai baris yang dihapus dari versi pertama, sedangkan + menandai baris yang ditambahkan pada versi kedua. Baris konteks diawali spasi. Header nama berkas yang juga diawali tanda minus atau plus bukan baris isi yang dihapus atau ditambahkan.

Segera sesudah diff, jalankan printf '%s\n' "$?" untuk melihat status perintah sebelumnya. Pada contoh ini hasilnya 1 karena old berbeda dari new. Perintah lain yang dijalankan di antaranya akan mengganti nilai $?; simpan terlebih dahulu dengan status=$? jika nilainya masih diperlukan.

Opsi utama

Opsi Kegunaan
-u Tampilkan perubahan dalam format unified beserta konteks.
-r, --recursive Bandingkan subdirektori secara rekursif.
-q, --brief Laporkan apakah berkas berbeda tanpa rincian baris.
-s, --report-identical-files Laporkan juga pasangan berkas yang sama.
-w, --ignore-all-space Abaikan perbedaan spasi putih di dalam baris; batas baris tetap penting.
-b, --ignore-space-change Abaikan perbedaan jumlah spasi putih serta spasi putih di akhir baris.
-i, --ignore-case Abaikan perbedaan huruf besar dan kecil pada isi berkas.
--color=auto Warnai keluaran terminal pada versi GNU yang mendukungnya; berkas hasil pengalihan biasa tidak memerlukan kode warna.

Opsi pengabaian mengubah arti “sama” dalam hasil perbandingan. Sebagai contoh, -b dapat menganggap satu dan beberapa spasi di antara kata sama, tetapi tetap membedakan tidak adanya pemisah dari adanya pemisah. -w juga dapat menyembunyikan perbedaan tersebut. Keduanya tidak berarti semua perubahan baris kosong diabaikan.

Contoh praktis

Buat berkas patch

Gunakan direktori latihan yang sama. Siapkan original.conf dengan cp before.txt original.conf dan modified.conf dengan cp after.txt modified.conf. Lalu simpan perubahan dari versi awal ke versi baru:

diff -u original.conf modified.conf > config.patch

Pengalihan > membuat atau menimpa config.patch, sedangkan kedua konfigurasi tetap utuh. Status 1 pada langkah ini wajar bila patch memuat perubahan. Jalur relatif pada header ditafsirkan dari lokasi kerja saat patch diterapkan; gunakan lokasi yang konsisten dan periksa header sebelum membagikannya.

Jika GNU patch tersedia, uji pada salinan latihan dengan patch --dry-run original.conf < config.patch. Setelah pratinjau berhasil, patch original.conf < config.patch menerapkan perubahan; cmp original.conf modified.conf seharusnya selesai tanpa keluaran dan berstatus 0. Untuk membalikkan latihan yang baru saja diterapkan, gunakan patch -R original.conf < config.patch. Jangan menganggap pembalikan aman bila berkas sudah diedit lagi; simpan salinan sebelum mengubah berkas nyata.

Ringkas perbedaan direktori

Untuk dua direktori rilis yang sudah ada, gabungan -qr menampilkan nama berkas yang berbeda dan entri yang hanya ada di satu sisi. Ini berguna untuk memilih berkas yang perlu diperiksa lebih rinci dengan diff -u.

diff -qr release-a release-b

Perbedaan isi menghasilkan laporan seperti Files ... differ; entri satu sisi dilaporkan sebagai Only in .... Status 0 menunjukkan tidak ada perbedaan yang dilaporkan, 1 menunjukkan perbedaan, dan 2 menunjukkan masalah pemeriksaan. Diff tidak menyalin, menghapus, atau menyelaraskan kedua direktori.

Abaikan perubahan jumlah spasi

Contoh berikut memakai dua berkas latihan sebelumnya. Karena kata old dan new berbeda, opsi -b tetap melaporkan perubahan. Untuk melihat efek opsi tersebut, bandingkan berkas yang isinya hanya berbeda antara a b dan a b, masing-masing diakhiri baris baru: diff biasa melaporkan perbedaan, tetapi diff -b tidak.

diff -u -b before.txt after.txt

Gunakan pengabaian hanya jika spasi memang tidak memengaruhi makna. Pada Python atau format yang memakai indentasi, perbedaan yang disembunyikan dapat mengubah perilaku. Perbandingan LF dan CRLF juga dapat memperlihatkan perbedaan akhir baris; opsi GNU --strip-trailing-cr tersedia bila normalisasi itu memang sesuai tujuan pemeriksaan.

Perbandingan dengan perintah terkait

Perintah Peran utama Kapan digunakan
diff Perbedaan teks per baris. Meninjau konfigurasi, kode sumber, dan isi direktori.
cmp Perbandingan per bita; biasanya melaporkan perbedaan pertama. Memeriksa kesamaan isi dan posisi perbedaan, termasuk data biner.
git diff Perbandingan perubahan dalam alur kerja Git. Meninjau direktori kerja, staging, atau commit; pilihan argumen menentukan pasangan yang dibandingkan.
comm Memisahkan baris bersama dan baris unik dari dua masukan terurut. Membandingkan daftar yang telah diurutkan memakai aturan pengurutan yang sama.

Jika perlu memeriksa posisi perbedaan bita, tersedia panduan cmp dalam bahasa Inggris. Diff berfokus pada isi, sehingga hasilnya tidak membuktikan bahwa semua atribut sistem berkas dua berkas identik.

Hal yang perlu diperhatikan

Bedakan perbedaan dan kesalahan pada skrip

Jangan menganggap semua status bukan nol sebagai gangguan perbandingan. Perintah yang dirangkai dengan && tidak meneruskan langkah berikutnya saat diff berstatus 1; shell dengan set -e juga memerlukan penanganan yang sesuai konteks. Letakkan diff sebagai kondisi if bila skrip perlu memproses kedua hasil, lalu ambil $? segera pada cabang else untuk membedakan 1 dari kesalahan 2.

Pilih perbandingan yang sesuai untuk data biner

Diff biasanya hanya melaporkan bahwa berkas biner berbeda. Memaksanya sebagai teks tidak selalu menghasilkan keluaran yang berguna. Gunakan cmp jika pertanyaannya adalah kesamaan bita atau lokasi perbedaan pertama, dan periksa statusnya juga.

Pastikan opsi tidak menyembunyikan perubahan penting

Perbedaan huruf besar-kecil, spasi, dan akhir baris dapat bermakna bagi format tertentu. Mulailah dengan perbandingan tanpa opsi pengabaian, kemudian tambahkan opsi yang benar-benar sesuai kebutuhan. Hasil kosong sesudah pengabaian berarti tidak ada perbedaan yang dilaporkan dengan aturan itu, bukan jaminan bahwa kedua berkas identik per bita.

FAQ

Apa arti diff tidak menampilkan keluaran?

Jika statusnya 0, tidak ada perbedaan yang perlu dilaporkan menurut opsi yang dipilih. Periksa pesan kesalahan dan status sebelum menyimpulkan kesamaan.

Format mana yang mudah dibaca untuk meninjau perubahan?

Format unified dari diff -u biasanya praktis karena menyertakan konteks. Perhatikan urutan berkas agar arah penambahan dan penghapusannya benar.

Bisakah diff membandingkan seluruh direktori?

Gunakan -r untuk menelusuri subdirektori yang bersesuaian, atau -qr untuk ringkasan. Hasilnya merupakan perbandingan isi, bukan sinkronisasi atau audit seluruh metadata.

Apakah status keluar 1 menandakan kesalahan?

Pada GNU diff, 1 berarti perbedaan ditemukan, 0 berarti tidak ada perbedaan menurut aturan perbandingan, dan 2 berarti terjadi masalah.

Dokumentasi