Semantic Diff Utilities [geschlossen]


105

Ich versuche einige gute Beispiele für semantische Diff / Merge-Dienstprogramme zu finden. Das traditionelle Paradigma des Vergleichs von Quellcodedateien besteht darin, Zeilen und Zeichen zu vergleichen. Gibt es jedoch Dienstprogramme (für jede Sprache), die beim Vergleichen von Dateien tatsächlich die Struktur des Codes berücksichtigen ?

Beispielsweise melden vorhandene Diff-Programme "Unterschied in Zeichen 2 von Zeile 125 gefunden. Datei x enthält void, wobei Datei y bool enthält". Ein spezialisiertes Tool sollte in der Lage sein, "Rückgabetyp der Methode doSomething () von void in bool geändert" zu melden.

Ich würde argumentieren, dass diese Art von semantischer Information tatsächlich das ist, wonach der Benutzer beim Vergleichen von Code sucht, und das Ziel von Programmierwerkzeugen der nächsten Generation sein sollte. Gibt es Beispiele dafür in verfügbaren Tools?


3
Es sieht so aus, als ob einige Untersuchungen zur Entfernung von Baumbearbeitungen durchgeführt wurden. Das auf die ASTs anzuwenden, scheint das erste zu sein, was man versuchen sollte. (Wenn jemand versuchen wollte, so etwas zu schreiben.)
Jay Kominek

2
Ich bin mir nicht sicher, ob es wirklich nützlich wäre. Ein Unterschied wie der von Ihnen erwähnte ist leichter zu erkennen als zu lesen, insbesondere wenn Sie ein Werkzeug haben, das Unterschiede innerhalb einer Linie hervorhebt . Die Fähigkeit zu erkennen, ob ein Code gerade unverändert verschoben wurde, wäre einfacher und nützlicher, imho!
Onkel Zeiv

2
@UncleZeiv Ich würde hoffen, dass sich diese Funktion natürlich aus der Art des Tools ergibt. Darüber hinaus kann festgestellt werden, dass keine Änderungen vorgenommen wurden, wenn beispielsweise jemand die geschweiften Klammern oder Einrückungsstile geändert oder die Datei neu angeordnet hat, sodass statische Methoden gruppiert werden usw.
jasonmray

8
Ich brauche das jetzt in Visual Studio. Entwickler innerhalb eines Teams dazu zu zwingen, dieselbe Formatierungsstruktur zu verwenden, um Unterschiede zu ermöglichen, ist rückwärts gedacht. Der Code sollte beim Einchecken nach einem Standard formatiert werden, und jedes Mal, wenn ein Entwickler eine Datei öffnet, sollte er nach seinen Wünschen formatiert werden. Ich bin schockiert, dass diese Art des Denkens zu diesem Zeitpunkt nicht weiter verbreitet ist.
Langdon

3
IMHO ist dies ein gutes Thema für SO. Wenn Sie damit einverstanden sind, stimmen Sie für "Wiedereröffnung"
Ira Baxter

Antworten:


36

Wir haben ein Tool entwickelt, das genau mit diesem Szenario umgehen kann. Überprüfen Sie http://www.semanticmerge.com

Es wird basierend auf der Codestruktur zusammengeführt (und unterscheidet sich) und verwendet keine textbasierten Algorithmen. Dies ermöglicht es Ihnen grundsätzlich, Fälle wie die folgenden mit starkem Refactor zu behandeln. Es ist auch in der Lage, sowohl die Unterschiede als auch die Zusammenführungskonflikte zu rendern, wie Sie unten sehen können:

Geben Sie hier die Bildbeschreibung ein

Und anstatt mit den zu verschiebenden Textblöcken verwechselt zu werden, können die Konflikte, da sie zuerst analysiert werden, pro Methode (tatsächlich pro Element) angezeigt werden. In einem Fall wie dem vorherigen müssen nicht einmal manuelle Konflikte gelöst werden.

Geben Sie hier die Bildbeschreibung ein

Es ist ein sprachbewusstes Zusammenführungswerkzeug und es war großartig, diese SO-Frage endlich beantworten zu können :-)


Ist es möglich, es in SVN zu integrieren?
Revious

1
Die Linux- und Mac-Versionen sind jedoch uralt.
Michael Piefel

29

Eclipse hat diese Funktion schon lange. Es heißt "Structure Compare" und ist sehr schön. Hier ist ein Beispiel-Screenshot für Java, gefolgt von einem weiteren für eine XML-Datei:

(Beachten Sie die Minus- und Plus-Symbole für Methoden im oberen Bereich.)

Java Structure Comparer von Eclipse XML-Strukturvergleicher von Eclipse


3
Ermöglicht Structure Compare das Zusammenführen von Änderungen wie bei anderen Editoren zum Zusammenführen von Quellcodeverwaltungen? Dh Kopieren Sie diese Methode von dieser Version in die andere Version.
Jonathan Parker

1
Ja, wenn Sie eine Änderung oder einen Unterschied auswählen (entweder im oberen oder unteren Bereich), können Sie über die Symbolleistenschaltflächen (in den Screenshots gezeigt) die Änderung von links nach rechts oder umgekehrt kopieren.
Hosam Aly

1
Leider sind die Screenshots in Ihrer Antwort (am höchsten bewertet und akzeptiert!) Nicht mehr sichtbar. Könnten Sie sie erneut einreichen?
Blubb

@blubb Danke, dass du mich benachrichtigt hast. Ich habe den Fehler mit dem Java Comparer-Image behoben. Ich werde versuchen, bald einen Screenshot für den XML-Strukturvergleich hinzuzufügen.
Hosam Aly

1
Und funktioniert das für andere Sprachen als Java?
Einpoklum

14

Um "semantische Vergleiche" gut durchführen zu können, müssen Sie die Syntaxbäume der Sprachen vergleichen und die Bedeutung von Symbolen berücksichtigen. Ein wirklich guter semantischer Unterschied würde die Sprachsemantik verstehen und erkennen, wann ein Codeblock in seiner Funktion einem anderen äquivalent ist. Um so weit zu gehen, ist ein Theorembeweiser erforderlich, und obwohl er äußerst niedlich wäre, ist er für ein echtes Werkzeug derzeit nicht praktikabel.

Eine praktikable Annäherung daran besteht einfach darin, Syntaxbäume zu vergleichen und Änderungen in Bezug auf eingefügte, gelöschte, verschobene oder geänderte Strukturen zu melden. Wenn man sich einem "semantischen Vergleich" etwas nähert, kann man berichten, wenn ein Bezeichner in einem Codeblock konsistent geändert wird.

In unserer http://www.semanticdesigns.com/Products/SmartDifferencer/index.html finden Sie eine auf Syntaxbäumen basierende Vergleichs-Engine, die mit vielen Sprachen funktioniert und die obige Annäherung ausführt.

EDIT Jan 2010: Versionen für C ++, C #, Java, PHP und COBOL verfügbar. Die Website zeigt spezifische Beispiele für die meisten davon.

EDIT Mai 2010: Python und JavaScript hinzugefügt.

EDIT Okt 2010: EGL hinzugefügt.

EDIT Nov 2010: VB6, VBScript, VB.net hinzugefügt


2
Hallo Ira, hast du einen Artikel über deinen Diff-Algorithmus veröffentlicht? Ich habe Probleme beim Auffinden von Diff-Literatur zum Thema Baumbearbeitung. Danke, Terence.
Terence Parr

Um genauer zu sein, suchen Sie nach diff3 nicht einfach diff2
Terence Parr

2
@Terence: Es gibt keine Veröffentlichung unseres Diff-Algorithmus. Es handelt sich um eine Levenstein-Min-Entfernungsberechnung unter Verwendung von Suffixbäumen zur Identifizierung gleicher Teilbäume, wobei einige Huerstics die Umbenennung übernehmen. IIRC, Yang hatte ein Papier dazu in Software Practice and Experience. Unsere und Yangs sind diff2, nicht diff3.
Ira Baxter

@IraBaxter Der Link ist derzeit defekt und die Website scheint beim Öffnen über den Google-Link nicht erreichbar zu sein.
Răzvan Flavius ​​Panda

Die Site ist gesichert, der Link sollte in Ordnung sein.
Ira Baxter

12

Was Sie suchen, ist ein "Baumdiff". Es stellt sich heraus, dass dies viel schwieriger ist als ein einfaches zeilenorientiertes Textdiff, das eigentlich nur der Vergleich zweier flacher Sequenzen ist.

" Ein feinkörniger XML-Strukturvergleichsansatz " schließt teilweise mit:

Unsere theoretische Studie sowie unsere experimentelle Bewertung zeigten, dass die vorgeschlagene Methode verbesserte strukturelle Ähnlichkeitsergebnisse in Bezug auf bestehende Alternativen bei gleicher zeitlicher Komplexität liefert (O (N ^ 2)).

(Hervorhebung von mir)

Wenn Sie nach weiteren Beispielen für die Differenzierung von Bäumen suchen, empfehle ich, sich auf XML zu konzentrieren, da dies die praktischen Entwicklungen in diesem Bereich vorantreibt.


Danke für den Link. Ich kann mir ein paar verschiedene Ansätze für die Implementierung sematischer Diff-Tools vorstellen, und Sie haben Recht - die meisten können in einen "Tree Diff" abstrahiert werden. Komplexere Situationen müssen möglicherweise sogar in einen "Graph Diff" abstrahiert werden.
Jasonmray

Ja. IBMs Rational Modeler (basierend auf Eclipse) versucht dies mit UML-Modellen (wobei die Unterschiede zwischen zwei Modellen grafisch dargestellt werden). Ich kann die Nützlichkeit der Ergebnisse nicht kommentieren, da ich sie nicht oft benutze.
Bendin

Ich bin damit einverstanden, dass XML ein guter Ausgangspunkt ist, da Sie einfach Schemata erstellen können, um andere Strukturen (wie z. B. Java-Code) darzustellen, und ein XML-basiertes Tree-Diff verwenden können, um ein Code-Diff zu implementieren.
Jasonmray

"do this" => mache etwas, das einem "graph diff" ähnelt.
Bendin

1
Unter semdesigns.com/Products/SmartDifferencer/index.html finden Sie eine syntaxbaumbasierte Vergleichs-Engine, die mit vielen Sprachen funktioniert.
Ira Baxter


2

Die Lösung hierfür wäre pro Sprache. Das heißt, wenn es nicht mit einer Plugin-Architektur entworfen wurde, die das Parsen des Codes in einen Baum und den semantischen Vergleich mit einem sprachspezifischen Plugin stark verzögert, ist es sehr schwierig, mehrere Sprachen zu unterstützen. Für welche Sprache (n) interessieren Sie sich für ein solches Tool? Persönlich würde ich einen für C # lieben.

Für C # gibt es ein Assembly-Diff-Add-In für Reflector, aber es gibt nur ein Diff für das IL, nicht für das C #.

Sie können die diff Add-In herunterladen hier [zip] oder auf der Codeplex - Website zu dem Projekt gehen hier .


1
Unter semdesigns.com/Products/SmartDifferencer/index.html finden Sie eine syntaxbaumbasierte Vergleichs-Engine, die mit vielen Sprachen funktioniert und genau den Sprach-Plugin-Stil verwendet. Noch nicht veröffentlicht, aber eine C # -Version ist sehr nah.
Ira Baxter

Jan 2010: C # Smart Differencer wird veröffentlicht.
Ira Baxter

2

Eine Firma namens Zynamics bietet ein semantisches Diff-Tool auf Binärebene an. Es verwendet eine Meta-Assemblersprache namens REIL, um eine graphentheoretische Analyse von zwei Versionen einer Binärdatei durchzuführen, und erstellt ein farbcodiertes Diagramm, um die Unterschiede zwischen ihnen zu veranschaulichen. Ich bin mir des Preises nicht sicher, aber ich bezweifle, dass er kostenlos ist.


Link zum semantischen Diff auf Binärebene
emallove

2

http://prettydiff.com/

Pretty Diff minimiert jede Eingabe, um Kommentare und unnötigen Leerraum zu entfernen, und verschönert dann den Code vor dem Diff-Algorithmus. Ich kann mir sowieso nicht vorstellen, mehr Codesemantik als diese zu werden. Und es ist JavaScript geschrieben, so dass es direkt im Browser ausgeführt wird.


5
Dann haben Sie eine begrenzte Vorstellungskraft! Was ist mit dem Vertauschen der Positionen zweier Methoden in einer Datei, während sie unverändert bleiben? Was ist mit Refactorings?
Robin Green

(Sie können Datendeklarationen in Java auf diese Weise nicht austauschen und haben aufgrund von Initialisierern immer noch eine Äquivalenz. Ich gehe davon aus, dass C # ähnliche Probleme hat.) Wenn Sie sich für eine reine semantische Diff entscheiden, versuchen Sie, die Turing-Maschinenäquivalenz zu lösen. Es gibt viel Spielraum, um besser als reinen Textabgleich zu machen, und schlechter als Turing unmöglich.
Ira Baxter

@IraBaxter Das Tool zeigt konzeptionell offensichtlich nur als äquivalente Dinge, die tatsächlich äquivalent sind. Wenn es richtig codiert ist, hat es nicht den von Ihnen erwähnten Problemtyp.
Răzvan Flavius ​​Panda

"Richtig codiert" bedeutet, die Algorithmusäquivalenz zu beweisen, wenn Sie das ultimative Tool wünschen. Algorithmenäquivalenzbeweise sind im Allgemeinen sehr schwierig, daher werden Sie in der Praxis kein solches Tool erhalten. Möglicherweise erhalten Sie ein Tool, das andere Äquivalenzen als nur Syntaxänderungen behandelt. Bisher habe ich noch niemanden gesehen, der versucht hat, ein solches Tool zu erstellen.
Ira Baxter
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.