Utilitas Diff Semantik [ditutup]

105

Saya mencoba menemukan beberapa contoh bagus dari utilitas diff / merge semantik. Paradigma tradisional dari membandingkan file kode sumber bekerja dengan membandingkan baris dan karakter .. tetapi apakah ada utilitas di luar sana (untuk bahasa apa pun) yang benar-benar mempertimbangkan struktur kode saat membandingkan file?

Misalnya, program diff yang ada akan melaporkan "perbedaan ditemukan pada karakter 2 baris 125. File x berisi void, di mana file y berisi bool". Alat khusus harus dapat melaporkan "Jenis pengembalian metode doSomething () diubah dari void ke bool".

Saya berpendapat bahwa jenis informasi semantik ini sebenarnya adalah apa yang dicari pengguna saat membandingkan kode, dan harus menjadi tujuan alat pemrograman generasi berikutnya. Apakah ada contohnya di alat yang tersedia?

jasonmray
sumber
3
Sepertinya sudah ada penelitian yang dilakukan tentang jarak edit pohon. Menerapkan itu ke AST sepertinya itu akan menjadi hal pertama yang dicoba. (Jika seseorang ingin mencoba menulis hal semacam ini.)
Jay Kominek
2
Saya tidak yakin apakah itu benar-benar berguna. perbedaan seperti yang Anda sebutkan lebih mudah dilihat daripada dibaca, terutama jika Anda memiliki alat yang menyoroti perbedaan dalam satu baris. kemampuan untuk mengenali jika beberapa kode baru saja dipindahkan tanpa perubahan akan lebih mudah dan lebih berguna, imho!
UncleZeiv
2
@UncleZeiv Saya berharap fitur tersebut secara alami mengikuti sifat dari alat tersebut. Selain itu, ini akan dapat mendeteksi bahwa tidak ada perubahan jika seseorang melalui dan mengubah tanda kurung kurawal atau gaya indentasi, misalnya, atau mengatur ulang file sehingga metode statis dikelompokkan, dll ..
jasonmray
8
Saya membutuhkan ini di Visual Studio sekarang. Memaksa pengembang dalam tim untuk menggunakan struktur pemformatan yang sama untuk memfasilitasi perbedaan adalah berpikir mundur. Kode harus diformat ke beberapa standar saat check-in, dan setiap kali pengembang membuka file, itu harus diformat sesuai dengan keinginan mereka. Saya terkejut pemikiran semacam ini tidak tersebar luas pada saat ini.
Langdon
3
IMHO ini adalah topik yang bagus untuk SO. Jika Anda setuju, pilih untuk "membuka kembali"
Ira Baxter

Jawaban:

37

Kami telah mengembangkan alat yang mampu menangani skenario ini dengan tepat. Periksa http://www.semanticmerge.com

Ini menggabungkan (dan diff) berdasarkan struktur kode dan tidak menggunakan algoritma berbasis teks, yang pada dasarnya memungkinkan Anda untuk menangani kasus-kasus seperti berikut, yang melibatkan refactor yang kuat. Itu juga dapat membuat perbedaan dan konflik penggabungan seperti yang Anda lihat di bawah ini:

masukkan deskripsi gambar di sini

Dan alih-alih menjadi bingung dengan blok teks yang dipindahkan, karena ia mengurai terlebih dahulu, ia dapat menampilkan konflik pada basis per metode (sebenarnya per elemen). Kasus seperti sebelumnya bahkan tidak akan memiliki konflik manual untuk diselesaikan.

masukkan deskripsi gambar di sini

Ini adalah alat penggabung yang memahami bahasa dan sangat menyenangkan akhirnya dapat menjawab pertanyaan SO ini :-)

pablo
sumber
Apakah mungkin untuk mengintegrasikannya dengan SVN?
Revious
1
Namun, versi Linux dan Mac sudah kuno.
Michael Piefel
29

Eclipse memiliki fitur ini sejak lama. Ini disebut "Perbandingan Struktur", dan ini sangat bagus. Berikut adalah contoh tangkapan layar untuk Java, diikuti oleh yang lain untuk file XML:

(Perhatikan ikon minus dan plus pada metode di panel atas.)

Pembanding Struktur Java Eclipse XML Structure Comparer dari Eclipse

Hosam Aly
sumber
3
Apakah Perbandingan Struktur memungkinkan Anda menggabungkan perubahan seperti editor gabungan kontrol sumber lainnya? Ie Salin metode ini dari versi ini ke versi lain.
Jonathan Parker
1
Ya, saat Anda memilih perubahan atau perbedaan (baik di panel atas atau bawah), tombol toolbar (ditampilkan di tangkapan layar) memberi Anda opsi untuk menyalin perubahan dari kiri ke kanan atau sebaliknya.
Hosam Aly
1
Sayangnya, tangkapan layar tidak lagi terlihat di jawaban Anda (diberi suara positif tertinggi dan diterima!). Bisakah Anda mengirimkannya lagi?
blubb
@blubb Terima kasih telah memberi tahu saya. Saya telah memperbaiki kesalahan dengan gambar Java Comparer. Saya akan mencoba menambahkan tangkapan layar untuk XML Structure Comparer segera.
Hosam Aly
1
Dan apakah itu berfungsi untuk bahasa selain Java?
einpoklum
14

Untuk melakukan "perbandingan semantik" dengan baik, Anda perlu membandingkan pohon sintaks bahasa, dan mempertimbangkan arti simbol. Perbedaan semantik yang sangat bagus akan memahami semantik bahasa, dan menyadari ketika satu blok kode memiliki fungsi yang setara dengan yang lain. Untuk melangkah sejauh ini membutuhkan teorema prover, dan meskipun akan sangat lucu, saat ini tidak praktis untuk alat yang nyata.

Perkiraan yang bisa diterapkan dari ini hanyalah membandingkan pohon sintaks, dan melaporkan perubahan dalam hal struktur yang disisipkan, dihapus, dipindahkan, atau diubah. Semakin mendekati "perbandingan semantik", seseorang dapat melaporkan bila pengenal diubah secara konsisten di seluruh blok kode.

Lihat http://www.semanticdesigns.com/Products/SmartDifferencer/index.html kami untuk mesin perbandingan berbasis pohon sintaks yang bekerja dengan banyak bahasa, yang melakukan pendekatan di atas.

EDIT Jan 2010: Versi tersedia untuk C ++, C #, Java, PHP, dan COBOL. Situs web menunjukkan contoh spesifik untuk sebagian besar ini.

EDIT Mei 2010: Python dan JavaScript ditambahkan.

EDIT Okt 2010: EGL ditambahkan.

EDIT November 2010: VB6, VBScript, VB.net ditambahkan

Ira Baxter
sumber
2
Hai Ira, apakah Anda sudah menerbitkan makalah tentang algoritme diff Anda? Saya kesulitan menemukan literatur perbedaan jarak sunting pohon. Terima kasih, Terence.
Terence Parr
Untuk lebih spesifik, cari diff3 bukan diff2 biasa
Terence Parr
2
@Terence: Tidak ada publikasi dari algoritma diff kami. Ini adalah komputasi jarak min Levenstein menggunakan pohon sufiks untuk mengidentifikasi subpohon yang sama, dengan beberapa huerstics untuk menangani penggantian nama. IIRC, Yang memiliki makalah tentang ini dalam Praktik dan Pengalaman Perangkat Lunak. Milik kita dan Yang adalah diff2, bukan diff3.
Ira Baxter
@IraBaxter Tautan saat ini rusak dan situs sepertinya turun saat membuka dari tautan google.
Răzvan Flavius ​​Panda
Situs sudah di-backup, link harus oke.
Ira Baxter
12

Apa yang Anda cari adalah "perbedaan pohon". Ternyata ini jauh lebih sulit untuk dilakukan dengan baik daripada perbedaan tekstual berorientasi garis sederhana, yang sebenarnya hanyalah perbandingan dua urutan datar.

" Pendekatan Perbandingan Struktural XML Berbutir Halus " diakhiri, sebagian dengan:

Studi teoritis kami serta evaluasi eksperimental kami menunjukkan bahwa metode yang diusulkan menghasilkan peningkatan hasil kesamaan struktural sehubungan dengan alternatif yang ada, sementara memiliki kompleksitas waktu yang sama (O (N ^ 2))

(penekanan saya)

Memang, jika Anda mencari lebih banyak contoh perbedaan pohon, saya sarankan untuk fokus pada XML karena itu telah mendorong perkembangan praktis di bidang itu.

bendin
sumber
Terima kasih untuk tautannya. Saya dapat memikirkan beberapa pendekatan berbeda untuk mengimplementasikan alat diff sematic, dan Anda benar - kebanyakan dapat disarikan menjadi "tree diff". Situasi yang lebih kompleks bahkan mungkin perlu disarikan menjadi "grafik diff".
jasonmray
Ya. Pemodel Rasional IBM (dibangun di atas gerhana) mencoba melakukan ini dengan model UML (menunjukkan perbedaan antara dua model secara grafis). Saya tidak dapat berkomentar tentang kegunaan hasil karena saya tidak banyak menggunakannya.
bendin
Saya setuju bahwa XML adalah tempat yang baik untuk memulai, karena Anda dapat dengan mudah membuat skema untuk mewakili struktur lain (seperti kode java, misalnya), dan menggunakan pohon-diff berbasis XML untuk mengimplementasikan kode diff.
jasonmray
"lakukan ini" => lakukan sesuatu yang mirip dengan "perbedaan grafik".
bendin
1
Lihat semdesigns.com/Products/SmartDifferencer/index.html untuk mesin perbandingan berbasis pohon sintaks yang bekerja dengan banyak bahasa.
Ira Baxter
2

Solusi untuk ini akan berdasarkan per bahasa. Yaitu, kecuali jika dirancang dengan arsitektur plugin yang menolak banyak penguraian kode menjadi pohon dan perbandingan semantik dengan plugin khusus bahasa, maka akan sangat sulit untuk mendukung banyak bahasa. Bahasa apa yang Anda minati untuk memiliki alat semacam itu. Secara pribadi saya suka satu untuk C #.

Untuk C # ada add-in diff assembly untuk Reflector tetapi hanya melakukan diff pada IL bukan C #.

Anda dapat mengunduh add-in diff di sini [zip] atau pergi ke proyek di situs codeplex di sini .

Jonathan Parker
sumber
1
Lihat semdesigns.com/Products/SmartDifferencer/index.html untuk mesin perbandingan berbasis pohon sintaks yang bekerja dengan banyak bahasa, menggunakan persis gaya plugin bahasa. Belum dirilis, tapi versi C # sudah sangat dekat.
Ira Baxter
Jan 2010: C # Smart Differencer dirilis.
Ira Baxter
2

Sebuah perusahaan bernama Zynamics menawarkan alat diff semantik tingkat biner. Ini menggunakan bahasa rakitan meta yang disebut REIL untuk melakukan analisis teoretis grafik dari 2 versi biner, dan menghasilkan grafik berkode warna untuk menggambarkan perbedaan di antara keduanya. Saya tidak yakin dengan harganya, tapi saya ragu itu gratis.

David V McKay
sumber
Tautan ke diff semantik tingkat biner: zynamics.com/bindiff.html
emallove
2

http://prettydiff.com/

Pretty Diff mengecilkan setiap masukan untuk menghapus komentar dan spasi kosong yang tidak perlu, lalu mempercantik kode sebelum algoritma diff. Saya tidak bisa memikirkan untuk menjadi kode semantik lebih dari ini. Dan, JavaScript-nya tertulis sehingga berjalan langsung di browser.

austincheney.dll
sumber
5
Maka Anda memiliki imajinasi yang terbatas! Bagaimana dengan menukar posisi dua metode dalam file sementara membiarkannya tidak berubah? Bagaimana dengan refactorings?
Robin Green
(Anda tidak dapat menukar deklarasi data di Java dengan cara ini, dan masih memiliki kesetaraan, karena penginisialisasi; Saya berasumsi C # memiliki masalah yang sama). Jika Anda menggunakan diff semantik murni, maka Anda mencoba menyelesaikan kesetaraan mesin Turing. Ada banyak rentang untuk melakukan lebih baik daripada pencocokan teks murni, dan lebih buruk daripada Turing tidak mungkin.
Ira Baxter
@IraBaxter Alat secara konseptual jelas hanya akan ditampilkan sebagai hal-hal ekuivalen yang sebenarnya ekuivalen. Jika dikodekan dengan benar, itu tidak akan memiliki jenis masalah yang Anda sebutkan.
Răzvan Flavius ​​Panda
"Kode yang benar" berarti membuktikan kesetaraan algoritme jika Anda menginginkan alat pamungkas. Bukti kesetaraan algoritme pada umumnya bersifat Turing-hard, jadi Anda tidak akan mendapatkan alat seperti itu dalam praktiknya. Apa yang mungkin Anda dapatkan adalah alat yang menangani beberapa persamaan selain perubahan sintaks. Sampai saat ini, saya belum melihat ada orang yang mencoba membuat alat seperti itu.
Ira Baxter