<chapter id="svn-ch-1">

  <title>Introduction</title>

  <simplesect>
    <para>Version control is the art of managing changes to
      information.  It has long been a critical tool for programmers,
      who typically spend their time making small changes to software
      and then undoing those changes the next day.  But the usefulness
      of version control software extends far beyond the bounds of the
      software development world.  Anywhere you can find people using
      computers to manage information that changes often, there is
      room for version control.  And that's where Subversion comes
      into play.</para>

    <para>This chapter contains a high-level introduction to
      Subversion&mdash;what it is; what it does; how to get it.</para>

  </simplesect>


  <!-- ================================================================= -->
  <!-- ======================== SECTION 1 ============================== -->
  <!-- ================================================================= -->
  <sect1 id="svn-ch-1-sect-1">

    <title>What is Subversion?</title>
      
    <para>Subversion is a free/open-source version control system.
      That is, Subversion manages files and directories over time.  A
      tree of files is placed into a central
      <firstterm>repository</firstterm>.  The repository is much like
      an ordinary file server, except that it remembers every change
      ever made to your files and directories.  This allows you to
      recover older versions of your data, or examine the history of
      how your data changed.  In this regard, many people think of a
      version control system as a sort of <quote>time
      machine</quote>.</para>
    
    <para>Subversion can access its repository across networks, which
      allows it to be used by people on different computers.  At some
      level, the ability for various people to modify and manage the
      same set of data from their respective locations fosters
      collaboration.  Progress can occur more quickly without a single
      conduit through which all modifications must occur.  And because
      the work is versioned, you need not fear that quality is the
      trade-off for losing that conduit&mdash;if some incorrect change
      is made to the data, just undo that change.</para>

    <para>Some version control systems are also software configuration
      management (SCM) systems.  These systems are specifically
      tailored to manage trees of source code, and have many features
      that are specific to software development&mdash;such as natively
      understanding programming languages, or supplying tools for
      building software.  Subversion, however, is not one of these
      systems.  It is a general system that can be used to manage
      <emphasis>any</emphasis> collection of files.  For you, those
      files might be source code&mdash;for others, anything from
      grocery shopping lists to digital video mixdowns and
      beyond.</para>

  </sect1>

  <!-- ================================================================= -->
  <!-- ======================== SECTION 2 ============================== -->
  <!-- ================================================================= -->
  <sect1 id="svn-ch-1-sect-2">

    <title>Subversion's History</title>

    <para>In early 2000, CollabNet, Inc. (<systemitem
      class="url">http://www.collab.net</systemitem>) began seeking
      developers to write a replacement for CVS.  CollabNet offers a
      collaboration software suite called SourceCast, of which one
      component is version control.  Although SourceCast used CVS as
      its initial version control system, CVS's limitations were
      obvious from the beginning, and CollabNet knew it would
      eventually have to find something better.  Unfortunately, CVS
      had become the <foreignphrase>de facto</foreignphrase> standard
      in the open source world largely because there
      <emphasis>wasn't</emphasis> anything better, at least not under
      a free license.  So CollabNet determined to write a new version
      control system from scratch, retaining the basic ideas of CVS,
      but without the bugs and misfeatures.</para>

    <para>In February 2000, they contacted Karl Fogel, the author of
      <citetitle>Open Source Development with CVS</citetitle>
      (Coriolis, 1999), and asked if he'd like to work on this new
      project.  Coincidentally, at the time Karl was already
      discussing a design for a new version control system with his
      friend Jim Blandy.  In 1995, the two had started Cyclic
      Software, a company providing CVS support contracts, and
      although they later sold the business, they still used CVS every
      day at their jobs.  Their frustration with CVS had led Jim to
      think carefully about better ways to manage versioned data, and
      he'd already come up with not only the name
      <quote>Subversion</quote>, but also with the basic design of the
      Subversion repository.  When CollabNet called, Karl immediately
      agreed to work on the project, and Jim got his employer, RedHat
      Software, to essentially donate him to the project for an
      indefinite period of time.  CollabNet hired Karl and Ben
      Collins-Sussman, and detailed design work began in May.  With
      the help of some well-placed prods from Brian Behlendorf and
      Jason Robbins of CollabNet, and Greg Stein (at the time an
      independent developer active in the WebDAV/DeltaV specification
      process), Subversion quickly attracted a community of active
      developers.  It turned out that many people had had the same
      frustrating experiences with CVS, and welcomed the chance to
      finally do something about it.</para>

    <para>The original design team settled on some simple goals.  They
      didn't want to break new ground in version control methodology,
      they just wanted to fix CVS.  They decided that Subversion would
      match CVS's features, and preserve the same development model,
      but not duplicate CVS's most obvious flaws.  And although it did
      not need to be a drop-in replacement for CVS, it should be
      similar enough that any CVS user could make the switch with
      little effort.</para>

    <para>After fourteen months of coding, Subversion became
      <quote>self-hosting</quote> on August 31, 2001.  That is,
      Subversion developers stopped using CVS to manage Subversion's
      own source code, and started using Subversion instead.</para>

    <para>While CollabNet started the project, and still funds a large
      chunk of the work (it pays the salaries of a few full-time
      Subversion developers), Subversion is run like most open-source
      projects, governed by a loose, transparent set of rules that
      encourage meritocracy.  CollabNet's copyright license is fully
      compliant with the Debian Free Software Guidelines.  In other
      words, anyone is free to download, modify, and redistribute
      Subversion as he pleases; no permission from CollabNet or anyone
      else is required.</para>

  </sect1>

  <!-- ================================================================= -->
  <!-- ======================== SECTION 3 ============================== -->
  <!-- ================================================================= -->
  <sect1 id="svn-ch-1-sect-3">

    <title>Subversion's Features</title>

    <para>When discussing the features that Subversion brings to the
      version control table, it is often helpful to speak of them in
      terms of how they improve upon CVS's design.  If you're not
      familiar with CVS, you may not understand all of these features.
      And if you're not familiar with version control at all, your
      eyes may glaze over unless you first read <xref
      linkend="svn-ch-2"/>, in which we provide a gentle introduction
      to version control in general.</para>

    <para>Subversion provides:</para>

    <variablelist>
      <varlistentry>
        <term>Directory versioning</term>
        <listitem>
          <para>CVS only tracks the history of individual files, but
            Subversion implements a <quote>virtual</quote> versioned
            filesystem that tracks changes to whole directory trees
            over time.  Files <emphasis>and</emphasis> directories are
            versioned.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>True version history</term>
        <listitem>
          <para>Since CVS is limited to file versioning, operations
            such as copies and renames&mdash;which might happen to
            files, but which are really changes to the contents of
            some containing directory&mdash;aren't supported in CVS.
            Additionally, in CVS you cannot replace a versioned file
            with some new thing of the same name without the new item
            inheriting the history of the old&mdash;perhaps completely
            unrelated&mdash; file.  With Subversion, you can add,
            delete, copy, and rename both files and directories.  And
            every newly added file begins with a fresh, clean
            history all its own.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Atomic commits</term>
        <listitem>
          <para>A collection of modifications either goes into the
            repository completely, or not at all.  This allows
            developers to construct and commit changes as logical
            chunks, and prevents problems that can occur when only a
            portion of a set of changes is successfully sent to the
            repository.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Versioned metadata</term>
        <listitem>
          <para>Each file and directory has a set of
            properties&mdash;keys and their values&mdash; associated
            with it.  You can create and store any arbitrary key/value
            pairs you wish.  Properties are versioned over time, just
            like file contents.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Choice of network layers</term>
        <listitem>
          <para>Subversion has an abstracted notion of repository
            access, making it easy for people to implement new network
            mechanisms.  Subversion can plug into the Apache HTTP
            Server as an extension module.  This gives Subversion a
            big advantage in stability and interoperability, and
            instant access to existing features provided by that
            server&mdash;authentication, authorization, wire
            compression, and so on.  A more lightweight, standalone
            Subversion server process is also available.  This server
            speaks a custom protocol which can be easily tunneled over
            SSH.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Consistent data handling</term>
        <listitem>
          <para>Subversion expresses file differences using a binary
            differencing algorithm, which works identically on both
            text (human-readable) and binary (human-unreadable) files.
            Both types of files are stored equally compressed in the
            repository, and differences are transmitted in both
            directions across the network.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Efficient branching and tagging</term>
        <listitem>
          <para>
            The cost of branching and tagging need not be proportional to the
            project size.  Subversion creates branches and tags by
            simply copying the project, using a mechanism similar to a
            hard-link.  Thus these operations take only a very small,
            constant amount of time.
          </para>
        </listitem>
      </varlistentry>
      
      <varlistentry>
        <term>Hackability</term>
        <listitem>
          <para>Subversion has no historical baggage; it is
            implemented as a collection of shared C libraries with
            well-defined APIs.  This makes Subversion extremely
            maintainable and usable by other applications and
            languages.</para>
        </listitem>
      </varlistentry>

    </variablelist>

  </sect1>

  <!-- ================================================================= -->
  <!-- ======================== SECTION 4 ============================== -->
  <!-- ================================================================= -->
  <sect1 id="svn-ch-1-sect-4">

    <title>Subversion's Architecture</title>

    <para><xref linkend="svn-ch-1-dia-1"/> illustrates what one might
      call a <quote>mile-high</quote> view of Subversion's
      design.</para>
    
    <figure id="svn-ch-1-dia-1">
      <title>Subversion's Architecture</title>
      <graphic fileref="images/ch01dia1.png"/>
    </figure>

    <para>On one end is a Subversion repository that holds all of your
      versioned data.  On the other end is your Subversion client
      program, which manages local reflections of portions of that
      versioned data (called <quote>working copies</quote>).  Between
      these extremes are multiple routes through various Repository
      Access (RA) layers.  Some of these routes go across computer
      networks and through network servers which then access the
      repository.  Others bypass the network altogether and access the
      repository directly.</para>

  </sect1>

  <!-- ================================================================= -->
  <!-- ======================== SECTION 5 ============================== -->
  <!-- ================================================================= -->
  <sect1 id="svn-ch-1-sect-5">

    <title>Installing Subversion</title>

    <para>Subversion is built on a portability layer called APR (the
      Apache Portable Runtime library).  This means Subversion should
      work on any operating system that the Apache httpd server runs
      on: Windows, Linux, all flavors of BSD, Mac OS X, Netware, and
      others.</para>

    <para>The easiest way to get Subversion is to download a binary
      package built for your operating system.  Subversion's website
      (<systemitem
      class="url">http://subversion.tigris.org</systemitem>) often has
      these packages available for download, posted by volunteers.
      The site usually contains graphical installer packages for users
      of Microsoft operating systems.  If you run a Unix-like
      operating system, you can use your system's native package
      distribution system (RPMs, DEBs, the ports tree, etc.) to get
      Subversion.</para>

    <para>Alternately, you can build Subversion directly from source
      code.  From the Subversion website, download the latest
      source-code release.  After unpacking it, follow the
      instructions in the <filename>INSTALL</filename> file to build
      it.  Note that a released source package contains everything you
      need to build a command-line client capable of talking to a
      remote repository (in particular, the apr, apr-util, and neon
      libraries).  But optional portions of Subversion have many other
      dependencies, such as Berkeley DB and possibly Apache httpd.  If
      you want to do a complete build, make sure you have all of the
      packages documented in the <filename>INSTALL</filename> file.
      If you plan to work on Subversion itself, you can use your
      client program to grab the latest, bleeding-edge source code.
      This is documented in <xref
      linkend="svn-ch-8-sect-6.2"/>.</para>

  </sect1>

  <!-- ================================================================= -->
  <!-- ======================== SECTION 6 ============================== -->
  <!-- ================================================================= -->
  <sect1 id="svn-ch-1-sect-6">

    <title>Subversion's Components</title>
    
    <para>Subversion, once installed, has a number of different
      pieces.  The following is a quick overview of what you get.
      Don't be alarmed if the brief descriptions leave you scratching
      your head&mdash;there are <emphasis>plenty</emphasis> more pages
      in this book devoted to alleviating that confusion.</para>

    <variablelist>
      <varlistentry>
        <term>svn</term>
        <listitem>
          <para>The command-line client program.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>svnversion</term>
        <listitem>
          <para>A program for reporting the state (in terms of
            revisions of the items present) of a working copy.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>svnlook</term>
        <listitem>
          <para>A tool for inspecting a Subversion repository.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>svnadmin</term>
        <listitem>
          <para>A tool for creating, tweaking or repairing a Subversion
            repository.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>svndumpfilter</term>
        <listitem>
          <para>A program for filtering Subversion repository dumpfile
            format streams.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>mod_dav_svn</term>
        <listitem>
          <para>A plug-in module for the Apache HTTP Server, used to
            make your repository available to others over a
            network.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>svnserve</term>
        <listitem>
          <para>A custom standalone server program, runnable as a
            daemon process or invokable by SSH; another way to make
            your repository available to others over a network.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>Assuming you have Subversion installed correctly, you should
      be ready to start.  The next two chapters will walk you through
      the use of <command>svn</command>, Subversion's command-line client 
      program.</para>

  </sect1>


  <!-- ================================================================= -->
  <!-- ======================== SECTION 7 ============================== -->
  <!-- ================================================================= -->
  <sect1 id="svn-ch-1-sect-7">

    <title>A Quick Start</title>
    
    <para>Some people have trouble absorbing a new technology by
      reading the sort of "top down" approach provided by this book.
      This section is a very short introduction to Subversion, and is
      designed to give "bottom up" learners a fighting chance.  If
      you're one of those folks who prefers to learn by
      experimentation, the following demonstration will get you up and
      running.  Along the way, we give links to the relevant chapters
      of this book.</para>

    <para>If you're new to the entire concept of version control or to
      the <quote>copy-modify-merge</quote> model used by both CVS and
      Subversion, then you should read <xref linkend="svn-ch-2"/>
      before going any further.</para>

    <note>
      <para>The following example assumes that you have
      <command>svn</command>, the Subversion commandline client, and
      <command>svnadmin</command>, the administrative tool, ready to
      go.  It also assumes that your <command>svn</command> client has
      been compiled against Berkeley DB.  To verify this, run
      <command>svn --version</command> and make sure the
      <literal>ra_local</literal> module is available.  Without this
      module, the client cannot access <literal>file://</literal>
      URLs.</para>
    </note>

    <para>Subversion stores all versioned data in a central
    repository.  To begin, create a new repository:</para>

    <screen>
$ svnadmin create /path/to/repos
$ ls /path/to/repos
conf/  dav/  db/  format  hooks/  locks/  README.txt
</screen>

    <para>This command creates a new directory
    <filename>/path/to/repos</filename> which contains a Subversion
    repository.  Make sure that this directory lives on a local disk,
    <emphasis>not</emphasis> a network share.  This new directory
    mainly contains a collection of Berkeley DB database files.  You
    won't see your versioned files if you peek inside.  For more
    information about repository creation and maintenance, see <xref
    linkend="svn-ch-5"/>.</para>

    <para>Next, create a tree of files and directories to import into
    the repository.  For reasons that will be clear later on (see
    <xref linkend="svn-ch-4"/>), your structure should contain three
    top-level directories named <filename>branches</filename>,
    <filename>tags</filename>, and <filename>trunk</filename>:</para>

    <screen>
/tmp/project/branches/
/tmp/project/tags/
/tmp/project/trunk/
               foo.c
               bar.c
               Makefile
               &hellip;
</screen>

    <para>Once you have a tree of data ready to go, import the data
    into the repository with the <command>svn import</command>
    command (see <xref linkend="svn-ch-3-sect-7.3"/>):</para>

    <screen>
$ svn import /tmp/project file:///path/to/repos -m "initial import"
Adding         /tmp/project/branches
Adding         /tmp/project/tags
Adding         /tmp/project/trunk
Adding         /tmp/project/trunk/foo.c
Adding         /tmp/project/trunk/bar.c
Adding         /tmp/project/trunk/Makefile
&hellip;
Committed revision 1.
$ 
</screen>

    <para>Now the repository contains this tree of data.  Note that
      the original <filename>/tmp/project</filename> directory is
      unchanged; Subversion is unaware of it.  (In fact, you can even
      delete that directory if you wish.)  In order to start
      manipulating repository data, you need to create a new
      <quote>working copy</quote> of the data, a sort of private
      workspace.  Ask Subversion to <quote>check out</quote> a working
      copy of the repository's <filename>trunk</filename>
      directory:</para>

    <screen>
$ svn checkout file:///path/to/repos/trunk project
A  project/foo.c
A  project/bar.c
A  project/Makefile
&hellip;
Checked out revision 1.
</screen>

    <para>Now you have a personal copy of part of the repository in a
      new directory named <filename>project</filename>.  You can edit
      the files in your working copy and then commit those changes
      back into the repository.</para>

    <itemizedlist>
      <listitem><para>Enter your working copy and edit a
      file's contents.</para></listitem>
      <listitem><para>Run <command>svn diff</command> to see unified
      diff output of your changes.</para></listitem>
      <listitem><para>Run <command>svn commit</command> to commit the
      new version of your file to the repository.</para></listitem>
      <listitem><para>Run <command>svn update</command> to bring your
      working copy <quote>up-to-date</quote> with the repository.
      </para></listitem>
    </itemizedlist>

    <para>For a full tour of all the things you can do with your
      working copy, read <xref linkend="svn-ch-3"/>.</para>

    <para>At this point, you have the option of making your repository
      available to others over a network.  See <xref
      linkend="svn-ch-6"/> to learn about the different sorts of
      server processes available and how to configure them.</para>

  </sect1>


</chapter>

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