Manchmal kann es nützlich sein, eine Arbeitskopie anzulegen, die aus einer Anzahl verschiedener Checkouts besteht. Es könnte beispielsweise sein, dass Sie verschiedene Unterverzeichnisse aus verschiedenen Bereichen des Projektarchivs haben möchten oder vielleicht sogar aus völlig verschiedenen Projektarchiven. Natürlich könnten Sie ein solches Szenario manuell erstellen – indem Sie svn checkout verwenden, um die verschachtelte Verzeichnisstruktur Ihrer Wahl anzulegen. Wenn diese Struktur jedoch für jeden Benutzer Ihres Projektarchivs wichtig ist, müsste jeder andere Benutzer dieselben Checkouts ausführen wie Sie.
Glücklicherweise unterstützt Subversion
Externals-Definitionen. Eine
Externals-Definition ist eine Abbildung eines lokalen
Verzeichnisses auf den URL – und idealerweise eine
bestimmte Revision – eines versionierten Verzeichnisses.
In Subversion deklarieren Sie Externals-Definitionen in Gruppen
unter Verwendung der Eigenschaft
svn:externals
. Sie können diese Eigenschaft
mit svn propset oder svn
propedit erstellen oder ändern (siehe „Ändern von Eigenschaften“). Sie kann jedem
versionierten Verzeichnis zugeordnet werden, und ihr Wert
beschreibt sowohl die Adresse des externen Projektarchivs als
auch das Verzeichnis auf dem Client, in dem diese Adresse
ausgecheckt werden soll.
Sobald sie mit einem versionierten Verzeichnis verknüpft
ist, bietet die Eigenschaft svn:externals
den
Komfort, dass jeder, der eine Arbeitskopie mit diesem
Verzeichnis auscheckt, die Vorteile der Externals-Definition
mitbekommt. Mit anderen Worten: Sobald sich jemand die Mühe
gemacht hat, die verschachtelte Struktur der Arbeitskopie zu
definieren, braucht sich niemand mehr darum zu kümmern –
Subversion checkt nach der ursprünglichen Arbeitskopie
automatisch die externen Arbeitskopien aus.
Warnung | |
---|---|
Die relativen Zielverzeichnisse von Externals-Definitionen dürfen nicht bereits auf Ihrem oder dem Systemen anderer Benutzer vorhanden sein – Subversion erzeugt sie beim Auschecken der externen Arbeitskopie. |
Mit dem Design der Externals-Definition bekommen Sie auch
alle normalen Vorteile der Subversion-Eigenschaften. Die
Definitionen sind versioniert. Falls Sie eine
Externals-Definition ändern müssen, können Sie das mit den
üblichen Unterbefehlen zum Ändern von Eigenschaften
bewerkstelligen. Wenn Sie eine Änderung an der Eigenschaft
svn:externals
übergeben, wird Subversion beim
nächsten svn update
die ausgecheckten
Elemente mit der geänderten Externals-Definition
synchronisieren. Dasselbe passiert, wenn andere ihre
Arbeitskopie aktualisieren und Ihre Änderungen an der
Externals-Definition erhalten.
Tipp | |
---|---|
Da die Eigenschaft |
Subversion-Versionen vor 1.5 akzeptieren ein Format für Externals-Definitionen, welches eine mehrzeilige Tabelle ist, die aus Unterverzeichnissen (relativ zum versionierten Verzeichnis, mit dem die Eigenschaft verknüpft ist), optionalen Revisions-Flags und vollqualifizierten, absoluten Subversion-Projektarchiv-URLs besteht. Ein Beispiel könnte so aussehen:
$ svn propget svn:externals calc third-party/sounds http://svn.example.com/repos/sounds third-party/skins -r148 http://svn.example.com/skinproj third-party/skins/toolkit -r21 http://svn.example.com/skin-maker
Wenn jemand eine Arbeitskopie des Verzeichnisses
calc
aus dem obigen Beispiel auscheckt,
fährt Subversion damit fort, die Objekte in der
Externals-Definition auszuchecken.
$ svn checkout http://svn.example.com/repos/calc A calc A calc/Makefile A calc/integer.c A calc/button.c Ausgecheckt. Revision 148. Hole externen Verweis nach calc/third-party/sounds A calc/third-party/sounds/ding.ogg A calc/third-party/sounds/dong.ogg A calc/third-party/sounds/clang.ogg … A calc/third-party/sounds/bang.ogg A calc/third-party/sounds/twang.ogg Ausgecheckt. Revision 14. Hole externen Verweis nach calc/third-party/skins …
Seit Subversion 1.5 wird jedoch ein neues Format der
Eigenschaft svn:externals
unterstützt.
Die Externals-Definitionen sind immer noch mehrzeilig, jedoch
hat sich die Reihenfolge und das Format der verschiedenen
Informationen geändert. Die neue Syntax lehnt sich nun mehr an
die Reihenfolge der Argumente an, die Sie svn
checkout übergeben: Zunächst kommen die
Revisions-Flags, dann der URL des externen
Subversion-Projektarchivs und schließlich das relative lokale
Unterverzeichnis. Beachten Sie jedoch, dass wir diesmal nicht
von „vollqualifizierten, absoluten
Subversion-Projektarchiv-URLs“ gesprochen haben. Das
liegt daran, dass das neue Format relative URLs und URLs mit
Peg-Revisionen unterstützt. Das vorausgegangene Beispiel einer
Externals-Definition könnte in Subversion 1.5 so aussehen:
$ svn propget svn:externals calc http://svn.example.com/repos/sounds third-party/sounds -r148 http://svn.example.com/skinproj third-party/skins -r21 http://svn.example.com/skin-maker third-party/skins/toolkit
Bei Verwendung der Syntax für Peg-Revisionen (die wir detailliert in „Peg- und operative Revisionen“ behandeln), könnte es so aussehen:
$ svn propget svn:externals calc http://svn.example.com/repos/sounds third-party/sounds http://svn.example.com/skinproj@148 third-party/skins http://svn.example.com/skin-maker@21 third-party/skins/toolkit
Tipp | |
---|---|
Sie sollten ernsthaft erwägen, explizite Revisionsnummern in all Ihren Externals-Definitionen zu verwenden. Wenn Sie das tun, bedeutet dies, dass Sie entscheiden, wann ein anderer Schnappschuss mit externen Informationen herangezogen werden soll und welcher Schnappschuss genau. Außer der Vermeidung überraschender Änderungen an Projektarchiven Dritter, auf die Sie keinen Einfluss haben, bedeuten explizite Revisionsnummern, dass beim Zurücksetzen Ihrer Arbeitskopie auf eine frühere Revision auch die Externals-Definitionen auf den entsprechenden früheren Stand zurückgesetzt werden, was wiederum bedeutet, dass die externen Arbeitskopien derart aktualisiert werden, dass sie so aussehen wie zum Zeitpunkt Ihres Projektarchivs der früheren Revision. Für Software-Projekte kann das den Unterschied zwischen einem erfolgreichen und einem gescheiterten Build eines älteren Schnappschusses Ihrer komplexen Codebasis ausmachen. |
Bei den meisten Projektarchiven bewirken die drei Formate
der Externals-Definition letztendlich dasselbe. Alle bringen die
gleichen Vorteile. Leider bringen alle aber auch die gleichen
Ärgernisse. Da die Definitionen absolute URLs verwenden, hat das
Kopieren oder Verschieben eines damit verknüpften Verzeichnisses
keine Auswirkungen auf das, was als extern ausgescheckt wird
(obwohl natürlich das relative lokale Zielverzeichnis mit dem
umbenannten Verzeichnis mitwandert). Das kann in bestimmten
Situationen verwirrend – sogar frustrierend – sein.
Nehmen wir beispielsweise an, dass Sie ganz oben ein Verzeichnis
namens my-project
haben und eine
Externals-Definition auf eins seiner Unterverzeichnisse erstellt
haben (my-project/some-dir
), welches
wiederum die letzte Revision eines anderen Unterverzeichnisses
verfolgt (my-project/external-dir
).
$ svn checkout http://svn.example.com/projects . A my-project A my-project/some-dir A my-project/external-dir … Hole externen Verweis nach »my-project/some-dir/subdir« Externer Verweis ausgecheckt, Revision 11. Ausgecheckt, Revision 11. $ svn propget svn:externals my-project/some-dir subdir http://svn.example.com/projects/my-project/external-dir $
Nun benennen Sie mit svn move das
Verzeichnis my-project
um. Zu diesem
Zeitpunkt verweist Ihre Externals-Definition noch immer auf
einen Pfad unterhalb des Verzeichnisses
my-project
, obwohl das Verzeichnis nicht
mehr existiert.
$ svn move -q my-project renamed-project $ svn commit -m "Rename my-project to renamed-project." Lösche my-project Hinzufügen renamed-project Revision 12 übertragen. $ svn update Hole externen Verweis nach »renamed-project/some-dir/subdir« svn: Zielpfad existiert nicht $
Absolute URLs können außerdem Probleme bei Projektarchiven
hervorrufen, die über verschiedene URL-Schemata verfügbar sind.
Falls Ihr Subversion-Server so konfiguriert sein sollte, dass
jeder das Projektarchiv über http://
oder
https://
auschecken darf, Übertragungen
jedoch nur über https://
erlaubt sind, haben
Sie ein interessantes Problem. Wenn Ihre Externals-Definitionen
die http://
-Form der Projektarchiv-URLs
verwenden, werden Sie nicht im Stande sein, irgend etwas aus den
mit diesen Externals erzeugten Arbeitskopien zu übertragen.
Wenn Sie andererseits die https://
-Form der
URLs verwenden, kann jemand, der mit http://
auscheckt, da sein Client https://
nicht
unterstützt, die externen Verweise nicht heranziehen. Beachten
Sie ferner, dass beim Umhängen Ihrer Arbeitskopie (mit
svn switch und der Option
--relocate
) die Externals-Definitionen
nicht automatisch umgehängt werden.
Subversion 1.5 unternimmt einen riesigen Schritt, um diese Frustrationen zu lindern. Wie bereits früher erwähnt wurde, können die URLs im neuen Externals-Format relativ sein, und Subversion stellt eine besondere Syntax zur Verfügung, um verschiedene Arten relativer URLs darzustellen.
../
Relativ zum URL des Verzeichnisses, an dem die
Eigenschaft svn:externals
gesetzt
ist
^/
Relativ zur Wurzel des Projektarchivs, in dem
die Eigenschaft svn:externals
versioniert ist
//
Relativ zum Schema des URL des
Verzeichnisses, an dem die Eigenschaft
svn:externals
gesetzt
ist
/
Relativ zum Wurzel-URL des Servers, auf dem
die Eigenschaft svn:externals
versioniert
ist
Wenn wir uns nun ein viertes Mal das vorangegangene Beispiel mit der Externals-Definition ansehen und von der neuen absoluten URL-Syntax auf verschiedene Weise Gebrauch machen, könnten wir nun das sehen:
$ svn propget svn:externals calc ^/sounds third-party/sounds /skinproj@148 third-party/skins //svn.example.com/skin-maker@21 third-party/skins/toolkit
Subversions Unterstützung für Externals-Definitionen bleibt
aber trotzdem alles andere als ideal. Eine Externals-Definition
kann nur auf Verzeichnisse zeigen, nicht auf Dateien. Auch
darf der lokale Unterverzeichnis-Teil keine
..
-Verweise auf Elternverzeichnisse enthalten
(etwa ../../skins/myskin
). Die größte
Enttäuschung ist vielleicht, dass Arbeitskopien, die mit
Unterstützung von Externals-Definitionen erzeugt wurden, nach
wie vor getrennt sind von der primären Arbeitskopie (auf deren
versionierten Verzeichnissen die Eigenschaft
svn:externals
ursprünglich gesetzt wurde).
Und Subversion arbeitet nur auf nicht-disjunkten Arbeitskopien
genau. Wenn Sie beispielsweise Änderungen übertragen möchten,
die Sie in einer oder mehreren dieser externen Arbeitskopien
vorgenommen haben, müssen Sie für diese Arbeitskopien explizit
svn commit aufrufen – das Übertragen
der primären Arbeitskopie greift nicht auf irgendwelche externen
über.
Wir haben bereits einige der Mängel des alten Formats von
svn:externals
und die Verbesserungen durch
das neue Format von Subversion 1.5 erwähnt. Seien Sie jedoch
vorsichtig, dass Sie bei Verwendung des neuen Formats nicht
versehentlich Probleme für andere verursachen, die mit älteren
Subversion-Clients auf Ihr Projektarchiv zugreifen wollen.
Während Clients von Subversion 1.5 weiterhin das ursprüngliche
Format der Externals-Definitionen verstehen und unterstützen,
sind ältere Clients nicht in der Lage, das
neue Format korrekt zu verarbeiten.
Neben den Befehlen svn checkout,
svn update, svn switch und
svn export, welche die
disjunkten (oder unzusammenhängenden)
Unterverzeichnisse mit den ausgecheckten Externals eigentlich
verwalten, berücksichtigt auch der Befehl svn
status Externals-Definitionen. Er zeigt für die
disjunkten externen Unterverzeichnisse einen Zustandscode
X
an und durchläuft dann diese Verzeichnisse,
um den Zustand der eigentlichen externen Objekte anzuzeigen. Sie
können jedem dieser Unterbefehle die Option
--ignore-externals
mitgeben, um die Bearbeitung
der Externals-Definitionen zu unterbinden.