blob: 7e541e5a2fe5a0bbdd8a2b79dfb7742300593b16 [file]
@node Getting Started
@chapter Getting Started
How to get started with Subversion.
@menu
* Introduction:: History and overview of features.
* Design:: Overview of system design.
* Installation:: How to obtain Subversion.
* Basics:: Casual description and first-time walk-through.
@end menu
@c ------------------------------------------------------------------
@node Introduction
@section Introduction
@subsection A Revision Control System
Subversion is a free/open-source @dfn{revision control system}.
That is, Subversion manages files over time. The files are placed into
a central @dfn{repository}. The repository is much like an ordinary
file server, except that it remembers every change ever made to your
files. This allows you to recover older versions of your files, or
browse the history of how your files changed. Many people think of
a revision control system as a sort of ``time machine.''
Some revision control systems are also @dfn{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 (such as natively understanding programming
languages). Subversion, however, is not one of these systems; it is a
general system that can be used to manage @emph{any} sort of collection
of files, including source code.
@subsection History
Subversion aims to be the successor to CVS (@uref{http://www.cvshome.org/}).
At the time of writing, CVS is the standard Free revision control system
used by the open-source community. It has a hard-earned, well-deserved
reputation as stable and useful software, and has a design that makes it
perfect for open-source development. However, it also has a number of
problems that are difficult to fix.
Subversion's original designers settled on a few simple goals. First,
it was decided that Subversion should be a functional replacement for
CVS. That is, it should do everything that CVS does, preserving the
same development model while fixing the most obvious flaws. Secondly,
with existing CVS users as the first target audience, Subversion should
be written such that any CVS user should be able to start using it with
little effort.
Collabnet (@uref{http://www.collab.net/}) provided the initial funding
in 2000 to begin development work, and the effort has now blossomed
into a large, open-source project backed by a community of free
software developers.
@subsection Audience
The intended audience of this book is anyone who has used a revision
control system before, although perhaps not Subversion or CVS. It
assumes that the reader is computer-literate, and reasonably
comfortable at a Unix command-line.
People familiar with CVS may want to skip some of the introductory
sections that describe Subversion's concurrent versioning model.
Also, there is a quick guide for CVS users attached as an appendix
(@xref{SVN for CVS users}.)
@subsection Features
What sort of things does Subversion do better than CVS? Here's a short
list to whet your appetite:
@itemize @bullet
@item
@b{Directory versioning} The Subversion repository doesn't use RCS files
like CVS; instead, it implements a ``virtual'' versioned filesystem that
tracks changes to directory/file heirarchies over time. Files
@emph{and} directories are versioned. At last, there are real
client-side `move' and `copy' commands.
@item
@b{Atomic commits} A commit either goes into the repository
completely, or not all.
@item
@b{Advanced network layer} The Subversion network server is Apache,
and client and server speak WebDAV protocol to one another. (see
@ref{Design})
@item
@b{Faster network access} A binary diffing algorithm is used to store
and transmit deltas in both directions, regardless of whether a file
is of text or binary type.
@item
@b{Meta-data} Each file or directory has an invisible hash table
attached. You can invent and store any arbitrary key/value pairs you
wish: owner, perms, icons, app-creator, mime-type, personal notes,
etc. This is a general-purpose feature for users. Properties are
versioned over time, just like file contents.
@item
@b{Hackability} Subversion has no historical baggage; it is primarily
a collection of shared C libraries with well-defined APIs. This makes
Subversion extremely maintainable and usable by other applications and
languages.
@end itemize
@c ------------------------------------------------------------------
@node Design
@section Design
Subversion has a modular design; it's implemented as a collection of C
libraries. Each layer has a well-defined purpose and interface.
If you aren't interested in how Subversion works under the hood, feel
free to skip this section and move on to @ref{Installation} and
@ref{Basics}.
Here's a helpful diagram of Subversion's layers. Program flow begins at
the top of the diagram (initiated by the user) and flows ``downward.''
@c ### Insert Fitz's nicer TIFF graphic here? Perhaps use that
@c graphic for dvi or html output, but use the ASCII diagram for info
@c output? We'll need texinfo conditionals for that.
@example
@group
+--------------------+
| commandline or GUI |
| client app |
+----------+--------------------+----------+ <=== Client interface
| Client Library |
| |
| +----+ |
| | | |
+-------+--------+ +--------------+--+----------+ <=== Network interface
| Working Copy | | Remote | | Local |
| Management lib | | Repos Access | | Repos |
+----------------+ +--------------+ | Access |
| neon | | |
+--------------+ | |
^ | |
/ | |
DAV / | |
/ | |
v | |
+---------+ | |
| | | |
| Apache | | |
| | | |
+---------+ | |
| mod_DAV | | |
+-------------+ | |
| mod_DAV_SVN | | |
+----------+-------------+--------------+----------+ <=== Filesystem interface
| |
| Subversion Filesystem |
| |
+--------------------------------------------------+
@end group
@end example
@subsection Filesystem
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. It is implemented as library which exports a C
API that simulates a filesystem -- specifically, a ``versioned''
filesystem -- but uses a database system for the back-end storage
mechanism.
This means that writing a program to access the repository is like
writing against other filesystem APIs: you can open files and
directories for reading and writing as usual. The main difference is
that this particular filesystem never loses data when written to; old
versions of files and directories are always saved as historical
artifacts.
Currently, the database system in use is BerkeleyDB, which provides
other nice features that Subversion needs: data integrity, atomic
writes, recoverability, and hot backups.
@subsection Network Layer
Subversion has the mark of Apache all over it. At its very core, the
client uses the Apache Portable Runtime (APR) library. This means that
the Subversion client compiles and runs anywhere Apache httpd does --
right now, this list includes all flavors of Unix, Win32, BeOS, OS/2,
Mac OS X, and possibly Netware.
However, Subversion depends on more than just APR -- the Subversion
"server" is Apache httpd itself. Apache httpd is a time-tested,
extensible open-source server process that is ready for serious use. It
can sustain a high network load, runs on many platforms, and can operate
through firewalls. It can use a number of different authentication
protocols and do network pipelining and caching. By using Apache as a
server, Subversion gets all these features for free.
Subversion uses WebDAV as its network protocol. DAV (Distributed
Authoring and Versioning) is a whole discussion in itself (see
@uref{http://www.webdav.org/}) -- but in short, it's an extension to
HTTP that allows reads/writes and ``versioning'' of files over the web.
The Subversion project is hoping to ride a slowly rising tide of
support for this protocol: all of the latest file-browsers for Win32,
MacOS, and GNOME speak this protocol already. Interoperability will
(hopefully) become more and more of a boon over time.
For users who simply wish to access Subversion repositories on their
local disk, the client can do this too; no network is required. The
"Repository Access" layer (RA) is an abstract API implemented by both
the DAV and local-access RA libraries. This is a specific benefit of
writing a ``librarized'' revision control system -- if you feel like
writing a new network protocol for Subversion, just write a new library
that implements the RA API.
@subsection Client Libraries
On the client side, the Subversion ``working copy'' library maintains
administrative information within special .svn subdirectories, similar
in purpose to the CVS administrative directories found in CVS working
copies.
A glance inside the typical .svn directory turns up a bit more than what
CVS maintains in its administrative directories, however.
The `entries' file contains XML which describes
the current state of the working copy directory (and which basically
serves the purposes of CVS's Entries, Root, and Repository files
combined). But other items present (and not found in CVS) include
storage locations for the versioned ``properties'' (the metadata
mentioned in ``Subversion Features'' above) and private caches of
pristine versions of each file. This latter feature provides the
ability to report local modifications -- and do reversions --
@emph{without} network access. Authentication data is also stored
within .svn/, rather than in a single .cvspass-like file.
The Subversion ``client'' library has the broadest responsibility; its job
is to mingle the functionality of the working-copy library with that of
the repository-access library, and then to provide a highest-level API
to any application that wishes to perform general revision control
actions.@footnote{For example: the C routine `svn_client_checkout()'
takes a URL as an argument. It passes this URL to the repository-access
library 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.)}
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.
@c ------------------------------------------------------------------
@node Installation
@section Installation
### Somebody please write this. It should describe how to fetch various
binary packages of Subversion for different platforms. Maybe this
will flesh out once RPMs, .debs, and BSD ports are widely available
from standard locations?
To build from source code, @xref{Compiling and installing}.
@c ------------------------------------------------------------------
@node Basics
@section Basics
If you're an existing CVS user, then the first section, @ref{The
Subversion Development Model}, should already be familiar. You may just
want to skim it quickly, noting the special definition of ``Revision'' in
the second subsection. At some point, you should probably also read the
appendix which describes fundamental differences between CVS and SVN
(@xref{SVN for CVS users}.)
@menu
* The Subversion Development Model::
* Quick Walkthrough::
@end menu
@node The Subversion Development Model
@subsection The Subversion Development Model
@menu
* Working Directories and Repositories::
* Transactions and Revision Numbers::
* How Working Directories Track the Repository::
* Subversion Does Not Lock Files::
@end menu
@node Working Directories and Repositories
@subsubsection Working Directories and Repositories
Suppose you are using Subversion to manage a software project. There
are two things you will interact with: your working directory, and the
repository.
Your @dfn{working directory} is an ordinary directory tree, on your
local system, containing your project's sources. You can edit these
files and compile your program from them in the usual way. Your working
directory is your own private work area: Subversion never changes the
files in your working directory, or publishes the changes you make
there, until you explicitly tell it to do so.
After you've made some changes to the files in your working directory,
and verified that they work properly, Subversion provides commands to
publish your changes to the other people working with you on your
project. If they publish their own changes, Subversion provides
commands to incorporate those changes into your working directory.
A working directory contains some extra files, created and maintained by
Subversion, to help it carry out these commands. In particular, these
files help Subversion recognize which files contain unpublished changes,
and which files are out-of-date with respect to others' work.
While your working directory is for your use alone, the @dfn{repository}
is the common public record you share with everyone else working on the
project. To publish your changes, you use Subversion to put them in the
repository. (What this means, exactly, we explain below.) Once your
changes are in the repository, others can tell Subversion to incorporate
your changes into their working directories. In a collaborative
environment like this, each user will typically have their own working
directory (or perhaps more than one), and all the working directories
will be backed by a single repository, shared amongst all the users.
A Subversion repository holds a single directory tree, and records the
history of changes to that tree. The repository retains enough
information to recreate any prior state of the tree, compute the
differences between any two prior trees, and report the relations
between files in the tree --- which files are derived from which other
files.
A Subversion repository can hold the source code for several projects;
usually, each project is a subdirectory in the tree. In this
arrangement, a working directory will usually correspond to a particular
subtree of the repository.
For example, suppose you have a repository laid out like this:
@example
/trunk/paint/Makefile
canvas.c
brush.c
write/Makefile
document.c
search.c
@end example
In other words, the repository's root directory has a single
subdirectory named @file{trunk}, which itself contains two
subdirectories: @file{paint} and @file{write}.
To get a working directory, you must @dfn{check out} some subtree of the
repository. If you check out @file{/trunk/write}, you will get a working
directory like this:
@example
write/Makefile
document.c
search.c
.svn/
@end example
This working directory is a copy of the repository's @file{/trunk/write}
directory, with one additional entry --- @file{.svn} --- which holds the
extra information needed by Subversion, as mentioned above.
Suppose you make changes to @file{search.c}. Since the @file{.svn}
directory remembers the file's modification date and original contents,
Subversion can tell that you've changed the file. However, Subversion
does not make your changes public until you explicitly tell it to.
To publish your changes, you can use Subversion's @samp{commit} command:
@example
$ pwd
/home/jimb/write
$ ls -a
.svn/ Makefile document.c search.c
$ svn commit search.c
$
@end example
Now your changes to @file{search.c} have been committed to the
repository; if another user checks out a working copy of
@file{/trunk/write}, they will see your text.
Suppose you have a collaborator, Felix, who checked out a working
directory of @file{/trunk/write} at the same time you did. When you
commit your change to @file{search.c}, Felix's working copy is left
unchanged; Subversion only modifies working directories at the user's
request.
To bring his working directory up to date, Felix can use the Subversion
@samp{update} command. This will incorporate your changes into his
working directory, as well as any others that have been committed since
he checked it out.
@example
$ pwd
/home/felix/write
$ ls -a
.svn/ Makefile document.c search.c
$ svn update
U search.c
$
@end example
The output from the @samp{svn update} command indicates that Subversion
updated the contents of @file{search.c}. Note that Felix didn't need to
specify which files to update; Subversion uses the information in the
@file{.svn} directory, and further information in the repository, to
decide which files need to be brought up to date.
We explain below what happens when both you and Felix make changes to
the same file.
@node Transactions and Revision Numbers
@subsubsection Transactions and Revision Numbers
A Subversion @samp{commit} operation can publish changes to any number
of files and directories as a single atomic transaction. In your
working directory, you can change files' contents, create, delete,
rename and copy files and directories, and then commit the completed set
of changes as a unit.
In the repository, each commit is treated as an atomic transaction:
either all the commit's changes take place, or none of them take place.
Subversion tries to retain this atomicity in the face of program
crashes, system crashes, network problems, and other users' actions. We
may call a commit a @dfn{transaction} when we want to emphasize its
indivisible nature.
Each time the repository accepts a transaction, this creates a new state
of the tree, called a @dfn{revision}. Each revision is assigned a unique
natural number, one greater than the number of the previous revision.
The initial revision of a freshly created repository is numbered zero,
and consists of an empty root directory.
Unlike those of many other systems, Subversion's revision numbers apply
to an entire tree, not individual files. Each revision number selects an
entire tree.
It's important to note that working directories do not always correspond
to any single revision in the repository; they may contain files from
several different revisions. For example, suppose you check out a
working directory from a repository whose most recent revision is 4:
@example
write/Makefile:4
document.c:4
search.c:4
@end example
At the moment, this working directory corresponds exactly to revision 4
in the repository. However, suppose you make a change to
@file{search.c}, and commit that change. Assuming no other commits have
taken place, your commit will create revision 5 of the repository, and
your working directory will look like this:
@example
write/Makefile:4
document.c:4
search.c:5
@end example
Suppose that, at this point, Felix commits a change to
@file{document.c}, creating revision 6. If you use @samp{svn update} to
bring your working directory up to date, then it will look like this:
@example
write/Makefile:6
document.c:6
search.c:6
@end example
Felix's changes to @file{document.c} will appear in your working copy of
that file, and your change will still be present in @file{search.c}. In
this example, the text of @file{Makefile} is identical in revisions 4, 5,
and 6, but Subversion will mark your working copy with revision 6 to
indicate that it is still current. So, after you do a clean update at
the root of your working directory, your working directory will
generally correspond exactly to some revision in the repository.
@node How Working Directories Track the Repository
@subsubsection How Working Directories Track the Repository
For each file in a working directory, Subversion records two essential
pieces of information:
@itemize @bullet
@item
what revision of what repository file your working copy is based on
(this is called the file's @dfn{working revision}), and
@item
a timestamp recording when the local copy was last updated by the repository.
@end itemize
Given this information, by talking to the repository, Subversion can
tell which of the following four states a file is in:
@itemize @bullet
@item
@b{Unchanged, and current.} The file is unchanged in the working
directory, and no changes to that file have been committed to the
repository since its base revision.
@item
@b{Locally changed, and current}. The file has been changed in the
working directory, and no changes to that file have been committed to
the repository since its base revision. There are local changes that
have not been committed to the repository.
@item
@b{Unchanged, and out-of-date}. The file has not been changed in the
working directory, but it has been changed in the repository. The file
should eventually be updated, to make it current with the public
revision.
@item
@b{Locally changed, and out-of-date}. The file has been changed both
in the working directory, and in the repository. The file should be
updated; Subversion will attempt to merge the public changes with the
local changes. If it can't complete the merge in a plausible way
automatically, Subversion leaves it to the user to resolve the conflict.
@end itemize
The subversion @samp{status} command will show you the state of any item in
your working copy. @xref{Basic Work Cycle}, in particular the
subsection ``Examine your changes''.
@node Subversion Does Not Lock Files
@subsubsection Subversion Does Not Lock Files
Subversion does not prevent two users from making changes to the same
file at the same time. For example, if both you and Felix have checked
out working directories of @file{/trunk/write}, Subversion will allow
both of you to change @file{write/search.c} in your working directories.
Then, the following sequence of events will occur:
@itemize @bullet
@item
Suppose Felix tries to commit his changes to @file{search.c} first. His
commit will succeed, and his text will appear in the latest revision in
the repository.
@item
When you attempt to commit your changes to @file{search.c}, Subversion
will reject your commit, and tell you that you must update
@file{search.c} before you can commit it.
@item
When you update @file{search.c}, Subversion will try to merge Felix's
changes from the repository with your local changes. By default,
Subversion merges as if it were applying a patch: if your local changes
do not overlap textually with Felix's, then all is well; otherwise,
Subversion leaves it to you to resolve the overlapping
changes. In either case,
Subversion carefully preserves a copy of the original pre-merge text.
@item
Once you have verified that Felix's changes and your changes have been
merged correctly, you can commit the new revision of @file{search.c},
which now contains everyone's changes.
@end itemize
Some revision control systems provide ``locks'', which prevent others
from changing a file once one person has begun working on it. In our
experience, merging is preferable to locks, because:
@itemize @bullet
@item
changes usually do not conflict, so Subversion's behavior does the right
thing by default, while locking can interfere with legitimate work;
@item
locking can prevent conflicts within a file, but not conflicts between
files (say, between a C header file and another file that includes it),
so it doesn't really solve the problem; and finally,
@item
people often forget that they are holding locks, resulting in
unnecessary delays and friction.
@end itemize
Of course, the merge process needs to be under the users' control.
Contextual, line-by-line patching is not appropriate for files with
rigid formats, like images or executables. Subversion attempts to
notice when a file is in a binary format, or is of any mime-type other
than text/*. For these rigid-format files, Subversion simply presents
you with the two original texts to choose from. @xref{Basic Work
Cycle}, in particular the subsection ``Merge others' changes''.
@c ------------------------------------
@node Quick Walkthrough
@subsection Quick Walkthrough
The previous section gave an abstract overview of the Subversion
development model. Here's an opportunity to play with Subversion in
some hands-on examples. The Subversion commands demoed here are just
small examples of what Subversion can do; see Chapter 2 for full
explanations of each.
@menu
* Make a repository::
* Make some working copies::
@end menu
@node Make a repository
@subsubsection Make a repository
The Subversion client has an abstract interface for accessing a
repository. Two ``Repository Access'' (RA) implementations currently
exist as libraries. You can see which methods are available to your svn
client like so:
@example
$ svn --version
Subversion Client, version N
compiled Jan 26 2002, 16:43:58
Copyright (C) 2000-2002 CollabNet.
Subversion is open source software, see @uref{http://subversion.tigris.org/}
The following repository access (RA) modules are available:
* ra_dav : Module for accessing a repository via WebDAV (DeltaV) protocol.
- handles 'http' schema
* ra_local : Module for accessing a repository on local disk.
- handles 'file' schema
@end example
If you don't see ra_local, it probably means that Berkeley DB (or
relevant database back-end) wasn't found when compiling your client
binary. To continue with these examples, you'll need to have ra_local
available.
Start by creating a new, empty repository using the @command{svnadmin}
tool:
@example
$ svnadmin create myrepos
@end example
Let's assume you have a directory @file{someproject} which contains
files that you wish to place under version control:
@example
someproject/foo
bar
baz/
baz/gloo
baz/bloo
@end example
Once the repository exists, you can initially import your data into it,
using the ra_local access method (invoked by using a ``file'' URL):
@example
$ svn import file:///absolute/path/to/myrepos someproject myproj
@dots{}
Committed revision 1.
@end example
The example above creates a new directory @file{myproj} in the root of
the repository's filesystem, and copies all the data from
@file{someproject} into it.
@node Make some working copies
@subsubsection Make some working copies
Now check out a fresh ``working copy'' of your project. To do this, we
specify a URL to the exact directory within the repository that we want.
The parameter after the URL allows us to name the working copy we check out.
@example
$ svn co file:///usr/local/svn/repos/myproj wc
A wc/foo
A wc/bar
A wc/baz
A wc/baz/gloo
A wc/baz/bloo
@end example
Now we have a working copy in a local directory called @file{wc}, which
represents the location @file{/myproj} in the repository (assuming the
repository's root is @url{file:///usr/local/svn/repos}.)
For the sake of example, let's duplicate the working copy, and pretend
it belongs to someone else:
@example
$ cp -R wc wc2
@end example
From here, let's make some changes within our original working copy:
@example
$ cd wc
$ echo "new text" >> bar # change bar's text
$ svn propset color green foo # add a metadata property to foo
$ svn rm baz # schedule baz directory for deletion
$ touch newfile
$ svn add newfile # schedule newfile for addition
@end example
That's a lot of changes! If we were to leave and come back tomorrow,
how could we remember what changes we'd made? Easy. The @samp{status}
command will show us all of the ``local modifications'' in our working
copy:
@example
$ svn status # See what's locally modified
M ./bar
_M ./foo
A ./newfile
D ./baz
D ./baz/gloo
D ./baz/bloo
@end example
According to this output, three items are scheduled to be (D)eleted from
the repository, one item is scheduled to be (A)dded to the repository,
and two items have had their contents (M)odified in some way. For more
details, be sure to read about @command{svn status} in Chapter 2.
Now we decide to commit our changes, creating Revision 2 in the
repository:
@example
$ svn commit -m "fixed bug #233"
Sending bar
Sending foo
Adding newfile
Deleting baz
Transmitting data...
Committed revision 2.
@end example
The -m argument is a way of specifying a @dfn{log message}: that is, a
specific description of your change-set sent to the repository. The log
message is now attached to Revision 2. A future user might peruse
repository log messages, and now will know what your Revision 2 changes
were for.
Finally, pretend that you are now Felix, or some other collaborator. If
you go @file{wc2} (that other working copy you made), it will need the
@samp{svn update} command to receive the Revision 2 changes:
@example
$ cd ../wc2 # change to the back-up working copy
$ svn update # get changes from repository
U ./bar
_U ./foo
A ./newfile
D ./baz
@end example
The output of the @samp{svn update} command tells Felix that baz was
(D)eleted from his working copy, newfile was (A)dded to his working
copy, and that bar and foo had their contents (U)pdated.
If for some reason @file{bar} contained some local changes made by
Felix, then the server changes would be @dfn{merged} into @file{bar}:
that is, @file{bar} would now contain both sets of changes. Whenever
server changes are merged into a locally-modified file, two possible
things can happen:
@itemize @bullet
@item
The merge can go smoothly. That is, the two sets of changes do not
overlap. In this case, @samp{svn update} prints a @samp{G} (``mer(G)ed'').
@item
The sets of changes overlap, and a @samp{C} for (C)onflict is printed. See
section ??? for information about how conflict resolution works.
@end itemize