Earlier in this chapter (in the section called “Strategies for Repository Deployment”), we looked at some of the important decisions that should be made before creating and configuring your Subversion repository. Now, we finally get to get our hands dirty! In this section, we'll see how to actually create a Subversion repository and configure it to perform custom actions when special repository events occur.
Subversion repository creation is an incredibly simple task. The svnadmin utility that comes with Subversion provides a subcommand (svnadmin create) for doing just that.
$ # Create a repository $ svnadmin create /var/svn/repos $
Assuming that the parent directory 
        /var/svn exists and that you have
        sufficient permissions to modify that directory, the previous
        command creates a new repository in the directory
        /var/svn/repos, and with the default
        filesystem data store (FSFS).  You can explicitly choose the
        filesystem type using the --fs-type argument,
        which accepts as a parameter either fsfs or
        bdb.
$ # Create an FSFS-backed repository $ svnadmin create --fs-type fsfs /var/svn/repos $
# Create a Berkeley-DB-backed repository $ svnadmin create --fs-type bdb /var/svn/repos $
After running this simple command, you have a Subversion repository. Depending on how users will access this new repository, you might need to fiddle with its filesystem permissions. But since basic system administration is rather outside the scope of this text, we'll leave further exploration of that topic as an exercise to the reader.
| ![[Tip]](images/tip.png)  | Tip | 
|---|---|
| The path argument to svnadmin is just
          a regular filesystem path and not a URL like the
          svn client program uses when referring to
          repositories.  Both svnadmin and
          svnlook are considered server-side
          utilities—they are used on the machine where the
          repository resides to examine or modify aspects of the
          repository, and are in fact unable to perform tasks across a
          network.  A common mistake made by Subversion newcomers is
          trying to pass URLs (even “local”
           | 
Present in the db/ subdirectory of
        your repository is the implementation of the versioned
        filesystem.  Your new repository's versioned filesystem begins
        life at revision 0, which is defined to consist of nothing but
        the top-level root (/) directory.
        Initially, revision 0 also has a single revision property,
        svn:date, set to the time at which the
        repository was created.
Now that you have a repository, it's time to customize it.
| ![[Warning]](images/warning.png)  | Warning | 
|---|---|
| While some parts of a Subversion repository—such as the configuration files and hook scripts—are meant to be examined and modified manually, you shouldn't (and shouldn't need to) tamper with the other parts of the repository “by hand.” The svnadmin tool should be sufficient for any changes necessary to your repository, or you can look to third-party tools (such as Berkeley DB's tool suite) for tweaking relevant subsections of the repository. Do not attempt manual manipulation of your version control history by poking and prodding around in your repository's data store files! | 
A hook is a program triggered by some repository event, such as the creation of a new revision or the modification of an unversioned property. Some hooks (the so-called “pre hooks”) run in advance of a repository operation and provide a means by which to both report what is about to happen and prevent it from happening at all. Other hooks (the “post hooks”) run after the completion of a repository event and are useful for performing tasks that examine—but don't modify—the repository. Each hook is handed enough information to tell what that event is (or was), the specific repository changes proposed (or completed), and the username of the person who triggered the event.
The hooks subdirectory is, by
        default, filled with templates for various repository
        hooks:
$ ls repos/hooks/ post-commit.tmpl post-unlock.tmpl pre-revprop-change.tmpl post-lock.tmpl pre-commit.tmpl pre-unlock.tmpl post-revprop-change.tmpl pre-lock.tmpl start-commit.tmpl $
There is one template for each hook that the Subversion
        repository supports; by examining the contents of those
        template scripts, you can see what triggers each script
        to run and what data is passed to that script.  Also present
        in many of these templates are examples of how one might use
        that script, in conjunction with other Subversion-supplied
        programs, to perform common useful tasks.  To actually install
        a working hook, you need only place some executable program or
        script into the repos/hooks directory,
        which can be executed as the name (such as
        start-commit or
        post-commit) of the hook.
On Unix platforms, this means supplying a script or
        program (which could be a shell script, a Python program, a
        compiled C binary, or any number of other things) named
        exactly like the name of the hook.  Of course, the template
        files are present for more than just informational
        purposes—the easiest way to install a hook on Unix
        platforms is to simply copy the appropriate template file to a
        new file that lacks the .tmpl extension,
        customize the hook's contents, and ensure that the script is
        executable.  Windows, however, uses file extensions to
        determine whether a program is executable, so you would
        need to supply a program whose basename is the name of the
        hook and whose extension is one of the special extensions
        recognized by Windows for executable programs, such as
        .exe for programs and
        .bat for batch files.
| ![[Tip]](images/tip.png)  | Tip | 
|---|---|
| For security reasons, the Subversion repository executes
          hook programs with an empty environment—that is, no
          environment variables are set at all, not even
           | 
Subversion executes hooks as the same user who owns the process that is accessing the Subversion repository. In most cases, the repository is being accessed via a Subversion server, so this user is the same user as whom the server runs on the system. The hooks themselves will need to be configured with OS-level permissions that allow that user to execute them. Also, this means that any programs or files (including the Subversion repository) accessed directly or indirectly by the hook will be accessed as the same user. In other words, be alert to potential permission-related problems that could prevent the hook from performing the tasks it is designed to perform.
There are several hooks implemented by the Subversion repository, and you can get details about each of them in the section called “Repository Hooks” in Chapter 9, Subversion Complete Reference. As a repository administrator, you'll need to decide which hooks you wish to implement (by way of providing an appropriately named and permissioned hook program), and how. When you make this decision, keep in mind the big picture of how your repository is deployed. For example, if you are using server configuration to determine which users are permitted to commit changes to your repository, you don't need to do this sort of access control via the hook system.
There is no shortage of Subversion hook programs and scripts that are freely available either from the Subversion community itself or elsewhere. These scripts cover a wide range of utility—basic access control, policy adherence checking, issue tracker integration, email- or syndication-based commit notification, and beyond. Or, if you wish to write your own, see Chapter 8, Embedding Subversion.
| ![[Warning]](images/warning.png)  | Warning | 
|---|---|
| While hook scripts can do almost
          anything, there is one dimension in which hook script
          authors should show restraint:  do not
          modify a commit transaction using hook scripts.  While it
          might be tempting to use hook scripts to automatically
          correct errors, shortcomings, or policy violations present
          in the files being committed, doing so can cause problems.
          Subversion keeps client-side caches of certain bits of
          repository data, and if you change a commit transaction in
          this way, those caches become indetectably stale.  This
          inconsistency can lead to surprising and unexpected
          behavior.  Instead of modifying the transaction, you should
          simply validate the transaction in the
           | 
A Berkeley DB environment is an encapsulation of one or more databases, logfiles, region files, and configuration files. The Berkeley DB environment has its own set of default configuration values for things such as the number of database locks allowed to be taken out at any given time, the maximum size of the journaling logfiles, and so on. Subversion's filesystem logic additionally chooses default values for some of the Berkeley DB configuration options. However, sometimes your particular repository, with its unique collection of data and access patterns, might require a different set of configuration option values.
The producers of Berkeley DB understand that different
        applications and database environments have different
        requirements, so they have provided a mechanism for overriding
        at runtime many of the configuration values for the Berkeley
        DB environment.  BDB checks for the presence of a file named
        DB_CONFIG in the environment directory
        (namely, the repository's db
        subdirectory), and parses the options found in that file.
        Subversion itself creates this file when it creates the rest
        of the repository.  The file initially contains some default
        options, as well as pointers to the Berkeley DB online
        documentation so that you can read about what those options do.  Of
        course, you are free to add any of the supported Berkeley DB
        options to your DB_CONFIG file.  Just be
        aware that while Subversion never attempts to read or
        interpret the contents of the file and makes no direct use of
        the option settings in it, you'll want to avoid any
        configuration changes that may cause Berkeley DB to behave in
        a fashion that is at odds with what Subversion might expect.
        Also, changes made to DB_CONFIG won't
        take effect until you recover the database environment (using
        svnadmin recover).