Diese Dokumentation wurde zur Beschreibung der Serie 1.6.x von Subversion erstellt. Falls Sie eine unterschiedliche Version von Subversion einsetzen, sei Ihnen dringend angeraten, bei http://www.svnbook.com/ vorbeizuschauen und stattdessen die zu Ihrer Version von Subversion passende Version dieser Dokumentation heranzzuiehen.
Bis hierhin haben wir nur über Konflikte auf der Ebene von Dateiinhalten gesprochen. Wenn Sie und Ihre Mitarbeiter überlappende Änderungen innerhalb derselben Datei vornehmen, zwingt Sie Subversion dazu, diese Änderungen zusammenzuführen, bevor Sie sie übergeben können.[9]
Was passiert aber, wenn Ihre Mitarbeiter eine Datei verschieben oder löschen, an der Sie noch arbeiten? Vielleicht gab es ein Verständnisproblem oder die eine Person glaubt, die Datei soll gelöscht werden, während die andere Person noch Änderungen an der Datei übergeben will. Vielleicht haben Ihre Mitarbeiter ja auch etwas Refactoring betrieben und dabei Dateien umbenannt und Verzeichnisse verschoben. Falls Sie noch an diesen Dateien gearbeitet haben, müssten diese Änderungen auf die Dateien am der neuen Stelle angewendet werden. Derartige Konflikte äußern sich auf der Ebene der Verzeichnisstruktur statt des Dateiinhaltes und sind bekannt als Baumkonflikte.
Wie bei textuellen Konflikten verhindern Baumkonflikte eine Übergabe aus dem Konfliktzustand und geben dem Anwender die Gelegenheit, den Zustand der Arbeitskopie auf potenzielle Probleme, die aus dem Baumkonflikt entstehen könnten, zu überprüfen und vor der Übergabe aufzulösen.
Gegeben sei folgendes Softwareprojekt, an dem Sie gerade arbeiten:
$ svn list -Rv svn://svn.example.com/trunk/ 4 harry Feb 06 14:34 ./ 4 harry 23 Feb 06 14:34 COPYING 4 harry 41 Feb 06 14:34 Makefile 4 harry 33 Feb 06 14:34 README 4 harry Feb 06 14:34 code/ 4 harry 51 Feb 06 14:34 code/bar.c 4 harry 124 Feb 06 14:34 code/foo.c
Ihr Kollege Harry hat die Datei bar.c
in baz.c
umbenannt. Sie arbeiten immer
noch an bar.c
in Ihrer Arbeitskopie, doch
wissen noch nicht, dass die Datei im Projektarchiv umbenannt
wurde.
Die Protokollmeldung für Harrys Übergabe sah so aus:
$ svn log -r5 svn://svn.example.com/trunk ------------------------------------------------------------------------ r5 | harry | 2009-02-06 14:42:59 +0000 (Fri, 06 Feb 2009) | 2 lines Geänderte Pfade: M /trunk/Makefile D /trunk/code/bar.c A /trunk/code/baz.c (from /trunk/code/bar.c:4) bar.c nach baz.c umbenannt und Makefile entsprechend angepasst.
Die von Ihnen vorgenommenen Änderungen sehen so aus:
$ svn diff Index: code/foo.c =================================================================== --- code/foo.c (revision 4) +++ code/foo.c (working copy) @@ -3,5 +3,5 @@ int main(int argc, char *argv[]) { printf("I don't like being moved around!\n%s", bar()); - return 0; + return 1; } Index: code/bar.c =================================================================== --- code/bar.c (revision 4) +++ code/bar.c (working copy) @@ -1,4 +1,4 @@ const char *bar(void) { - return "Me neither!\n"; + return "Well, I do like being moved around!\n"; }
Ihre Änderungen bauen alle auf Revision 4 auf. Sie können nicht übergeben werden, da Harry bereits Revision 5 übergeben hat:
$ svn commit -m "Small fixes" Sende code/bar.c Sende code/foo.c Übertrage Daten .. svn: Übertragen schlug fehl (Details folgen): svn: Datei nicht gefunden: Transaktion »5-5«, Pfad »/trunk/code/bar.c«
An dieser Stelle müssen Sie svn update aufrufen. Außer Ihre Arbeitskopie zu aktualisieren, so dass Sie Harrys Änderungen sehen können, markiert es auch einen Baumkonflikt, so dass Sie die Gelegenheit bekommen, die Situation abzuschätzen und entsprechend aufzulösen.
$ svn update C code/bar.c A code/baz.c U Makefile Aktualisiert zu Revision 5. Konfliktübersicht: Baumkonflikte: 1
In seiner Ausgabe zeigt svn update Baumkonflikte mit einem großen C in der vierten Spalte an. svn status enthüllt weitere Details zum Konflikt:
$ svn status M code/foo.c A + C code/bar.c > lokal editiert, eingehend gelöscht bei Aktualisierung M code/baz.c
Beachten Sie, wie bar.c automatisch in Ihrer Arbeitskopie zum erneuten Hinzufügen vorgemerkt wird, was die Sache vereinfacht, sollten sie sich entscheiden, die Datei zu behalten.
Da eine Verschiebung in Subversion als eine Kopie mit anschließender Löschung implementiert ist, und diese beiden Operationen sich bei einer Aktualisierung sich nicht einfach in Beziehung setzen lassen, kann Sie Subversion lediglich über eine hereinkommende Löschung einer lokal modifizierten Datei warnen. Diese Löschung kann Teil einer Verschiebung sein oder eine tatsächliche Löschung. Um herauszufinden, was wirklich passiert ist, empfiehlt es sich, mit Ihren Kollegen Rücksprache zu halten, oder, als letzte Möglichkeit, svn log zu befragen.
Sowohl foo.c
als auch
baz.c
werden in der Ausgabe von
svn status als lokal modifiziert angezeigt.
Sie selbst haben Änderungen an foo.c
vorgenommen, das sollte Sie nicht überraschen. Aber warum wird
baz.c
als lokal modifiziert
angezeigt?
Die Antwort ist, dass, trotz der Einschränkungen bei der
Implementierung der Verschiebung, Subversion klug genug war,
Ihre lokalen Änderungen an bar.c
nach
baz.c
zu übertragen:
$ svn diff code/baz.c Index: code/baz.c =================================================================== --- code/baz.c (revision 5) +++ code/baz.c (working copy) @@ -1,4 +1,4 @@ const char *bar(void) { - return "Me neither!\n"; + return "Well, I do like being moved around!\n"; }
Warnung | |
---|---|
Lokale Änderungen an der Datei
|
svn info zeigt die URLs der am Konflikt beteiligten Objekte. Der linke URL zeigt die Quelle der lokalen Seite des Konfliktes, während die rechte URL die Quelle der hereinkommenden Seite des Konfliktes anzeigt. Diese URLs weisen darauf hin, wo Sie mit der Suche nach der mit Ihrer lokalen Änderung in Konflikt stehenden Änderung in der Vorgeschichte des Projektarchivs beginnen sollten.
$ svn info code/bar.c | tail -n 4 Baumkonflikt: lokal editiert, eingehend gelöscht bei Aktualisierung Quelle links: (Datei) ^/trunk/code/bar.c@4 Quelle rechts: (nichts) ^/trunk/code/bar.c@5
bar.c
heißt nun
Opfer eines Baumkonfliktes. Sie kann
nicht übergeben werden, bevor der Konflikt aufgelöst
wird:
$ svn commit -m "Small fixes" svn: Übertragen schlug fehl (Details folgen): svn: Übertragung abgebrochen: »code/bar.c« bleibt im Konflikt
Wie kann denn dieser Konflikt nun aufgelöst werden? Sie
können entweder mit Harrys Vorgehen einverstanden sein oder
nicht. Falls ja, löschen Sie bar.c
und
markieren den Baumkonflikt als aufgelöst:
$ svn delete --force code/bar.c D code/bar.c $ svn resolve --accept=working code/bar.c Konflikt von »code/bar.c« aufgelöst $ svn status M code/foo.c M code/baz.c $ svn diff Index: code/foo.c =================================================================== --- code/foo.c (revision 5) +++ code/foo.c (working copy) @@ -3,5 +3,5 @@ int main(int argc, char *argv[]) { printf("I don't like being moved around!\n%s", bar()); - return 0; + return 1; } Index: code/baz.c =================================================================== --- code/baz.c (revision 5) +++ code/baz.c (working copy) @@ -1,4 +1,4 @@ const char *bar(void) { - return "Me neither!\n"; + return "Well, I do like being moved around!\n"; }
Falls Sie mit dem Vorgehen nicht einverstanden sind,
können Sie stattdessen baz.c
löschen,
nachdem Sie sichergestellt haben, das alle nach der
Umbenennung vorgenommenen Änderungen entweder bewahrt worden
sind, oder verworfen werden können. Vergessen Sie nicht, die
Änderungen zurückzunehmen, die Harry an
Makefile
gemacht hat. Da
bar.c
bereits zum neu Hinzufügen
vorgemerkt ist, bleibt nichts mehr zu tun, und der Konflikt
kann als aufgelöst markiert werden:
$ svn delete --force code/baz.c D code/baz.c $ svn resolve --accept=working code/bar.c Konflikt von »code/bar.c« aufgelöst $ svn status M code/foo.c A + code/bar.c D code/baz.c M Makefile $ svn diff Index: code/foo.c =================================================================== --- code/foo.c (revision 5) +++ code/foo.c (working copy) @@ -3,5 +3,5 @@ int main(int argc, char *argv[]) { printf("I don't like being moved around!\n%s", bar()); - return 0; + return 1; } Index: code/bar.c =================================================================== --- code/bar.c (revision 5) +++ code/bar.c (working copy) @@ -1,4 +1,4 @@ const char *bar(void) { - return "Me neither!\n"; + return "Well, I do like being moved around!\n"; } Index: code/baz.c =================================================================== --- code/baz.c (revision 5) +++ code/baz.c (working copy) @@ -1,4 +0,0 @@ -const char *bar(void) -{ - return "Me neither!\n"; -} Index: Makefile =================================================================== --- Makefile (revision 5) +++ Makefile (working copy) @@ -1,2 +1,2 @@ foo: - $(CC) -o $@ code/foo.c code/baz.c + $(CC) -o $@ code/foo.c code/bar.c
In jedem Fall haben Sie nun Ihren ersten Baumkonflikt aufgelöst! Sie können Ihre Änderungen übergeben und Harry in der Kaffeepause erzählen, welche Mehrarbeit er Ihnen bereitet hat.
[9] Natürlich könnten Sie Dateien, die Konfliktmarkierungen enthalten, als konfliktfrei erklären und übergeben, wenn Sie es wirklich wollten, doch das wird in der Praxis kaum gemacht.