Dieser Text befindet sich gegenwärtig in Bearbeitung, unterliegt ständigen Änderungen und kann dadurch nicht stets akkurat irgendeine freigegebene Version der Software Apache™ Subversion® beschreiben. Das Speichern dieser Seite als Lesezeichen oder andere auf diese Seite zu verweisen, ist keine so gute Idee. Besuchen Sie http://www.svnbook.com/, um stabile Versionen dieses Buchs zu erhalten.
Die Schnittstelle zwischen Subversion und externen Zwei- und
Dreiwege-Vergleichswerkzeugen geht zurück bis in eine Zeit, als
sich die kontextabhängigen Vergleichsfähigkeiten von Subversion
allein auf Aufrufe der GNU-diffutils-Werkzeuge stützten,
insbesondere diff und
diff3. Um das von Subversion benötigte
Verhalten zu bekommen, wurden diese Werkzeuge mit mehr als einer
handvoll Optionen und Parametern aufgerufen, von denen die
meisten sehr werkzeugspezifisch waren. Einige Zeit später
entwickelte Subversion seine eigene interne
Vergleichsbibliothek, und als Ausfallsicherung wurden dem
Subversion-Kommandozeilen-Client die Optionen
--diff-cmd
und --diff3-cmd
hinzugefügt, so dass Benutzer auf einfache Art mitteilen
konnten, dass sie die GNU-Werkzeuge diff und diff3 gegenüber der
neumodischen internen Vergleichsbibliothek bevorzugen. Wenn
diese Optionen verwendet wurden, ignorierte Subversion einfach
die interne Vergleichsbibliothek und benutzte die externen
Programmen mit den langen Argumentlisten und dem ganzen
Drumherum. Uns so ist es noch heute.
Es dauerte nicht lange, bis einige Leute feststellten, das diese einfachen Konfigurationsmechanismen zur Festlegung der Benutzung der externen GNU-Werkzeuge diff und diff3, die an einem bestimmten Ort im System liegen, auch für andere Vergleichswerkzeuge verwendet werden können. Schließlich hat Subversion nicht überprüft, ob die Werkzeuge zur Werkzeugkette der GNU diffutils gehören. Der einzige konfigurierbare Aspekt bei der Verwendung dieser externen Werkzeuge ist allerdings der Speicherort im System – weder die Menge der Optionen noch die Reihenfolge der Parameter usw. Subversion übergibt all diese GNU-Werkzeug-Optionen an Ihr externes Vergleichswerkzeug, ohne zu berücksichtigen, ob das Programm sie überhaupt versteht. Und hier hört es für die meisten Benutzer auf, intuitiv zu sein.
Anmerkung | |
---|---|
Die Entscheidung, wann ein kontextabhängiges Zwei- oder
Dreiwege-Vergleichswerkzeug als Teil einer größeren Operation
von Subversion gestartet wird, wird von Subversion intern
getroffen und
wird unter anderem dadurch beeinflusst, ob die Dateien nach
Maßgabe der Eigenschaft |
Viel später hat Subversion 1.5 die interaktive Auflösung von
Konflikten eingeführt (beschrieben in
„Lösen Sie etwaige Konflikte auf“). Eine den Benutzern
durch diese Funktionalität angebotene Option ist die
Fähigkeit, interaktiv ein Werkzeug zum Zusammenführen eines
Drittanbieters starten zu können. Wenn dieses Vorgehen gewählt
wird, prüft Subversion, ob der Anwender ein solches Werkzeug für
diesen Einsatzzweck bestimmt hat. Subversion prüft zunächst die
Umgebungsvariable SVN_MERGE
auf den Namen
eines externen Zusammenführungswerkzeugs. Sollte diese Variable
nicht gesetzt sein, wird im Wert der Laufzeitoption
merge-tool-cmd
nach derselben Information
gesucht. Wird das eingestellte externe Werkzeug zum Zusammenführen
gefunden, wird es gestartet.
Anmerkung | |
---|---|
Während der allgemeine Zweck des Dreiwege-Vergleichs- und des Werkzeug zum Zusammenführens weitestgehend derselbe ist (einen Weg zu finden, um getrennte, sich jedoch überlappende, Dateiänderungen zu harmonisieren), führt Subversion jede dieser Optionen zu unterschiedlichen Zeitpunkten aus unterschiedlichen Gründen aus. Die interne Dreiwege-Vergleichsmaschine und ihr optionaler externer Ersatz werden verwendet, wenn die Zusammenarbeit mit dem Anwender nicht erwartet wird. Tatsächlich kann eine durch ein solches Werkzeug herbeigeführte spürbare Verzögerung letztendlich zum Fehlschlagen einer zeitkritischen Subversion-Operation führen. Für den interaktiven Aufruf ist das externe Werkzeug zum Zusammenführen vorgesehen. |
Obwohl die Schnittstelle zwischen Subversion und einem externen Werkzeug zum Zusammenführen wesentlich gradliniger ist als die zwischen Subversion und den diff und diff3 Werkzeugen, ist die Wahrscheinlichkeit doch ziemlich gering, ein solches Tool zu finden, dessen Aufrufkonventionen exakt den Erwartungen von Subversion entspricht. Der Schlüssel in der Benutzung externer Vergleichs- und Zusammenführungswerkzeuge liegt in der Verwendung von Wrapper-Skripten, die die Eingabe von Subversion in irgendetwas umwandeln, das Ihr besonderes Vergleichswerkzeug versteht, und dann die Ausgabe ihres Programms in ein Format zurück überführt, das Subversion erwartet. Die folgenden Abschnitte behandeln die Details solcher Erwartungen.
Subversion ruft externe diff-Programme mit Parametern auf, die für GNU diff passen und erwartet lediglich, dass das externe Programm mit einem, nach GNU diff Definition, Erfolg signalisierenden Rückgabewert zurückkommt. Für die meisten alternativen diff-Programme sind nur die Argumente an sechster und siebter Stelle interessant – die Pfade der Dateien, die die linke bzw. rechte Seite des Vergleichs repräsentieren. Beachten Sie, dass Subversion das diff-Programm jeweils einmal pro modifizierter Datei aufruft, die die Subversion-Operation berührt, falls Ihr Programm also asynchron läuft (oder als „Hintergrundprozess“), könnte es sein, dass mehrere Instanzen gleichzeitig ausgeführt werden. Schließlich erwartet Subversion, dass Ihr Programm den Rückgabewert 1 liefert, falls es Unterschiede entdeckt hat, oder 0, falls nicht – jeder andere Rückgabewert wird als fataler Fehler angesehen.[75]
Beispiel 7.2, „diffwrap.py“ und Beispiel 7.3, „diffwrap.bat“ sind „Verpackungs“-Vorlagen für externe diff-Werkzeuge in den Skriptsprachen Python bzw. Windows-Batch.
Beispiel 7.2. diffwrap.py
#!/usr/bin/env python import sys import os # Geben Sie hier Ihr bevorzugtes diff-Programm an. DIFF = "/usr/local/bin/my-diff-tool" # Subversion liefert die benötigten Pfade als die letzten beiden Parameter. LEFT = sys.argv[-2] RIGHT = sys.argv[-1] # Aufruf des diff-Befehls (ändern Sie die folgende Zeile passend für # Ihr diff-Programm). cmd = [DIFF, '--left', LEFT, '--right', RIGHT] os.execv(cmd[0], cmd) # Rückgabewert 0 falls keine Unterschiede, 1 falls doch. # Jeder andere Rückgabewert wird als fatal betrachtet.
Beispiel 7.3. diffwrap.bat
@ECHO OFF REM Geben Sie hier Ihr bevorzugtes diff-Programm an. SET DIFF="C:\Program Files\Funky Stuff\My Diff Tool.exe" REM Subversion liefert die benötigten Pfade als die letzten beiden Parameter. REM Das sind die Parameter 6 und 7 (außer Sie benutzen svn diff -x, dann REM ist alles möglich). SET LEFT=%6 SET RIGHT=%7 REM Aufruf des diff-Befehls (ändern Sie die folgende Zeile passend für REM Ihr diff-Programm). %DIFF% --left %LEFT% --right %RIGHT% REM Rückgabewert 0 falls keine Unterschiede, 1 falls doch. REM Jeder andere Rückgabewert wird als fatal betrachtet.
Subversion ruft für die Ausführung nicht-interaktiver Zusammenführungen Dreiwege-Vergleichswerkzeuge auf. Parametern auf, die für das GNU diff3-Werkzeug passen und erwartet, dass das externe Programm einen Erfolg signalisierenden Rückgabewert liefert und der vollständige Inhalt als Ergebnis der beendeten Zusammenführung in den Standardausgabestrom geschrieben wird (damit Subversion diesen in die entsprechende Datei unter Versionskontrolle umleiten kann). Für die meisten alternativen Werkzeug zum Zusammenführene sind nur die Argumente an neunter, zehnter und elfter Stelle interessant, die den Pfaden der Dateien entsprechen, die die Eingaben „eigene“, „ältere“ bzw. „fremde“ repräsentieren. Beachten Sie, dass Ihr Skript nicht beendet werden darf, bevor die Ausgabe an Subversion abgeliefert wurde, da Subversion auf die Ausgabe Ihres Werkzeug zum Zusammenführens angewiesen ist. Wenn es schließlich beendet wird, sollte es einen Rückgabewert 0 im Erfolgsfall und 1 bei verbleibenden Konflikten zurückgeben – jeder andere Rückgabewert wird als fataler Fehler angesehen.
Beispiel 7.4, „diff3wrap.py“ und Beispiel 7.5, „diff3wrap.bat“ sind „Verpackungs“-Vorlagen für externe Dreiwege-Vergleichswerkzeuge in den Skriptsprachen Python bzw. Windows-Batch.
Beispiel 7.4. diff3wrap.py
#!/usr/bin/env python import sys import os # Konfigurieren Sie hier Ihr bevorzugtes Dreiwege-Vergleichswerkzeug DIFF3 = "/usr/local/bin/my-diff3-tool" # Subversion liefert die von uns benötigten Pfade als die letzten drei Parameter MINE = sys.argv[-3] OLDER = sys.argv[-2] YOURS = sys.argv[-1] # Aufruf des Dreiwege-Vergleichs-Befehls (ändern Sie die folgende # Zeile, damit es für Ihr Dreiwege-Vergleichswerkzeug einen Sinn # ergibt). cmd = [DIFF3, '--older', OLDER, '--mine', MINE, '--yours', YOURS] os.execv(cmd[0], cmd) # Nach der Zusammenführung muss das Script den Inhalt der # zusammengeführten Datei an die Standardausgabe schreiben. Machen Sie # das wie Sie möchten. # Nach erfolgreicher Zusammenführung wird 0 zurückgegeben; 1, falls # offene Konflikte im Ergebnis zurückbleiben. Jeder andere Fehlercode # wird als fatal behandelt.
Beispiel 7.5. diff3wrap.bat
@ECHO OFF REM Konfigurieren Sie hier Ihr bevorzugtes Dreiwege-Vergleichswerkzeug SET DIFF3="C:\Program Files\Funky Stuff\My Diff3 Tool.exe" REM Subversion liefert die von uns benötigten Pfade als die letzten REM drei Parameter REM Dies sind die Parameter 9, 10 und 11. Allerdings haben wir REM gleichzeitig nur Zugriff auf neun Parameter, also verschieben wir REM das Neun-Parameter-Fenster zweimal, damit wir das bekommen, was REM wir benötigen SHIFT SHIFT SET MINE=%7 SET OLDER=%8 SET YOURS=%9 REM Aufruf des Dreiwege-Vergleichs-Befehls (ändern Sie die folgende REM Zeile, damit es für Ihr Dreiwege-Vergleichswerkzeug einen Sinn REM ergibt). %DIFF3% --older %OLDER% --mine %MINE% --yours %YOURS% REM Nach der Zusammenführung muss das Script den Inhalt der REM zusammengeführten Datei an die Standardausgabe schreiben. Machen REM Sie das wie Sie möchten. REM Nach erfolgreicher Zusammenführung wird 0 zurückgegeben; 1, falls REM offene Konflikte im Ergebnis zurückbleiben. Jeder andere Fehlercode REM wird als fatal behandelt.
Optional ruft Subversion ein externes Werkzeug zum Zusammenführen als Teil der Unterstützung für interaktive Konfliktauflösung auf. Als Argumente für das Werkzeug zum Zusammenführen werden die folgenden geliefert: der Pfad der unmodifizierten Basisdatei, der Pfad der „theirs“-Datei (die Änderungen der Autoren enthält), der Pfad der „mine“-Datei (die lokale Änderungen enthält), der Pfad der Datei, in die das Werkzeug zum Zusammenführen letztendlich den zusammengeführte Inhalt schreiben soll und der Pfad der Arbeitskopie der in Konflikt stehenden Dateien (relativ zum ursprünglichen Ziel der Zusammenführungsoperation). Vom Werkzeug zum Zusammenführen wird erwartet, dass es im Erfolgsfall 0 und im Fehlerfall 1 zurückgibt.
Beispiel 7.6, „mergewrap.py“ und Beispiel 7.7, „mergewrap.bat“ sind Vorlagen für externe Wrapper für das Werkzeug zum Zusammenführen in der Python- bzw. Windows-Batch-Programmiersprache.
Beispiel 7.6. mergewrap.py
#!/usr/bin/env python import sys import os # Geben Sie hier Ihr bevorzugtes diff-Programm an. MERGE = "/usr/local/bin/my-merge-tool" # Holen Sie sich die durch Subversion gelieferten Pfade BASE = sys.argv[1] THEIRS = sys.argv[2] MINE = sys.argv[3] MERGED = sys.argv[4] WCPATH = sys.argv[5] # Aufruf des merge-Befehls (ändern Sie die folgende Zeile passend für # Ihr merge-Programm). cmd = [MERGE, '--base', BASE, '--mine', MINE, '--theirs', THEIRS, '--outfile', MERGED] os.execv(cmd[0], cmd) # Rückgabewert 0 bei erfolgreicher Zusammenführung, 1 bei noch # unaufgelösten Konflikten. Alles andere wird als fatal behandelt.
Beispiel 7.7. mergewrap.bat
@ECHO OFF REM Geben Sie hier Ihr bevorzugtes merge-Programm an. SET MERGE="C:\Program Files\Funky Stuff\My Merge Tool.exe" REM Holen Sie sich die durch Subversion gelieferten Pfade SET BASE=%1 SET THEIRS=%2 SET MINE=%3 SET MERGED=%4 SET WCPATH=%5 REM Aufruf des merge-Befehls (ändern Sie die folgende Zeile passend REM für Ihr merge-Programm). %MERGE% --base %BASE% --mine %MINE% --theirs %THEIRS% --outfile %MERGED% REM Rückgabewert 0 bei erfolgreicher Zusammenführung, 1 bei noch REM unaufgelösten Konflikten. Alles andere wird als fatal betrachtet,
[75] Das Handbuch zu GNU diff beschreibt es so: „Ein Rückgabewert 0 bedeutet, dass keine Unterschiede gefunden wurden, 1 bedeutet, dass einige Unterschiede gefunden wurden und 2 bedeutet Ärger.“