# Information für EntwicklerInnen

Subversion ist ein Open-Source Softwareprojekt, welches unter einer Lizenz, die der von Apache ähnlich ist, entwickelt wird. Das Projekt wird finanziell von CollabNet, Inc., einer Softwarefirma mit Sitz in Kalifornien getragen. Neue Mitglieder, die ihre Zeit und Aufmerksamkeit dem Projekt widmen können sind in der Gemeinschaft, die sich um die Entwicklung von Subversion gebildet hat gerne willkommen. Freiwillige sind aufgerufen das Projekt entsprechend ihren Möglichkeiten zu unterstützen. Das kann heissen Programmfehler zu finden und zu melden, bestehenden Code zu verbessern oder komplett neue Funktionen zu programmieren.

Dieses Kapitel ist für Personen, welche die kontinuierliche Weiterentwicklung dadurch unterstützen, dass sie Hand an den Sourcecode legen. Wir werden einige Internas der Software betrachten, sehr spezifische technische Details, die von denjenigen beachtet werden sollen, die Subversion selbst — oder Werkzeuge, die auf den Subversion Bibliotheken basieren — entwickeln. Wenn sie nicht beabsichtigen an der Software auf einer solchen Ebene teilzuhaben, dann können sie dieses Kapitel überspringen, ohne Dinge zu versäumen, die sie als AnwenderIn wissen müssten.

## Ebenenmodell (Schichtenmodell) der Bibliotheken

Subversion hat ein modulares Design, welches als Sammlung von C Bibliotheken (libraries) umgesetzt wird. Jede Bibliothek hat eine genau definierte Aufgabe und Schnittstelle (interface) und die meisten Module existieren in einer von drei Hauptebenen — Projektarchiv-, Archivzugriff- (AZ) oder Client-Ebene. Wir werden diese Ebenen gleich näher betrachten, aber zuerst wollen wir einen Blick auf die Auflistung der Bibliotheken in werfen. Der Einheitlichkeit halber werden wir für die Bibliotheken die Namen unter Unix — ohne Dateierweiterung — verwenden (z.B. libsvn_fs, libsvn_wc, mod_dav_svn).

### Eine kurze Auflistung der Subversion Bibliotheken

Bibliothek | Beschreibung
--- | ---
libsvn_client | Hauptsächliche Schnittstelle für Client Programme
libsvn_delta | Ermittelt Unterschiede in Baumstruktur oder Text
libsvn_fs | Bibliothek für das Dateisystem im Projektarchiv
libsvn_ra | Allgemeine Routinen für den Archivzugriff und zum Laden der AZ Module
libsvn_ra_dav | Modul für den Archivzugriff über WebDAV
libsvn_ra_local | Modul für den lokalen Archivzugriff
libsvn_ra_svn | Modul für den Archivzugriff über ein eigenes Protokoll
libsvn_repos | Schnittstelle zum Projektarchiv
libsvn_subr | Diverse hilfreiche Subroutinen
libsvn_wc | Routinen für die Verwaltung der Arbeitskopie
mod_authz_svn | Modul für Apache zur Authenitifizierung beim Archivzugriff über WebDAV.
mod_dav_svn | Modul für Apache zur Übersetzung von WebDAV Operationen auf solche für Subversion

Der Umstand, dass das Wort diverse nur einmal in vorkommt ist ein gutes Zeichen. Das Entwicklungsteam von Subversion ist sehr darauf bedacht, dass die einzelnen Funktionalitäten der richtigen Ebene und der richtigen Bibliothek zugeordnete werden. Möglicherweise ist die fehlende Komplexheit aus der Sicht der EntwicklerInnen der grösste Vorteil des modularen Designs. Als EntwicklerIn kann schnell eine Art Übersichtskarte erstellt werden, die ein punktgenaues Auffinden einer bestimmten Funktionalität relativ einfach macht.

Ein anderer Vorteil des modularen Aufbaues ist die Möglichkeit ein Modul mit einer komplett neuen Bibliothek zu ersetzen, welche die gleiche API verwendet, ohne den Rest der Codebasis zu berühren. In einigen Fällen ist dies bei Subversion bereits geschehen. Die Module libsvn_ra_dav, libsvn_ra_local und libsvn_ra_svn implementieren die gleiche Schnittstelle. Alle drei kommunizieren mit der Projektarchiv-Ebene — libsvn_ra_dav und libsvn_ra_svn über das Netzwerk, libsvn_ra_local lokal.

Der Client seinerseits hebt den modularen Aufbau hervor. Während Subversion derzeit nur eine Kommandozeilen Clienten besitzt, wurden von DrittanbieterInnen bereits einige Programme entwickelt, die als GUIs (Grafisches User Interface) für Subversion eingesetzt werden können. Diese GUIs verwenden die gleichen APIs wie der einfache Kommandozeilen Client. Die libsvn_client Bibliothek ist die zentrale Anlaufstelle für die meisten Funktionen, die benötigt werden um einen funktionierenden Subversion Client zu entwerfen (siehe ).

### Projektarchiv-Ebene

Wenn wir auf die Projektarchiv-Ebene verweisen, sprechen wir über zwei Bibliotheken — die Projektarchiv- und die Dateisystem-Bibliothek. Diese stellen die Speicher- und Berichtsfunktionen für die verschiedenen Daten unter Versionskontrolle zur Verfügung. Diese Ebene ist mit der Client-Ebene über die Archivzugriffs-Ebene verbunden und ist aus der Sicht der AnwenderInnen das Ding am anderen Ende der Leitung.

Der Zugriff auf das Subversion Dateisystem erfolgt über die libsvn_fs API. Es ist kein kernel-level Dateisystem filesystem das im Betriebssystem installiert werden muss (wie z.B. Linux ext2 oder NTFS), sondern ein virtuelles Dateisystem. Anders als beim Speichern von Dateien und Verzeichnissen als wirkliche Dateien und Verzeichnisse (das ist in der Art, dass diese mit allen Programmen verwendet werden können), wird ein Datenbanksystem zur Speicherung verwendet. Derzeit ist als Datenbanksystem die Berkeley DB im Einsatz. Die Berkeley DB brachte einige elementare Eigenschaften, die Subversion benötigt, wie Daten Integrität, atomare Schreiboperationen, Wiederherstellung und Sicherung im laufenden Betrieb. Trotzdem gab es beträchtliches Interesse der Entwicklungsgemeinschaft in zukünftigen Versionen die Möglichkeit vorzusehen andere Datenbanksysteme zu benutzen, möglicherweise über einen Mechanismus wie Open Database Connectivity (ODBC).

Die von libsvn_fs zur Verfügung gestellte Dateisystem API enthält die Funktionalität, die sie von jeder anderen Dateisystem API erwarten würden: Sie können Dateien und Verzeichnisse erzeugen, entfernen, kopieren und verschieben, den Dateiinhalt verändern usw. Das Dateisystem hat auch Fähigkeiten die nicht so üblich sind, wie die Möglichkeit Metadaten (Eigenschaften) für jede Datei oder jedes Verzeichnis hinzuzufügen, zu ändern und zu entfernen. Weiters ist das Dateisystem von Subversion ein versionserzeugendes, was bedeutet, dass sich Subversion bei Änderungen im Verzeichnisbaum den Zustand vor der Änderung merkt. Und alle Änderungen, die davorliegen ebenso — zurück durch alle Versionen bis zum Beginn der Versionskontrolle (und sogar darüber hinaus *TODO: hab ich das richtig verstanden? :TODO*).

Alle Änderungen im Verzeichnisbaum werden im Zusammenhang mit einer Subversion Transaktion durchgeführt. Im Folgenden eine einfache generelle Routine zur Änderung des Dateisystems:

1. Beginn einer Subversion Transaktion.

2. Änderungen durchführen (hinzufügen, löschen, Eigenschaften ändern, etc.).

3. Transaktion übertragen.

Sobald die Transaktion übertragen wurde, werden die Änderungen am Dateisystem dauerhaft als geschichtliches Ereignis gespeichert. Jeder dieser Durchgänge erzeugt eine eigene neue Revision und jede Revision ist als unveränderliche Momentaufnahme so wie die Dinge waren jederzeit verfügbar.

#### Der Transaktionsbegriff

Die Bedeutung einer Subversion Transaktion, besonders im Zusammenhang mit dem Datenbank Code in libsvn_fs kann leicht verwechselt werden mit einer Transaktion, wie sie vom darunterliegenden Datenbanksystem verwendet wird. Beide Arten von Transaktionen existieren um die Zusammengehörigkeit und Abgeschlossenheit eines Vorganges auszudrücken. Transaktionen bieten die Möglichkeit um mehrere Aktionen in einem alles oder nichts Prozess durchzuführen — entweder alle alle Aktionen werden erfolgreich beendet, oder sie werden so behandelt, als wenn keine einzige Aktion erledigt worden wäre — und das in einer Art und Weise, dass keine anderen Prozesse beeinflusst werden, die gleichzeitig mit den Daten interagieren.

Datenbanktransaktionen umfassen generell kleine Operationen, die spezifisch für die Änderung von Daten in der Datenbank selbst sind (wie das Ändern des Inhaltes in einer Datenzelle). Subversions Transaktionen haben einen grösseren Umfang, umfassen Operationen auf höherer Ebene wie die Änderung einer Gruppe von Dateien und Verzeichnissen, für die geplant ist, dass diese als nächste Revision des Verzeichnisbaumes gespeichert werden sollen. Als ob das nicht verwirrend genug wäre, wird während der Erstellung einer Subversion Transaktion eine Datenbank Transaktion benutzt (sodass die Datenbank aussieht, als ob wir dies gar nicht versucht hätten falls die Erstellung fehlschlägt)!

Glücklicherweise ist für die BenutzerInnen der Dateisystem API, der Transaktionsmechanismus der Datenbank weitestgehend verborgen (wie es von einem sauber mudularisiertem Bibliotheksschema erwartet werden darf). Es ist nur sichtbar, wenn sie die Umsetzung des Dateisystems selbst untersuchen oder bearbeiten wollen.

Die meisten Funktionalitäten, die von der Schnittstelle zum Dateisystem angeboten werden sind Aktionen, die auf einen Dateisystem Pfad angewendet werden. Der primäre Mechanismus um von aussen eine bestimmte Revision von Dateien und Verzeichnissen zu beschreiben geschieht durch Angaben wie `/foo/bar`, genauso, wie wenn sie Dateien oder Verzeichnisse mit ihrem bevorzugtem Shell-Programm verwenden. Neue Dateien und Verzeichnisse werden hinzugefügt indem ihr gewünschter Pfad im Verzeichnisbaum an die richtigen API Funktionen übergeben wird. Sie finden Informationen darüber bei den entsprechenden Mechanismen.

Im Unterschied zu den meisten Dateisystemen ist der Pfad alleine nicht genug um eine Datei oder Verzeichnis in Subversion zu identifizieren. Stellen sie sich ein Verzeichnis als zweidimensionales System vor, in dem die Knoten eine Art rechts-links Reihenfolge haben und Unterverzeichnisse durch eine Bewegung nach unten dargestellt werden. zeigt eine typische Darstellung davon.

#### Zweidimensionale Darstellung von Dateien und Verzeichnissen

Das Dateisystem von Subversion aber hat eine dritte Dimension, welche die meisten Dateisysteme nicht haben — Zeit! Wir verstehen, dass dies für Sci-Fi Fans, die lange geglaubt haben, dass Zeit die vierte Dimension ist, ein Schock sein muss und wir entschuldigen uns für die Traumata die durch die Einführung einer neuen Theorie entstehen können. In der Dateisystem Schnittstelle hat beinahe jede Funktion ein `Pfad` Argument und erwartet auch ein `Basis` Argument (root). Dieses svn_fs_root_t Argument beschreibt eintweder eine Revision oder eine Subversion Transaktion (die üblicherweise eine zukünftige Revision verkörpert) und benötigt dieses dreidimensionale Modell um den Unterschied zwischen `/foo/bar` in Revision 32 und dem gleichen Pfad in Revision 98 verstehen zu können. zeigt die Revisions Historie als eine zusätzliche Dimension im Subversions Dateisystem Universium.

#### Revisionszeit — die dritte Dimension!

Wie wir früher erwähnten gleicht die libsvn_fs API anderen Dateisystemen, mit der Ausnahme, dass sie diese herrliche Fähigkeit der Versionierung hat. Sie wurde für den Gebrauch mit jedem Programm, das Bedarf an Versionskontrolle hat, entwickelt. Nicht zufällig ist Subversion selbst an dieser Funktionalität interessiert. Aber während die Dateisystem API ausreichen sollte um eine Basisunterstützung für die Versionskontrolle von Dateien und Verzeichnissen zu bieten, will Subversion mehr — und hier kommt libsvn_repos ins Spiel.

Die Subversion Projektarchiv Bibliothek (libsvn_repos) ist grundsätzlich eine Kapsel Bibliothek (wrapper library) um die Dateisystem Funktionalität. Diese Bibliothek ist zuständig für die Erstellung des Projektarchives, stellt sicher, dass das darunterliegende Dateisystem initialisiert wird, usw. Libsvn_repos implementiert eine Reihe von Haken (hooks) — Skripte, die vom Projektarchiv Code ausgeführt werden, wenn bestimmte Aktionen stattfinden. Diese Skripte dienen zur Benachrichtigung, Authentifizierung oder was immer die Administration des Projektarchives wünscht. Diese Art der Funktionalität und andere Hilfsroutinen, die von der Projektarchiv Bibliothek angeboten werden sind für eine Versionskontrolle nicht unbedingt erforderlich, weshalb diese in eine eigene Bibliothek gelegt wurden.

EntwicklerInnen, welche die libsvn_repos API benutzen wollen, werden bemerken, dass diese keine komplette Kapsel (wrapper) um die Dateisystem Schnittstelle darstellt. Nur gewisse Hauptereignisse der Dateisystem Aktivitäten werden von der Projektarchiv Schnittstelle abgedeckt. Einige davon beinhalten die Erstellung und Übertragung von Subversion Transaktionen und die Änderung von Versionseigenschaften. Diese Ereignisse wurden deshalb ausgewählt, weil Haken (hooks) damit verbunden sind. In Zukunft werden vielleicht auch andere Ereignisse von der Projektarchiv Schnittstelle abgedeckt werden. Die restliche Interaktion mit dem Dateisystem wird weiterhin direkt über die libsvn_fs API durchgeführt.

Als Beispiel ein Codestück, welches die Verwendung von beiden, der Projektarchiv- und der Dateisystem-Schnittstelle zeigt um eine neue Revision des Dateisystems zu erstellen, in dem ein Verzeichnis hinzugefügt wird. Beachten sie, dass in diesem Beispiel (und allen anderen im diesem Buch) das `SVN_ERR` Makro einfach die Rückgabe der eingekapselten (wrapped) Funktion auf nicht-erfolgreich Fehler überprüft und dann selbst diesen Fehler weitergibt, falls einer aufgetreten ist.

#### Benutzung der Projektarchiv Bibliothek

    /* Create a new directory at the path NEW_DIRECTORY in the Subversion
       repository located at REPOS_PATH.  Perform all memory allocation in
       POOL.  This function will create a new revision for the addition of
       NEW_DIRECTORY.  */
    static svn_error_t *
    make_new_directory (const char *repos_path,
                        const char *new_directory,
                        apr_pool_t *pool)
    {
      svn_error_t *err;
      svn_repos_t *repos;
      svn_fs_t *fs;
      svn_revnum_t youngest_rev;
      svn_fs_txn_t *txn;
      svn_fs_root_t *txn_root;
      const char *conflict_str;

      /* Open the repository located at REPOS_PATH.  */
      SVN_ERR (svn_repos_open (&repos, repos_path, pool));

      /* Get a pointer to the filesystem object that is stored in
         REPOS.  */
      fs = svn_repos_fs (repos);

      /* Ask the filesystem to tell us the youngest revision that
         currently exists.  */
      SVN_ERR (svn_fs_youngest_rev (&youngest_rev, fs, pool));

      /* Begin a new transaction that is based on YOUNGEST_REV.  We are
         less likely to have our later commit rejected as conflicting if we
         always try to make our changes against a copy of the latest snapshot
         of the filesystem tree.  */
      SVN_ERR (svn_fs_begin_txn (&txn, fs, youngest_rev, pool));

      /* Now that we have started a new Subversion transaction, get a root
         object that represents that transaction.  */
      SVN_ERR (svn_fs_txn_root (&txn_root, txn, pool));

      /* Create our new directory under the transaction root, at the path
         NEW_DIRECTORY.  */
      SVN_ERR (svn_fs_make_dir (txn_root, new_directory, pool));

      /* Commit the transaction, creating a new revision of the filesystem
         which includes our added directory path.  */
      err = svn_repos_fs_commit_txn (&conflict_str, repos,
                                     &youngest_rev, txn, pool);
      if (! err)
        {
          /* No error?  Excellent!  Print a brief report of our success.  */
          printf ("Directory '%s' was successfully added as new revision "
                  "'%" SVN_REVNUM_T_FMT "'.\n", new_directory, youngest_rev);
        }
      else if (err->apr_err == SVN_ERR_FS_CONFLICT)
        {
          /* Uh-oh.  Our commit failed as the result of a conflict
             (someone else seems to have made changes to the same area
             of the filesystem that we tried to modify).  Print an error
             message.  */
          printf ("A conflict occurred at path '%s' while attempting "
                  "to add directory '%s' to the repository at '%s'.\n",
                  conflict_str, new_directory, repos_path);
        }
      else
        {
          /* Some other error has occurred.  Print an error message.  */
          printf ("An error occurred while attempting to add directory '%s' "
                  "to the repository at '%s'.\n",
                  new_directory, repos_path);
        }

      /* Return the result of the attempted commit to our caller.  */
      return err;
    }

Im vorangegangenen Codestück werden Aufrufe sowohl mit der Projektarchiv- als auch der Dateisystem-Schnittstelle durchgeführt. Wir hätten die Übertragung ebenso mit `svn_fs_commit_txn` durchführen können, aber die Dateisystem API weiss nichts über den Hakenmechanismus aus der Projektarchiv Bibliothek Wenn das Subversion Projektarchiv automatisch bei jeder Übertragung einige Aktionen ausführen soll, die nicht in den Bereich von Subversion fallen (z.B. eine Email, welche die Änderungen beschreibt an die Mailingliste der EntwicklerInnen senden), dann müssen sie die Version `svn_repos_fs_commit_txn` aus der Projektarchiv Bibliothek nehmen. Diese Funktion wird derzeit zuerst den `pre-commit` Haken (hook script) ausführen wenn einer existiert, dann die Transaktion übertragen und zum Schluss den `post-commit` Haken (hook script) ausführen. Die Haken bieten einen speziellen Berichtsmechanismus, der nicht wirklich zu den Kernaufgaben der Dateisystem Bibliothek gehören. (Für weitere Information zum Hakensystem von Subversion siehe .)

Der Haken (hook) Mechanismus ist der Grund für eine eigene Projektarchiv Bibliothek neben dem Rest vom Dateisystem Code. Die libsvn_repos API bietet verschiedene andere wichtige Hilfsroutinen für Subversion. Dies inkludiert:

1. Erzeugen, Öffnen, Zerstören und Wiederherstellen von Projektarchiven und dem Dateisystem in einem solchen Projektarchiv.

2. Beschreiben der Unterschiede zwischen zwei Dateisystem Bäumen.

3. Abfragen der Log-Nachrichten, die mit allen (oder einigen) Revisionen in Zusammenhang stehen, in denen eine Gruppe von Dateien im Dateisystem geändert wurde.

4. Erzeugen eines menschenlesbaren dump des Dateisystems, einer kompletten Darstellung der Revisionen im Dateisystem.

5. Durchsuchen des dump Formats, Laden der Revisionen von der dump Datei in ein anderes Subversion Projektarchiv.

Da sich Subversion weiterentwickelt wird die Projektarchiv Bibliothek mit der Dateisystem Bibliothek wachsen um eine erweiterte Funktionalität und konfigurierbare Einstellungen anzubieten.

### Archivzugriffs-Ebene

Wenn die Projektarchiv-Ebene das andere Ende der Leitung ist, dann ist die Ebene des Archivzugriffs (AZ) die Leitung selbst. Beauftragt mit dem Verschub der Daten zwischen den Client Bibliotheken und dem Projektarchiv umfasst diese Ebene die libsvn_ra Bibliothek zum Laden der AZ Module, die Archivzugriffs Module selbst (welche derzeit aus libsvn_ra_dav, libsvn_ra_local und libsvn_ra_svn bestehen) und alle zusätzlichen Bibliotheken, die von einem oder mehrerer dieser Module benötigt werden, wie das mod_dav_svn Apache Modul, mit dem libsvn_ra_dav kommuniziert oder `svnserve` vom libsvn_ra_svn Server,.

Da Subversion URLs verwendet um das Projektarchiv zu identifizieren, wird der Protokollteil des URL Schemas (`file:`, `http:`, `https:` oder `svn:`) benutzt, um festzulegen, welches AZ Modul die Verbindung durchführt. Jedes Modul registriert eine Liste von Protokollen die es kennt und so kann der AZ Modullader zur Laufzeit entscheiden, welches Modul zu verwenden ist, um die anstehende Aufgabe zu erledigen. Sie können feststellen welche AZ Module und Protokolle der Subversion Kommandozeilen Client zur Verfügung stellt indem sie `svn --version` aufrufen:

    $ svn --version
    svn, version 1.0.1 (r9023)
       compiled Mar 17 2004, 09:31:13

    Copyright (C) 2000-2004 CollabNet.
    Subversion is open source software, see http://subversion.tigris.org/
    This product includes software developed by CollabNet (http://www.Collab.Net/).

    The following repository access (RA) modules are available:

    * ra_dav : Module for accessing a repository via WebDAV (DeltaV) protocol.
      - handles 'http' schema
      - handles 'https' schema
    * ra_local : Module for accessing a repository on local disk.
      - handles 'file' schema
    * ra_svn : Module for accessing a repository using the svn network protocol.
      - handles 'svn' schema

#### Archivzugriff über HTTP/DAV (RA-DAV/AZ-DAV)

Die libsvn_ra_dav Bibliothek ist für den Gebrauch durch Clienten, die nicht auf derjenigen Maschine laufen auf der das Projektarchiv liegt, entworfen. Die Clienten erreichen die Maschine auf der das Projketarchiv liegt unter Verwendung von URLs deren Protokollteil `http:` oder `https:` enthält. Um zu verstehen, wie diese Module arbeiten, sollten wir zuerst einige andere Schlüsselkomponenten dieser speziellen Konfiguration der Archivzugriffs-Ebene erwähnen — den mächtigen Apache HTTP Server und die Neon HTTP/WebDAV Clienten Bibliothek.

Der primäre Netzwerkserver für Subversion ist der Apache HTTP Server. Apache ist ein lange erprobter, erweiterbarer Open-Source Server der in vielen geschäftskritischen Bereichen zum Einsatz kommt. Er verträgt eine massive Netzwerkauslastung und läuft auf vielen Plattformen. Der Apache Server untersützt eine Vielzahl von verschiedenen Standard Authentifizierungs Protokollen und erlaubt die Erweiterung durch die Verwendung von Modulen, die zusätzliche Protokolle zur Verfügung stellen. Er erlaubt auch Optimierungen wie wie Netzwerk Pipelining und Bufferung (caching). Durch die Verwendung von Apache als Server bekommt Subversion alle diese Fähigkeiten umsonst. Da die meisten Firewalls HTTP Verkehr erlauben, ist im Normalfall keine Änderung der Firewall Konfiguration erforderlich, damit Subversion unbehindert arbeiten kann.

Subversion verwendet HTTP und WebDAV (mit DeltaV) um mit dem Apache Server zu kommunizieren. Im WebDAV Abschnitt in diesem Kapitel können sie mehr darüber erfahren. Hier sei nur gesagt, dass WebDAV und DeltaV Erweiterungen zum HTTP 1.1 Standard Protokoll sind, die eine gemeinsame Nutzung von Dateien bzw eine Versionskontrolle über das Internet erlauben. Apache 2.0 bietet mod_dav, ein Apache Modul, das die DAV Erweiturung zu HTTP versteht. Subversion selbst stellt mod_dav_svn zur Verfügung. Man kann sich dieses als ein eigenes Apache Modul vorstellen, das in Verbindung mit (in Wirklichkeit als Back-End für) mod_dav arbeitet, um die spezifische Umsetzung von WebDAV und DeltaV durch Subversion zu unterstützen.

Wenn mit dem Projektarchiv über HTTP kommuniziert wird, wählt die AZ Lader Bibliothek libsvn_ra_dav als das Zugriffs Modul. Der Subversion Client macht seine Aufrufe über die generische AZ Schnittstelle und libsvn_ra_dav setzt diese Aufrufe (die Subversions Aktionen von grossem Umfang zur Folge haben können) in eine Folge von HTTP/WebDAV Aufrufen um. Durch die Verwendung der Neon Bibliothek übermittelt libsvn_ra_dav die Aufrufe an den Apache Server. Apache empfängt diese Anfragen (genauso wie allgemeine Anfragen eines Webbrowsers zum Beispiel), erkennt, dass die Anfrage auf eine URL verweist, die — durch die Verwendung der `Location` Direktive in der `httpd.conf` — als DAV Zuordnung konfiguriert ist und übergibt die Anfrage das eigene mod_dav Modul. Wenn korrekt konfiguriert, weiss mod_dav, dass es mod_dav_svn von Subversion für alle dateisystemrelevanten Aktionen verwenden soll anstatt des allgmeinen mod_dav_fs Modules, das mit Apache ausgeliefert wird. So kommuniziert der Client letztendlich mit mod_dav_svn, welches direkt mit der Projektarchiv Ebene von Subversion in Verbindung steht.

Das war eine vereinfachte Darstellung des Übertragungsvorganges. Zum Beispiel kann das Projektarchiv von Subversion durch Authentifizierungs Direktiven von Apache geschützt werden. Dies könnte dazu führen, dass der Verbindungsaufbau zum Projektarchiv von Apache aus Authentifizierungsgründen unterbunden wird. In diesem Fall bekommt libsvn_ra_dav von Apache die Rückmeldung, dass die Identifikation ungenügend ist und gibt den Aufruf zurück auf die Client Ebene um neuerlich die Authentifikationsdaten anzufordern. Wenn die Daten korrekt zur Verfügung gestellt werden und der/die BenutzerIn die Rechte hat, die Apache benötigt, dann wird der nächste automatische Versuch von libsvn_ra_dav dir ursprüngiche Operation auszuführen gestattet und alles ist gut. Wenn keine zufriedenstellende Authentifizierung stattfindet, dann wird der Aufruf schlussendlich fehlschlagen und der Client wird wird dies an den/die BenutzerIn zurückmelden.

Durch die Verwendung von Neon und Apache erhält Subversion auch Funktionalitäten in verschiedenen anderen komplexen Bereichen. Wenn zum Beispiel Neon die OpenSSL Bibliotheken findet, erlaubt es dem Subversion Clienten eine SSL-verschlüsselte Verbindung zum Apache Server aufzubauen (dessen mod_ssl diese Sprache spricht). Ebenso verstehen sowohl Neon selbst, als auch mod_deflate von Apache den deflate Algorithmus (welcher von PKZIP und gzip verwendet wird), sodass Anforderungen in kleineren, komprimierten Stücken über die Leitung gesendet werden können. Weitere komplexe Fähigkeiten, die Subversion hofft in Zukunft unterstützen zu können umfassen die Möglichkeit von serverspezifizierten Umleitungen (redirects) (zum Beispiel, wenn das Projektarchiv auf eine andere URL verschoben wurde) und die Nutzung von HTTP Pipelining.

#### Archivzugriff über das subversions-eigene Protokoll (RA-SVN/AZ-SVN)

Zusätzlich zum Standard HTTP/WebDAV Protokol bietet Subversion einen Archivzugriff über eine eigenes Protokoll. Das libsvn_ra_svn Modul implementiert seine eigene Netwerk Socket Lösung und kommuniziert mit einem eigenständigen Server — dem `svnserve` Programm — auf der Maschine, die das Projektarchiv beherbergt. Clienten greifen auf das Projektarchiv unter Verwendung des `svn://` Schemas zu.

Dieser Umsetzung des Archivzugriffs fehlen die meisten Vorteile der Apache Methode, die im vorigen Abschnitt besprochen wurde. Trotzdem kann sie sehr attraktiv sein, weil sie wesentlich einfacher zu installieren und zu konfigurieren ist. Das aufsetzen eines `svnserve` Prozesses geht Blitzschnell. Er ist viel kleiner (in Hinblick auf die Anzahl der Codezeilen) als Apache und kann daher leichter überprüft werden — auf Sicherheitsprobleme und auch sonst. Weiters kann es sein, dass bereits eine bestehende SSH Sicherheits Infrastruktur existiert und Subversion diese benutzen sollte. Clienten, die ra_svn verwenden, können das Protokoll einfach über SSH tunneln.

#### Direkter Archivzugriff (RA-Local/AZ-Lokal)

Nicht jede Kommunikation mit dem Projektarchiv von Subversion erfordert einen riesigen Server und ein Netzwerk. Wenn das Projektarchiv auf der eigenen Platte verwendet werden soll, geschieht dies über `file:` URLs und die Funktionalität, die von libsvn_ra_local zur Verfügung gestellt wird. Dieses Archivzugriffs Modul steht direkt mit den Projektarchiv und Dateisystem Bibliotheken in Verbindung, sodass keine Netzwerkkommunikation erforderlich ist.

Subversion erwartet, dass der Servername, der als Teil der `file:` URL angegeben wird entweder `localhost` lautet oder leer bleibt und dass keine Portangaben verwendet werden. Die URLs sollten also entweder in der Form `file://localhost/path/to/repos` oder in der Form `file:///path/to/repos` eingegeben werden.

Seien sie sich also bewusst, dass die `file:` URLs von Subversion in einem normalen Webbrowser nicht in der gewohnten Weise verwendet werden können. Wenn sie eine Datei mittels `file:` URL in einem normalen Webbrowser anschauen wollen, dann liest dieser den Inhalt der Datei indem er direkt auf das Dateisystem zugreift. Die Ressourcen von Subversion hingegen liegen in einem virtuellen Dateisystem (siehe ) und der Browser kann dieses Dateisystem normalerweise nicht verstehen.

#### Hier ist der Platz für ihre Archivzugriffs Bibliothek

Wenn auf ein Subversion Projektarchiv über ein andres Protokoll zugegreifen werden soll — genau das ist der Grund warum die Archivzugriffs Ebene modularisiert wurde! Schreiben sie eine neue Bibliothek, welche die Archivzugriffs Schnittstelle auf der einen Seite implementiert und auf der anderen Seite mit dem Projektarchiv Ebene kommuniziert. Die neue Bibliothek kann bestehende Netzwerkprotokolle verwenden oder sie können neue entwerfen. Sie sollten Inter-Prozess-Kommunikation (IPC) Aufrufe verwenden oder — lassen wir uns etwas verrücktes einfallen — sie können auch ein Email-basiertes Protokoll umsetzen. Subversion stellt die APIs zur Verfügung und sie ihre Kreativität.

### Client Ebene

Auf der Client Seite ist die Suversion Arbeitskopie der Ort an dem alle Aktionen stattfinden. Die Fülle an Funktionalität, die durch die clientseitige Bibliothek implementiert ist, existiert einzig dazu um die Arbeitskopie — das sind Verzeichnisse voll mit Dateien und weiteren Unterverzeichnissen, die als eine Art lokaler, veränderbarer Wiederschein von einem oderer mehreren Projektarchiven dienen — zu verwalten und um Änderungen von der und an die Archivzugriffs Ebene zu übertragen.

Die Arbeitskopie Bibiothek von Subversion, libsvn_wc, ist direkt zuständig um die Daten in den Arbeitskopien zu verwalten. Um das zu bewerkstelligen speichert die Bibliothek Verwaltungsinformationen über jede Arbeitskopie in einem speziellen Unterverzeichnis. Dieses Unterverzeichnis mit dem Namen `.svn` existiert in jedem Verzeichnis der Arbeitskopie und enthält verschiedene andere Dateien und Verzeichnisse, die den Zustand festhalten und eine private Arbeitsumgebung für administrative Aktionen bieten. Für jene, die mit CVS vertraut sind, sei gesagt, dass dieses `.svn` Unterverzeichnis einen ähnlichen Zweck hat, wie die `CVS` Verzeichnisse in CVS Arbeitskopien. Für weitere Informationen über den administrativen Bereich `.svn` siehe in diesem Kapitel.

Die Subversion Client Bibliothek, libsvn_client, hat die weitreichendsten Aufgaben; ihr Job ist die Vereinigung der Funktionalität der Arbeitskopie Bibliothek mit jener der Archivzugriffs Ebene. Die API stellt die höchste angebotene Ebene für Programme zur Verfügung, die allgemeine Aktionen der Revisionskontrolle durchführen wollen. (*TODO* der letzte Satz wollte mir absolut nicht gelingen - original: ..., and then to provide the highest-level API to any application that wishes to perform general revision control actions.) Zum Beispiel die Funktion `svn_client_checkout` nimmt eine URL als Argument. Sie übergibt diese URL an die Archivzugriffs Ebene und öffnet eine authentifizierte Sitzung mit einem bestimmten Projektarchiv. Sie fordert vom Projektarchiv einen sicheren (Datei)Baum und übergibt diesen an die Arbeitskopie Bibliothek, welche eine vollständige Arbeitskopie auf die Platte schreibt (`.svn` Verzeichnisse usw).

Die Clienten Bibliothek wurde so entworfen, das sie von jeder Anwendung benutzt werden kann. Während der Sourcecode von Subversion standardmässig nur einen Kommandozeilen Clienten enthält, sollte es sehr einfach sein, unter Benutzung der Client Bibliothek eine Vielzahl von GUI Clienten zu schreiben. Neue GUIs (oder eigentliche jeder neue Client) für Subversion müssen nicht als kluge Kapseln (wrappers) um den Kommandozeilen Clienten operieren — sie haben über die libsvn_client API vollen Zugriff auf die gleiche Funktionalität, die gleichen Daten und Callback Mechanismen, wie der der Kommandozeilen Client.

#### Direkte Bindung — Einige Worte über Genauigkeit

Warum sollte ihr GUI Program direkt mit der libsvn_client Bibliothek binden, anstatt als Hülle (wrapper) um das Kommandozeilen Programm zu agieren? Neben dem Umstand, dass es einfach effizienter ist, kann auch die gebotene Genauigkeit betroffen sein. Ein Kommandozeilen Programm (wie das mit Subversion mitgelieferte), das direkt mit der Client Bibliothek bindet muss angeforderte und zurückgegeben Daten von C Typen in irgendeine menschenlesbare Ausgabe übersetzen. Diese Art von Übersetzung kann verlustbehaftet sein. Das heisst, dass das Programm möglicherweise nicht alle Informationen die von der API gesammelt wurden anzeigt oder möglicherweise Informationen kombiniert bzw zusammenfasst um eine kompakte Darstellung zu erreichen.

Wenn sie ein solches Kommandozeilen Progamm in ein weiteres Progamm kapseln (wrap), dann hat dieses zweite Programm nur Zugriff auf die bereits interpretierte (und wie wir erwähnt haben möglicherweise unvollständige) Information, welche es dann nochmals auf seine Darstellung umsetzen muss. Mit jeder Ebene der Kapselung (wrapping) besteht die Gefahr, dass die Unversehrtheit der Daten mehr und mehr verloren geht, vergleichbar mit dem Ergebnis, wenn sie eine analoge Kopie von einer Kopie (von einer Kopie …) einer Audio- oder Videokassette machen.

## Benutzung der APIs

Applikationen für die Bibliotheks APIs von Subversion zu entwickeln ist wirklich einfach. Alle öffentlichen Header Dateien sind im Verzeichnis `subversion/include` des Source Baumes. Diese Header werden auf die System Speicherplätze kopiert, wenn sie Subversion aus dem Source erzeugen und installieren. Diese Header repräsentieren die Gesamtheit der Funktionen und Typen, die für den Zugriff auf die Bibliotheken vorgesehen sind.

Das Erste was sie festestellen werden, ist, dass die Datentypen und Funktionen von Subversion in einen eigenen Namensraum liegen. Jeder öffentliche Symbolname von Subversion beginnt mit `svn_` gefolgt von einem Kürzel für die Bibliothek in welcher das Symbol definiert ist (wie zum Beispiel `wc`, `client`, `fs`, usw.), gefolgt von einem Unterstrich (`_`) und dann der Rest des Symbolnamens. Halböffentliche Funktionen (also solche, die sich innalb der Bibliotheksverzeichnisse befinden und die zwar von den Bibliotheken untereinander benutzt werden, aber nicht von Code ausserhalb davon) unterscheiden sich insofern vom Namensschema, als dass nach dem Bibliotheks Kürzel zwei Unterstriche (`__`) verwendet werden. Funktionen, die privat in Bezug auf eine gegebene Quelldatei sind, haben kein spezielles Präfix und sind `static` deklariert. Natürlich interessiert den Compiler dieses Namensschema nicht, aber es hilft definitiv den Gültigkeitsbereich einer Funktion oder eines Datentypes klarzustellen.

### Die Apache Portable Runtime Library

Gemeinsam mit den eigenen Datentypen von Subversion werden sie viele Referenzen sehen, die mit `apr_` beginnen — Symbole von der transportablen Laufzeit Bibliothek von Apache (APR steht für Apache Portable Runtime Library) APR ist eine Portierungs Bibliothek — urprünglich herausgelöst aus dem Server Code als Versuch die betriebssystemspezifischen Teile vom betriebssystemunabhängigen Code zu trennen. Das Ergebnis war eine Bibliothek, die eine allgemeine API für Operationen, die sich von Betriebssystem zu Betriebssystem mehr oder weniger unterscheiden, zur Verfügung stellt. Während der Apache HTTP Server selbstverständlich das erste Programm war, das diese APR Bibliothek nutzte, haben die EntwicklerInnen von Subversion sofort den Wert dieser APR erkannt. Das heisst, dass es in Subversion selbst so gut wie keinen betriebssystemabhängigen Code gibt. Weiters bedeutet es, dass der Subversion Client überall dort compiliert werden kann und läuft, wo dies der Server (*TODO* klarstellen: der Apache Server nehme ich an) auch tut. Derzeit sind dies alle Varianten von Unix, Win32, BeOS, OS/2, and Mac OS X.

Zusätzlich zur einheitlichen Umsetzung der Systemaufrufe, die sich von Betriebssystem zu Betriebssystem unterscheiden, Subversion benutzt ANSI Systemaufrufe und Datentypen wo immer dies möglich ist. gibt APR Subversion direkten Zugriff auf viele interne Datentypen wie zum Beispiel dynamische Arrays und Hash Tabellen. Subversion benutzt diese Typen intensiv im eigenen Code. Der wahrscheinlich markanteste APR Datentyp, der in nahezu allen API Prototypen von Subversion anzutreffen ist, ist der apr_pool — der APR Speicherpool. Subversion nuzt Pools intern immer, wenn Hauptspeicher angefordert wird (ausser eine externe Bibliothek erfordert ein anderes Speicher Mangement Schema für Daten, die an diese API übergeben werden). Neon und Berkeley DB sind Beispiele für solche Bibliotheken. Obwohl Personen, die für die APIs von Subversion programmieren, dies nicht so handhaben müssen, ist es erforderlich, dass diese Pools für Funktionen zur Verfügung gestellt werden, die diese brauchen. Das heisst, dass bei der Benutzung der API von Subversion die `apr_initialize()` aufgerufen werden muss, um das APR Subsytem zu initialisieren und dann muss ein Pool für die API Aufrufe von Subversion angefordert werden. Siehe für weitere Informationen.

### Anforderungen an URLs und Pfade

Mit Versionskontrolle <qoute>in der Ferne als zentralem Kriterium für die Existenz von Subversion macht es Sinn, dass der Internationalisierung (i18n) einige Aufmerksam geschenkt wurde, wobei <qoute>in der Ferne bedeuten kann quer durchs Bürogebäude, aber auch quer über den Globus. Um dies zu ermöglichen erwarten alle öffentlichen Schnittstellen von Subversion die Pfade akzeptieren, dass diese Pfade in eine Normform (canonicalized) gebracht werden und dass sie in UTF-8 umgewandelt sind. Das bedeutet zum Beispiel, dass jedes neue Clientenprogramm, welches die libsvn_client Schnittstelle benutzt, die Pfade zuerst von der lokalne Zeichenkodierung auf UTF-8 umwandeln muss, bevor diese an die Bibliotheken von Subversion übergeben werden und dass zurückgegebene Pfade dann auf die lokale Zeichenkodierung umgewandelt werden müssen, bevor diese ausserhalb von Subversion weiterverwendet werden. Glücklicherweise stellt Subversion einen Satz von Funktionen (siehe `subversion/include/svn_utf.h`) zur Verfügung, die von jedem Programm genutzt werden können um diese Umwandlungen vorzunehmen.

Ausserdem verlangen die APIs von Subversion, dass alle URL Parameter in sauberer URI Kodierung vorliegen. So muss anstatt file:///home/username/My File.txt als URL für die Datei mit den Namen `My File.txt` die URL in der Form file:///home/username/My%20File.txt vewendet werden. Wie gesagt, Subversion bietet Hilfsfunktionen, die ihre Applikation nutzen kann — `svn_path_uri_encode` und `svn_path_uri_decode` zur Umwandlung von bzw auf die URI Kodierung beispielsweise.

### Andere Programmiersprachen als C und C++

Wenn sie sie Bibliotheken von Subversion mit etwas anderem als einem C Programm nutzen wollen — sagen wir ein Python Script oder eine Java Applikation — dann bietet Subversion eine Basisunterstützung dafür über den Simplified Wrapper und Interface Generator (SWIG). SWIG Bindungen für Subversion befinden sich in `subversion/bindings/swig` und erreichen langsam einen brauchbaren Zustand. Diese Bindungen erlauben den indirekten Aufruf von API Funktionen für Subversion indem sie Wrapper benutzen, welche die Datentypen der Scriptsprache in soche für die C Bibliothek von Subversion umsetzen.

Es gibt einen offensichtliches Argument für den Zugriff auf die APIs von Subversion über programmiersprachenspezifische Bindungen — Einfachheit. Allgemein ausgedrückt sind Programmiersprachen wie Python und Perl viel flexibler und leichter zu benutzen als C oder C++. Die Art der verallgemeinerten Datentypen und der kontextabhängigen Typprüfung, die von diesen Sprachen geboten wird, sind häufig besser für den Umgang mit Informationen geeignet, die direkt von den BenutzerInnen kommen. Wie sie wissen sind Menschen fähig, unmögliche Eingaben in einem Programm zu machen und Scriptsprachen neigen dazu solche Eingabefehler eleganter zu behandeln. Natürlich geht diese Flexibilität häufig auf Kosten der Geschwindigkeit. Das ist der Grund, warum eine straffe, optimierte C basierte Schnittstelle und Bibliothek kombiniert mit einer mächtigen und flexiblen daran gebundenen Scriptsprache so reizvoll ist.

Werfen wir einen Blick auf ein Beispiel, das die SWIG Bindung von Subversion für Python nutzt. Dieses Beispiel macht das Gleiche wie unser letztes Beispiel. Beachten sie die Unterschiede in Grösse und Komplexität!

#### Benutzung der Projektarchiv Ebene mit Python

    from svn import fs
    import os.path

    def crawl_filesystem_dir (root, directory, pool):
      """Recursively crawl DIRECTORY under ROOT in the filesystem, and return
      a list of all the paths at or below DIRECTORY.  Use POOL for all
      allocations."""

      # Get the directory entries for DIRECTORY.
      entries = fs.dir_entries(root, directory, pool)

      # Initialize our returned list with the directory path itself.
      paths = [directory]

      # Loop over the entries
      names = entries.keys()
      for name in names:
        # Calculate the entry's full path.
        full_path = os.path.join(basepath, name)

        # If the entry is a directory, recurse.  The recursion will return
        # a list with the entry and all its children, which we will add to
        # our running list of paths.
        if fs.is_dir(fsroot, full_path, pool):
          subpaths = crawl_filesystem_dir(root, full_path, pool)
          paths.extend(subpaths)

        # Else, it is a file, so add the entry's full path to the FILES list.
        else:
          paths.append(full_path)

      return paths

Eine Umsetzung des vorangegangenen Beispieles in C wäre um einiges länger. Die gleiche Routine in C müsste sich penibel um die Speichernutzung kümmern und müsste eigene Datentypen für die Repräsentation der Hash Elemente und der Pfadlisten benutzen. Python hat eingebaute Hash- und Listen-Typen (unter der Bezeichnung Verzeichnisse beziehungsweise Sequenzen) und bietet wunderbare Methoden um mit diesen Datentypen zu operieren. Und da Python Referenzzähler und automatische Speicherbereinigung verwendet, müssen sich BenuzterInnen der Sprache nicht selbst mit der Anforderung und Freigabe von Hauptspeicher herumschlagen.

Im vorigen Abschnitt dieses Kapitels erwähnten wir, die `libsvn_client` Schnittstelle und dass diese einzig und allene existiert um das Schreiben eines Clienten für Subversion zu vereinfachen. Im folgenden ein Beispiel, wie diese Bibliothek über die SWIG Anbindung genutzt werden kann. Mit einigen wenigen Zeilen in Python können sie eine voll funktionsfähige Subversion Arbeitskopie auschecken!

#### Ein Beispielscript um eine Arbeitskopie auszuchecken.

    #!/usr/bin/env python
    import sys
    from svn import util, _util, _client

    def usage():
      print "Usage: " + sys.argv[0] + " URL PATH\n"
      sys.exit(0)

    def run(url, path):
      # Initialize APR and get a POOL.
      _util.apr_initialize()
      pool = util.svn_pool_create(None)

      # Checkout the HEAD of URL into PATH (silently)
      _client.svn_client_checkout(None, None, url, path, -1, 1, None, pool)

      # Cleanup our POOL, and shut down APR.
      util.svn_pool_destroy(pool)
      _util.apr_terminate()

    if __name__ == '__main__':
      if len(sys.argv) != 3:
        usage()
      run(sys.argv[1], sys.argv[2])

Die Sprachbindungen von Subversion neigen unglücklicherweise dazu, dass ihnen nicht die gleiche Aufmerksamkeit zukommt wie den Kernmodulen von Subversion. Trotzdem wurden signifikante Anstrengungen unternommen, um funktionierende Bindungen für Python, Perl und Java bereitzustellen. Wenn die SWIG Schnittstelle erst einmal sauber konfiguriert ist, sollte die Erzeugung der spezifischen Wrapper für die unterstützten Sprachen (welche derzeit Versionen von C#, Guile, Java, Mzscheme, OCaml, Perl, PHP, Python, Ruby, and Tcl umfassen) trivial sein. Trotzdem ist noch zusätzliche Programmierarbeit erforderlich, um für die komplexen APIs, die SWIG benötigt, eine allgemeine Hilfestellung zu bieten. Für weitere Informationen zu SWIG befinden sich auf der Homepage des Projektes http://www.swig.org/.

## Der administrative Bereich in der Arbeitskopie

Wie wir früher erwähnten, enthält jedes Verzeichnis einer Arbeitskopie von Subversion ein spezielles Unterverzeichnis namens `.svn`, welches die Verwaltungsdaten für das jeweilige Verzeichnis der Arbeitskopie enthält. Subversion benutzt die Information in `.svn` um Übersicht über verschiedene Dinge zu behalten, wie:

- Welches Projektarchiv wird durch die Dateien und Unterverzeichnisse im Arbeitskopie Verzeichnis repräsentiert — es können auch mehrere Projektarchive sein.

- Welche Revision der Dateien und Verzeichnisse befindet sich derzeit in der Arbeitskopie.

- Beliebige eigene Eigenschaften können mit diesen Dateien und Verzeichnissen verknüpft werden.

- Unveränderte Kopien der Dateien in der Arbeitskopie.

Obwohl mehr Information im `.svn` Verzeichnis gespeichert wird, werden wir nur einige der wichtigsten Punkte untersuchen.

### Die Entries Datei

Die wahrscheinlich wichtigste Datei im `.svn` Verzeichnis ist die `entries` Datei. Die entries Datei ist ein XML Dokument, welches eine Menge administrative Informationen über eine Ressource unter Versionskontrolle in einem Arbeitskopie Verzeichnis enthält. In dieser Datei werden die URLs der Projektarchive, die ursprüngliche Revision, Datei Prüfsummen, Zeitstempel des ursprünglichen Textes und der Eigenschaften, Status über vorgemerkte Aktionen und Konflikte, Information über die letzte Übertragung (AutorIn, Revision, Zeitstempel), die Geschichte von lokalen Kopien — praktisch alles, was ein Subversion Client über eine Ressource unter Versionskontrolle steht (oder gestellt werden soll) wissen muss!

#### Verchleich zwischen den administrativen Bereichen von Subversion und CVS

Ein Blick in ein typisches `.svn` Verzeichnis zeigt, dass hier ein bischen mehr administriert wird als CVS in seinem adminstrativen `CVS` Verzeichnis verwaltet. Die `entries` Datei enthält XML, welche den aktuellen Status des Arbeitskopie Verzeichnisses beschreibt und grundsätzlich den gleichen Zweck erfüllt, wie die Kombination der Dateien `Entries`, `Root` und `Repository` unter CVS.

Im Folgenden ein Beispiel einer entries Datei:

#### Inhalt einer typischen `.svn/entries` Datei

    <?xml version="1.0" encoding="utf-8"?>
    <wc-entries
       xmlns="svn:">
    <entry
       committed-rev="1"
       name="svn:this_dir"
       committed-date="2002-09-24T17:12:44.064475Z"
       url="http://svn.red-bean.com/tests/.greek-repo/A/D"
       kind="dir"
       revision="1"/>
    <entry
       committed-rev="1"
       name="gamma"
       text-time="2002-09-26T21:09:02.000000Z"
       committed-date="2002-09-24T17:12:44.064475Z"
       checksum="QSE4vWd9ZM0cMvr7/+YkXQ=="
       kind="file"
       prop-time="2002-09-26T21:09:02.000000Z"/>
    <entry
       name="zeta"
       kind="file"
       schedule="add"
       revision="0"/>
    <entry
       url="http://svn.red-bean.com/tests/.greek-repo/A/B/delta"
       name="delta"
       kind="file"
       schedule="add"
       revision="0"/>
    <entry
       name="G"
       kind="dir"/>
    <entry
       name="H"
       kind="dir"
       schedule="delete"/>
    </wc-entries>

Wie sie sehen können ist die Datei grundsätzlich eine Liste von Einträgen (entries). Jede `entry` Marke repräsentiert eine von drei Dingen: das Arbeitskopie Verzeichnis selbst (der sogenannte dieses Verzeichnis Eintrag — zu erkennen am leeren name Attribut), eine Datei in diesem Arbeitskopie Verzeichnis (das kind Attribut ist auf `"file"` gesetzt) oder ein Unterverzeichnis in diesem Arbeitsverzeichnis (das kind Attribut ist hier auf `"dir"` gesetzt). Die Dateien und Unterverzeichnisse deren Einträge in dieser Datei gespeichert sind sind entweder bereits unter Versioskontrolle oder sind (wie im Fall der Datei `zeta` im obigen Beispiel) für das Hinzufügen zur Versionskontrolle vorgemerkt, wenn die Änderungen an der Arbeitskopie das nächste Mal an das Projektarchiv übertragen werden. Jeder Eintrag hat einen eindeutigen Namen und ein kind (Art) Attribut.

Beim Entwickeln sollten sie auf einige spezielle Regeln achten, die Subversion anwendet, wenn es seine `entries` Dateien liest und schreibt. Obwohl jeder Eintrag mit einer Revision und einer URL verknüpft ist, fällt auf, dass nicht jede `entry` Marke in der Beispieldatei ein explizites revision oder url Attribut aufweist. Subversion erlaubt das Weglassen dieser beiden Attribute, wenn ihr Wert der gleich ist (im Falle des revision Attributes) oder einfach ermittelt werden kann Indem die URL aus der Verkettung der URL des Elternverzeichnisses und dem Namen des Eintrags gebildet wird. (im Falle des url Attributes) aus den Daten, die für den dieses Verzeichnis Eintrag gespeichert sind. Beachten sie also, dass Subversion für Unterverzeichnisse nur die Schlüssel Attribute speichert, also name, kind, url, revision, und schedule. In der Absicht redundante Information zu verringern legt Subversion fest, dass die korrekte Methode zur Ermittlung des vollen Attributsatzes darin besteht in dieses Verzeichnis hinunterzusteigen und den dieses Verzeichnis Eintrag in der dazugehörigen `.svn/entries` Datei zu lesen. Trotzdem wird eine Referenz auf das Unterverzeichnis in der `entries` Datei des Elternverzeichnises gehalten, mit ausreichend Information, um grundlegende Operationen der Versionskontrolle möglich zu machen, für den Fall, dass sich das Unterverzeichnis selbst nicht auf der Platte befindet.

### Pristine Copies and Property Files

Wie zuvor erwähnt, enthält das `.svn` Verzeichnis die ursprüngliche text-base Version von Dateien. Diese sind unter `.svn/text-base` zu finden. Die Vorteile dieser Kopien sind vielfältig — ohne Netzwerkverbindung kann so auf lokale Änderungen geprüft werden, können Unterschiede ausgegeben werden, können Änderungen an oder Löschungen von Dateien rückgängig gemacht werden und die Informationen zur Übertragung von Änderungen können klein gehalten werden. Der Preis dafür ist, dass jede Datei unter Versionskontrolle doppelt auf der Platte gespeichert werden muss. Heutzutage scheint dies für die meisten Dateien ein vernachlässigbarer Nachteil. Allerdings verschlimmert sich die Lage mit dem Anwachsen der Dateien, die unter Versionskontrolle stehen. Einige Überlegungen wurden angestellt, um diese text-base Dateien als Option vorzusehen. Ironischerweise wird die Existenz mit dem Anwachsen der Dateien unter Versionskontrolle auch wichtiger — wer will schon eine riesige Datei über das Netzwerk übertragen, nur weil eine winzige Änderung vorgenommen wurde? (Anm. d. Übers: Sinnvoll wäre diese optionale Möglichkeit auf die text-base Dateien zu verzichten vor allem dort, wo auch das Projektarchiv selbst lokal auf der eigenen Platte liegt)

Ähnliche Aufgaben wie die text-base Dateien haben die Dateien mit den Eigenschaften (properties) und deren prop-base Kopien mit dem Ausgangszustand in `.svn/props` beziehungsweise `.svn/prop-base`. Da auch Verzeichnisse Eigenschaften haben können, gibt es auch `.svn/dir-props` und `.svn/dir-prop-base` Dateien. Jede dieser Eigenschaften Dateien (sowohl die Arbeitsdatei als auch die base Version) benutzt ein einfaches hash-on-disk Datei Format um die Namen und Werte der Eigenschaften zu speichern.

## WebDAV

WebDAV (die Abkürzung für Web-based Distributed Authoring and Versioning, also ein webbasiertes, verteiltes, AutorInnen und Versionskontroll System) ist eine Erweiterung des Standard HTTP Protokolls, das entworfen wurde um das Web als Lese- und Schreibmedium nutzen zu können, im Gegensatz zu der heute vorherschenden Nutzung als reines Nur-Lesen Medium. Das Ziel ist die gemeinsame Nutzung von Verzeichnissen und Dateien über das Web — sowohl zum Lesen als auch zum Schreiben. RFCs 2518 and 3253 beschreiben die WebDAV/DeltaV Erweiterung zu HTTP und sind (neben einer Menge anderer nützlicher Information) unter http://www.webdav.org/ verfügbar.

Eine Anzahl von Dateimanagern können bereits jetzt Netzwerkverzeichnisse über WebDAV einbinden. Unter Win32 kann der Windows Explorer sogenannte WebFolder (nichts anderes als WebDAV fähige Netzwerk Ablageorte) darstellen, als ob es sich um normale Netzwerkfreigaben handeln würde. Mac OS X hat diese Fähigkeit ebenfalls — genauso wie Nautilus und der Konqueror Browser (unter GNOME beziehungsweise KDE).

Wie hängt das alles mit Subversion zusammen? Das mod_dav_svn Apache Modul benutzt HTTP, erweitert um WebDAV und DeltaV als eines seiner Netzwerkprotokolle. Subversion benutzt mod_dav_svn um die Umsetzung zwischen dem eigenen Versionskonzept und dem von RFCs 2518 und 3253 zu bewerkstelligen.

Für eine grundsätzlichere Diskussion über WebDAV, wie es arbeitet und wie es von Subversion genutzt wird siehe . Neben anderen Dingen erläutert dieser Anhang den Grad in welchem Subversion an die allgemeine WebDAV Spezifikation gebunden ist und wie das die Interoperabilität zwischen generischen WebDAV Clienten beeinflusst.

## Programmieren mit den Speicherpools

Fast alle EntwicklerInnen, die mit der Programmsprache C gearbeitet haben, kennen die entmutigendende Aufgabe die Speicherverwendung zu verwalten. Genug Speicher bei Bedarf anfordern, die Belegung verfolgen, nicht mehr benötigten Speicherplatz wieder freigeben — Diese Aufgaben können wirklich komplex sein. Und selbstverständlich können Fehler in diesem Bereich zu Programmen führen, die abstürzen oder noch schlechter, die das ganze System zum Absturz bringen. Glücklicherweise bietet die APR Bibliothek, die Subversion aus Portabilitätsgründen verwendet, den apr_pool_t Typ, einen Pool, von dem die Applikation Speicher anfordern kann.

Ein Speicherpool ist eine abstrakte Repräsentation für eine Menge Speicher, die vom Programm benutzt werden kann. Im Gegensatz zu der direkten Anforderung von Speicher vom Betriebssystem über die Standardfunktionen `malloc()` und Konsorten können Programme die gegen APR gelinkt sind einfach anfordern, dass ein Speicherpool erstellt wird (indem sie die `apr_pool_create()` Funktion benutzen). Jedes Mal, wenn das Programm Speicher aus dem Pool braucht, verwendet es eine der Funktionen der APR Pool API, wie `apr_palloc()`, welche eine generische Speicherlokation aus dem Pool zurückgibt. Das Programm kann kleinere oder grössere Speicherbereiche aus dem Pool anfordern und APR wird dafür sorgen, dass die Anforderungen bedient werden. Pools können automatisch in der Grösse wachsen um einem Programm mehr Speicher zur Verfügung zu stellen, als der Pool ursprünglich enthalten hat und zwar solange, bis dem System kein Speicher mehr zur Verfügung steht.

Nun, wenn dies das Ende der Pool Geschichte wäre, dann würde sie kaum besondere Aufmerksamkeit verdienen. Glücklicherweise ist das nicht der Fall. Pools können nicht nur erzeugt, sondern auch geleert und zerstört werden, indem `apr_pool_clear()` beziehungsweise `apr_pool_destroy()` verwendet werden. Damit ist es möglich mehrmals — oder mehrere tausend Male — Dinge vom Pool anzufordern und dann den ganzen zur Verfügung gestellten Speicher mit einem einzigen Funktionsaufruf zu löschen! Weiters besitzen Pools eine Hierarchie. Wenn sie einen Pool entleeren, dann werden alle seine Subpools zerstört; wenn sie einen Pool zerstören, dann werden der Pool und seine Subpools zerstört.

Bevor wir weiter gehen, sollten sie sich bewusst sein, dass sie möglicherweise nicht viele Aufrufe für die soeben beschriebenen APR Pool Funktionen im Quellcode von Subversion finden werden. APR Pools bieten einige erweiterbare Mechanismen, wie die Möglichkeit selbstdefinierte user data an den Pool anzuhängen und Mechanismen, um Löschfunktionen zu registrieren, die aufgerufen werden, wenn ein Pool zerstört wird. Subversion nutzt diese Erwerterungen in einer etwas nicht-trivialen Art. So bietet Subversion die Wrapper Funktionen `svn_pool_create()`, `svn_pool_clear()` und `svn_pool_destroy()` und verwendet hauptsächlich diese.

Obwohl die Pool auch bei der Basis Speicherverwaltung hilfreich sind, glänzen sie insbesondere bei Schleifen und rekursiven Szenarien. Da die Anzahl der Durchläufe bei Schleifen und die Tiefe bei Iterationen oft nicht vorhersehbar sind, ist auch der Speicherbedarf in diesen Bereichen unberechenbar. Glücklicherweise besteht durch die Nutzung von geschachtelten Speicherpools ein einfacher Weg um diese potentiell haarigen Situationen zu verwalten. Das folgende Beispiel demonstriert den Einsatz von verschachtelten Pools in einer durchaus üblichen Situation — rekursives Durchschreiten eines Verzeichnisbaumes, wobei für jedes Element im Baum einige Aufgaben zu erledigen sind.

### Effizienter Einsatz von Pools

    /* Recursively crawl over DIRECTORY, adding the paths of all its file
       children to the FILES array, and doing some task to each path
       encountered.  Use POOL for the all temporary allocations, and store
       the hash paths in the same pool as the hash itself is allocated in.  */
    static apr_status_t
    crawl_dir (apr_array_header_t *files,
               const char *directory,
               apr_pool_t *pool)
    {
      apr_pool_t *hash_pool = files->pool;  /* array pool */
      apr_pool_t *subpool = svn_pool_create (pool);  /* iteration pool */
      apr_dir_t *dir;
      apr_finfo_t finfo;
      apr_status_t apr_err;
      apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;

      apr_err = apr_dir_open (&dir, directory, pool);
      if (apr_err)
        return apr_err;

      /* Loop over the directory entries, clearing the subpool at the top of
         each iteration.  */
      for (apr_err = apr_dir_read (&finfo, flags, dir);
           apr_err == APR_SUCCESS;
           apr_err = apr_dir_read (&finfo, flags, dir))
        {
          const char *child_path;

          /* Clear the per-iteration SUBPOOL.  */
          svn_pool_clear (subpool);

          /* Skip entries for "this dir" ('.') and its parent ('..').  */
          if (finfo.filetype == APR_DIR)
            {
              if (finfo.name[0] == '.'
                  && (finfo.name[1] == '\0'
                      || (finfo.name[1] == '.' && finfo.name[2] == '\0')))
                continue;
            }

          /* Build CHILD_PATH from DIRECTORY and FINFO.name.  */
          child_path = svn_path_join (directory, finfo.name, subpool);

          /* Do some task to this encountered path. */
          do_some_task (child_path, subpool);

          /* Handle subdirectories by recursing into them, passing SUBPOOL
             as the pool for temporary allocations.  */
          if (finfo.filetype == APR_DIR)
            {
              apr_err = crawl_dir (files, child_path, subpool);
              if (apr_err)
                return apr_err;
            }

          /* Handle files by adding their paths to the FILES array.  */
          else if (finfo.filetype == APR_REG)
            {
              /* Copy the file's path into the FILES array's pool.  */
              child_path = apr_pstrdup (hash_pool, child_path);

              /* Add the path to the array.  */
              (*((const char **) apr_array_push (files))) = child_path;
            }
        }

      /* Destroy SUBPOOL.  */
      svn_pool_destroy (subpool);

      /* Check that the loop exited cleanly. */
      if (apr_err)
        return apr_err;

      /* Yes, it exited cleanly, so close the dir. */
      apr_err = apr_dir_close (dir);
      if (apr_err)
        return apr_err;

      return APR_SUCCESS;
    }

Das vorangegangene Beispiel demonstriert den effizienten Einsatz von Pools in beiden Einsatzbereichen — Schleifen und rekursive Aufrufe. Jede Rekursion beginnt mit der Erstellung eines Subpools aus dem Pool der an die Funktion übergeben wurde. Dieser Subpool wird für den Schleifenbereich verwendet und nach jedem Durchlauf geleert. Die Speichernutzung ist dadurch annähernd proportional zur Tiefe der Rekursion und nicht zur Anzahl der vorhandenen Dateien und Verzeichnisse die als Unterverzeichnisse im Top-Level Verzeichnis existieren. Wenn der erste Aufruf dieser rekursiven Funktion endet, sind nur sehr wenig Daten in dem Pool der an diese Funktion übergeben wurde gespeichert. Stellen sie sich die zusätzliche Komplexität vor, die entstehen würde, wenn diese Funktion für jedes Datenelement `alloc()` und `free()` aufrufen müsste!

Pools sind möglicherweise nicht für jede Applikation ideal, aber sie sind extrem nützlich in Subversion. Wenn sie Subversion entwicklen müssen sie sich mit Pools vertraut machen und wie diese korrekt eingesetzt werden. Fehler in der Speicherverwaltung sind unabhängig von der API oft schwierig zu finden und zu beheben, aber das Pool Konstrukt von APR hat sich als extrem angenehme, zeitsparende Funktionalität erwiesen.

## Subversion unterstützen

Die offizielle Informationsquelle über Subversion ist natürlich die Projekt Website unter http://subversion.tigris.org/. Dort finden sie Informationen, wie sie Zugriff auf den Quellcode bekommen und wie sie an Diskussionslisten teilnehmen können. Die Subversions Gemeinschaft freut sich immer über neue Mitglieder. Wenn sie Interesse haben an der Gemeinschaft teilzunehmen indem sie Änderungen am Quellcode beisteuern, dann bieten wir hier einige Tipps für den Beginn.

### Verbindung mit der Gemeinschaft aufnehmen

Der erste Schritt für die Teilnahme an der Gemeinschaft besteht darin, einen Weg zu finden über die aktuellen Geschehnisse informiert zu sein. Am effizientesten geschieht dies, indem sie sich in die Hauptdiskussionsliste der Entwicklungsgemeinschaft (dev@subversion.tigris.org) und die (*TODO* commit) Mail Liste (svn@subversion.tigris.org) eintragen. Wenn sie diese Listen — wenn auch nur lückenhaft — mitverfolgen, bekommen sie Informationen über wichtige Design Diskussionen, können sie aktuelle Änderungen am Quellcode von Subversion erfahren, sobald diese passieren und können zu diesen Änderungen beziehungsweise angekündigten Änderungen Stellung nehmen. Diese emailbasierten Diskussionslisten sind das primäre Kommunikationsmedium der Entwicklungsgemeinschaft. Siehe auch den Mailing Listen Abschnitt der Website für andere Listen im Zusammenhang mit Subversion, an denen sie eventuell interessiert sein könnten.

Aber woher wissen sie nun was getan werden muss? Es ist durchaus üblich für ProgrammiererInenn, dass sie die Absicht haben bei der Entwicklung zu helfen, aber keine gute Möglichkeit für den Einstieg finden. Schlussendlich stossen nicht viele Leute zur Gemeinschaft, die sich bereits entschlossenhaben ein bestimmtes Vorhaben zu erledigen. Aber indem sie die Diskussionsliste der Entwicklungsgemeinde verfolgen werden ihnen Fehlerberichte (bugreports) oder Wünsche für zusätzliche Fähigkeiten (feature requests) auffallen, die sie besonders interessieren. Ebenfalls ein grossartiger Platz um nach ausständigen, nicht bearbeiteten Aufgaben Ausschau zu halten, ist die Issue Tracking Datenbank (so in etwa: Problem Verfolgungs Datenbank) auf der Website. Dort finden sie die derzeitige Liste von bekannten Fehlern und Erweiterungswünschen. Wenn sie mit irgendeinem kleinen Problem beginnen wollen, suchen sie nach Einträgen, die als bite-sized markiert sind.

### Get the Source Code

Um den Code zu bearbeiten, müssen sie diesen zuerst haben. Das heisst sie müssen eine Arbeitskopie aus dem öffentlichen Projektarchiv für den Quellcode von Subversion auschecken. So einfach das klingt, kann die Aufgabe doch geringfügig problematischer sein. Da der Quellcode von Subversion selbst unter der Versionskontrolle von Subversion steht, müssen sie sich derzeit zuerst einen funktionierenden Subversion Clienten über einen anderen Weg besorgen. Die verbreitetsten Methoden sind der Download der letzten Binärversion (wenn eine solche für ihre Plattform verfügbar ist) oder der Download des tarballs mit dem Quellcode und der anschliessende Eigenbau (build) des Subversion Clienten. Wenn sie Subversion aus dem Quellcode erzeugen, dann lesen sie bitte unbedingt die Anleitungen in der `INSTALL` Datei im Basisverzeichnis des installierten Verzeichnisbaumes.

Nachdem sie einen funktionierenden Subversion Clienten haben, sind sie bereit um eine Arbeitskopie aus dem Subversion Quellcode Projektarchiv http://svn.collab.net/repos/svn/trunk/ auszuchecken: Beachten sie, dass die URL, die im obigen Beispiel für das Auschecken verwendet wird nicht bei `svn` endet, sondern mit einem Unterverzeichnis, das hier `trunk` benannt ist. Siehe unsere Diskussion über das Modell für Verzweigungen (branches) und Markierungen (tags) von Subversion für die dahinterliegenden Gründe.

    $ svn checkout http://svn.collab.net/repos/svn/trunk subversion
    A  HACKING
    A  INSTALL
    A  README
    A  autogen.sh
    A  build.conf
    …

Das obigige Kommando wird die allerneueste Version des Quellcodes von Subversion in das Unterverzeichnis `subversion` in ihrem aktuellen Arbeitsverzeichnis auschecken. Klarerweise können sie das letzte Argument an ihre Bedürfnisse anpassen. Unabhängig davon, wie sie das Verzeichnis mit der neuen Arbeitskopie nennen — nachdem die Operation abgeschlossen ist, haben sie den Quellcode von Subversion auf ihrer Platte. Natürlich müssen sie auch einige Hilfsbibliotheken (apr, apr-util, usw.) holen, sofern nicht bereits vorhanden — Details dazu finden sie in der `INSTALL` Datei im Basisverzeichnis des installierten Verzeichnisbaumes.

### Become Familiar with Community Policies

Nun da sie eine Arbeitskopie mit dem letzten Quellcode von Subversion haben, wollen sie höchstwahrscheinlich einen Blick in die `HACKING` Datei im Basisverzeichnis der Arbeitskopie werfen. Die `HACKING` Datei enthält allgemeine Anleitungen für Beiträge zu Subversion inklusive den Richtlinien, wie sie ihren Quellcode formatieren sollen, damit dieser zum Rest der Codebasis passt, wie die Beschreibung von Änderungen aussehen soll, um effiziente Log-Nachrichten zu erstellen, wie Änderungen zu testen sind, usw. Übertragungsrechte in das Projektarchiv mit dem Quellcode von Subversion wird erworben — Herrschaft durch Leistung. Obwohl dieses sie müssen sich ihre Übertragungsrechte verdienen oberflächlich als eine Art Elitemechanismus erscheint, geht es eigentlich um Effizienz — ob es mehr Zeit und Mühe verursacht Änderungen, die wahrscheinlich sicher und sinnvoll sind vorher zu begutachten und anzuwenden im Vergleich zu dem potentiellen Aufwand gefährliche Ändungen nachträglich wieder zu entfernen. Die HACKING Datei ist eine unbezahlbare Ressource wenn sie sicherstellt, dass ihre vorgeschlagenen Änderungen die Wertschätzung bekommen, die sie verdienen, ohne wegen Formfehler zurückgewiesen zu werden.

### Make and Test Your Changes

Mit dem Code und den wohlverstandenen Richtlinien der Gemeinschaft können sie nun darangehen ihre eigenen Änderungen zu machen. Es ist das beste zu versuchen kleinere, aber zusammengehörige Ändungen zu machen, gerade wenn grössere Aufgaben darauf warten angepackt zu werden, anstatt riesige Umwälzungen zu machen. Ihre vorgeschlagenen Änderungen sind leichter zu verstehen (und daher auch leichter zu begutachten), wenn sie die geringstmögliche Anzahl von Codezeilen einsetzen um ihr Ziel sauber zu erreichen. Nach jedem Satz von vorgeschlagenen Änderungen sollte ihre Codebasis in einem Zustand sein, in dem sie ohne Warnungen compiliert werden kann.

Subversion hat eine wirkich gründliche Sie sollten sich vielleicht eine Packung Popcorn vergönnen. Gründlich bedeutet in diesem Zusammenhang so etwas wie eine halbe Stunde nicht-interaktive Maschinenvolllast. Regressions Testumgebung und es wird erwartet, dass ihre vorgeschlagenen Änderungen alle vorgesehenen Tests bestehen. Durch den Aufruf von `make check` (in Unix) im Basisverzeichnis des Quellcodes können sie eine Plausibilitätsprüfung (sanity-check) durchführen. Der schnellste Weg, damit ihre Code Beiträge abgelehnt werden, ist (neben dem Erstellen einer vernünftigen Log-Nachricht) die Übermittlung von Änderungen, welche Fehler in der Testumgebung verursachen.

Im günstigsten Fall haben sie zusätzliche Tests zu dieser Testumgebung hinzugefügt die überprüfen, dass ihre vorgeschlagenen Änderungen erwartungsgemäss arbeiten. In der Tat, manchmal besteht der beste Beitrag, den jemand leistet darin neue Test bereitzustellen. Sie können Regressionstest für Funktionalitäten schreiben, die derzeit in Subversion korrekt arbeiten, um diese gegen zukünftige Änderungen zu schützen, die vielleicht Fehler in diesen Bereichen mit sich bringen. Sie können auch neue Tests schreiben, um bekannte Fehler aufzuzeigen. Zu diesem Zweck erlaubt die Testumgebung von Subversion, dass sie definieren, dass erwartet wird, dass ein Test fehlschlägt (als `XFAIL` bezeichnet) und solange Subversion in der Art scheitert, wie dies erwartet wird, solange wird das Testresultat von `XFAIL` als erfolgreicher Test gewertet. Schlussendlich gilt, je besser die Testumgebung desto weniger Zeit wird verschwendet um möglicherweise obskure Regressionsfehler zu suchen.

### Die Änderungen zur Verfügung stellen

Nachdem sie ihre Änderungen am Quellcode vorgenommen haben, erstellen sie eine verständliche und konistente Log-Nachricht, um die Änderungen und die Gründe dafür zu beschreiben. Dann schicken sie eine Email mit ihrer Log-Nachricht und der Ausgabe von `svn diff` (aufgerufen vom Basisverzeichnis der Arbeitskopie) an die Entwicklungsliste. Wenn die Mitglieder der Gemeinschaft ihre Änderungen als akzeptabel betrachten, dann wird jemand mit Übertragungsrechten (dem Recht eine neue Revision im Projektarchiv von Subversion zu erstellen) ihre Änderungen zum öffentlichen Quellcode hinzufügen. Erinnern sie sich, dass das Recht Änderungen direkt an das Projektarchiv übertragen zu dürfen durch Verdienste erworben wird — wenn sie Verständnis von Subversion beweisen, Programmierkompetenz und Teamgeist besitzen, dann wird ihnen wahrscheinlich dieses Recht erteilt werden.