[svnbook commit] r2677 - trunk/src/en/book

cmpilato noreply at red-bean.com
Fri Feb 9 05:36:27 CST 2007


Author: cmpilato
Date: Fri Feb  9 05:36:27 2007
New Revision: 2677

Modified:
   trunk/src/en/book/ch-developer-info.xml
   trunk/src/en/book/ch-fundamental-concepts.xml

Log:
* src/en/book/ch-developer-info.xml
  Overhaul this chapter.  (Note quite complete... need to decide what to do
  with the WebDAV section.)

* src/en/book/ch-fundamental-concepts.xml
  Move a URL-related warning into the URL section.


Modified: trunk/src/en/book/ch-developer-info.xml
==============================================================================
--- trunk/src/en/book/ch-developer-info.xml	(original)
+++ trunk/src/en/book/ch-developer-info.xml	Fri Feb  9 05:36:27 2007
@@ -1,24 +1,24 @@
 <chapter id="svn.developer">
-  <title>Developer Information</title>
+  <title>Embedding Subversion</title>
   
-  <para>Subversion has a modular design, implemented as a collection
-    of C libraries.  Each library has a well-defined purpose and
-    interface, and those interfaces are available not only for
-    Subversion itself to use, but for any software that wishes to
-    embed or otherwise programmatically control Subversion.  Most of
-    those interfaces are available not only in C, but also in
-    higher-level languages such as Python or Java.</para>
-
-  <para>This chapter is for those who wish to interact with
-    Subversion through its public Application Programming Interface
-    (API) or various language bindings.  If you wish to write robust
-    wrapper scripts around Subversion functionality to simplify your
-    own life, are trying to develop more complex integrations
-    between Subversion and other pieces of software, or just have an
-    interest in Subversion's various library modules and what they
-    offer, this chapter is for you.  If, however, you don't foresee
-    yourself participating with Subversion at such a level, feel
-    free to skip this chapter with the confidence that your
+  <para>Subversion has a modular design, written in C and implemented
+    as a collection of libraries.  Each library has a well-defined
+    purpose and Application Programming Interface (API), and that
+    interface is available not only for Subversion itself to use, but
+    for any software that wishes to embed or otherwise
+    programmatically control Subversion.  And the interface is
+    available not only to other C programs, but also to programs
+    written in higher-level languages such as Python or Java.</para>
+
+  <para>This chapter is for those who wish to interact with Subversion
+    through its public API or various language bindings.  If you wish
+    to write robust wrapper scripts around Subversion functionality to
+    simplify your own life, are trying to develop more complex
+    integrations between Subversion and other pieces of software, or
+    just have an interest in Subversion's various library modules and
+    what they offer, this chapter is for you.  If, however, you don't
+    foresee yourself participating with Subversion at such a level,
+    feel free to skip this chapter with the confidence that your
     experience as a Subversion user will not be affected.</para>
 
 
@@ -85,6 +85,11 @@
             <entry>The local Repository Access module</entry>
           </row>
           <row>
+            <entry>libsvn_ra_serf</entry>
+            <entry>Another (experimental) WebDAV Repository Access 
+              module</entry>
+          </row>
+          <row>
             <entry>libsvn_ra_svn</entry>
             <entry>The custom protocol Repository Access module</entry>
           </row>
@@ -103,12 +108,12 @@
           <row>
             <entry>mod_authz_svn</entry>
             <entry>Apache authorization module for Subversion
-            repositories access via WebDAV</entry>
+              repositories access via WebDAV</entry>
           </row>
           <row>
             <entry>mod_dav_svn</entry>
             <entry>Apache module for mapping WebDAV operations to
-            Subversion ones</entry>
+              Subversion ones</entry>
           </row>
         </tbody>
       </tgroup>
@@ -128,55 +133,61 @@
       given module with a whole new library that implements the same
       API without affecting the rest of the code base.  In some sense,
       this happens within Subversion already.  The libsvn_ra_dav,
-      libsvn_ra_local, and libsvn_ra_svn all implement the same
-      interface.  And all three communicate with the Repository
-      Layer—libsvn_ra_dav and libsvn_ra_svn do so across a
-      network, and libsvn_ra_local connects to it directly.  The
-      libsvn_fs_base and libsvn_fs_fs libraries are another example of
-      this.</para>
-
-    <para>The client itself also highlights modularity in the
-      Subversion design.  While Subversion itself comes with only a
-      command-line client program, there are several third party
-      programs which provide various forms of client GUI.  These GUIs
-      use the same APIs that the stock command-line client does.
-      Subversion's libsvn_client library is the one-stop shop for most
+      libsvn_ra_local, libsvn_ra_serf, and libsvn_ra_svn libraries
+      each implement the same interface, all working as plugins to
+      libsvn_ra.  And all four communicate with the Repository
+      Layer—libsvn_ra_local connects to the repository directly;
+      the other three do so over a network.  The libsvn_fs_base and
+      libsvn_fs_fs libraries are another pair of libraries that
+      implement the same functionality in different ways—they
+      are plugins to the common libsvn_fs library.</para>
+
+    <para>The client itself also highlights the benefits of modularity
+      in the Subversion design.  While Subversion itself comes with
+      only a command-line client program, there are several third
+      party programs which provide various forms of client GUI.  These
+      GUIs use the same APIs that the stock command-line client does.
+      Subversion's libsvn_client library is a one-stop shop for most
       of the functionality necessary for designing a working
       Subversion client (see <xref
-      linkend="svn.developer.layerlib.client"/>).</para>
+      linkend="svn.developer.layerlib.client"/>), and this played a
+      large role in the proliferation of available Subversion clients
+      and IDE integrations.</para>
 
     <!-- =============================================================== -->
     <sect2 id="svn.developer.layerlib.repos">
       <title>Repository Layer</title>
 
       <para>When referring to Subversion's Repository Layer, we're
-        generally talking about two libraries—the repository
-        library, and the filesystem library.  These libraries provide
-        the storage and reporting mechanisms for the various revisions
-        of your version-controlled data.  This layer is connected to
-        the Client Layer via the Repository Access Layer, and is, from
-        the perspective of the Subversion user, the stuff at the
+        generally talking about two basic concepts—the versioned
+        filesystem implementation (accessed via libsvn_fs, and
+        supported by its libsvn_fs_base and libsvn_fs_fs plugins), and
+        the repository logic that wraps it (as implemented in
+        libsvn_repos).  These libraries provide the storage and
+        reporting mechanisms for the various revisions of your
+        version-controlled data.  This layer is connected to the
+        Client Layer via the Repository Access Layer, and is, from the
+        perspective of the Subversion user, the stuff at the
         <quote>other end of the line.</quote></para>
 
-      <para>The Subversion Filesystem is accessed via the libsvn_fs
-        API, and is not a kernel-level filesystem that one would
-        install in an operating system (like the Linux ext2 or NTFS),
-        but a virtual filesystem.  Rather than storing
+      <para>The Subversion Filesystem is not a kernel-level filesystem
+        that one would install in an operating system (like the Linux
+        ext2 or NTFS), but a virtual filesystem.  Rather than storing
         <quote>files</quote> and <quote>directories</quote> as real
         files and directories (as in, the kind you can navigate
         through using your favorite shell program), it uses one of two
         available abstract storage backends—either a Berkeley DB
         database environment, or a flat-file representation.  (To
         learn more about the two repository back-ends, see <xref
-        linkend="svn.reposadmin.basics.backends"/>.)  However, there has been
-        considerable interest by the development community in giving
-        future releases of Subversion the ability to use other
+        linkend="svn.reposadmin.basics.backends"/>.)  However, there
+        has been considerable interest by the development community in
+        giving future releases of Subversion the ability to use other
         back-end database systems, perhaps through a mechanism such as
         Open Database Connectivity (ODBC).</para>
 
       <para>The filesystem API exported by libsvn_fs contains the
         kinds of functionality you would expect from any other
-        filesystem API: you can create and remove files and
+        filesystem API—you can create and remove files and
         directories, copy and move them around, modify file contents,
         and so on.  It also has features that are not quite as common,
         such as the ability to add, modify, and remove metadata
@@ -190,13 +201,13 @@
         started adding things to the filesystem.</para>
 
       <para>All the modifications you make to your tree are done
-        within the context of a Subversion transaction.  The following
-        is a simplified general routine for modifying your
+        within the context of a Subversion commit transaction.  The
+        following is a simplified general routine for modifying your
         filesystem:</para>
 
       <orderedlist>
         <listitem>
-          <para>Begin a Subversion transaction.</para>
+          <para>Begin a Subversion commit transaction.</para>
         </listitem>
         <listitem>
           <para>Make your changes (adds, deletes, property
@@ -216,15 +227,15 @@
       <sidebar>
         <title>The Transaction Distraction</title>
 
-        <para>The notion of a Subversion transaction, especially given
-          its close proximity to the database code in libsvn_fs, can
-          become easily confused with the transaction support provided
-          by the underlying database itself.  Both types of
-          transaction exist to provide atomicity and isolation.  In
-          other words, transactions give you the ability to perform a
-          set of actions in an <quote>all or nothing</quote>
-          fashion—either all the actions in the set complete
-          with success, or they all get treated as if
+        <para>The notion of a Subversion transaction can become easily
+          confused with the transaction support provided by the
+          underlying database itself, especially given the former's
+          close proximity to the Berkeley DB database code in
+          libsvn_fs_base.  Both types of transaction exist to provide
+          atomicity and isolation.  In other words, transactions give
+          you the ability to perform a set of actions in an
+          all-or-nothing fashion—either all the actions in the
+          set complete with success, or they all get treated as if
           <emphasis>none</emphasis> of them ever happened—and in
           a way that does not interfere with other processes acting on
           the data.</para>
@@ -236,11 +247,11 @@
           encompassing higher-level operations like making
           modifications to a set of files and directories which are
           intended to be stored as the next revision of the filesystem
-          tree.  If that isn't confusing enough, consider this:
-          Subversion uses a database transaction during the creation
-          of a Subversion transaction (so that if the creation of
-          Subversion transaction fails, the database will look as if
-          we had never attempted that creation in the first
+          tree.  If that isn't confusing enough, consider the fact
+          that Subversion uses a database transaction during the
+          creation of a Subversion transaction (so that if the
+          creation of Subversion transaction fails, the database will
+          look as if we had never attempted that creation in the first
           place)!</para>
 
         <para>Fortunately for users of the filesystem API, the
@@ -254,31 +265,33 @@
       </sidebar>
 
       <para>Most of the functionality provided by the filesystem
-        interface comes as an action that occurs on a filesystem path.
-        That is, from outside of the filesystem, the primary mechanism
-        for describing and accessing the individual revisions of files
-        and directories comes through the use of path strings like
-        <filename>/foo/bar</filename>, just as if you were addressing
-        files and directories through your favorite shell program.
-        You add new files and directories by passing their paths-to-be
-        to the right API functions.  You query for information about
-        them by the same mechanism.</para>
+        interface is the result of an action that occurs on a
+        filesystem path.  That is, from outside of the filesystem, the
+        primary mechanism for describing and accessing the individual
+        revisions of files and directories comes through the use of
+        path strings like <filename>/foo/bar</filename>, just as if
+        you were addressing files and directories through your
+        favorite shell program.  You add new files and directories by
+        passing their paths-to-be to the right API functions.  You
+        query for information about them by the same mechanism.</para>
 
       <para>Unlike most filesystems, though, a path alone is not
         enough information to identify a file or directory in
         Subversion.  Think of a directory tree as a two-dimensional
         system, where a node's siblings represent a sort of
         left-and-right motion, and descending into subdirectories a
-        downward motion.  <xref linkend="svn.developer.layerlib.repos.dia-1"/> shows
-        a typical representation of a tree as exactly that.</para>
+        downward motion.  <xref
+        linkend="svn.developer.layerlib.repos.dia-1"/> shows a typical
+        representation of a tree as exactly that.</para>
 
       <figure id="svn.developer.layerlib.repos.dia-1">
         <title>Files and directories in two dimensions</title>
         <graphic fileref="images/ch08dia1.png"/>
       </figure>
 
-      <para>Of course, the Subversion filesystem has a nifty third
-        dimension that most filesystems do not have—Time!
+      <para>The different here is that the Subversion filesystem has a
+        nifty third dimension that most filesystems do not
+        have—Time!
         <footnote>
           <para>We understand that this may come as a shock to sci-fi
             fans who have long been under the impression that Time was
@@ -290,24 +303,20 @@
         <parameter>path</parameter> argument also expects a
         <parameter>root</parameter> argument.  This
         <structname>svn_fs_root_t</structname> argument describes
-        either a revision or a Subversion transaction (which is
-        usually just a revision-to-be), and provides that
-        third-dimensional context needed to understand the difference
-        between <filename>/foo/bar</filename> in revision 32, and the
-        same path as it exists in revision 98.  <xref
-        linkend="svn.developer.layerlib.repos.dia-2"/> shows revision history as an
-        added dimension to the Subversion filesystem universe.</para>
+        either a revision or a Subversion transaction (which is simply
+        a revision-in-the-making), and provides that third-dimensional
+        context needed to understand the difference between
+        <filename>/foo/bar</filename> in revision 32, and the same
+        path as it exists in revision 98.  <xref
+        linkend="svn.developer.layerlib.repos.dia-2"/> shows revision
+        history as an added dimension to the Subversion filesystem
+        universe.</para>
 
       <figure id="svn.developer.layerlib.repos.dia-2">
         <title>Versioning time—the third dimension!</title>
         <graphic fileref="images/ch08dia2.png"/>
       </figure>
 
-      <!-- Perhaps dig into the DAG/tree layers a bit here, talking
-           about the hard-link design and how that affords such
-           pleasures as cheap copies.  If "bubble-up" isn't covered
-           twelve other times in the book, maybe give it a go here. -->
-
       <para>As we mentioned earlier, the libsvn_fs API looks and feels
         like any other filesystem, except that it has this wonderful
         versioning capability.  It was designed to be usable by any
@@ -318,146 +327,25 @@
         Subversion wants more—and that is where libsvn_repos
         comes in.</para>
 
-      <para>The Subversion repository library (libsvn_repos) is
-        basically a wrapper library around the filesystem
-        functionality.  This library is responsible for creating the
-        repository layout, making sure that the underlying filesystem
-        is initialized, and so on.  Libsvn_repos also implements a set
-        of hooks—scripts that are executed by the repository
-        code when certain actions take place.  These scripts are
-        useful for notification, authorization, or whatever purposes
-        the repository administrator desires.  This type of
-        functionality, and other utilities provided by the repository
-        library, are not strictly related to implementing a versioning
-        filesystem, which is why it was placed into its own
-        library.</para>
-      
-      <para>Developers who wish to use the libsvn_repos API will find
-        that it is not a complete wrapper around the filesystem
-        interface.  That is, only certain major events in the general
-        cycle of filesystem activity are wrapped by the repository
-        interface.  Some of these include the creation and commit of
-        Subversion transactions, and the modification of revision
-        properties.  These particular events are wrapped by the
-        repository layer because they have hooks associated with them.
-        In the future, other events may be wrapped by the repository
-        API.  All of the remaining filesystem interaction will
-        continue to occur directly via the libsvn_fs API, though.</para>
-
-      <para>For example, here is a code segment that illustrates the
-        use of both the repository and filesystem interfaces to create
-        a new revision of the filesystem in which a directory is
-        added.  Note that in this example, the
-        <function>SVN_ERR()</function> macro simply checks for a
-        non-successful error return from the function it wraps, and
-        returns that error if it exists.</para>
-
-      <example id="svn.developer.layerlib.repos.ex-1">
-        <title>Using the Repository Layer</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 (&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 "
-              "'%ld'.\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>In the previous code segment, calls were made to both the
-        repository and filesystem interfaces.  We could just as easily
-        have committed the transaction using
-        <function>svn_fs_commit_txn()</function>.  But the filesystem
-        API knows nothing about the repository library's hook
-        mechanism.  If you want your Subversion repository to
-        automatically perform some set of non-Subversion tasks every
-        time you commit a transaction (like, for example, sending an
-        email that describes all the changes made in that transaction
-        to your developer mailing list), you need to use the
-        libsvn_repos-wrapped version of that
-        function—<function>svn_repos_fs_commit_txn()</function>.
-        This function will actually first run the
-        <literal>pre-commit</literal> hook script if one exists, then
-        commit the transaction, and finally will run a
-        <literal>post-commit</literal> hook script.  The hooks provide
-        a special kind of reporting mechanism that does not really
-        belong in the core filesystem library itself.  (For more
-        information regarding Subversion's repository hooks, see <xref
-        linkend="svn.reposadmin.create.hooks" />.)</para>
+      <para>The Subversion repository library (libsvn_repos) sits
+        (logically speaking) atop the libsvn_fs API, providing
+        additional functionality beyond that of the underlying
+        versioned filesystem logic.  It does not completely wrap each
+        and every filesystem function—only certain major steps
+        in the general cycle of filesystem activity are wrapped by the
+        repository interface.  Some of these include the creation and
+        commit of Subversion transactions, and the modification of
+        revision properties.  These particular events are wrapped by
+        the repository layer because they have hooks associated with
+        them.  A repository hook system is not strictly related to
+        implementing a versioning filesystem, so it lives in the
+        repository wrapper library.</para>
       
-      <para>The hook mechanism requirement is but one of the reasons
-        for the abstraction of a separate repository library from the
-        rest of the filesystem code.  The libsvn_repos API provides
-        several other important utilities to Subversion.  These
-        include the abilities to:</para>
+      <para>The hooks mechanism is but one of the reasons for the
+        abstraction of a separate repository library from the rest of
+        the filesystem code.  The libsvn_repos API provides several
+        other important utilities to Subversion.  These include the
+        abilities to:</para>
 
       <orderedlist>
         <listitem>
@@ -470,9 +358,9 @@
             trees.</para>
         </listitem>
         <listitem>
-          <para>query for the commit log messages
-            associated with all (or some) of the revisions in which a
-            set of files was modified in the filesystem.</para>
+          <para>query for the commit log messages associated with all
+            (or some) of the revisions in which a set of files was
+            modified in the filesystem.</para>
         </listitem>
         <listitem>
           <para>generate a human-readable <quote>dump</quote> of the
@@ -496,15 +384,16 @@
       <title>Repository Access Layer</title>
 
       <para>If the Subversion Repository Layer is at <quote>the other
-        end of the line</quote>, the Repository Access Layer is the
-        line itself.  Charged with marshalling data between the client
-        libraries and the repository, this layer includes the
+        end of the line</quote>, the Repository Access (RA) Layer is
+        the line itself.  Charged with marshalling data between the
+        client libraries and the repository, this layer includes the
         libsvn_ra module loader library, the RA modules themselves
-        (which currently includes libsvn_ra_dav, libsvn_ra_local, and
-        libsvn_ra_svn), and any additional libraries needed by one or
-        more of those RA modules, such as the mod_dav_svn Apache
-        module with which libsvn_ra_dav communicates or
-        libsvn_ra_svn's server, <command>svnserve</command>.</para>
+        (which currently includes libsvn_ra_dav, libsvn_ra_local,
+        libsvn_ra_serf, and libsvn_ra_svn), and any additional
+        libraries needed by one or more of those RA modules, such as
+        the mod_dav_svn Apache module with which libsvn_ra_dav
+        communicates or libsvn_ra_svn's server,
+        <command>svnserve</command>.</para>
 
       <para>Since Subversion uses URLs to identify its repository
         resources, the protocol portion of the URL schema (usually
@@ -538,184 +427,28 @@
   - handles 'file' scheme
 
 </screen>
-    
-      <sect3 id="svn.developer.layerlib.ra.dav">
-        <title>RA-DAV (Repository Access Using HTTP/DAV)</title>
 
-        <para>The libsvn_ra_dav library is designed for use by clients
-          that are being run on different machines than the servers
-          with which they communicating, specifically servers reached
-          using URLs that contain the <literal>http:</literal> or
-          <literal>https:</literal> protocol portions.  To understand
-          how this module works, we should first mention a couple of
-          other key components in this particular configuration of the
-          Repository Access Layer—the powerful Apache HTTP
-          Server, and the Neon HTTP/WebDAV client library.</para>
-  
-        <para>Subversion's primary network server is the Apache HTTP
-          Server.  Apache is a time-tested, extensible open-source
-          server process that is ready for serious use.  It can
-          sustain a high network load and runs on many platforms.  The
-          Apache server supports a number of different standard
-          authentication protocols, and can be extended through the
-          use of modules to support many others.  It also supports
-          optimizations like network pipelining and caching.  By using
-          Apache as a server, Subversion gets all of these features
-          for free.  And since most firewalls already allow HTTP
-          traffic to pass through, system administrators typically
-          don't even have to change their firewall configurations to
-          allow Subversion to work.</para>
-  
-        <para>Subversion uses HTTP and WebDAV (with DeltaV) to
-          communicate with an Apache server.  You can read more about
-          this in the WebDAV section of this chapter, but in short,
-          WebDAV and DeltaV are extensions to the standard HTTP 1.1
-          protocol that enable sharing and versioning of files over
-          the web.  Apache 2.0 and later versions come with mod_dav,
-          an Apache module that understands the DAV extensions to
-          HTTP.  Subversion itself supplies mod_dav_svn, though, which
-          is another Apache module that works in conjunction with
-          (really, as a back-end to) mod_dav to provide Subversion's
-          specific implementations of WebDAV and DeltaV.</para>
-
-        <para>When communicating with a repository over HTTP, the RA
-          loader library chooses libsvn_ra_dav as the proper access
-          module.  The Subversion client makes calls into the generic
-          RA interface, and libsvn_ra_dav maps those calls (which
-          embody rather large-scale Subversion actions) to a set of
-          HTTP/WebDAV requests.  Using the Neon library, libsvn_ra_dav
-          transmits those requests to the Apache server.  Apache
-          receives these requests (exactly as it does generic HTTP
-          requests that your web browser might make), notices that the
-          requests are directed at a URL that is configured as a DAV
-          location (using the <literal><Location></literal>
-          directive in <filename>httpd.conf</filename>), and hands the
-          request off to its own mod_dav module.  When properly
-          configured, mod_dav knows to use Subversion's mod_dav_svn for
-          any filesystem-related needs, as opposed to the generic
-          mod_dav_fs that comes with Apache.  So ultimately, the client
-          is communicating with mod_dav_svn, which binds directly to the
-          Subversion Repository Layer.</para>
-  
-        <para>That was a simplified description of the actual
-          exchanges taking place, though.  For example, the Subversion
-          repository might be protected by Apache's authorization
-          directives.  This could result in initial attempts to
-          communicate with the repository being rejected by Apache on
-          authorization grounds.  At this point, libsvn_ra_dav gets
-          back the notice from Apache that insufficient identification
-          was supplied, and calls back into the Client Layer to get
-          some updated authentication data.  If the data is supplied
-          correctly, and the user has the permissions that Apache
-          seeks, libsvn_ra_dav's next automatic attempt at performing
-          the original operation will be granted, and all will be
-          well.  If sufficient authentication information cannot be
-          supplied, the request will ultimately fail, and the client
-          will report the failure to the user.</para>
-  
-        <!-- A diagram here? -->
-  
-        <para>By using Neon and Apache, Subversion gets free
-          functionality in several other complex areas, too.  For
-          example, if Neon finds the OpenSSL libraries, it allows the
-          Subversion client to attempt to use SSL-encrypted
-          communications with the Apache server (whose own mod_ssl can
-          <quote>speak the language</quote>).  Also, both Neon itself
-          and Apache's mod_deflate can understand the
-          <quote>deflate</quote> algorithm (the same one used by the
-          PKZIP and gzip programs), so requests can be sent in smaller,
-          compressed chunks across the wire.  Other complex features
-          that Subversion hopes to support in the future include the
-          ability to automatically handle server-specified redirects
-          (for example, when a repository has been moved to a new
-          canonical URL) and taking advantage of HTTP
-          pipelining.</para>
-  
-        <!-- Talk about another difference between CVS and Subversion.
-             CVS users had to specify which auth mechanism to use
-             (with :ext: vs. :pserver:) and whether or not to use
-             compressed communications (with the -z option).  In
-             Subversion, Apache takes some of that responsibility.
-             The server will tell the client whether it can understand
-             compression, and ... hmm.  Is this really true? -->
-
-      </sect3>
-
-      <sect3 id="svn.developer.layerlib.ra.svn">
-        <title>RA-SVN (Custom Protocol Repository Access)</title>
-
-        <para>In addition to the standard HTTP/WebDAV protocol,
-          Subversion also provides an RA implementation that uses a
-          custom protocol.  The libsvn_ra_svn module implements
-          its own network socket connectivity, and communicates with a
-          stand-alone server—the <filename>svnserve</filename>
-          program—on the machine that hosts the
-          repository.  Clients access the repository using the
-          <literal>svn://</literal> schema.</para>
-
-        <para>This RA implementation lacks most of the advantages of
-          Apache mentioned in the previous section; however, it may be
-          appealing to some system administrators nonetheless.  It is
-          dramatically easier to configure and run; setting up an
-          <filename>svnserve</filename> process is nearly
-          instantaneous.  It is also much smaller (in terms of lines
-          of code) than Apache, making it much easier to audit, for
-          security reasons or otherwise.  Furthermore, some system
-          administrators may already have an SSH security
-          infrastructure in place, and want Subversion to use it.
-          Clients using ra_svn can easily tunnel the protocol over
-          SSH.</para>
-
-      </sect3>
-
-      <sect3 id="svn.developer.layerlib.ra.local">
-        <title>RA-Local (Direct Repository Access)</title>
-
-        <para>Not all communications with a Subversion repository
-          require a powerhouse server process and a network layer.
-          For users who simply wish to access the repositories on
-          their local disk, they may do so using
-          <literal>file:</literal> URLs and the functionality provided
-          by libsvn_ra_local.  This RA module binds directly with the
-          repository and filesystem libraries, so no network
-          communication is required at all.</para>
-
-        <para>Subversion requires that the server name included as part
-          of the <literal>file:</literal> URL be either
-          <literal>localhost</literal> or empty, and that there be no
-          port specification.  In other words, your URLs should look
-          like either
-          <literal>file://localhost/path/to/repos</literal> or
-          <literal>file:///path/to/repos</literal>.</para>
-
-        <para>Also, be aware that Subversion's
-          <literal>file:</literal> URLs cannot be used in a regular
-          web browser the way typical <literal>file:</literal> URLs
-          can.  When you attempt to view a <literal>file:</literal>
-          URL in a regular web browser, it reads and displays the
-          contents of the file at that location by examining the
-          filesystem directly.  However, Subversion's resources exist
-          in a virtual filesystem (see <xref
-          linkend="svn.developer.layerlib.repos" />), and your browser will not
-          understand how to read that filesystem.</para>
-
-      </sect3>
-
-      <sect3 id="svn.developer.layerlib.ra.yours">
-        <title>Your RA Library Here</title>
-
-        <para>For those who wish to access a Subversion repository
-          using still another protocol, that is precisely why the
-          Repository Access Layer is modularized!  Developers can
-          simply write a new library that implements the RA interface
-          on one side and communicates with the repository on the
-          other.  Your new library can use existing network protocols,
-          or you can invent your own.  You could use inter-process
-          communication (IPC) calls, or—let's get crazy, shall
-          we?—you could even implement an email-based protocol.
-          Subversion supplies the APIs; you supply the creativity.</para>
+      <para>The public API exported by the RA Layer contains
+        functionality necessary for sending and recieving versioned
+        data to and from the repository.  And each of the available RA
+        plugins is able to perform that task using a specific
+        protocol—libsvn_ra_dav speaks HTTP/WebDAV (optionally
+        using SSL encryption) with an Apache HTTP Server that is
+        running the mod_dav_svn Subversion server module;
+        libsvn_ra_svn speaks a proprietary network protocol with the
+        <command>svnserve</command> program; and so on.</para>
+
+      <para>And for those who wish to access a Subversion repository
+        using still another protocol, that is precisely why the
+        Repository Access Layer is modularized!  Developers can simply
+        write a new library that implements the RA interface on one
+        side and communicates with the repository on the other.  Your
+        new library can use existing network protocols, or you can
+        invent your own.  You could use inter-process communication
+        (IPC) calls, or—let's get crazy, shall we?—you
+        could even implement an email-based protocol.  Subversion
+        supplies the APIs; you supply the creativity.</para>
 
-      </sect3>
     </sect2>
 
     <!-- =============================================================== -->
@@ -813,25 +546,29 @@
       locations when you build and install Subversion itself from
       source.  These headers represent the entirety of the functions
       and types meant to be accessible by users of the Subversion
-      libraries.</para>
-
-    <para>The first thing you might notice is that Subversion's
-      datatypes and functions are namespace protected.  Every public
-      Subversion symbol name begins with <literal>svn_</literal>,
-      followed by a short code for the library in which the symbol is
-      defined (such as <literal>wc</literal>,
-      <literal>client</literal>, <literal>fs</literal>, etc.),
-      followed by a single underscore (<literal>_</literal>) and
-      then the rest of the symbol name.  Semi-public functions (used
-      among source files of a given library but not by code outside
-      that library, and found inside the library directories
-      themselves) differ from this naming scheme in that instead of a
-      single underscore after the library code, they use a double
-      underscore (<literal>__</literal>).  Functions that are private
-      to a given source file have no special prefixing, and are declared
-      <literal>static</literal>.  Of course, a compiler isn't
-      interested in these naming conventions, but they help to clarify
-      the scope of a given function or datatype.</para>
+      libraries.  The Subversion developer community is meticulous
+      about ensuring that the public API is
+      well-documented—refer directly to the header files for
+      that documentation.</para>
+
+    <para>When examining the public header files, the first thing you
+      might notice is that Subversion's datatypes and functions are
+      namespace protected.  Every public Subversion symbol name begins
+      with <literal>svn_</literal>, followed by a short code for the
+      library in which the symbol is defined (such as
+      <literal>wc</literal>, <literal>client</literal>,
+      <literal>fs</literal>, etc.), followed by a single underscore
+      (<literal>_</literal>) and then the rest of the symbol name.
+      Semi-public functions (used among source files of a given
+      library but not by code outside that library, and found inside
+      the library directories themselves) differ from this naming
+      scheme in that instead of a single underscore after the library
+      code, they use a double underscore (<literal>__</literal>).
+      Functions that are private to a given source file have no
+      special prefixing, and are declared <literal>static</literal>.
+      Of course, a compiler isn't interested in these naming
+      conventions, but they help to clarify the scope of a given
+      function or datatype.</para>
 
     <!-- =============================================================== -->
     <sect2 id="svn.developer.usingapi.apr">
@@ -946,10 +683,167 @@
         library suite, combined with a powerful, flexible binding
         language, is so appealing.</para>
 
-      <para>Let's look at a sample program that uses Subversion's
-        Python SWIG bindings to recursively crawl the youngest
-        repository revision, and print the various paths reached
-        during the crawl.</para>
+      <para>Unfortunately, Subversion's language bindings tend to lack
+        the level of developer attention given to the core Subversion
+        modules.  However, there have been significant efforts towards
+        creating functional bindings for Python, Perl, and Ruby.  To
+        some extent, the work done preparing the SWIG interface files
+        for these languages is reusable in efforts to generate
+        bindings for other languages supported by SWIG (which include
+        versions of C#, Guile, Java, MzScheme, OCaml, PHP, and Tcl,
+        among others).  However, some extra programming is required to
+        compensate for complex APIs that SWIG needs some help
+        translating between languages.  For more information on SWIG
+        itself, see the project's website at <ulink
+        url="http://www.swig.org/"/>.</para>
+
+    </sect2>
+
+    <!-- =============================================================== -->
+    <sect2 id="svn.developer.usingapi.codesamples">
+      <title>Code Samples</title> 
+
+      <para><xref linkend="svn.developer.layerlib.repos.ex-1" />
+        contains a code segment (written in C) that illustrates some
+        of the concepts we've been discussing.  It uses both the
+        repository and filesystem interfaces (as can be determined by
+        the prefixes <literal>svn_repos_</literal> and
+        <literal>svn_fs_</literal> of the function names,
+        respectively) to create a new revision in which a directory is
+        added.  You can see the use of an APR pool, which is passed
+        around for memory allocation purposes.  Also, the code reveals
+        a somewhat obscure fact about Subversion error
+        handling—all Subversion errors must be explicitly
+        handled to avoid memory leakage (and in some cases,
+        application failure).</para>
+
+      <example id="svn.developer.layerlib.repos.ex-1">
+        <title>Using the Repository Layer</title>
+
+        <programlisting>
+/* Convert a Subversion error into a simple boolean error code.
+ *
+ * NOTE:  Subversion errors must be consumed because they are allocated
+ *        from the global pool, else memory leaking occurs.
+ */
+#define INT_ERR(expr)                           \
+  do {                                          \
+    svn_error_t *__temperr = (expr);            \
+    if (__temperr)                              \
+      {                                         \
+        svn_error_clear(__temperr);             \
+        return 1;                               \
+      }                                         \
+    return 0;                                   \
+  } while (0)
+
+/* 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.  Return zero if the operation completes
+ * successfully, non-zero otherwise.
+ */
+static int
+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. 
+   */
+  INT_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. 
+   */
+  INT_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. 
+   */
+  INT_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. 
+   */
+  INT_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  
+  /* Create our new directory under the transaction root, at the path
+   * NEW_DIRECTORY. 
+   */
+  INT_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 "
+             "'%ld'.\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);
+    }
+
+  INT_ERR(err);
+} 
+</programlisting>
+      </example>
+
+      <para>Note that in <xref
+        linkend="svn.developer.layerlib.repos.ex-1" />, the code could
+        just as easily have committed the transaction using
+        <function>svn_fs_commit_txn()</function>.  But the filesystem
+        API knows nothing about the repository library's hook
+        mechanism.  If you want your Subversion repository to
+        automatically perform some set of non-Subversion tasks every
+        time you commit a transaction (like, for example, sending an
+        email that describes all the changes made in that transaction
+        to your developer mailing list), you need to use the
+        libsvn_repos-wrapped version of that function was adds the
+        hook triggering functionality—in this case,
+        <function>svn_repos_fs_commit_txn()</function>.  (For more
+        information regarding Subversion's repository hooks, see <xref
+        linkend="svn.reposadmin.create.hooks" />.)</para>
+
+      <para>Now let's switch languages.  <xref
+        linkend="svn.developer.usingapi.otherlangs.ex-1" /> is a
+        sample program that uses Subversion's SWIG Python bindings to
+        recursively crawl the youngest repository revision, and print
+        the various paths reached during the crawl.</para>
 
       <example id="svn.developer.usingapi.otherlangs.ex-1">
         <title>Using the Repository Layer with Python</title>
@@ -963,58 +857,48 @@
 import os.path
 import svn.fs, svn.core, svn.repos
 
-def crawl_filesystem_dir(root, directory, pool):
+def crawl_filesystem_dir(root, directory):
     """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."""
+    a list of all the paths at or below DIRECTORY."""
 
     # Print the name of this path.
     print directory + "/"
     
     # Get the directory entries for DIRECTORY.
-    entries = svn.fs.svn_fs_dir_entries(root, directory, pool)
-
-    # Use an iteration subpool.
-    subpool = svn.core.svn_pool_create(pool)
+    entries = svn.fs.svn_fs_dir_entries(root, directory)
 
     # Loop over the entries.
     names = entries.keys()
     for name in names:
-        # Clear the iteration subpool.
-        svn.core.svn_pool_clear(subpool)
-
         # Calculate the entry's full path.
         full_path = directory + '/' + 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 svn.fs.svn_fs_is_dir(root, full_path, subpool):
-            crawl_filesystem_dir(root, full_path, subpool)
+        if svn.fs.svn_fs_is_dir(root, full_path):
+            crawl_filesystem_dir(root, full_path)
         else:
             # Else it's a file, so print its path here.
             print full_path
 
-    # Destroy the iteration subpool.
-    svn.core.svn_pool_destroy(subpool)
-
-def crawl_youngest(pool, repos_path):
+def crawl_youngest(repos_path):
     """Open the repository at REPOS_PATH, and recursively crawl its
     youngest revision."""
     
     # Open the repository at REPOS_PATH, and get a reference to its
     # versioning filesystem.
-    repos_obj = svn.repos.svn_repos_open(repos_path, pool)
+    repos_obj = svn.repos.svn_repos_open(repos_path)
     fs_obj = svn.repos.svn_repos_fs(repos_obj)
 
     # Query the current youngest revision.
-    youngest_rev = svn.fs.svn_fs_youngest_rev(fs_obj, pool)
+    youngest_rev = svn.fs.svn_fs_youngest_rev(fs_obj)
     
     # Open a root object representing the youngest (HEAD) revision.
-    root_obj = svn.fs.svn_fs_revision_root(fs_obj, youngest_rev, pool)
+    root_obj = svn.fs.svn_fs_revision_root(fs_obj, youngest_rev)
 
     # Do the recursive crawl.
-    crawl_filesystem_dir(root_obj, "", pool)
+    crawl_filesystem_dir(root_obj, "")
     
 if __name__ == "__main__":
     # Check for sane usage.
@@ -1023,22 +907,22 @@
                          % (os.path.basename(sys.argv[0])))
         sys.exit(1)
 
-    # Canonicalize (enough for Subversion, at least) the repository path.
-    repos_path = os.path.normpath(sys.argv[1])
-    if repos_path == '.': 
-        repos_path = ''
-
-    # Call the app-wrapper, which takes care of APR initialization/shutdown
-    # and the creation and cleanup of our top-level memory pool.
-    svn.core.run_app(crawl_youngest, repos_path)
+    # Canonicalize the repository path.
+    repos_path = svn.core.svn_path_canonicalize(sys.argv[1])
+
+    # Do the real work.
+    crawl_youngest(repos_path)
 </programlisting>
       </example>
 
-      <para>This same program in C would need to deal with custom
-        datatypes (such as those provided by the APR library) for
-        representing the hash of entries and the list of paths, but
-        Python has hashes (called <quote>dictionaries</quote>) and
-        lists as built-in datatypes, and provides a rich collection of
+      <para>This same program in C would need to deal with APR's
+        memory pool system.  But Python handles memory usage
+        automatically, and Subversion's Python bindings adhere to that
+        convention.  In C, you'd be working with custom datatypes
+        (such as those provided by the APR library) for representing
+        the hash of entries and the list of paths, but Python has
+        hashes (called <quote>dictionaries</quote>) and lists as
+        built-in datatypes, and provides a rich collection of
         functions for operating on those types.  So SWIG (with the
         help of some customizations in Subversion's language bindings
         layer) takes care of mapping those custom datatypes into the
@@ -1049,10 +933,11 @@
         copy operations, too.  In the previous section of this
         chapter, we mentioned the <filename>libsvn_client</filename>
         interface, and how it exists for the sole purpose of
-        simplifying the process of writing a Subversion client.  The
-        following is a brief example of how that library can be
-        accessed via the SWIG bindings to recreate a scaled-down
-        version of the <command>svn status</command> command.</para>
+        simplifying the process of writing a Subversion client.  <xref
+        linkend="svn.developer.usingapi.otherlangs.ex-2" /> is a brief
+        example of how that library can be accessed via the SWIG
+        Python bindings to recreate a scaled-down version of the
+        <command>svn status</command> command.</para>
 
       <example id="svn.developer.usingapi.otherlangs.ex-2">
         <title>A Python Status Crawler</title>
@@ -1070,38 +955,24 @@
 def generate_status_code(status):
     """Translate a status value into a single-character status code,
     using the same logic as the Subversion command-line client."""
+    code_map = { svn.wc.svn_wc_status_none        : ' ',
+                 svn.wc.svn_wc_status_normal      : ' ',
+                 svn.wc.svn_wc_status_added       : 'A',
+                 svn.wc.svn_wc_status_missing     : '!',
+                 svn.wc.svn_wc_status_incomplete  : '!',
+                 svn.wc.svn_wc_status_deleted     : 'D',
+                 svn.wc.svn_wc_status_replaced    : 'R',
+                 svn.wc.svn_wc_status_modified    : 'M',
+                 svn.wc.svn_wc_status_merged      : 'G',
+                 svn.wc.svn_wc_status_conflicted  : 'C',
+                 svn.wc.svn_wc_status_obstructed  : '~',
+                 svn.wc.svn_wc_status_ignored     : 'I',
+                 svn.wc.svn_wc_status_external    : 'X',
+                 svn.wc.svn_wc_status_unversioned : '?',
+               }
+    return code_map.get(status, '?')
 
-    if status == svn.wc.svn_wc_status_none:
-        return ' '
-    if status == svn.wc.svn_wc_status_normal:
-        return ' '
-    if status == svn.wc.svn_wc_status_added:
-        return 'A'
-    if status == svn.wc.svn_wc_status_missing:
-        return '!'
-    if status == svn.wc.svn_wc_status_incomplete:
-        return '!'
-    if status == svn.wc.svn_wc_status_deleted:
-        return 'D'
-    if status == svn.wc.svn_wc_status_replaced:
-        return 'R'
-    if status == svn.wc.svn_wc_status_modified:
-        return 'M'
-    if status == svn.wc.svn_wc_status_merged:
-        return 'G'
-    if status == svn.wc.svn_wc_status_conflicted:
-        return 'C'
-    if status == svn.wc.svn_wc_status_obstructed:
-        return '~'
-    if status == svn.wc.svn_wc_status_ignored:
-        return 'I'
-    if status == svn.wc.svn_wc_status_external:
-        return 'X'
-    if status == svn.wc.svn_wc_status_unversioned:
-        return '?'
-    return '?'
-
-def do_status(pool, wc_path, verbose):
+def do_status(wc_path, verbose):
     # Calculate the length of the input working copy path.
     wc_path_len = len(wc_path)
 
@@ -1119,7 +990,7 @@
         
     # Do the status crawl, using _status_callback() as our callback function.
     svn.client.svn_client_status(wc_path, None, _status_callback,
-                                 1, verbose, 0, 0, ctx, pool)
+                                 1, verbose, 0, 0, ctx)
 
 def usage_and_exit(errorcode):
     """Print usage message, and exit with ERRORCODE."""
@@ -1146,29 +1017,30 @@
     if len(args) != 1:
         usage_and_exit(2)
             
-    # Canonicalize (enough for Subversion, at least) the working copy path.
-    wc_path = os.path.normpath(args[0])
-    if wc_path == '.': 
-        wc_path = ''
-
-    # Call the app-wrapper, which takes care of APR initialization/shutdown
-    # and the creation and cleanup of our top-level memory pool.
-    svn.core.run_app(do_status, wc_path, verbose)
+    # Canonicalize the repository path.
+    wc_path = svn.core.svn_path_canonicalize(args[0])
+
+    # Do the real work.
+    do_status(wc_path, verbose)
 </programlisting>
       </example>
 
-      <para>Subversion's language bindings unfortunately tend to lack
-        the level of attention given to the core Subversion modules.
-        However, there have been significant efforts towards creating
-        functional bindings for Python, Perl, and Ruby.  To some extent,
-        the work done preparing the SWIG interface files for these
-        languages is reusable in efforts to generate bindings for other
-        languages supported by SWIG (which includes versions of C#,
-        Guile, Java, MzScheme, OCaml, PHP, Tcl, and others).
-        However, some extra programming is required to compensate for
-        complex APIs that SWIG needs some help interfacing with.  For
-        more information on SWIG itself, see the project's website at
-        <ulink url="http://www.swig.org/"/>.</para>
+      <para>As was the case in <xref
+        linkend="svn.developer.usingapi.otherlangs.ex-1" />, this
+        program is pool-free and uses, for the most part, normal
+        Python data types.  The call to
+        <function>svn_client_ctx_t()</function> is deceiving because
+        the public Subversion API has no such function—this just
+        happens to be a case where SWIG's automatic language
+        generation bleeds through a little bit (the function is a sort
+        of factory function for Python's version of the corresponding
+        complex C structure).  Also note that the path passed to this
+        program (like the last one) gets run through
+        <function>svn_path_canonicalize()</function>, because to
+        <emphasis>not</emphasis> do so runs the risk of triggering the
+        underlying Subversion C library's assertions about such
+        things, which translate into rather immediate and
+        unceremonious program abortion.</para>
 
     </sect2>
   </sect1>
@@ -1205,9 +1077,18 @@
       </listitem>
     </itemizedlist>
 
-    <para>While there are several other bits of data stored in the
-      <filename>.svn</filename> directory, we will examine only a
-      couple of the most important items.</para>
+    <para>The Subversion working copy administration area's layout and
+      contents are considered implementation details not really
+      intended for human consumption.  Developers are encouraged to
+      use Subversion's public APIs or provided tools to access and
+      manipulate the working copy data, as opposed to directly reading
+      or modifying the files of which the working copy administrative
+      area is comprised.  The file formats employed by the working
+      copy library for its administrative data do change from time to
+      time—a fact that the public APIs do a great job of
+      successfully hiding from the average user.  In this section, we
+      expose some of these implementation details sheerly to appease
+      your overwhelming curiousity.</para>
 
     <!-- =============================================================== -->
     <sect2 id="svn.developer.insidewc.entries">
@@ -1215,9 +1096,9 @@
 
       <para>Perhaps the single most important file in the
         <filename>.svn</filename> directory is the
-        <filename>entries</filename> file.  The entries file is an XML
-        document which contains the bulk of the administrative
-        information about a versioned resource in a working copy
+        <filename>entries</filename> file.  The entries file is a
+        single file which contains the bulk of the administrative
+        information about a versioned item in a working copy
         directory.  It is this one file which tracks the repository
         URLs, pristine revision, file checksums, pristine text and
         property timestamps, scheduling and conflict state
@@ -1226,118 +1107,12 @@
         that a Subversion client is interested in knowing about a
         versioned (or to-be-versioned) resource!</para>
 
-      <sidebar>
-        <title>Comparing the Administrative Areas of Subversion and
-          CVS</title>
-
-        <para>A glance inside the typical <filename>.svn</filename>
-          directory turns up a bit more than what CVS maintains in its
-          <filename>CVS</filename> administrative directories.  The
-          <filename>entries</filename> file contains XML which
-          describes the current state of the working copy directory,
-          and basically serves the purposes of CVS's
-          <filename>Entries</filename>, <filename>Root</filename>, and
-          <filename>Repository</filename> files combined.</para>
-
-      </sidebar>
-
-      <para>The following is an example of an actual entries
-        file:</para>
-
-      <example id="svn.developer.insidewc.entries.ex-1">
-        <title>Contents of a Typical <filename>.svn/entries</filename>
-          File</title>
-        <programlisting>
-<?xml version="1.0" encoding="utf-8"?>
-<wc-entries
-   xmlns="svn:">
-<entry
-   committed-rev="1"
-   name=""
-   committed-date="2005-04-04T13:32:28.526873Z"
-   url="http://svn.red-bean.com/repos/greek-tree/A/D"
-   last-author="jrandom"
-   kind="dir"
-   uuid="4e820d15-a807-0410-81d5-aa59edf69161"
-   revision="1"/>
-<entry
-   name="lambda"
-   copied="true"
-   kind="file"
-   copyfrom-rev="1"
-   schedule="add"
-   copyfrom-url="http://svn.red-bean.com/repos/greek-tree/A/B/lambda"/>
-<entry
-   committed-rev="1"
-   name="gamma"
-   text-time="2005-12-11T16:32:46.000000Z"
-   committed-date="2005-04-04T13:32:28.526873Z"
-   checksum="ada10d942b1964d359e048dbacff3460"
-   last-author="jrandom"
-   kind="file"
-   prop-time="2005-12-11T16:32:45.000000Z"/>
-<entry
-   name="zeta"
-   kind="file"
-   schedule="add"
-   revision="0"/>
-<entry
-   name="G"
-   kind="dir"/>
-<entry
-   name="H"
-   kind="dir"
-   schedule="delete"/>
-</wc-entries>
-</programlisting>
-      </example>
-
-      <para>As you can see, the entries file is essentially a list of
-        entries.  Each <sgmltag>entry</sgmltag> tag represents one of
-        three things: the working copy directory itself (called the
-        <quote>this directory</quote> entry, and noted as having an
-        empty value for its <structfield>name</structfield>
-        attribute), a file in that working copy directory (noted by
-        having its <structfield>kind</structfield> attribute set to
-        <literal>"file"</literal>), or a subdirectory in that working
-        copy (<structfield>kind</structfield> here is set to
-        <literal>"dir"</literal>).  The files and subdirectories whose
-        entries are stored in this file are either already under
-        version control, or (as in the case of the file named
-        <filename>zeta</filename> above) are scheduled to be added to
-        version control when the user next commits this working copy
-        directory's changes.  Each entry has a unique name, and each
-        entry has a node kind.</para>
-
-      <para>Developers should be aware of some special rules that
-        Subversion uses when reading and writing its
-        <filename>entries</filename> files.  While each entry has a
-        revision and URL associated with it, note that not every
-        <sgmltag>entry</sgmltag> tag in the sample file has explicit
-        <structfield>revision</structfield> or
-        <structfield>url</structfield> attributes attached to it.
-        Subversion allows entries to not explicitly store those two
-        attributes when their values are the same as (in the
-        <structfield>revision</structfield> case) or trivially
-        calculable from
-        <footnote>
-          <para>That is, the URL for the entry is the same as the
-            concatenation of the parent directory's URL and the
-            entry's name.</para>
-        </footnote>
-        (in the <structfield>url</structfield> case) the data stored
-        in the <quote>this directory</quote> entry.  Note also that
-        for subdirectory entries, Subversion stores only the crucial
-        attributes—name, kind, url, revision, and schedule.  In
-        an effort to reduce duplicated information, Subversion
-        dictates that the method for determining the full set of
-        information about a subdirectory is to traverse down into that
-        subdirectory, and read the <quote>this directory</quote> entry
-        from its own <filename>.svn/entries</filename> file.  However,
-        a reference to the subdirectory is kept in its parent's
-        <filename>entries</filename> file, with enough information to
-        permit basic versioning operations in the event that the
-        subdirectory itself is actually missing from disk.</para>
+      <para>Folks familiar with CVS's administrative directories will
+        have recognized at this point that Subversion's
+        <filename>.svn/entries</filename> file serves the purposes of,
+        among other things, CVS's <filename>CVS/Entries</filename>,
+        <filename>CVS/Root</filename>, and
+        <filename>CVS/Repository</filename> files combined.</para>
 
     </sect2>
 

Modified: trunk/src/en/book/ch-fundamental-concepts.xml
==============================================================================
--- trunk/src/en/book/ch-fundamental-concepts.xml	(original)
+++ trunk/src/en/book/ch-fundamental-concepts.xml	Fri Feb  9 05:36:27 2007
@@ -347,6 +347,19 @@
         vertical bar character is not interpreted as a pipe.  Also, note
         that a URL uses forward slashes even though the native
         (non-URL) form of a path on Windows uses backslashes.</para>
+
+      <note>
+        <para>Subversion's <literal>file:</literal> URLs cannot be
+          used in a regular web browser the way typical
+          <literal>file:</literal> URLs can.  When you attempt to view
+          a <literal>file:</literal> URL in a regular web browser, it
+          reads and displays the contents of the file at that location
+          by examining the filesystem directly.  However, Subversion's
+          resources exist in a virtual filesystem (see <xref
+          linkend="svn.developer.layerlib.repos" />), and your browser
+          will not understand how to interact with that
+          filesystem.</para>
+      </note>
       
       <para>Finally, it should be noted that the Subversion client will
         automatically encode URLs as necessary, just like a web browser




More information about the svnbook-dev mailing list