<chapter id="svn-ch-8">
  <title>Information für EntwicklerInnen</title>
  
  <simplesect id="svn-ch-8-sect-0"> <para>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.</para>
    
    <para>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 &mdash;
      oder Werkzeuge, die auf den Subversion Bibliotheken basieren
      &mdash; 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.</para>

  </simplesect>

  <!-- ******************************************************************* -->
  <!-- *** SECTION 1:  LAYERED LIBRARY DESIGN                          *** -->
  <!-- ******************************************************************* -->
  <sect1 id="svn-ch-8-sect-1">
    <title>Ebenenmodell (Schichtenmodell) der Bibliotheken</title>

    <para>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
      &mdash; 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
      <xref linkend="svn-ch-8-table-1"/> werfen.  Der Einheitlichkeit
      halber werden wir für die Bibliotheken die Namen unter Unix
      &mdash; ohne Dateierweiterung &mdash; verwenden (z.B. libsvn_fs,
      libsvn_wc, mod_dav_svn).</para>

    <table id="svn-ch-8-table-1">
      <title>Eine kurze Auflistung der Subversion Bibliotheken</title>
      <tgroup cols="2">
        <thead>
          <row>
            <entry>Bibliothek</entry>
            <entry>Beschreibung</entry>
          </row>
        </thead>
        <tbody>
          <row>
            <entry>libsvn_client</entry> 
            <entry>Hauptsächliche Schnittstelle für Client Programme</entry>
          </row>
          <row>
            <entry>libsvn_delta</entry>
            <entry>Ermittelt Unterschiede in Baumstruktur oder Text</entry>
          </row>
          <row>
            <entry>libsvn_fs</entry>
            <entry>Bibliothek für das Dateisystem im Projektarchiv</entry>
          </row>
          <row>
            <entry>libsvn_ra</entry>
            <entry>Allgemeine Routinen für den Archivzugriff und zum Laden der AZ Module</entry>
          </row>
          <row>
            <entry>libsvn_ra_dav</entry>
            <entry>Modul für den Archivzugriff über WebDAV</entry>
          </row>
          <row>
            <entry>libsvn_ra_local</entry>
            <entry>Modul für den lokalen Archivzugriff</entry>
          </row>
          <row>
            <entry>libsvn_ra_svn</entry>
            <entry>Modul für den Archivzugriff über ein eigenes Protokoll</entry>
          </row>
          <row>
            <entry>libsvn_repos</entry>
            <entry>Schnittstelle zum Projektarchiv</entry>
          </row>
          <row>
            <entry>libsvn_subr</entry>
            <entry>Diverse hilfreiche Subroutinen</entry>
          </row>
          <row>
            <entry>libsvn_wc</entry>
            <entry>Routinen für die Verwaltung der Arbeitskopie</entry>
          </row>
          <row>
            <entry>mod_authz_svn</entry>
            <entry>Modul für Apache zur Authenitifizierung beim
              Archivzugriff über WebDAV.</entry>
          </row>
          <row>
            <entry>mod_dav_svn</entry>
            <entry>Modul für Apache zur Übersetzung von WebDAV Operationen auf
              solche für Subversion</entry>
          </row>
        </tbody>
      </tgroup>
    </table>

    <para>Der Umstand, dass das Wort <quote>diverse</quote> nur einmal
      in <xref linkend="svn-ch-8-table-1"/> 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 <quote>Übersichtskarte</quote> erstellt
      werden, die ein punktgenaues Auffinden einer bestimmten
      Funktionalität relativ einfach macht.</para>

    <para>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 &mdash; libsvn_ra_dav und libsvn_ra_svn über
      das Netzwerk, libsvn_ra_local lokal.</para>

    <para>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 <xref
      linkend="svn-ch-8-sect-1.3"/>).</para>

    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-1.1">
      <title>Projektarchiv-Ebene</title>

      <para>Wenn wir auf die Projektarchiv-Ebene verweisen, sprechen
        wir über zwei Bibliotheken &mdash; 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 <quote>anderen
        Ende der Leitung.</quote></para>

      <para>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
        <quote>Dateien</quote> und <quote>Verzeichnissen</quote> 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.
        <footnote> <para>Die Berkeley DB brachte einige elementare
          Eigenschaften, die Subversion benötigt, wie Daten
          Integrität, atomare Schreiboperationen, Wiederherstellung
          und Sicherung im laufenden Betrieb.</para> 
        </footnote>
        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).</para>

      <para>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 (<quote>Eigenschaften</quote>) 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 &mdash;
        zurück durch alle Versionen bis zum Beginn der
        Versionskontrolle (und sogar darüber hinaus *TODO: hab ich das
        richtig verstanden? :TODO*).</para>

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

      <orderedlist>
        <listitem>
          <para>Beginn einer Subversion Transaktion.</para>
        </listitem>
        <listitem>
          <para>Änderungen durchführen (hinzufügen, löschen,
            Eigenschaften ändern, etc.).</para>
        </listitem>
        <listitem>
          <para>Transaktion übertragen.</para>
        </listitem>
      </orderedlist>

      <para>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 <quote>so wie die Dinge waren</quote> jederzeit
        verfügbar.</para>

      <sidebar>
        <title>Der Transaktionsbegriff</title>

        <para>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 <quote>alles oder nichts</quote>
          Prozess durchzuführen &mdash; entweder alle alle Aktionen
          werden erfolgreich beendet, oder sie werden so behandelt,
          als wenn <emphasis>keine</emphasis> einzige Aktion erledigt
          worden wäre &mdash; und das in einer Art und Weise, dass
          keine anderen Prozesse beeinflusst werden, die gleichzeitig
          mit den Daten interagieren.</para>

        <para>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)!</para>

        <para>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.</para>

      </sidebar>

      <para>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
        <filename>/foo/bar</filename>, 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.</para>

      <para>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. <xref linkend="svn-ch-8-dia-1"/> zeigt eine typische
        Darstellung davon.</para>

      <figure id="svn-ch-8-dia-1">
        <title>Zweidimensionale Darstellung von Dateien und Verzeichnissen</title>
        <graphic fileref="images/ch08dia1.png"/>
      </figure>

      <para>Das Dateisystem von Subversion aber hat eine dritte 
        Dimension, welche die meisten Dateisysteme nicht haben &mdash; Zeit!
        <footnote>
          <para>Wir verstehen, dass dies für Sci-Fi Fans, die lange
            geglaubt haben, dass Zeit die <emphasis>vierte</emphasis>
            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.</para>
        </footnote>
        In der Dateisystem Schnittstelle hat beinahe jede Funktion ein
        <parameter>Pfad</parameter> Argument und erwartet auch ein
        <parameter>Basis</parameter> Argument (root).  Dieses
        <structname>svn_fs_root_t</structname> 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 <filename>/foo/bar</filename> in Revision 32 und dem
        gleichen Pfad in Revision 98 verstehen zu können.  <xref
        linkend="svn-ch-8-dia-2"/> zeigt die Revisions Historie als
        eine zusätzliche Dimension im Subversions Dateisystem
        Universium.</para>

      <figure id="svn-ch-8-dia-2">
        <title>Revisionszeit &mdash; die dritte Dimension!</title>
        <graphic fileref="images/ch08dia2.png"/>
      </figure>

      <!-- Hier könnte ein bischen über DAG/tree layers ins Detail
           gegangen werden, über das hard-link Design und wie das
           solche Annehmlichkeiten wie billige Kopien (cheap copies)
           beeinflusst.  Wenn "bubble-up" nicht an anderen Stellen in
           diesem Buch behandelt wird, dann wäre vielleicht hier ein
           guter Platz dafür. -->

      <para>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 &mdash; und hier kommt libsvn_repos ins
        Spiel.</para>

      <para>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)
        &mdash; 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.</para>
      
      <para>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.</para>

      <para>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
        <function>SVN_ERR</function> 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.</para>

      <example id="svn-ch-8-sect-1.1-ex-1">
        <title>Benutzung der Projektarchiv Bibliothek</title>

        <programlisting>
/* 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 (&amp;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 (&amp;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 (&amp;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 (&amp;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 (&amp;conflict_str, repos, 
                                 &amp;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;
} 
</programlisting>
      </example>

      <para>Im vorangegangenen Codestück werden Aufrufe sowohl mit der
        Projektarchiv- als auch der Dateisystem-Schnittstelle
        durchgeführt.  Wir hätten die Übertragung ebenso mit
        <function>svn_fs_commit_txn</function> 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
        <function>svn_repos_fs_commit_txn</function> aus der
        Projektarchiv Bibliothek nehmen.  Diese Funktion wird derzeit
        zuerst den <literal>pre-commit</literal> Haken (hook script)
        ausführen wenn einer existiert, dann die Transaktion
        übertragen und zum Schluss den <literal>post-commit</literal>
        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 <xref
        linkend="svn-ch-5-sect-2.1" />.)</para>
      
      <para>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:</para>

      <orderedlist>
        <listitem>
          <para>Erzeugen, Öffnen, Zerstören und Wiederherstellen von
            Projektarchiven und dem Dateisystem in einem solchen
            Projektarchiv.</para>
        </listitem>
        <listitem>
          <para>Beschreiben der Unterschiede zwischen zwei
            Dateisystem Bäumen.</para>
        </listitem>
        <listitem>
          <para>Abfragen der Log-Nachrichten, die mit allen (oder
            einigen) Revisionen in Zusammenhang stehen, in denen eine
            Gruppe von Dateien im Dateisystem geändert wurde.</para>
        </listitem>
        <listitem>
          <para>Erzeugen eines menschenlesbaren <quote>dump</quote>
            des Dateisystems, einer kompletten Darstellung der
            Revisionen im Dateisystem.</para>
        </listitem>
        <listitem>
          <para>Durchsuchen des dump Formats, Laden der Revisionen
            von der dump Datei in ein anderes Subversion
            Projektarchiv.</para>
        </listitem>
      </orderedlist>

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

    </sect2>

    <!-- ****************************************************************** -->
    <sect2 id="svn-ch-8-sect-1.2">
      <title>Archivzugriffs-Ebene</title>

      <para>Wenn die Projektarchiv-Ebene <quote>das andere Ende der
        Leitung</quote> 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
        <command>svnserve</command> vom libsvn_ra_svn Server,.</para>

      <para>Da Subversion URLs verwendet um das Projektarchiv zu
        identifizieren, wird der Protokollteil des URL Schemas
        (<literal>file:</literal>, <literal>http:</literal>,
        <literal>https:</literal> oder <literal>svn:</literal>)
        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 <command>svn
        --version</command> aufrufen:</para>
     
      <screen>
$ 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
</screen>
    
      <sect3 id="svn-ch-8-sect-1.2.1">
        <title>Archivzugriff über HTTP/DAV (RA-DAV/AZ-DAV)</title>

        <para>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
          <literal>http:</literal> oder <literal>https:</literal>
          enthält.  Um zu verstehen, wie diese Module arbeiten,
          sollten wir zuerst einige andere Schlüsselkomponenten dieser
          speziellen Konfiguration der Archivzugriffs-Ebene erwähnen
          &mdash; den mächtigen Apache HTTP Server und die Neon
          HTTP/WebDAV Clienten Bibliothek.</para>
  
        <para>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.</para>
  
        <para>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.</para>

        <para>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 &mdash; durch die Verwendung der
          <sgmltag>Location</sgmltag> Direktive in der
          <filename>httpd.conf</filename> &mdash; 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.</para>
  
        <para>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.</para>
  
        <!-- A diagram here? -->
  
        <para>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 <quote>diese Sprache spricht</quote>).
          Ebenso verstehen sowohl Neon selbst, als auch mod_deflate
          von Apache den <quote>deflate</quote> 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.</para>
  
        <!-- Beschreibung weiterer Unterschiede zwischen CVS und
             Subversion.  CVS AnwenderInnen müssen angeben, welcher
             Authentifizierungs Mechanismus verwendet werden soll.
             (mittels :ext: oder :pserver:) und ob komprimierte
             Kommunikation verwendet werden soll (mit der -z Option)
             oder nicht.  In Subversion übernimmt Apache einige dieser
             Aufgaben.  Der Server teilt dem Client mit ob er
             Kompression beherrscht oder nicht und ... hmm.  Stimmt
             das auch wirklich? -->

      </sect3>

      <sect3 id="svn-ch-8-sect-1.2.2">
        <title>Archivzugriff über das subversions-eigene Protokoll (RA-SVN/AZ-SVN)</title>

        <para>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 &mdash; dem <filename>svnserve</filename> Programm
          &mdash; auf der Maschine, die das Projektarchiv beherbergt.
          Clienten greifen auf das Projektarchiv unter Verwendung des
          <literal>svn://</literal> Schemas zu.</para>

        <para>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
          <filename>svnserve</filename> Prozesses geht Blitzschnell.
          Er ist viel kleiner (in Hinblick auf die Anzahl der
          Codezeilen) als Apache und kann daher leichter überprüft
          werden &mdash; 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.</para>

      </sect3>

      <sect3 id="svn-ch-8-sect-1.2.3">
        <title>Direkter Archivzugriff (RA-Local/AZ-Lokal)</title>

        <para>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 <literal>file:</literal>
          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.</para>

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

        <para>Seien sie sich also bewusst, dass die
          <literal>file:</literal> URLs von Subversion in einem
          normalen Webbrowser nicht in der gewohnten Weise verwendet
          werden können.  Wenn sie eine Datei mittels
          <literal>file:</literal> 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 <xref
          linkend="svn-ch-8-sect-1.1" />) und der Browser kann dieses
          Dateisystem normalerweise nicht verstehen.</para>

      </sect3>

      <sect3 id="svn-ch-8-sect-1.2.4">
        <title>Hier ist der Platz für ihre Archivzugriffs Bibliothek</title>

        <para>Wenn auf ein Subversion Projektarchiv über ein andres
          Protokoll zugegreifen werden soll &mdash; 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 &mdash; lassen wir uns etwas
          verrücktes einfallen &mdash; sie können auch ein
          Email-basiertes Protokoll umsetzen.  Subversion stellt die
          APIs zur Verfügung und sie ihre Kreativität.</para>

      </sect3>
    </sect2>

    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-1.3">
      <title>Client Ebene</title>
      
      <para>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
        &mdash; das sind Verzeichnisse voll mit Dateien und weiteren
        Unterverzeichnissen, die als eine Art lokaler, veränderbarer
        <quote>Wiederschein</quote> von einem oderer mehreren
        Projektarchiven dienen &mdash; zu verwalten und um Änderungen
        von der und an die Archivzugriffs Ebene zu übertragen.</para>

      <para>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 <filename>.svn</filename> 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
        <filename>.svn</filename> Unterverzeichnis einen ähnlichen
        Zweck hat, wie die <filename>CVS</filename> Verzeichnisse in
        CVS Arbeitskopien.  Für weitere Informationen über den
        administrativen Bereich <filename>.svn</filename> siehe <xref
        linkend="svn-ch-8-sect-3"/>in diesem Kapitel.</para>

      <para>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 <function>svn_client_checkout</function> 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
        (<filename>.svn</filename> Verzeichnisse usw).</para>

      <para>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 &mdash; 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.</para>

      <sidebar>
        <title>Direkte Bindung &mdash; Einige Worte über Genauigkeit</title>

        <para>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.</para>

        <para>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 <emphasis>nochmals</emphasis>
          auf <emphasis>seine</emphasis> 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 &hellip;) einer
          Audio- oder Videokassette machen.</para>

      </sidebar>

    </sect2>
  </sect1>

  <!-- ******************************************************************* -->
  <!-- *** SECTION 2:  USING THE APIS                                  *** -->
  <!-- ******************************************************************* -->
  <sect1 id="svn-ch-8-sect-2">
    <title>Benutzung der APIs</title>

    <para>Applikationen für die Bibliotheks APIs von Subversion zu
      entwickeln ist wirklich einfach.  Alle öffentlichen Header
      Dateien sind im Verzeichnis
      <filename>subversion/include</filename> 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.</para>

    <para>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 <literal>svn_</literal> gefolgt von einem Kürzel für
      die Bibliothek in welcher das Symbol definiert ist (wie zum
      Beispiel <literal>wc</literal>, <literal>client</literal>,
      <literal>fs</literal>, usw.), gefolgt von einem Unterstrich
      (<literal>_</literal>) 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
      (<literal>__</literal>) verwendet werden.  Funktionen, die
      privat in Bezug auf eine gegebene Quelldatei sind, haben kein
      spezielles Präfix und sind <literal>static</literal> deklariert.
      Natürlich interessiert den Compiler dieses Namensschema nicht,
      aber es hilft definitiv den Gültigkeitsbereich einer Funktion
      oder eines Datentypes klarzustellen.</para>

    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-2.1">
      <title>Die Apache Portable Runtime Library</title>

      <para>Gemeinsam mit den eigenen Datentypen von Subversion werden
        sie viele Referenzen sehen, die mit <literal>apr_</literal>
        beginnen &mdash; Symbole von der <quote>transportablen</quote>
        Laufzeit Bibliothek von Apache (APR steht für Apache Portable
        Runtime Library) APR ist eine Portierungs Bibliothek &mdash;
        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.</para>

      <para>Zusätzlich zur einheitlichen Umsetzung der Systemaufrufe, die sich von
        Betriebssystem zu Betriebssystem unterscheiden,
        <footnote>
          <para>Subversion benutzt ANSI Systemaufrufe und Datentypen
            wo immer dies möglich ist.</para>
        </footnote>
        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 &mdash; 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).
        <footnote>
          <para>Neon und Berkeley DB sind Beispiele für solche
            Bibliotheken.</para>
        </footnote>
        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
        <function>apr_initialize()</function> aufgerufen werden muss,
        um das APR Subsytem zu initialisieren und dann muss ein Pool
        für die API Aufrufe von Subversion angefordert werden.  Siehe
        <xref linkend="svn-ch-8-sect-5"/> für weitere
        Informationen.</para>

    </sect2>

    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-2.2">
      <title>Anforderungen an URLs und Pfade</title>

      <para>Mit Versionskontrolle <qoute>in der Ferne</quote> 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</quote> bedeuten
        kann <quote>quer durchs Bürogebäude</quote>, aber auch
        <quote>quer über den Globus</quote>.  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 <filename>subversion/include/svn_utf.h</filename>) zur
        Verfügung, die von jedem Programm genutzt werden können um
        diese Umwandlungen vorzunehmen.</para>

      <para>Ausserdem verlangen die APIs von Subversion, dass alle URL
        Parameter in sauberer URI Kodierung vorliegen.  So muss
        anstatt <systemitem class="url">file:///home/username/My
        File.txt</systemitem> als URL für die Datei mit den Namen
        <literal>My File.txt</literal> die URL in der Form <systemitem
        class="url">file:///home/username/My%20File.txt</systemitem>
        vewendet werden.  Wie gesagt, Subversion bietet
        Hilfsfunktionen, die ihre Applikation nutzen kann &mdash;
        <function>svn_path_uri_encode</function> und
        <function>svn_path_uri_decode</function> zur Umwandlung von
        bzw auf die URI Kodierung beispielsweise.</para> </sect2>

    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-2.3">
      <title>Andere Programmiersprachen als C und C++</title> 

      <para>Wenn sie sie Bibliotheken von Subversion mit etwas anderem
        als einem C Programm nutzen wollen &mdash; sagen wir ein
        Python Script oder eine Java Applikation &mdash; dann bietet
        Subversion eine Basisunterstützung dafür über den Simplified
        Wrapper und Interface Generator (SWIG).  SWIG Bindungen für
        Subversion befinden sich in
        <filename>subversion/bindings/swig</filename> 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.</para>

      <para>Es gibt einen offensichtliches Argument für den Zugriff
        auf die APIs von Subversion über
        programmiersprachenspezifische Bindungen &mdash; 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.</para>

      <para>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!</para>

      <example id="svn-ch-8-sect-2.3-ex-1">
        <title>Benutzung der Projektarchiv Ebene mit Python</title>

        <programlisting>
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
</programlisting>
      </example>

      <para>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 <quote>Verzeichnisse</quote> beziehungsweise
        <quote>Sequenzen</quote>) 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.</para>

      <para>Im vorigen Abschnitt dieses Kapitels erwähnten wir, die
        <filename>libsvn_client</filename> 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!</para>

      <example id="svn-ch-8-sect-2.3-ex-2">
        <title>Ein Beispielscript um eine Arbeitskopie auszuchecken.</title>

        <programlisting>
#!/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])
</programlisting>
      </example>

      <para>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 <systemitem
        class="url">http://www.swig.org/</systemitem>.</para>

    </sect2>
  </sect1>

  <!-- ******************************************************************* -->
  <!-- *** SECTION 3:  INSIDE THE WORKING COPY ADMINISTRATION AREA     *** -->
  <!-- ******************************************************************* -->
  <sect1 id="svn-ch-8-sect-3">
    <title>Der administrative Bereich in der Arbeitskopie</title>
    
    <para>Wie wir früher erwähnten, enthält jedes Verzeichnis einer
      Arbeitskopie von Subversion ein spezielles Unterverzeichnis
      namens <filename>.svn</filename>, welches die Verwaltungsdaten
      für das jeweilige Verzeichnis der Arbeitskopie enthält.
      Subversion benutzt die Information in <filename>.svn</filename>
      um Übersicht über verschiedene Dinge zu behalten, wie:</para>

    <itemizedlist>
      <listitem>
        <para>Welches Projektarchiv wird durch die Dateien und
          Unterverzeichnisse im Arbeitskopie Verzeichnis repräsentiert
          &mdash; es können auch mehrere Projektarchive sein.</para>
      </listitem>
      <listitem>
        <para>Welche Revision der Dateien und Verzeichnisse befindet
          sich derzeit in der Arbeitskopie.</para>
      </listitem>
      <listitem>
        <para>Beliebige eigene Eigenschaften können mit diesen Dateien
          und Verzeichnissen verknüpft werden.</para>
      </listitem>
      <listitem>
        <para>Unveränderte Kopien der Dateien in der
          Arbeitskopie.</para>
      </listitem>
    </itemizedlist>

    <para>Obwohl mehr Information im <filename>.svn</filename>
      Verzeichnis gespeichert wird, werden wir nur einige der
      wichtigsten Punkte untersuchen.</para>

    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-3.1">
      <title>Die Entries Datei</title>

      <para>Die wahrscheinlich wichtigste Datei im
        <filename>.svn</filename> Verzeichnis ist die
        <filename>entries</filename> 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 &mdash;
        praktisch alles, was ein Subversion Client über eine Ressource
        unter Versionskontrolle steht (oder gestellt werden soll)
        wissen muss!</para>

      <sidebar>
        <title>Verchleich zwischen den administrativen Bereichen von
          Subversion und CVS</title>

        <para>Ein Blick in ein typisches <filename>.svn</filename>
          Verzeichnis zeigt, dass hier ein bischen mehr administriert
          wird als CVS in seinem adminstrativen
          <filename>CVS</filename> Verzeichnis verwaltet.  Die
          <filename>entries</filename> 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 <filename>Entries</filename>,
          <filename>Root</filename> und
          <filename>Repository</filename> unter CVS.</para>

      </sidebar>

      <para>Im Folgenden ein Beispiel einer entries Datei:</para>

      <example id="svn-ch-8-sect-3-ex-1">
        <title>Inhalt einer typischen
          <filename>.svn/entries</filename> Datei</title>
        <programlisting>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;wc-entries
   xmlns="svn:"&gt;
&lt;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"/&gt;
&lt;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"/&gt;
&lt;entry
   name="zeta"
   kind="file"
   schedule="add"
   revision="0"/&gt;
&lt;entry
   url="http://svn.red-bean.com/tests/.greek-repo/A/B/delta"
   name="delta"
   kind="file"
   schedule="add"
   revision="0"/&gt;
&lt;entry
   name="G"
   kind="dir"/&gt;
&lt;entry
   name="H"
   kind="dir"
   schedule="delete"/&gt;
&lt;/wc-entries&gt;
</programlisting>
      </example>

      <para>Wie sie sehen können ist die Datei grundsätzlich eine
        Liste von Einträgen (entries). Jede <sgmltag>entry</sgmltag>
        Marke repräsentiert eine von drei Dingen: das Arbeitskopie
        Verzeichnis selbst (der sogenannte <quote>dieses
        Verzeichnis</quote> Eintrag &mdash; zu erkennen am leeren
        <structfield>name</structfield> Attribut), eine Datei in
        diesem Arbeitskopie Verzeichnis (das
        <structfield>kind</structfield> Attribut ist auf
        <literal>"file"</literal> gesetzt) oder ein Unterverzeichnis
        in diesem Arbeitsverzeichnis (das
        <structfield>kind</structfield> Attribut ist hier auf
        <literal>"dir"</literal> 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 <filename>zeta</filename> 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.</para>

      <para>Beim Entwickeln sollten sie auf einige spezielle Regeln
        achten, die Subversion anwendet, wenn es seine
        <filename>entries</filename> Dateien liest und schreibt.
        Obwohl jeder Eintrag mit einer Revision und einer URL
        verknüpft ist, fällt auf, dass nicht jede
        <sgmltag>entry</sgmltag> Marke in der Beispieldatei ein
        explizites <structfield>revision</structfield> oder
        <structfield>url</structfield> Attribut aufweist.  Subversion
        erlaubt das Weglassen dieser beiden Attribute, wenn ihr Wert
        der gleich ist (im Falle des
        <structfield>revision</structfield> Attributes) oder einfach
        ermittelt werden kann <footnote> <para>Indem die URL aus der
        Verkettung der URL des Elternverzeichnisses und dem Namen des
        Eintrags gebildet wird.</para> </footnote> (im Falle des
        <structfield>url</structfield> Attributes) aus den Daten, die
        für den <quote>dieses Verzeichnis</quote> 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 <quote>dieses Verzeichnis</quote>
        Eintrag in der dazugehörigen <filename>.svn/entries</filename>
        Datei zu lesen.  Trotzdem wird eine Referenz auf das
        Unterverzeichnis in der <filename>entries</filename> 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.</para>

    </sect2>

    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-3.2">
      <title>Pristine Copies and Property Files</title>

      <para>Wie zuvor erwähnt, enthält das <filename>.svn</filename>
        Verzeichnis die ursprüngliche <quote>text-base</quote> Version
        von Dateien.  Diese sind unter
        <filename>.svn/text-base</filename> zu finden.  Die Vorteile
        dieser Kopien sind vielfältig &mdash; 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 <quote>text-base</quote> Dateien als
        Option vorzusehen.  Ironischerweise wird die Existenz mit dem
        Anwachsen der Dateien unter Versionskontrolle auch wichtiger
        &mdash; 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 <quote>text-base</quote> Dateien zu verzichten vor allem
        dort, wo auch das Projektarchiv selbst lokal auf der eigenen
        Platte liegt)</para>

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

    </sect2>
  </sect1>

  <!-- ******************************************************************* -->
  <!-- *** SECTION 4:  WEBDAV                                          *** -->
  <!-- ******************************************************************* -->
  <sect1 id="svn-ch-8-sect-4">
    <title>WebDAV</title>

    <para>WebDAV (die Abkürzung für <quote>Web-based Distributed
      Authoring and Versioning</quote>, 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 &mdash; 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 <systemitem
      class="url">http://www.webdav.org/</systemitem>
      verfügbar.</para>

    <para>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 &mdash; genauso wie Nautilus und der
      Konqueror Browser (unter GNOME beziehungsweise KDE).</para>

    <para>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.</para>

    <para>Für eine grundsätzlichere Diskussion über WebDAV, wie es
      arbeitet und wie es von Subversion genutzt wird siehe <xref
      linkend="svn-ap-c"/>.  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.</para>

  </sect1>

  <!-- ******************************************************************* -->
  <!-- *** SECTION 5:  PROGRAMMING WITH MEMORY POOLS                   *** -->
  <!-- ******************************************************************* -->
  <sect1 id="svn-ch-8-sect-5">
    <title>Programmieren mit den Speicherpools</title>

    <para>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 &mdash; 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
      <structname>apr_pool_t</structname> Typ, einen Pool, von dem die
      Applikation Speicher anfordern kann.</para>

    <para>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
      <function>malloc()</function> und Konsorten können Programme die
      gegen APR gelinkt sind einfach anfordern, dass ein Speicherpool
      erstellt wird (indem sie die
      <function>apr_pool_create()</function> Funktion benutzen).
      Jedes Mal, wenn das Programm Speicher aus dem Pool braucht,
      verwendet es eine der Funktionen der APR Pool API, wie
      <function>apr_palloc()</function>, 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.</para>

    <para>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
      <function>apr_pool_clear()</function> beziehungsweise
      <function>apr_pool_destroy()</function> verwendet werden.  Damit
      ist es möglich mehrmals &mdash; oder mehrere tausend Male
      &mdash; 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.</para>

    <para>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 <quote>user
      data</quote> 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 <function>svn_pool_create()</function>,
      <function>svn_pool_clear()</function> und
      <function>svn_pool_destroy()</function> und verwendet
      hauptsächlich diese.</para>

    <para>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 &mdash; rekursives
      Durchschreiten eines Verzeichnisbaumes, wobei für jedes Element
      im Baum einige Aufgaben zu erledigen sind.</para>

    <example id="svn-ch-8-sect-5-ex-1">
      <title>Effizienter Einsatz von Pools</title>
      <programlisting>
/* 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-&gt;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 (&amp;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 (&amp;finfo, flags, dir);
       apr_err == APR_SUCCESS;
       apr_err = apr_dir_read (&amp;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] == '.'
              &amp;&amp; (finfo.name[1] == '\0'
                  || (finfo.name[1] == '.' &amp;&amp; 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;
}
</programlisting>
    </example>

    <para>Das vorangegangene Beispiel demonstriert den effizienten
      Einsatz von Pools in <emphasis>beiden</emphasis>
      Einsatzbereichen &mdash; 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 <function>alloc()</function> und
      <function>free()</function> aufrufen müsste!</para>
    
    <para>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.</para>

  </sect1>

  <!-- ******************************************************************* -->
  <!-- *** SECTION 6:  CONTRIBUTING TO SUBVERSION                      *** -->
  <!-- ******************************************************************* -->
  <sect1 id="svn-ch-8-sect-6">
    <title>Subversion unterstützen</title>
    
    <para>Die offizielle Informationsquelle über Subversion ist
      natürlich die Projekt Website unter <systemitem
      class="url">http://subversion.tigris.org/</systemitem>.  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.</para>

    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-6.1">
      <title>Verbindung mit der Gemeinschaft aufnehmen</title>
      
      <para>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
        (<email>dev@subversion.tigris.org</email>) und die (*TODO*
        commit) Mail Liste (<email>svn@subversion.tigris.org</email>)
        eintragen.  Wenn sie diese Listen &mdash; wenn auch nur
        lückenhaft &mdash; 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.</para>

      <para>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
        <quote>bite-sized</quote> markiert sind.</para>
      
    </sect2>
    
    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-6.2">
      <title>Get the Source Code</title>
      
      <para>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 <filename>INSTALL</filename> Datei im
        Basisverzeichnis des installierten Verzeichnisbaumes.</para>

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

      <screen>
$ svn checkout http://svn.collab.net/repos/svn/trunk subversion
A  HACKING
A  INSTALL
A  README
A  autogen.sh
A  build.conf
&hellip;
</screen>

      <para>Das obigige Kommando wird die allerneueste Version des
        Quellcodes von Subversion in das Unterverzeichnis
        <filename>subversion</filename> 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 &mdash; 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 &mdash; Details dazu
        finden sie in der <filename>INSTALL</filename> Datei im
        Basisverzeichnis des installierten Verzeichnisbaumes.</para>

    </sect2>

    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-6.3">
      <title>Become Familiar with Community Policies</title>
      
      <para>Nun da sie eine Arbeitskopie mit dem letzten Quellcode von
        Subversion haben, wollen sie höchstwahrscheinlich einen Blick
        in die <filename>HACKING</filename> Datei im Basisverzeichnis
        der Arbeitskopie werfen.  Die <filename>HACKING</filename>
        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 &mdash; Herrschaft
        durch Leistung.
        <footnote>
          <para>Obwohl dieses <quote>sie müssen sich ihre
	    Übertragungsrechte verdienen</quote> oberflächlich als
	    eine Art Elitemechanismus erscheint, geht es eigentlich um
	    Effizienz &mdash; 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.</para>
        </footnote>
        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.</para>

    </sect2>

    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-6.4">
      <title>Make and Test Your Changes</title>
      
      <para>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.</para>

      <para>Subversion hat eine wirkich gründliche 
        <footnote>
          <para>Sie sollten sich vielleicht eine Packung Popcorn
            vergönnen.  <quote>Gründlich</quote> bedeutet in diesem
            Zusammenhang so etwas wie eine halbe Stunde
            nicht-interaktive Maschinenvolllast.</para>
        </footnote>
        Regressions Testumgebung und es wird erwartet, dass ihre
	vorgeschlagenen Änderungen alle vorgesehenen Tests bestehen.
	Durch den Aufruf von <command>make check</command> (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.</para>

      <!-- ### TODO: Describe building and testing on Windows. -->

      <para>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 <literal>XFAIL</literal> bezeichnet)
        und solange Subversion in der Art scheitert, wie dies erwartet
        wird, solange wird das Testresultat von
        <literal>XFAIL</literal> als erfolgreicher Test gewertet.
        Schlussendlich gilt, je besser die Testumgebung desto weniger
        Zeit wird verschwendet um möglicherweise obskure
        Regressionsfehler zu suchen.</para>

    </sect2>

    <!-- ***************************************************************** -->
    <sect2 id="svn-ch-8-sect-6.5">
      <title>Die Änderungen zur Verfügung stellen</title>
      
      <para>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 <command>svn diff</command>
        (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 &mdash; wenn sie
        Verständnis von Subversion beweisen, Programmierkompetenz und
        <quote>Teamgeist</quote> besitzen, dann wird ihnen
        wahrscheinlich dieses Recht erteilt werden.</para>

    </sect2>
  </sect1>
</chapter>

<!--
local variables: 
sgml-parent-document: ("book.xml" "chapter")
end:
-->
