อรรถประโยชน์ความแตกต่าง [ปิด]


106

ฉันกำลังพยายามหาตัวอย่างที่ดีของยูทิลิตี้ความแตกต่าง / ผสานความหมาย กระบวนทัศน์ดั้งเดิมของการเปรียบเทียบไฟล์ซอร์สโค้ดทำงานโดยการเปรียบเทียบบรรทัดและตัวอักษร .. แต่มียูทิลิตี้ใดบ้าง (สำหรับภาษาใด ๆ ) ที่พิจารณาโครงสร้างของโค้ดเมื่อเปรียบเทียบไฟล์หรือไม่?

ตัวอย่างเช่นโปรแกรม diff ที่มีอยู่จะรายงาน "พบความแตกต่างที่อักขระ 2 ของบรรทัด 125 ไฟล์ x มีโมฆะโดยที่ไฟล์ y มีบูล" เครื่องมือพิเศษควรสามารถรายงาน "Return type of method doSomething () เปลี่ยนจาก void เป็น bool"

ฉันขอยืนยันว่าข้อมูลเชิงความหมายประเภทนี้เป็นสิ่งที่ผู้ใช้กำลังมองหาเมื่อเปรียบเทียบโค้ดและควรเป็นเป้าหมายของเครื่องมือโปรแกมรุ่นต่อไป มีตัวอย่างในเครื่องมือที่มีอยู่หรือไม่?


3
ดูเหมือนว่าจะมีการวิจัยเกี่ยวกับระยะการแก้ไขต้นไม้ การใช้สิ่งนั้นกับ AST ดูเหมือนว่าจะเป็นสิ่งแรกที่ควรลอง (ถ้ามีคนอยากลองเขียนเรื่องแบบนี้)
Jay Kominek

2
ฉันไม่แน่ใจว่ามันจะมีประโยชน์จริงๆ ความแตกต่างเช่นเดียวกับที่คุณกล่าวถึงจะเห็นได้ง่ายกว่าการอ่านโดยเฉพาะอย่างยิ่งถ้าคุณมีเครื่องมือที่เน้นความแตกต่างภายในบรรทัด ความสามารถในการรับรู้ว่าโค้ดบางส่วนถูกย้ายไปรอบ ๆ โดยไม่มีการเปลี่ยนแปลงจะง่ายกว่าและมีประโยชน์มากกว่านี้ imho!
UncleZeiv

2
@UncleZeiv ฉันหวังว่าคุณลักษณะนี้จะเป็นไปตามธรรมชาติของเครื่องมือ นอกจากนี้จะสามารถตรวจพบว่าไม่มีการเปลี่ยนแปลงใด ๆ หากมีคนเดินผ่านและเปลี่ยนรูปแบบปีกกาหรือการเยื้องตัวอย่างเช่นหรือจัดเรียงไฟล์ใหม่เพื่อให้มีการจัดกลุ่มวิธีการคงที่เป็นต้น
jasonmray

8
ฉันต้องการสิ่งนี้ใน Visual Studio ทันที การบังคับให้นักพัฒนาภายในทีมใช้โครงสร้างการจัดรูปแบบเดียวกันเพื่ออำนวยความสะดวกต่าง ๆ คือการคิดแบบถอยหลัง รหัสควรได้รับการจัดรูปแบบให้เป็นมาตรฐานในการเช็คอินและเมื่อใดก็ตามที่นักพัฒนาเปิดไฟล์ควรจัดรูปแบบตามความต้องการ ฉันตกใจมากที่ความคิดแบบนี้ไม่ได้กระจายออกไปในวงกว้าง
Langdon

3
IMHO นี่เป็นหัวข้อที่ดีสำหรับ SO หากคุณเห็นด้วยให้โหวต "เปิดใหม่"
Ira Baxter

คำตอบ:


37

เราได้พัฒนาเครื่องมือที่สามารถจัดการกับสถานการณ์นี้ได้อย่างแม่นยำ ตรวจสอบhttp://www.semanticmerge.com

มันผสาน (และแตกต่าง) ตามโครงสร้างโค้ดและไม่ใช้อัลกอริทึมแบบข้อความซึ่งโดยพื้นฐานแล้วจะช่วยให้คุณจัดการกับกรณีต่างๆดังต่อไปนี้ซึ่งเกี่ยวข้องกับ refactor ที่แข็งแกร่ง นอกจากนี้ยังสามารถแสดงทั้งความแตกต่างและความขัดแย้งในการผสานดังที่คุณเห็นด้านล่าง:

ป้อนคำอธิบายภาพที่นี่

และแทนที่จะสับสนกับบล็อกข้อความที่ถูกย้ายเนื่องจากจะแยกวิเคราะห์ก่อนจึงสามารถแสดงความขัดแย้งตามวิธีการ (ต่อองค์ประกอบ) กรณีเช่นก่อนหน้านี้จะไม่มีความขัดแย้งด้วยตนเองให้แก้ไข

ป้อนคำอธิบายภาพที่นี่

เป็นเครื่องมือผสานที่รับรู้ภาษาและเป็นเรื่องที่ดีมากที่สามารถตอบคำถาม SO นี้ได้ในที่สุด :-)


เป็นไปได้ไหมที่จะรวมเข้ากับ SVN
คืน

1
อย่างไรก็ตามเวอร์ชัน Linux และ Mac นั้นเก่าแก่
Michael Piefel

29

Eclipseมีคุณสมบัตินี้มานานแล้ว มันเรียกว่า "Structure Compare" ดีมาก นี่คือภาพหน้าจอตัวอย่างสำหรับ Java ตามด้วยภาพอื่นสำหรับไฟล์ XML:

(สังเกตไอคอนลบและบวกบนวิธีการในบานหน้าต่างด้านบน)

ตัวเปรียบเทียบโครงสร้าง Java ของ Eclipse ตัวเปรียบเทียบโครงสร้าง XML ของ Eclipse


3
การเปรียบเทียบโครงสร้างอนุญาตให้คุณรวมการเปลี่ยนแปลงเช่นตัวแก้ไขการผสานการควบคุมแหล่งอื่น ๆ หรือไม่ คือคัดลอกวิธีนี้จากเวอร์ชันนี้ไปยังเวอร์ชันอื่น
Jonathan Parker

1
ใช่เมื่อคุณเลือกการเปลี่ยนแปลงหรือความแตกต่าง (ในบานหน้าต่างด้านบนหรือด้านล่าง) ปุ่มแถบเครื่องมือ (แสดงในภาพหน้าจอ) จะให้ตัวเลือกในการคัดลอกการเปลี่ยนแปลงจากซ้ายไปขวาหรือในทางกลับกัน
Hosam Aly

1
ขออภัยภาพหน้าจอจะไม่ปรากฏอีกต่อไปในคำตอบ (โหวตสูงสุดและได้รับการยอมรับ!) คุณช่วยส่งอีกครั้งได้ไหม
blubb

@blubb ขอบคุณที่แจ้งให้ทราบ ฉันได้แก้ไขข้อผิดพลาดด้วยอิมเมจ Java Comparer ฉันจะพยายามเพิ่มภาพหน้าจอสำหรับ XML Structure Comparer เร็ว ๆ นี้
Hosam Aly

1
และใช้ได้กับภาษาอื่นที่ไม่ใช่ Java หรือไม่?
einpoklum

14

ในการ "เปรียบเทียบความหมาย" ให้ดีคุณต้องเปรียบเทียบโครงสร้างไวยากรณ์ของภาษาและคำนึงถึงความหมายของสัญลักษณ์ด้วย ความแตกต่างทางความหมายที่ดีจริงๆจะเข้าใจความหมายของภาษาและตระหนักว่าเมื่อใดบล็อกหนึ่งของโค้ดเทียบเท่ากับฟังก์ชันอื่น การไปไกลขนาดนี้ต้องใช้ทฤษฎีบทสุภาษิตและแม้ว่ามันจะน่ารักมาก แต่ก็ไม่สามารถใช้งานได้จริงสำหรับเครื่องมือจริง

การประมาณที่สามารถใช้งานได้นี้เป็นเพียงการเปรียบเทียบโครงสร้างไวยากรณ์และการรายงานการเปลี่ยนแปลงในแง่ของโครงสร้างที่แทรกลบย้ายหรือเปลี่ยนแปลง เมื่อเข้าใกล้ "การเปรียบเทียบเชิงความหมาย" มากขึ้นเราสามารถรายงานได้เมื่อตัวระบุมีการเปลี่ยนแปลงอย่างสม่ำเสมอในบล็อกโค้ด

โปรดดูhttp://www.semanticdesigns.com/Products/SmartDifferencer/index.htmlของเรา สำหรับเครื่องมือเปรียบเทียบแบบโครงสร้างที่ใช้ไวยากรณ์ที่ทำงานได้กับหลายภาษาซึ่งใช้ประมาณข้างต้น

แก้ไขมกราคม 2010: เวอร์ชันสำหรับ C ++, C #, Java, PHP และ COBOL เว็บไซต์แสดงตัวอย่างเฉพาะสำหรับสิ่งเหล่านี้ส่วนใหญ่

แก้ไขพฤษภาคม 2010: เพิ่ม Python และ JavaScript

แก้ไข ต.ค. 2553: เพิ่ม EGL

แก้ไขพฤศจิกายน 2010: เพิ่ม VB6, VBScript, VB.net


2
สวัสดีไอราคุณได้ตีพิมพ์บทความเกี่ยวกับอัลกอริทึมที่แตกต่างของคุณหรือไม่? ฉันมีปัญหาในการค้นหาวรรณกรรมที่แตกต่างของระยะการแก้ไขแบบต้นไม้ ขอบคุณเทอเรนซ์
Terence Parr

เพื่อให้เจาะจงมากขึ้นให้มองหา diff3 ไม่ใช่ diff2 ธรรมดา
Terence Parr

2
@Terence: ไม่มีการตีพิมพ์ของอัลกอริทึมที่แตกต่างของเรา เป็นการคำนวณระยะทางขั้นต่ำของ Levenstein โดยใช้ต้นไม้ต่อท้ายเพื่อระบุต้นไม้ย่อยที่เท่ากันโดยมี huerstics บางอย่างเพื่อจัดการกับการเปลี่ยนชื่อ IIRC Yang มีเอกสารเกี่ยวกับเรื่องนี้ใน Software Practice and Experience ของเรากับหยางคือ diff2 ไม่ใช่ diff3
Ira Baxter

@IraBaxter ลิงก์เสียในขณะนี้และดูเหมือนว่าไซต์จะหยุดทำงานเมื่อเปิดจากลิงก์ Google
Răzvan Flavius ​​Panda

ไซต์กำลังสำรองลิงค์ควรจะโอเค
Ira Baxter

12

สิ่งที่คุณกำลังคล้าหาคือ "ความแตกต่างของต้นไม้" ปรากฎว่าสิ่งนี้ทำได้ยากกว่าการแตกต่างของข้อความเชิงเส้นแบบธรรมดาซึ่งจริงๆแล้วเป็นเพียงการเปรียบเทียบลำดับแบนสองลำดับ

" วิธีการเปรียบเทียบโครงสร้าง XML แบบละเอียด " สรุปในบางส่วนของ:

การศึกษาทางทฤษฎีของเราและการประเมินผลการทดลองของเราพบว่าวิธีการที่เสนอนั้นให้ผลลัพธ์ความคล้ายคลึงกันของโครงสร้างที่ดีขึ้นเมื่อเทียบกับทางเลือกที่มีอยู่ในขณะที่มีความซับซ้อนในเวลาเดียวกัน(O (N ^ 2))

(เน้นเหมือง)

อันที่จริงหากคุณกำลังมองหาตัวอย่างเพิ่มเติมของความแตกต่างของต้นไม้ฉันขอแนะนำให้เน้นที่ XML เนื่องจากนั่นเป็นการผลักดันการพัฒนาในทางปฏิบัติในพื้นที่นั้น


ขอบคุณสำหรับลิงค์ ฉันนึกถึงวิธีการที่แตกต่างกันสองสามวิธีในการใช้เครื่องมือ sematic diff และคุณถูกต้อง - ส่วนใหญ่สามารถสรุปเป็น "tree diff" ได้ สถานการณ์ที่ซับซ้อนมากขึ้นอาจจำเป็นต้องนำมาทำเป็น "ความแตกต่างของกราฟ"
jasonmray

ใช่. Rational Modeler ของ IBM (สร้างขึ้นบน eclipse) พยายามทำสิ่งนี้กับโมเดล UML (แสดงความแตกต่างระหว่างสองโมเดลในรูปแบบกราฟิก) ฉันไม่สามารถแสดงความคิดเห็นเกี่ยวกับประโยชน์ของผลลัพธ์ได้เนื่องจากฉันไม่ได้ใช้มันมากนัก
bendin

ฉันยอมรับว่า XML เป็นจุดเริ่มต้นที่ดีเนื่องจากคุณสามารถสร้างสคีมาเพื่อแสดงโครงสร้างอื่น ๆ (เช่นโค้ดจาวาเป็นต้น) และใช้แผนภูมิ XML ที่อิงตามต้นไม้เพื่อติดตั้งโค้ดที่แตกต่างกัน
jasonmray

"do this" => ทำบางสิ่งที่คล้ายกับ "กราฟ diff"
bendin

1
โปรดดูsemdesigns.com/Products/SmartDifferencer/index.htmlสำหรับเครื่องมือเปรียบเทียบโครงสร้างแบบไวยากรณ์ที่ทำงานได้กับหลายภาษา
Ira Baxter


2

วิธีแก้ปัญหานี้จะเป็นไปตามภาษา ยกเว้นกรณีที่ได้รับการออกแบบด้วยสถาปัตยกรรมปลั๊กอินที่เลื่อนการแยกวิเคราะห์โค้ดออกเป็นโครงสร้างจำนวนมากและการเปรียบเทียบความหมายกับปลั๊กอินเฉพาะภาษาจะเป็นการยากมากที่จะรองรับหลายภาษา ภาษาใดที่คุณสนใจที่จะมีเครื่องมือดังกล่าว โดยส่วนตัวแล้วฉันรัก C #

สำหรับ C # จะมีการประกอบ diff add-in ของ Reflector แต่จะสร้างความแตกต่างให้กับ IL ไม่ใช่ C #

คุณสามารถดาวน์โหลด diff add-in ที่นี่ [ซิป] หรือไปที่โครงการบนเว็บไซต์ CodePlex ที่นี่


1
โปรดดูsemdesigns.com/Products/SmartDifferencer/index.htmlสำหรับเครื่องมือเปรียบเทียบโครงสร้างแบบไวยากรณ์ที่ทำงานได้กับหลายภาษาโดยใช้รูปแบบปลั๊กอินภาษา ยังไม่เปิดตัว แต่รุ่น C # อยู่ใกล้มาก
Ira Baxter

ม.ค. 2553: C # Smart Differencer เปิดตัว
Ira Baxter

2

บริษัท ที่เรียกว่า Zynamics นำเสนอเครื่องมือความแตกต่างระดับไบนารี มันใช้ภาษาเมตาแอสเซมบลีที่เรียกว่า REIL เพื่อทำการวิเคราะห์กราฟ - ทฤษฏีของไบนารี 2 เวอร์ชันและสร้างกราฟรหัสสีเพื่อแสดงความแตกต่างระหว่างกัน ผมไม่แน่ใจราคา แต่สงสัยว่าฟรี


ลิงก์ไปยังความแตกต่างของความหมายระดับไบนารี: zynamics.com/bindiff.html
emallove

ตอนนี้ bindiff ฟรีและ binnavi (ผลิตภัณฑ์อื่น ๆ ของพวกเขา) เป็นโอเพ่นซอร์ส ปรากฏว่า REIL รวมอยู่ในรุ่น binnavi - github.com/google/binnavi/tree/master/src/main/java/com/google/…
มาร์ค

2

http://prettydiff.com/

Pretty Diff ลดทอนแต่ละอินพุตเพื่อลบความคิดเห็นและพื้นที่สีขาวที่ไม่จำเป็นจากนั้นปรับแต่งโค้ดก่อนอัลกอริทึม diff ฉันไม่สามารถคิดว่าจะกลายเป็นความหมายของรหัสมากกว่านี้ และ JavaScript ที่เขียนขึ้นเพื่อให้ทำงานโดยตรงในเบราว์เซอร์


5
ถ้าอย่างนั้นคุณมีจินตนาการที่ จำกัด ! สิ่งที่เกี่ยวกับการแลกเปลี่ยนตำแหน่งของสองวิธีในไฟล์ในขณะที่ไม่เปลี่ยนแปลง? แล้ว refactorings ล่ะ?
Robin Green

(คุณไม่สามารถสลับการประกาศข้อมูลใน Java ด้วยวิธีนี้และยังคงมีความเท่าเทียมกันเนื่องจากตัวเริ่มต้นฉันถือว่า C # มีปัญหาที่คล้ายกัน) ถ้าคุณไปหาความแตกต่างทางความหมายแบบบริสุทธิ์แสดงว่าคุณกำลังพยายามแก้ปัญหาความเท่าเทียมกันของเครื่องทัวริง มีช่วงมากมายสำหรับการจับคู่ข้อความที่ดีกว่าแล้วและแย่กว่าที่เป็นไปไม่ได้ของทัวริง
ไอราแบ็กซ์เตอร์

@IraBaxter เครื่องมือในแนวความคิดจะแสดงเป็นสิ่งที่เทียบเท่าซึ่งเทียบเท่ากันเท่านั้น หากเข้ารหัสอย่างถูกต้องจะไม่มีปัญหาแบบที่คุณกำลังกล่าวถึง
Răzvan Flavius ​​Panda

"เข้ารหัสอย่างถูกต้อง" หมายถึงการพิสูจน์ความเท่าเทียมกันของอัลกอริทึมหากคุณต้องการเครื่องมือขั้นสูงสุด การพิสูจน์ความเท่าเทียมกันของอัลกอริทึมเป็นเรื่องยากโดยทั่วไปของทัวริงดังนั้นคุณจะไม่ได้รับเครื่องมือดังกล่าวในทางปฏิบัติ สิ่งที่คุณอาจได้รับคือเครื่องมือที่จัดการการเทียบเท่าบางอย่างนอกเหนือจากการเปลี่ยนแปลงไวยากรณ์เท่านั้น จนถึงปัจจุบันฉันไม่เห็นใครพยายามสร้างเครื่องมือดังกล่าว
Ira Baxter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.