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.

Verzeichnis-Teilbäume

Standardmäßig gehen die meisten Operationen von Subversion rekursiv vor. Beispielsweise erzeugt svn checkout eine Arbeitskopie mit allen Dateien und Verzeichnissen aus dem angegebenen Bereich des Projektarchivs, indem es rekursiv durch den Verzeichnisbaum hinabsteigt, bis die gesamte Struktur auf Ihre lokale Platte kopiert worden ist. Subversion 1.5 führt die Funktionalität Verzeichnis-Teilbäume (oder flache Checkouts) ein, die es Ihnen auf einfache Weise erlaubt, eine Arbeitskopie – oder einen Teil davon – flacher als vollständig rekursiv auszuchecken und nachträglich möglicherweise anfangs ignorierte Dateien und Verzeichnisse hinzuzufügen.

Sagen wir beispielsweise, wir hätten ein Projektarchiv mit einem Baum aus Dateien und Verzeichnissen, die die Namen von Familienmitgliedern samt Haustieren hätten. (Es ist sicherlich ein seltsames Beispiel, aber bleiben Sie hier.) Eine normaler svn checkout Operation würde uns eine Arbeitskopie des gesamten Baums liefern:

$ svn checkout file:///var/svn/repos mom
A    mom/son
A    mom/son/grandson
A    mom/daughter
A    mom/daughter/granddaughter1
A    mom/daughter/granddaughter1/bunny1.txt
A    mom/daughter/granddaughter1/bunny2.txt
A    mom/daughter/granddaughter2
A    mom/daughter/fishie.txt
A    mom/kitty1.txt
A    mom/doggie1.txt 
Ausgecheckt, Revision 1.
$

Lassen Sie uns nun denselben Baum noch einmal auschecken; dieses Mal jedoch verlangen wir von Subversion nur das oberste Verzeichnis ohne irgendeins seiner Kinder:

$ svn checkout file:///var/svn/repos mom-empty --depth empty 
Ausgecheckt, Revision 1
$

Beachten Sie, dass wir unserer ursprünglichen Kommandozeile svn checkout eine neue Option --depth hinzugefügt haben. Diese Option gibt es für viele Subversion-Unterbefehle und ähnelt den Optionen --non-recursive (-N) und --recursive (-R). Tatsächlich ist sie eine Kombination, Verbesserung, Nachfolge und letztendlich die Ablösung der beiden älteren Optionen. Zunächst erweitert sie für Anwender die unterstützten Abstufungen zur Angabe der Tiefe, indem einige vorher nicht (oder inkonsistent) unterstützte Tiefenangaben hinzugefügt wurden. Hier sind die Werte, die Sie für die Tiefe bei einer gegebenen Operation in Subversion angeben können:

--depth empty

Umfasst nur das unmittelbare Ziel einer Operation, keine der darin enthaltenen Dateien oder Verzeichnisse.

--depth files

Umfasst das unmittelbare Ziel einer Operation mitsamt der darin unmittelbar enthaltenen Dateien.

--depth immediates

Umfasst das unmittelbare Ziel einer Operation mitsamt der darin unmittelbar enthaltenen Dateien oder Verzeichnisse. Diese Verzeichnisse werden als leer betrachtet.

--depth infinity

Umfasst das unmittelbare Ziel einer Operation mitsamt aller darin rekursiv enthaltenen Dateien und Verzeichnisse.

Natürlich handelt es sich bei der bloßen Zusammenlegung zweier bestehender Optionen zu einer kaum um eine neue Funktionalität, die es Wert wäre, ihr einen ganzen Abschnitt dieses Buches zu widmen. Erfreulicherweise steckt hier noch mehr drin. Der Begriff der Tiefe erstreckt sich nicht ausschließlich auf die Operationen, die Sie mit Ihrem Client ausführen, sondern auch auf die Beschreibung der Umgebungstiefe eines Angehörigen einer Arbeitskopie, nämlich die von der Arbeitskopie dauerhaft gespeicherte Tiefe dieses Objekts. Ihre Hauptstärke ist eben diese Dauerhaftigkeit – die Tatsache, dass sie klebrig ist. Die Arbeitskopie speichert die für jedes enthaltene Objekt gewählen Tiefe solange bis Sie diese später ändern; standardmäßig arbeiten Subversion-Befehle auf allen vorhandenen Angehörigen einer Arbeitskopie, egal welche Tiefe für sie gewählt wurde.

[Tipp] Tipp

Sie können die gespeicherte Umgebungstiefe einer Arbeitskopie mit dem Befehl svn info überprüfen. Falls die Umgebungstiefe einen anderen Wert als die unendliche Rekursion (infinity) hat, zeigt svn info eine Zeile mit dem Wert an:

$ svn info mom-immediates | grep "^Tiefe:"
Tiefe: immediates
$

Unsere vorhergehenden Beispiele zeigten Checkouts unendlicher Tiefe (der Standard für svn checkout) sowie leerer Tiefe. Lassen Sie uns nun Beispiele für die anderen Tiefenwerte ansehen:

$ svn checkout file:///var/svn/repos mom-files --depth files
A    mom-files/kitty1.txt
A    mom-files/doggie1.txt 
Ausgecheckt. Revision 1.
$ svn checkout file:///var/svn/repos mom-immediates --depth immediates
A    mom-immediates/son
A    mom-immediates/daughter
A    mom-immediates/kitty1.txt
A    mom-immediates/doggie1.txt 
Ausgecheckt. Revision 1.
$

Wie beschrieben, bedeutet jede dieser Tiefen etwas mehr als nur das Ziel, doch weniger als vollständige Rekursion.

Wir haben hier zwar svn checkout als Beispiel genommen, jedoch finden Sie die Option --depth auch bei vielen anderen Subversion-Befehlen. Bei diesen anderen Befehlen stellt die Tiefenangabe eine Möglichkeit dar, den Wirkbereich einer Operation auf eine bestimmte Tiefe zu begrenzen, etwa so, wie sich die älteren Optionen --non-recursive (-N) und --recursive (-R) verhalten. Das bedeutet, dass, wenn Sie in einer Arbeitskopie einer bestimmten Tiefe arbeiten und eine Funktion geringerer Tiefe verlangen, sich diese Funktion auf die geringere Tiefe beschränkt. Wir können eigentlich noch allgemeiner werden: Wenn eine Arbeitskopie mit einer beliebigen – sogar gemischten – Umgebungstiefe gegeben ist und ein Subversion-Befehl mit einer gewünschten Wirktiefe aufgerufen wird, so wird der Befehl die Umgebungstiefe der Arbeitskopie-Objekte berücksichtigen, wobei der Wirkbereich auf die gewünschte (oder standardmäßige) Wirktiefe beschränkt ist.

Zusätzlich zur Option --depth akzeptieren die Unterbefehle svn update und svn switch eine zweite Option, die mit Tiefe zu tun hat: --set-depth. Mit dieser Option können Sie die einem Objekt der Arbeitskopie anhaftende Tiefe ändern. Sehen Sie, was passiert, wenn wir unseren leeren Checkout nehmen und ihn mit svn update --set-depth NEW-DEPTH TARGET schrittweise tiefer gehen lassen:

$ svn update --set-depth files mom-empty 
Aktualisiere »mom-empty«:
A    mom-empty/kittie1.txt
A    mom-empty/doggie1.txt 
Aktualisiert zu Revision 1.
$ svn update --set-depth immediates mom-empty 
Aktualisiere »mom-empty«:
A    mom-empty/son
A    mom-empty/daughter 
Aktualisiert zu Revision 1.
$ svn update --set-depth infinity mom-empty 
Aktualisiere »mom-empty«:
A    mom-empty/son/grandson
A    mom-empty/daughter/granddaughter1
A    mom-empty/daughter/granddaughter1/bunny1.txt
A    mom-empty/daughter/granddaughter1/bunny2.txt
A    mom-empty/daughter/granddaughter2
A    mom-empty/daughter/fishie1.txt 
Aktualisiert zu Revision 1.
$

Während wir schrittweise eine größere Tiefe wählten, lieferte uns das Projektarchiv mehr Teile unseres Baums.

In unserem Beispiel arbeiteten wir nur auf der Wurzel unserer Arbeitskopie und änderten ihre Umgebungstiefe. Wir können aber auch die Umgebungstiefe irgendeines Unterverzeichnisses innerhalb der Arbeitskopie unabhängig ändern. Eine sorgfältige Verwendung dieser Fähigkeit erlaubt es uns, bestimmte Bereiche des Dateibaums der Arbeitskopie herauszustellen, während andere Teilbereiche komplett weggelassen werden. Hier ist ein Beispiel, wie wir einen Teilbereich eines Zweigs unseres Familienstammbaums aufbauen, einen anderen Zweig vollständig rekursiv darstellen und andere Teile beschnitten (nicht auf der Festplatte) lassen können.

$ rm -rf mom-empty
$ svn checkout file:///var/svn/repos mom-empty --depth empty 
Ausgecheckt. Revision 1.
$ svn update --set-depth empty mom-empty/son 
Aktualisiere »mom-empty/son«:
A    mom-empty/son 
Aktualisiert zu Revision 1.
$ svn update --set-depth empty mom-empty/daughter 
Aktualisiere »mom-empty/daughter«:
A    mom-empty/daughter 
Aktualisiert zu Revision 1.
$ svn update --set-depth infinity mom-empty/daughter/granddaughter1 
Aktualisiere »mom-empty/daughter/granddaughter1«:
A    mom-empty/daughter/granddaughter1
A    mom-empty/daughter/granddaughter1/bunny1.txt
A    mom-empty/daughter/granddaughter1/bunny2.txt 
Aktualisiert zu Revision 1.
$

Glücklicherweise wird Ihre Arbeit in der Arbeitskopie nicht komplizierter, falls Sie dort eine verzwickte Sammlung aus Umgebungstiefen haben. Sie können immer noch lokale Änderungen in Ihrer Arbeitskopie vornehmen, rückgängig machen, anzeigen und übertragen, ohne neue Optionen bei den entsprechenden Unterbefehlen angeben zu müssen (auch nicht --depth und --set-depth). Sogar svn update funktioniert wie dort, wo keine bestimmte Tiefe angegeben worden ist – es aktualisiert die Argumente in der Arbeitskopie, die vorhanden sind, wobei deren anhaftende Tiefen berücksichtigt werden.

An dieser Stelle könnten Sie sich vielleicht fragen: Was soll das Ganze? Wann brauche ich das? Ein Szenario, bei dem diese Funktionalität sehr nützlich ist, steht in Zusammenhang mit einer bestimmten Organisation des Projektarchivs, besonders dann, wenn Sie viele in Beziehung stehende oder gemeinsam abhängige Projekte oder Software-Module als Geschwister an einem einzelnen Ort des Projektarchivs untergebracht haben (trunk/project1, trunk/project2, trunk/project3, usw.). In solchen Szenarios könnte es vorkommen, dass Sie persönlich nur eine handvoll dieser Projekte interessiert – vielleicht ein Hauptprojekt sowie einige andere Module, von denen es abhängt. Sie könnten zwar individuelle Arbeitskopien dieser Teile auschecken, jedoch wären diese Arbeitskopien disjunkt und es könnte umständlich sein, Funktionen gleichzeitig auf einigen oder allen anzuwenden. Die Alternative ist die Verwendung der Funktionalität von Verzeichnis-Teilbäumen, bei dem eine einzelne Arbeitskopie erstellt wird, die nur diejenigen Module enthält, die Sie interessieren. Sie würden das gemeinsame Elternverzeichnis mit einer leeren Tiefe auschecken und anschließend die von Ihnen gewünschten Objekte mit unendlicher Tiefe, wie im vorhergehenden Beispiel gezeigt. Sehen Sie es wie ein Opt-In-System für Angehörige einer Arbeitskopie.

Die ursprüngliche (Subversion 1.5) Implementierung flacher Checkouts war zwar gut, unterstützte aber nicht die Verringerung der Wirktiefe von Objekten der Arbeitskopie. Subversion 1.6 behebt dieses Problem. Wenn Sie beispielsweise in einer Arbeitskopie unendlicher Wirktiefe svn update --set-depth empty aufrufen, wird das zur Folge haben, dass alles bis auf das oberste Verzeichnis verworfen wird.[28] Subversion 1.6 führt darüber hinaus einen weiteren unterstützten Wert für die Option --set-depth ein: exclude. Die Verwendung von --set-depth exclude mit svn update führt dazu, dass das Ziel der Aktualisierung vollständig aus der Arbeitskopie entfernt wird – ein Zielverzeichnis würde nicht einmal leer hinterlassen. Das ist besonders dann hilfreich, wenn es mehr Dinge gibt, die Sie in der Arbeitskopie behalten wollen als Dinge, die Sie nicht mehr haben möchten.

Betrachten Sie ein Verzeichnis mit hunderten von Unterverzeichnissen, von denen Sie eins lieber nicht in Ihrer Arbeitskopie hätten. Beim additiven Ansatz mit Teilbäumen könnten Sie das Verzeichnis mit einer leeren Tiefe auschecken und dann explizit (mit svn update --set-depth infinity) für jedes Unterverzeichnis die Wirktiefe hochsetzen, mit Ausnahme desjenigen, welches Sie nicht haben möchten.

$ svn checkout http://svn.example.com/repos/many-dirs --depth empty
…
$ svn update --set-depth infinity many-dirs/wanted-dir-1
…
$ svn update --set-depth infinity many-dirs/wanted-dir-2
…
$ svn update --set-depth infinity many-dirs/wanted-dir-3
… 
### usw., usw., ...

Das könnte recht lästig werden, insbesonders, da Sie nicht einmal Ansätze dieser Verzeichnisse in Ihrer Arbeitskopie haben, mit denen Sie arbeiten könnten. Eine solche Arbeitskopie hätte auch noch eine weitere Eigenschaft, die Sie nicht erwarten oder wünschen würden: falls jemand anderes neue Unterverzeichnisse in diesem Oberverzeichnis erzeugen würde, bekämen Sie bei der Aktualisierung der Arbeitskopie davon nichts mit.

Ab Subversion 1.6 können Sie einen anderen Ansatz wählen. Zunächst checken Sie das Verzeichnis vollständig aus. Dann rufen Sie svn update --set-depth exclude für das Unterverzeichnis auf, das Sie nicht haben möchten.

$ svn checkout http://svn.example.com/repos/many-dirs
…
$ svn update --set-depth exclude many-dirs/unwanted-dir
D         many-dirs/unwanted-dir
$

Dieser Ansatz hinterlässt Ihre Arbeitskopie mit demselben Inhalt wie der erste Ansatz, jedoch würden beim Aktualisieren auch alle neuen Unterverzeichnisse im obersten Verzeichnis auftauchen. Der Nachteil bei diesem Ansatz ist, dass Sie ein komplettes Unterverzeichnis auschecken müssen, das Sie gar nicht haben wollen, nur damit Sie Subversion sagen können, dass Sie es nicht benötigen. Es kann sogar unmöglich sein, falls das Unterverzeichnis zu groß für Ihre Platte ist (was vielleicht der eigentliche Grund ist, warum Sie es nicht in der Arbeitskopie haben möchten).

[Anmerkung] Anmerkung

Obwohl die Funktion des Ausschließens eines Objektes aus der Arbeitskopie an den Befehl svn update gehängt wurde, haben Sie vielleicht bemerkt, dass die Ausgabe von svn update --set-depth exclude sich von der einer normalen Aktualisierung unterscheidet. Diese Ausgabe verrät die Tatsache, dass unter der Haube der Ausschluss eine vollständig clientseitige Operation ist, also ganz anders als eine typische Aktualisierung.

In einer solchen Situation könnten Sie über einen Kompromissansatz nachdenken. Checken Sie zunächst das oberste Verzeichnis mit --depth immediates aus. Schließen Sie dann das Verzeichnis, das Sie nicht benötigen, mit svn update --set-depth exclude aus. Erweitern Sie schließlich die Wirktiefe für alle verbleibenden Objekte auf unendliche Tiefe, was ziemlich einfach sein sollte, da Sie alle in Ihrer Shell adressierbar sind.

$ svn checkout http://svn.example.com/repos/many-dirs --depth immediates
…
$ svn update --set-depth exclude many-dirs/unwanted-dir
D         many-dirs/unwanted-dir
$ svn update --set-depth infinity many-dirs/*
…
$

Auch hier wird Ihre Arbeitskopie denselben Inhalt haben wie in den vorhergegangenen beiden Szenarien. Aber nun werden Sie jede neu hinzugefügte Datei oder jedes neu hinzugefügte Verzeichnis beim Aktualisieren – mit leerer Tiefe – mitbekommen. Dann können Sie sich entscheiden, was mit solchen neu erscheinenden Objekten geschehen soll: in unendliche Tiefe expandieren oder vollständig ausschließen.



[28] Natürlich auf eine sichere Art und Weise. Wie in anderen Situationen lässt Subversion Dateien, die Sie bearbeitet haben oder die nicht versioniert sind, auf der Platte.