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.

Verwenden externer Werkzeuge zum Vergleichen und Zusammenführen

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] 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 svn:mime-type menschenlesbar sind. Das bedeutet beispielsweise, selbst falls Sie über das raffinierteste Vergleichs- oder Werkzeug zum Zusammenführen des Universums verfügten, welches Microsoft Word versteht, würde es normalerweise von Subversion nicht aufgerufen, falls Ihre versionierten Word-Dokumente einen MIME-Typen hätten, der sie als nicht-menschenlesbar kennzeichnet (so wie application/msword). Glücklicherweise können Sie dem Befehl svn diff die Option --force mitgeben, um diese MIME-bezogene Plausibilitätsprüfung zum umgehen, und die Unterschiedsberechnung zu erzwingen. Mehr über MIME-Type-Einstellungen unter „Datei-Inhalts-Typ“

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] 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.

Externes diff

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.

Externes diff3

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.

Externes merge

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.