Il disegno a strati delle librerie

Subversion has a modular design, implemented as a collection of C libraries. Each library has a well-defined purpose and interface, and most modules are said to exist in one of three main layers—the Repository Layer, the Repository Access (RA) Layer, or the Client Layer. We will examine these layers shortly, but first, see our brief inventory of Subversion's libraries in Tabella 8.2, «Un breve inventario delle librerie di Subversion». For the sake of consistency, we will refer to the libraries by their extensionless Unix library names (e.g.: libsvn_fs, libsvn_wc, mod_dav_svn).

Subversion ha un disegno modulare, implementato come una collezione di librerie C. Ogni libreria ha uno scopo e un'interfaccia ben definiti, e la maggior parte dei moduli sono dichiarati di esistere in uno dei tre strati principali—lo strato repository, lo strator accesso al repository (RA), o lo strato clien. Verranno esaminati questi strati brevemente, ma prima, vedere il breve inventario delle librerie di Subversion in Tabella 8.2, «Un breve inventario delle librerie di Subversion». Nell'interesse della consistenza, verrà fatto riferimento alla librerie con i loro nomi Unix senza estensione (es.: libsvn_fs, libsvn_wc, mod_dav_svn).

Table 8.1. A Brief Inventory of the Subversion Libraries

Library Description
libsvn_client Primary interface for client programs
libsvn_delta Tree and byte-stream differencing routines
libsvn_diff Contextual differencing and merging routines
libsvn_fs Filesystem commons and module loader
libsvn_fs_base The Berkeley DB filesystem back-end
libsvn_fs_fs The native filesystem (FSFS) back-end
libsvn_ra Repository Access commons and module loader
libsvn_ra_dav The WebDAV Repository Access module
libsvn_ra_local The local Repository Access module
libsvn_ra_svn The custom protocol Repository Access module
libsvn_repos Repository interface
libsvn_subr Miscellaneous helpful subroutines
libsvn_wc The working copy management library
mod_authz_svn Apache authorization module for Subversion repositories access via WebDAV
mod_dav_svn Apache module for mapping WebDAV operations to Subversion ones

Tabella 8.2. Un breve inventario delle librerie di Subversion

Libreria Descrizione
libsvn_client Interfaccia primaria per programmi client
libsvn_delta Procedure di differenza per alberi e byte-stream
libsvn_diff Procedure di differenza e fusione
libsvn_fs Caricatore di filesystem comuni e moduli
libsvn_fs_base L'interfaccia per il filesystem al database Berkeley DB
libsvn_fs_fs L'interfaccia per il filesystem nativo (FSFS)
libsvn_ra Caricatore di accesso a repository comuni e moduli
libsvn_ra_dav Il modulo per l'accesso a repository WebDAV
libsvn_ra_local Il modulo per l'accesso a repository locali
libsvn_ra_svn Il modulo per l'accesso a repository con protocolli personalizzati
libsvn_repos Interfaccia a repository
libsvn_subr Varie sottoprocedure di aiuto
libsvn_wc La libreria di gestione della copia di lavoro
mod_authz_svn Il modulo di autorizzazione Apache per l'accesso a repository Subversion via WebDAV
mod_dav_svn Modulo Apache per mappare operazioni WebDAV sulle corrispondenti Subversion

The fact that the word miscellaneous only appears once in Tabella 8.2, «Un breve inventario delle librerie di Subversion» is a good sign. The Subversion development team is serious about making sure that functionality lives in the right layer and libraries. Perhaps the greatest advantage of the modular design is its lack of complexity from a developer's point of view. As a developer, you can quickly formulate that kind of big picture that allows you to pinpoint the location of certain pieces of functionality with relative ease.

Il fatto che la parola «varie» compare una sola volta in Tabella 8.2, «Un breve inventario delle librerie di Subversion» è un buon segno. La squadra di sviluppo di Subversion è preoccupata riguardo il fatto di assicurarsi che le funzionalità esistano nello strato e nelle librerie giuste. Forse il più grande vantaggio del disegno modulare è la sua mancanza di complessità da un punto di vista dello sviluppatore. Come sviluppatore, si può formulare velocemente questo tipo di «grande immagine» che permette di individuare la posizione di certe parti di funzionalità con relativa semplicità.

Another benefit of modularity is the ability to replace a 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.

Un altro beneficio della modularità è l'abilità di sostituire un dato modulo con un'intera nuova libreria che implementa la stessa API senza interessare il resto del codice di base. In un certo senso, questo accade già allinterno di Subversion. libsvn_ra_dav, libsvn_ra_local, e libsvn_ra_svn implmentato tutte la stessa interfaccia. E tutte e tre comunicano con lo strato repository —libsvn_ra_dav e libsvn_ra_svn lo fanno attraverso una rete, e libsvn_ra_local ci si connette direttamente. Le librerie libsvn_fs_base e libsvn_fs_fs sono un altro esempio di ciò.

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 of the functionality necessary for designing a working Subversion client (see sezione chiamata «Strato client»).

Il client stesso evidenzia anche la madularità nel disegno di Subversion. Mentre Subversion stesso viene fornito solamente con un programma client a linea di comando, ci sono vari programmi di terze parti che forniscono varie forme di client a interfaccia grafica. Queste interfacce grafiche utilizzano le stesse API che usa il client a linea di comando predefinito. La libreria di Subversion libsvn_client è il negozio a fermata unica per la maggior parte delle funzionalità necessarie per progettare un client funzionante per Subversion (vedere sezione chiamata «Strato client»).

Strato repository

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 other end of the line.

Nel riferirsi allo strato repository di Subversion, si sta generalmente parlando di due librerie—la libreria per i repository, e la libreria per i filesystem. Queste librerie forniscono i meccanismi per l'immagazzinaggio e la segnalazione per le varie revisioni dei propri dati sotto controllo di versione. Questo strato è connesso allo strato client attraverso lo strato di accesso al repository, ed è, dalla prospettiva dell'utente di Subversion, la cosa all' «altro lato della linea.»

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 files and directories 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 sezione chiamata «Repository Data Stores».) 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).

Il filesystem di Subversion è acceduto attraverso l'API libsvn_fs, e non è un filesystem a livello di kernel che si installerebbe in un sistema operativo (come ext2 o NTFS di Linux), ma un filesystem virtuale. Piuttosto che immagazzinare «file» e «directory» come file e directory reali (il tipo in cui si può navigare utilizzando il proprio programma di shell favorito), utilizza una delle due interfacce astratte per immagazzinamento disponibili—o un ambientedatabase Berkeley DB, o una rappresentazione di file piatta. (Per imparare maggiormente circa le due interfacce per il repository, vedere sezione chiamata «Repository Data Stores».) Comunque, c'è stato un considerevole interesse della comunità di sviluppo nel dare ai rilasci futuri di Subversion l'abilità di utilizzare altre interfacce a sistemi database, forse attraverso un meccanismo come Open Database Connectivity (ODBC).

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 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 (properties) on each file or directory. Furthermore, the Subversion Filesystem is a versioning filesystem, which means that as you make changes to your directory tree, Subversion remembers what your tree looked like before those changes. And before the previous changes. And the previous ones. And so on, all the way back through versioning time to (and just beyond) the moment you first started adding things to the filesystem.

L'API per il filesystem esportata da libsvn_fs contiene il tipo di funzionalità ci si aspetterebbe da ogni altra API per filesystem: si può creare e rimuovere file e directory, copiarli e spostarli, modificare il contenuto dei file, e così via. Ha anche caratteristiche che non sono comuni, come l'abilità di aggiungere, modificare, e rimuovere metadati («proprietà») su ogni file o directory. Ancora, il filesystem di Subversion è un filesystem di versionamento, che significa che come vengono fatti dei cambiamenti all'albero delle directory, Subversion ricorda come era fatto l'albero prima di questi cambiamenti. E prima dei cambiamenti precedenti. E i precedenti ancora. E così via, tutti i modi indietro attraverso il tempo di versionamento fino al (e ancora oltre) momento in cui si è iniziato ad aggiungere cose al filesystem.

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 filesystem:

Tutte le modifiche fatte all'albero sono fatte all'interno del contesto di una transazione Subversion. Il seguente è una procedure semplificata generale per modificare il proprio filesystem:

  1. Begin a Subversion transaction.

    Iniziare una transazione Subversion.

  2. Make your changes (adds, deletes, property modifications, etc.).

    Fare i propri cambiamenti (aggiunte, eliminazioni, modifiche alle proprietà, ecc.).

  3. Commit your transaction.

    Fare il commit della transazione.

Once you have committed your transaction, your filesystem modifications are permanently stored as historical artifacts. Each of these cycles generates a single new revision of your tree, and each revision is forever accessible as an immutable snapshot of the way things were.

Una volta fatto il commit della transazione, le modifiche al filesystem sono immagazzinate permanentemente come artefatti storici. Ognuno di questi cicli genera un singola nuova revisione dell'albero, e ogni revisione è accessibile per sempre come un'istantanea immutabile di «come erano le cose.»

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

La maggior parte delle funzionalità fornite dalla interfaccia del filesystem avvengono come un'azione che occorre su un percorso del filesystem. Quello è, da fuori il filesystem, il meccanismo primario per descrivere e accedere le revisioni individuali di file e directory attraverso l'utilizzo di stringhe percorso come /foo/bar, come se si stessero indirizzando file e directory attraverso il proprio programma shell favorito. Si aggiungono nuovi file e directory passando il loro percorso alle funzioni giuste dell'API. Si interroga per informazioni su di loro con lo stesso meccanismo.

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. Figura 8.1, «File e directory in due dimensioni» shows a typical representation of a tree as exactly that.

A differenza della maggior parte dei filesystem un percorso da solo non è un'informazione sufficiente per identificare un file o una directory in Subversion. Si pensi all'albero delle directory come un sistema a due dimensioni, dove i fratelli dei nodi rappresentano una sorta di movimento sinistra destra, e discendendo all'interno delle sottodirectory un movimento verso il basso. Figura 8.1, «File e directory in due dimensioni» mostra una tipica rappresentazione di un albero esattamente come è.

Figura 8.1. File e directory in due dimensioni

File e directory in due dimensioni

Of course, the Subversion filesystem has a nifty third dimension that most filesystems do not have—Time! [65] In the filesystem interface, nearly every function that has a path argument also expects a root argument. This svn_fs_root_t 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 /foo/bar in revision 32, and the same path as it exists in revision 98. Figura 8.2, «Tempo di versionamento—la terza dimensione!» shows revision history as an added dimension to the Subversion filesystem universe.

Naturalmente, il filesystem di Subversion ha un'eccezionale terza dimensione che la maggior parte dei filesystem non hanno—il tempo! [66] Nell'interfaccia del filesystem, quasi ogni funzione che ha un argomento percorso prevede anche un argomento root. Questo argomento svn_fs_root_t descrive sia una revisione sia una transazione di Subversion (che è usualmente una revisione a essere), e fornisce questo contesto tridimensionale necessario per capire la differenza tra /foo/bar nella revisione 32, e lo stesso percorso come esiste nella revisione 98. Figura 8.2, «Tempo di versionamento—la terza dimensione!» mostra lo storico di revisione come una dimensione aggiunta all'universo del filesystem di Subversion.

Figura 8.2. Tempo di versionamento—la terza dimensione!

Tempo di versionamento—la terza dimensione!

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 program interested in a versioning filesystem. Not coincidentally, Subversion itself is interested in that functionality. But while the filesystem API should be sufficient for basic file and directory versioning support, Subversion wants more—and that is where libsvn_repos comes in.

Come menzionato prima, l'API di libsvn_fs sembra come ogni altro filesystem, eccetto che ha questa meravigliosa capacità di versionamento. È stata disegnata per essere usabile da ogni programma interessato a un filesystem di versionamento. Non per coincidenza, Subversion stesso è interessato a questa funzionalità. Ma mentre l'API del filesystem API dovrebbe essere sufficiente per il supporto di versionamento base a file e directory, Subversion vuole di più—e questo è dove entra libsvn_repos.

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.

La libreria per il repository di Subversion (libsvn_repos) è essenzialmente una libreria involucro attorno alle funzionalità del filesystem. Questa libreria è responsabile della creazione della disposizione del repository, assicurandosi che il filesystem sottostante sia inizializzato, e così via. Libsvn_repos implementa anche un insieme di ganci—script che sono eseguiti dal codice del repository quando certe avvengono azioni. Questi script sono utili per notificare, autorizzare, o a qualunque scopo l'amministratore del repository desideri. Questo tipo di funzionalità, e altre utilità fornite dalla libreria per il repository, non sono rigorosamente relative a implementare un filesystem di versionamento, che è il perché è stato messo all'interno della sua libreria.

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.

Gli sviluppatori che desiderano utilizzare l'API di libsvn_repos troveranno che non è un involucro completo attorno all'interfaccia del filesystem. Questo è, solamente certi eventi maggiori nel generale ciclo dell'attività del filesystem sono avvolte dall'interfaccia del repository. Alcuni di questi includono la creazione e il commit delle transazioni di Subversion, e la modifica delle proprietà di revisione. Questi particolari eventi sono avvolti dallo strato del repository perché hanno ganci associati a loro. In futuro, altri eventi posso essere inglobati dall'API del repository. Tutti le rimanenti interazioni del filesystem continueranno ad occorrere direttamente attraverso l'API di libsvn_fs.

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 (and all others throughout this book), the SVN_ERR() macro simply checks for a non-successful error return from the function it wraps, and returns that error if it exists.

Per esempio, questo è un segmento di codice che illustra l'utilizzo di entrambe le interfacce per il repository e il filesystem per creare una nuova revisione del filesystem nella quale una directory è aggiunta. Notare che in questo esempio (e tutti gli altri all'interno di questo libro), la macro SVN_ERR() controlla semplicemente per un errore di non successo che ritorna dalla funzione di cui è l'involucro, e ritorna questo errore se esiste.

Esempio 8.1. Utilizzare lo strato repository

/* 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;
} 

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 svn_fs_commit_txn(). 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—svn_repos_fs_commit_txn(). This function will actually first run the pre-commit hook script if one exists, then commit the transaction, and finally will run a post-commit 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 sezione chiamata «Hook Scripts».)

Nel precedente segmento di codice, le chiamate vengono fatte a entrambe le interfacce repository e filesystem. Si potrebbe facilmente aver fatto il commit della transazione utilizzando svn_fs_commit_txn(). Ma le API del filesystem non conoscono niente del meccanismo dei ganci della libreria del repository. Se si vuole che il proprio repository di Subversion effettui automaticamente qualche insieme di compiti non di Subversion ogni volta che si fa il commit di una transazione (come, per esempio, inviare una email che descrive tutti i cambiamenti fatti in quella transazione alla lista di posta del proprio sviluppatore), occorre utilizzare libsvn_repos-versione avvolta di quella funzione —svn_repos_fs_commit_txn(). Questa funzione eseguirà realmente prima uno script gancio pre-commit se ne esiste uno, poi farà il commit della transazione, e finalmente eseguirà uno script gancio post-commit. I ganci forniscono un tipo speciale di meccanismo di reportistica che non appartiene veramente al nucleo della libreria stessa per il filesystem. (Per maggiori informazioni riguardanti i gangi a repository di Subversion, vedere sezione chiamata «Hook Scripts».)

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:

Il requisito per il meccanismo del gancio è una delle ragioni per l'astrazione di una libreria separata per il repository dal resto del codice del filesystem. Le API libsvn_repos forniscono varie altre importanti utilità a Subversion. Queste includono le abilità di:

  1. create, open, destroy, and perform recovery steps on a Subversion repository and the filesystem included in that repository.

    creare, aprire, distruggere, ed effettuare i passi per il ripristino su un repository di Subversion e il filesystem incluso in questo repository.

  2. describe the differences between two filesystem trees.

    descrivere le differenze tra due alberi di filesystem.

  3. 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.

    interrogare per i messaggi commit di registro associati con tutte (o alcune) delle revisioni nelle quali un insieme di file fosse modificato nel filesystem.

  4. generate a human-readable dump of the filesystem, a complete representation of the revisions in the filesystem.

    generare un «dump» del filesystem leggibile dalle persone, una rappresentazione completa delle revisioni nel filesystem.

  5. parse that dump format, loading the dumped revisions into a different Subversion repository.

    interpretare il formato di questo dump, caricando la revisione di cui è stato fatto il dump in un repository di Subversion diverso.

As Subversion continues to evolve, the repository library will grow with the filesystem library to offer increased functionality and configurable option support.

Dato che Subversion continua ad evolversi, la libreria per il repository crescerà con la libreria per il filesystem per offrire funzionalità incrementate e il supporto a opzioni configurabili.

Strato di accesso al repository

If the Subversion Repository Layer is at the other end of the line, the Repository Access 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, svnserve.

Se lo strato per il repository Subversion è «all'altro capo della linea», lo strato per l'accesso al repository è la linea stessa. Caricato dei dati di ordinamento tra le librerie client e il repository, questo strato include la libreria per il caricamento del modulo libsvn_ra, i moduli RA stessi (che correntemente includono libsvn_ra_dav, libsvn_ra_local, e libsvn_ra_svn), e ogni libreria addizionale necessaria da uno o più di quei moduli RA, come il modulo Apache mod_dav_svn con cui libsvn_ra_dav comunica o il server di libsvn_ra_svn, svnserve.

Since Subversion uses URLs to identify its repository resources, the protocol portion of the URL schema (usually file:, http:, https:, or svn:) is used to determine which RA module will handle the communications. Each module registers a list of the protocols it knows how to speak so that the RA loader can, at runtime, determine which module to use for the task at hand. You can determine which RA modules are available to the Subversion command-line client, and what protocols they claim to support, by running svn --version:

Da allora Subversion utilizza gli URL per identificare le risorse dei suoi repository, la porzione del protocollo dello schema URL (usualmente file:, http:, https:, o svn:) è utilizzato per determinare quale modulo RA si occuperà della comunicazione. Ogni modulo registra una lista di protocolli che riesce a «parlare» così che il caricatore RA può, in esecuzione, determinare quale modulo utilizzare per il compito attuale. Si può determinare quali moduli RA sono disponibili al client a riga di comando di Subversion, e quali protocolli sostengono di supportare, eseguendo svn --version:

$ svn --version
svn, version 1.2.3 (r15833)
   compiled Sep 13 2005, 22:45:22

Copyright (C) 2000-2005 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' scheme
  - handles 'https' scheme
* ra_svn : Module for accessing a repository using the svn network protocol.
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme

RA-DAV (Accesso al repository utilizzando HTTP/DAV)

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 http: or https: 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.

La libreria libsvn_ra_dav è disegnata per essere utilizzata dai client che vengono eseguiti su macchine diverse dai server con cui loro comunicano, specificamente server raggiunti utilizzando URL che contengono le porzioni protocollo http: oppure https:. Per capire come questo modulo funziona, dobbiamo prima menzionare un paio di altri componenti chiave in questa particolare configurazione dello strato di accesso al repository—il potente server HTTP Apache, e la libreria client HTTP/WebDAV Neon.

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.

Il server di rete primario di Subversion è il server HTTP Apache. Apache è un processo server testato da tempo, estendibile e open-source che è pronto per un utilizzo serio. Può sostenere un alto carico di rete e essere eseguito su molte piattaforme. Il server Apache supporta un numero di differenti protocolli di autenticazione standard, e può essere esteso attraverso l'utilizzo di moduli per supportarne molti altri. Supporta anche ottimizzazioni come il pipelining e il caching di rete. Utilizzando Apache come server, Subversion ottiene tutte queste caratteristiche gratuitamente. E dato che la maggior parte dei firewall permettono già al traffico HTTP di attraversarli, tipicamente gli amministratori di sistema non hanno neppure da cambiare la configurazione dei propri firewall per permettere a Subversion di funzionare.

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.

Subversion utilizza HTTP e WebDAV (con DeltaV) per comunicare con un server Apache. Si può leggere altro a proposito di questo nella sezione di WebDAV in questo capitolo, ma in breve, WebDAV e DeltaV sono estensioni al protocollo standard HTTP 1.1 che abilita la condivisione e il versionamento di file sul web. Apache 2.0 e versioni più recenti hanno mod_dav, un modulo Apache che comprende le estensioni DAV a HTTP. Subversion stesso fornisce mod_dav_svn, che è un altro modulo Apache che funziona in congiunzione con (veramente, come un sottostrato di) mod_dav per fornire implementazioni specifiche di Subversion a WebDAV e DeltaV.

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 <Location> directive in httpd.conf), 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.

Quando comunica con un repository sopra HTTP, il caricatore di libreria RA sceglie libsvn_ra_dav come modulo di accesso adeguato. Il client Subversion effettua chiamate nella interfaccia generica RA, e libsvn_ra_dav mappa queste chiamate (che comprendono una scala piuttosto ambia di azioni di Subversion) ad un insieme di richieste HTTP/WebDAV. Utilizzando la libreria Neon, libsvn_ra_dav trasmette queste richieste al server Apache. Apache riceve queste richieste (esattamente come come richieste HTTP generiche che potrebbe fare il proprio navigatore web), avvisando che le richieste sono dirette a una URL che è configurata come una posizione DAV (utilizzando la direttiva <Location> in httpd.conf), e passa la richiesta al proprio modulo mod_dav. Quando adeguatamente configurato, mod_dav sa utilizzare mod_dav_svn di Subversion per ogni necessità relativa al filesystem, come opposto al generico mod_dav_fs che viene fornito con Apache. Così infine, il client sta comunicando con mod_dav_svn, che si lega direttamente allo strato repository di Subversion.

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.

Questa era una descrizione semplificata degli scambi attuali che avvengono. Per esempio, il repository Subversion potrebbe essere protetto delle direttive di autorizzazione di Apache. Questo può risultare in tentativi iniziali di comunicazione con il repository che vengono respinti da Apache per motivi di autorizzazione. A questo punto, libsvn_ra_dav ottiene come risposta l'avviso da Apache che è stata fornita un'identificazione insufficiente, e ritorna indietro nello strato client per ottenere qualche dato di autenticazione aggiornato. Se il dato viene fornito correttamente, e l'utente ha i permessi che Apache cerca, il tentativo automatico successivo di libsvn_ra_dav di effettuare l'operazione originale verrà assegnato, e tutto andrà bene. Se informazioni di autenticazione sufficienti non possono essere fornite, la richiesta finalmente fallirà, e il client riporterà il fallimento all'utente.

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 speak the language). Also, both Neon itself and Apache's mod_deflate can understand the deflate 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.

Utilizzando Neon e Apache, Subversion ottiene funzionalità gratuite anche in varie altre complesse aree. Per esempio, se Neon trova le librerie di OpenSSL, permette al client Subversion di tentare di utilizzare comunicazioni cifrate SSL con il server Apache (che possiede mod_ssl che può «parlare la lingua»). Inoltre, sia Neon stesso che mod_deflate di Apache possono capire l'algoritmo «deflate» (lo stesso utilizzato dai programmi PKZIP e gzip), così che le richieste possono essere inviate in pezzi più piccoli e compressi attraverso il collegamento. Altre caratteristiche complesse che Subversion spera di supportare in futuro includono l'abilità di maneggiare automaticamente redirezioni specificate dal server (per esempio, quando un repository è stato spostato a un nuovo URL canonico) e prendere del vantaggio dal pipelining HTTP.

RA-SVN (Accesso con protocollo personalizzato al repository)

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 svnserve program—on the machine that hosts the repository. Clients access the repository using the svn:// schema.

In aggiunta al protocollo standard HTTP/WebDAV, Subversion fornisce anche una implementazione RA che utilizza un protocollo personalizzato. Il modulo libsvn_ra_svn implementa il proprio socket di connettività di rete, e comunica con un server autonomo—il programma svnserve — sulla macchina che ospita il repository. I client accedono al repository utilizzando lo schema svn://.

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 svnserve 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.

Questa implementazione di RA difetta di molti dei vantaggi di Apache menzionati nella precedente sezione; tuttavia, può fare appello a qualche amministratore di sistema ciò nonostante. È drammaticamente facile da configurare ed eseguire; mettere in opera il processo svnserve è quasi istantaneo. È anche molto più piccolo (in termini di linee di codice) di Apache, rendendolo molto più facile da verificare, per ragioni di sicurezza o altrimenti. Ancora, qualche amministratore di sistema può già avere una infrastruttura di sicurezza SSH sul posto, e volere che Subversion la utilizzi. I client utilizzando ra_svn possono facilmente fare il tunnel del protocollo sopra SSH.

RA-Local (Accesso diretto al repository)

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 file: 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.

Non tutte le comunicazioni con un repository Subversion richiedono un processo server e uno strato di rete. Per utenti che semplicemente desiderano accedere ai repository nel loro disco locale, lo possono fare utilizzando l'URL file: e la funzionalità fornita da libsvn_ra_local. Questo modulo RA si lega direttamente con il repository e le librerie del filesystem, così nessuna comunicazione di rete è affatto richiesta.

Subversion requires that the server name included as part of the file: URL be either localhost or empty, and that there be no port specification. In other words, your URLs should look like either file://localhost/path/to/repos or file:///path/to/repos.

Subversion richiede che il nome del server incluso come parte dell'URL file: sia localhost o vuoto, e che possa non essere specificata la porta. In altre parole, l'URL dovrebbe assomigliare o a file://localhost/path/to/repos o a file:///path/to/repos.

Also, be aware that Subversion's file: URLs cannot be used in a regular web browser the way typical file: URLs can. When you attempt to view a file: 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 sezione chiamata «Strato repository»), and your browser will not understand how to read that filesystem.

Inoltre, occorre essere informati che l'URL di Subversion file: non può essere utilizzato in un regolare esploratore web nel tipico modo che l'URL file: può. Quando si tenta di visualizzare un URL file: in un regolare esploratore web, questo legge e visualizza i contenuti dei file a questa posizione esaminando direttamente il filesystem. Tuttavia, le risorse di Subversion esistono in un filesystem virtuale (vedere sezione chiamata «Strato repository»), e il proprio esploratore non capirà come leggere questo filesystem.

La vostra libreria RA qui

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.

Per chi desiderasse accedere al repository di Subversion utilizzando ancora un altro protocollo, questo è esattamente il perché lo strato di accesso al repository è modularizzato! Gli sviluppatori possono semplicemente scrivere una nuova libreria che implementa l'interfaccia di RA da una parte e comunicare con il repository dall'altra. La propria nuova libreria può utilizzare protocolli di rete esistenti, o se ne può inventare dei propri. Si possono utilizzare chiamate a comunicazioni tra processi (IPC), o—let's get crazy, shall we?—si può anche implementare un protocollo basato sulla posta elettronica. Subversion fornisce le API; voi fornite la creatività.

Strato client

On the client side, the Subversion working copy is where all the action takes place. The bulk of functionality implemented by the client-side libraries exists for the sole purpose of managing working copies—directories full of files and other subdirectories which serve as a sort of local, editable reflection of one or more repository locations—and propagating changes to and from the Repository Access layer.

Dalla parte del client, la copia di lavoro di Subversion è dove tutte le azioni hanno luogo. La massa delle funzionalità implementate delle librerie lato client esiste per il solo scopo di gestire le copie di lavoro—directory piene di file e altre sottodirectory che servono come una sorta di locale, modificabile «riflessione» di uno o più posizioni di repository—e propagare cambiamenti allo e dallo strato di accesso al repository.

Subversion's working copy library, libsvn_wc, is directly responsible for managing the data in the working copies. To accomplish this, the library stores administrative information about each working copy directory within a special subdirectory. This subdirectory, named .svn, is present in each working copy directory and contains various other files and directories which record state and provide a private workspace for administrative action. For those familiar with CVS, this .svn subdirectory is similar in purpose to the CVS administrative directories found in CVS working copies. For more information about the .svn administrative area, see sezione chiamata «All'interno dell'area di amminstrazione della copia di lavoro»in this chapter.

La libreria per copie di lavoro di Subversion, libsvn_wc, è direttamente responsabile della gestione dei dati nelle copie di lavoro. Per compiere questo, la libreria immagazzina informazioni amministrative circa ogni directory della copia di lavoro all'interno di una sottodirectory speciale. Questa sottodirectory, di nome .svn, è presente in ogni directory della copia di lavoro e contiene vari altri file e directory che registrano lo stato e forniscono uno spazio di lavoro privato per azioni amministrative. Per chi ha familiarità con CVS, questa sottodirectory .svn è simile nello scopo alle directory amministrative CVS che si trovano nelle copie di lavoro di CVS. Per maggiori informazioni circa l'area amminstrativa .svn, vedere sezione chiamata «All'interno dell'area di amminstrazione della copia di lavoro»in questo capitolo.

The Subversion client library, libsvn_client, has the broadest responsibility; its job is to mingle the functionality of the working copy library with that of the Repository Access Layer, and then to provide the highest-level API to any application that wishes to perform general revision control actions. For example, the function svn_client_checkout() takes a URL as an argument. It passes this URL to the RA layer and opens an authenticated session with a particular repository. It then asks the repository for a certain tree, and sends this tree into the working copy library, which then writes a full working copy to disk (.svn directories and all).

La libreria del client di Subversion, libsvn_client, ha la più vasta responsabilità; il suo lavoro è di mescolare le funzionalità della libreria della copia di lavoro con quella dello strato di accesso al repository, e poi di fornire il più alto livello delle API a qualunque applicazione che desidera eseguire azioni di controllo di revisione. Per esempio, la funzione svn_client_checkout() prende un URL come argomento. Passa questo URL allo strato RA e apre una sessione autenticata con un particolare repository. Poi chiede al repository un certo albero, e invia questo albero alla libreria per la copia di lavoro, che poi scrive una copia di lavoro completa su disco (le directory .svn e tutti).

The client library is designed to be used by any application. While the Subversion source code includes a standard command-line client, it should be very easy to write any number of GUI clients on top of the client library. New GUIs (or any new client, really) for Subversion need not be clunky wrappers around the included command-line client—they have full access via the libsvn_client API to same functionality, data, and callback mechanisms that the command-line client uses.

La libreria del client è disegnata per essere utilizzata da qualunque applicazione. Mentre il codice sorgente di Subversion include un client standard a linea di comando, dovrebbe essere molto facile scrivere qualunque numero di client con GUI sopra la libreria del client. Nuove GUI (o qualunque nuovo client, veramente) per Subversion need not be clunky wrappers attorno al client a linea di comando incluso—hanno pieno accesso attraverso le API di libsvn_client alle stesse funzionalità, dati, e ai meccanismi di callback che utilizza il client a linea di comando.



[65] We understand that this may come as a shock to sci-fi fans who have long been under the impression that Time was actually the fourth dimension, and we apologize for any emotional trauma induced by our assertion of a different theory.

[66] Capiamo che questo può essere come uno shock per un fan di fantascienza che è stato lungamente con l'impressione che il tempo fosse realmente la quarta dimensione, e ci scusiamo per ogni trauma emozionale indotto da questa asserzione di una differente teoria.