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.
An dieser Stelle sollten Sie verstehen, wie jede Übergabe an das Projektarchiv dort einen neuen Zustand des Dateibaums (genannt „Revision“) erzeugt. Wenn nicht, blättern Sie zurück und lesen Sie in „Revisionen“ über Revisionen nach.
Für dieses Kapitel verwenden wir das Beispiel aus Kapitel 1, Grundlegende Konzepte. Erinnern Sie sich, dass Sie und Ihre
Mitarbeiterin Sally sich ein Projektarchiv teilen, das zwei
Projekte beinhaltet: paint
und
calc
. Beachten Sie, dass in Abbildung 4.2, „Projektarchiv-Struktur zu Beginn“ dieses Mal jedoch jedes
Projektverzeichnis Unterverzeichnisse namens
trunk
und branches
beinhaltet. Der Grund hierfür wird bald klar sein.
Wie vorher sei hier angenommen, dass sowohl Sally als auch
Sie Arbeitskopien des „calc“ Projektes
besitzen. Ausdrücklich hat jeder von Ihnen eine Arbeitskopie von
/calc/trunk
. Alle Dateien des Projektes
befinden sich in diesem Unterverzeichnis statt in
/calc
selber, da Ihr Team entschieden hat,
dass in /calc/trunk
die
„Hauptlinie“ der Entwicklung stattfindet.
Sagen wir mal, dass Sie die Aufgabe bekommen haben, ein
großes Stück Software umzusetzen. Die Erstellung benötigt eine
lange Zeit und berührt alle Dateien im Projekt. Das Problem,
dass sofort auftaucht ist, dass Sie Sally nicht in die Quere
kommen möchten, die gerade hier und da kleinere Fehler
beseitigt. Sie ist davon abhängig, dass die letzte Version des
Projektes (in /calc/trunk
) stets benutzbar
ist. Wenn Sie nun damit beginnen, Stück für Stück Ihre
Änderungen zu übergeben, werden Sie die Dinge für Sally (und
auch für andere Teammitglieder) bestimmt in Unordnung
bringen.
Eine Strategie ist, sich in ein Loch zu verkriechen: Sie und
Sally können für eine Woche oder zwei den Informationsaustausch
einstellen. Das heißt, Sie fangen damit an, die Dateien Ihrer
Arbeitskopie auszuräumen und umzuorganisieren, ohne Änderungen
zu übergeben oder die Arbeitskopie zu aktualisieren, bevor Sie
mit Ihrer Arbeit vollständig fertig sind. Das wirft allerdings
einige Probleme auf. Erstens ist das nicht sehr sicher. Viele
Leute möchten Ihre Arbeit regelmäßig ins Projektarchiv sichern, für
den Fall, dass etwas Schlimmes mit der Arbeitskopie passieren
könnte. Zweitens ist das nicht sehr flexibel. Falls Sie Ihre
Arbeit an mehreren Rechnern verrichten (vielleicht haben Sie
eine Arbeitskopie von /calc/trunk
auf zwei
unterschiedlichen Maschinen), müssten Sie entweder alle
Änderungen manuell hin und her kopieren oder die gesamte Arbeit
an nur einem Rechner erledigen. Ebenso schwierig wäre es, Ihre
Änderungen mit anderen zu teilen. Eine weit verbreitete
„beste Vorgehensweise“ ist es, Ihren Mitarbeitern
zu erlauben, während Sie mit Ihrer Arbeit fortfahren, Ihre
bisherigen Ergebnisse zu überprüfen. Wenn niemand Ihre
unmittelbaren Änderungen sieht, haben Sie keine möglichen
Rückmeldungen und es könnte sein, dass Sie für Wochen einen
falschen Weg einschlagen, bevor es jemand aus Ihrem Team
bemerkt. Schließlich könnte es am Ende, wenn Sie mit Ihren
Änderungen fertig sind, sehr schwierig sein, Ihr Arbeitsergebnis
wieder mit dem Hauptteil der Quelltexte Ihrer Firma
zusammenzuführen. Sally (und andere) hätten viele andere
Änderungen ins Projektarchiv übergeben haben können, die sich
schwer in Ihre Arbeitskopie einarbeiten ließen –
besonders, falls Sie svn update nach Wochen
der Isolierung ausführen.
Die bessere Lösung ist, Ihren eigenen Zweig oder Ihre eigene Entwicklungslinie im Projektarchiv zu erzeugen. Dies erlaubt Ihnen, Ihre halbfertigen Arbeitsergebnisse regelmäßig zu sichern, ohne andere zu stören; dennoch können Sie selektiv Informationen mit Ihren Kollegen teilen. Im Weiteren werden Sie sehen, wie das funktioniert.
Es ist sehr einfach, einen Zweig zu erzeugen – Sie
erstellen mit dem Befehl svn copy eine
Kopie des Projektes im Projektarchiv. Subversion kann nicht nur
Dateien, sondern auch komplette Verzeichnisse kopieren. In
diesem Fall möchten Sie eine Kopie des Verzeichnisses
/calc/trunk
machen. Wo soll die neue
Kopie angelegt werden? Wo Sie wünschen – es ist eine
Frage der Projektkonventionen. Sagen wir mal, dass Ihr Team
die Konvention vereinbart hat, Zweige im Bereich
/calc/branches
des Projektarchivs anzulegen,
und Sie Ihren Zweig my-calc-branch
nennen
möchten. Sie werden ein neues Verzeichnis
/calc/branches/my-calc-branch
anlegen,
das als Kopie von /calc/trunk
beginnt.
Sie haben vielleicht schon gesehen, wie mit svn copy in einer Arbeitskopie eine Datei auf eine andere kopiert wird. Es kann allerdings auch verwendet werden, um eine „entfernte“ Kopie innerhalb des Projektarchivs durchzuführen. Kopieren Sie einfach einen URL auf einen anderen:
$ svn copy http://svn.example.com/repos/calc/trunk \ http://svn.example.com/repos/calc/branches/my-calc-branch \ -m "Privaten Zweig von /calc/trunk angelegt." Revision 341 übertragen.
Dieser Befehl bewirkt eine fast sofortige Übergabe im
Projektarchiv, wobei in Revision 341 ein neues Verzeichnis
erzeugt wird. Das neue Verzeichnis ist eine Kopie von
/calc/trunk
. Dies wird in Abbildung 4.3, „Projektarchiv mit neuer Kopie“ gezeigt.
[23]
Obwohl es auch möglich ist, einen Zweig zu erzeugen, indem
svn copy verwendet wird, um ein Verzeichnis
innerhalb der Arbeitskopie zu duplizieren, wird dieses
Vorgehen nicht empfohlen. Es kann in der Tat sehr langsam
sein! Das client-seitige Kopieren eines Verzeichnisses besitzt
einen linearen Zeitaufwand, da wirklich jede Datei und jedes
Verzeichnis innerhalb dieser Arbeitskopie auf der lokalen
Platte dupliziert werden muss. Das Kopieren eines
Verzeichnisses auf dem Server jedoch besitzt einen konstanten
Zeitaufwand und ist die Art und Weise, auf die die meisten
Leute Zweige erstellen.
Da Sie nun einen Zweig des Projektes erzeugt haben, können Sie eine neue Arbeitskopie auschecken, um ihn zu benutzen:
$ svn checkout http://svn.example.com/repos/calc/branches/my-calc-branch A my-calc-branch/Makefile A my-calc-branch/integer.c A my-calc-branch/button.c Ausgecheckt, Revision 341. $
An dieser Arbeitskopie ist nichts besonders; sie spiegelt
bloß ein anderes Verzeichnis im Projektarchiv wieder. Wenn Sie
Änderungen übergeben, wird sie Sally jedoch nicht sehen, wenn
sie aktualisiert, da sie eine Arbeitskopie von
/calc/trunk
hat. (Stellen Sie sicher,
dass Sie „Zweige durchlaufen“ weiter
unten in diesem Kapitel lesen: Der Befehl svn
switch ist eine Alternative für die Bereitstellung
einer Arbeitskopie eines Zweiges.)
Tun wir mal so, als ob eine Woche ins Land geht und die folgenden Übergaben stattfinden:
Sie machen eine Änderung an
/calc/branches/my-calc-branch/button.c
,
die die Revision 342 erzeugt.
Sie machen eine Änderung an
/calc/branches/my-calc-branch/integer.c
,
die die Revision 343 erzeugt.
Sally macht eine Änderung an
/calc/trunk/integer.c
, die die Revision
344 erzeugt.
Nun finden zwei unabhängige Entwicklungslinien (siehe
Abbildung 4.4, „Die Verzweigung der Geschichte einer Datei“) auf
integer.c
statt.
Es wird interessant, wenn Sie die Geschichte der
Änderungen an Ihrer Kopie von integer.c
betrachten:
$ pwd /home/user/my-calc-branch $ svn log -v integer.c ------------------------------------------------------------------------ r343 | user | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Geänderte Pfade: M /calc/branches/my-calc-branch/integer.c * integer.c: Wazjub gefrozzelt. ------------------------------------------------------------------------ r341 | user | 2002-11-03 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Geänderte Pfade: A /calc/branches/my-calc-branch (from /calc/trunk:340) Privaten Zweig von /calc/trunk angelegt. ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines Geänderte Pfade: M /calc/trunk/integer.c * integer.c: Einen Docstring geändert. ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines Geänderte Pfade: A /calc/trunk/integer.c * integer.c: Diese Datei dem Projekt hinzugefügt. ------------------------------------------------------------------------
Beachten Sie, dass Subversion die Geschichte von
integer.c
auf Ihrem Zweig über die
gesamte Zeit zurück verfolgt, und dabei sogar über den Punkt
hinweg geht, an dem es kopiert wurde. Es zeigt die Erzeugung
des Zweigs als ein Ereignis in der Geschichte, da
integer.c
implizit kopiert wurde, als
alles andere in /calc/trunk/
kopiert
wurde. Sehen Sie nun, was passiert, wenn Sally den gleichen
Befehl auf Ihre Arbeitskopie der Datei anwendet:
$ pwd /home/sally/calc $ svn log -v integer.c ------------------------------------------------------------------------ r344 | sally | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: Ein paar Rechtschreibfehler behoben. ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: Einen Docstring geändert. ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines Changed paths: A /calc/trunk/integer.c * integer.c: Diese Datei dem Projekt hinzugefügt. ------------------------------------------------------------------------
Sally sieht ihre eigene Änderung in Revision 344, aber nicht die Änderung, die Sie in Revision 343 gemacht haben. Was Subversion angeht, hatten diese beiden Übergaben Auswirkungen auf unterschiedliche Dateien an unterschiedlichen Stellen im Projektarchiv. Glwichwohl zeigt Subversion, dass die beiden Dateien einen Teil der Geschichte gemeinsam haben. Bevor die Kopie des Zweiges in Revision 341 gemacht wurde, waren die Dateien dieselbe Datei. Deshalb sehen sowohl Sie als auch Sally die Änderungen, die in den Revisionen 303 und 98 gemacht wurden.
Sie sollten sich zwei Lektionen aus diesem Abschnitt merken. Erstens besitzt Subversion kein internes Konzept für einen Zweig – es weiß lediglich, wie Kopien angelegt werden. Wenn Sie ein Verzeichnis kopieren, ist das entstehende Verzeichnis bloß ein „Zweig“, weil Sie ihm diese Bedeutung geben. Sie mögen über das Verzeichnis anders denken oder es anders behandeln, doch für Subversion ist es einfach ein gewöhnliches Verzeichnis, das nebenbei mit einigen zusätzlichen historischen Informationen ausgestattet ist.
Zweitens bestehen die Zweige von Subversion, bedingt durch
den Kopiermechanismus, als normale
Dateisystemverzeichnisse im Projektarchiv. Das ist ein
Unterschied zu anderen Versionskontrollsystemen, bei denen
Zweige typischerweise definiert werden, indem auf einer
eigenen Ebene den Dateisammlungen „Etiketten“
hinzugefügt werden. Der Ort Ihres Zweig-Verzeichnisses spielt
für Subversion keine Rolle. Die meisten Teams folgen der
Konvention, alle Zweige in einem Verzeichnis namens
/branches
abzulegen, jedoch steht es
Ihnen frei, eine Vorgehensweise nach Ihren Wünschen zu
erfinden.
[23] Subversion unterstützt nicht das Kopieren zwischen verschiedenen Projektarchiven. Wenn Sie mit svn copy oder svn move URLs verwenden, können Sie nur Objekte innerhalb desselben Projektarchivs kopieren oder verschieben.