@node Goals
@chapter Goals

The goal of the Subversion project is to write a version control system
that takes over CVS's current and future user base @footnote{If you're
not familiar with CVS or its shortcomings, then skip to
@ref{Model}}. The first release has all the major features of CVS, plus
certain new features that CVS users often wish they had.  In general,
Subversion works like CVS, except where there's a compelling reason to
be different.

So what does Subversion have that CVS doesn't?

@itemize @bullet
@item
It versions directories, file-metadata, renames, copies and
removals/resurrections.  In other words, Subversion records the changes
users make to directory trees, not just changes to file contents.

@item
Tagging and branching are constant-time and constant-space.

@item
It is natively client-server, hence much more maintainable than CVS.
(In CVS, the client-server protocol was added as an afterthought.
This means that most new features have to be implemented twice, or at
least more than once: code for the local case, and code for the
client-server case.)

@item
The repository is organized efficiently and comprehensibly.  (Without
going into too much detail, let's just say that CVS's repository
structure is showing its age.)

@item
Commits are atomic.  Each commit results in a single revision number,
which refers to the state of the entire tree.  Files no longer have
their own revision numbers.

@item
The locking scheme is only as strict as absolutely necessary.
Reads are never locked, and writes lock only the files being
written, for only as long as needed.

@item
It has internationalization support.

@item
It handles binary files gracefully (experience has shown that CVS's
binary file handling is prone to user error).

@item
It takes advantage of the Net's experience with CVS by choosing better
default behaviors for certain situations.

@end itemize

Some of these advantages are clear and require no further discussion.
Others are not so obvious, and are explained in greater detail below.

@menu
* Rename/removal/resurrection support::  
* Text vs binary issues::       
* I18N/Multilingual support::   
* Branching and tagging::       
* Miscellaneous new behaviors::  
@end menu

@c -----------------------------------------------------------------------
@node Rename/removal/resurrection support
@section Rename/removal/resurrection support

Full rename support means you can trace through ancestry by name
@emph{or} by entity.  For example, if you say "Give me revision 12 of
foo.c", do you mean revision 12 of the file whose name is @emph{now}
foo.c (but perhaps it was named bar.c back at revision 12), or the file
whose name was foo.c in revision 12 (perhaps that file no longer exists,
or has a different name now)?  In Subversion, both interpretations are
available to the user.

(Note:  we've not yet implemented this, but it wouldn't be too hard.
People are advocating switches to 'svn log' that cause history to be
traced backwards either by entity or by path.)

@c -----------------------------------------------------------------------
@node Text vs binary issues
@section Text vs binary issues

Historically, binary files have been problematic in CVS for two
unrelated reasons: keyword expansion, and line-end conversion.
@*
@itemize @bullet
@item
@dfn{Keyword expansion} is when CVS expands "$Revision: 1.1 $" into "$Revision
1.1$", for example.  There are a number of keywords in CVS: "$Author: sussman $",
"$Date: 2001/06/04 22:00:52 $", and so on.
@*
@item
@dfn{Line-end conversion} is when CVS gives plaintext files the
appropriate line-ending conventions for the working copy's platform.
For example, Unix working copies use LF, but Windows working copies use
CRLF.  (Like CVS, the Subversion repository stores text files in Unix LF
format).
@end itemize
@*
Both keyword substitution and line-end conversion are sensible only for
plain text files.  CVS only recognizes two file types anyway: plaintext
and binary.  And CVS assumes files are plain text unless you tell it
otherwise.

Subversion recognizes the same two types.  The question is, how does
it determine a file's type?  Experience with CVS suggests that
assuming text unless told otherwise is a losing strategy -- people
frequently forget to mark images and other opaque formats as binary,
then later they wonder why CVS mangled their data.  So Subversion will
not mangle data: when moving over the network, or when being stored in
the repository, it treats all files as binary.  In the working copy, a
tweakable meta-data property indicates whether to treat the file as
text or binary for purposes of whether or not to allow contextual
merging during updates.

Users can turn line-end conversion on or off per file by tweaking
meta-data.  Files do @emph{not} undergo keyword substitution by
default, on the theory that if someone wants substitution and isn't
getting it, they'll look in the manual; but if they are getting it and
didn't want it, they might just be confused and not know what to do.
Users can turn substitution on or off per file.

Both of these changes are done on the client side; the repository does
not even know about them.

@c -----------------------------------------------------------------------
@node I18N/Multilingual support
@section I18N/Multilingual support

Subversion is internationalized -- commands, user messages, and errors
can be customized to the appropriate human language at build-time (or
run time, if that's not much harder).

File names and contents may be multilingual; Subversion does not assume
an ASCII-only universe.  For purposes of keyword expansion and line-end
conversion, Subversion also understands the UTF-* encodings (but not
necessarily all of them by the first release).

@c -----------------------------------------------------------------------
@node Branching and tagging
@section Branching and tagging

Subversion supports branching and tagging with one efficient operation:
`clone'.  To clone a tree is to copy it, to create another tree exactly
like it (except that the new tree knows its ancestry relationship to the
old one).

At the moment of creation, a clone requires only a small, constant
amount of space in the repository -- most of its storage is shared with
the original tree.  If you never commit anything on the clone, then it's
just like a CVS tag.  If you start committing on it, then it's a branch.
Voila!  This also implies CVS's "vendor branching" feature, since
Subversion has real rename and directory support.

@c -----------------------------------------------------------------------
@node Miscellaneous new behaviors
@section Miscellaneous new behaviors

@menu
* Log messages::                
* Client side diff plug-ins::   
* Better merging::              
* Conflicts resolution::        
@end menu

@c -----------------------------------------------------------------------
@node Log messages
@subsection Log messages

Subversion has a flexible log message policy (a small matter, but one
dear to our hearts).

Log messages should be a matter of project policy, not version control
software policy.  If a user commits with no log message, then Subversion
defaults to an empty message.  (CVS tries to require log messages, but
fails: we've all seen empty log messages in CVS, where the user
committed with deliberately empty quotes.  Let's stop the madness now.)

@c -----------------------------------------------------------------------
@node Client side diff plug-ins
@subsection Client side diff plug-ins

Subversion supports client-side plug-in diff programs.

There is no need for Subversion to have every possible diff mechanism
built in.  It can invoke a user-specified client-side diff program on
the two revisions of the file(s) locally.

(Note:  This feature does not exist yet, but is planned for post-1.0.)

@c -----------------------------------------------------------------------
@node Better merging
@subsection Better merging

Subversion remembers what has already been merged in and what hasn't,
thereby avoiding the problem, familiar to CVS users, of spurious
conflicts on repeated merges.

(Note:  This feature does not exist yet, but is planned for post-1.0.)

For details, @xref{Merging and Ancestry}.

@c -----------------------------------------------------------------------
@node Conflicts resolution
@subsection Conflicts resolution

For text files, Subversion resolves conflicts similarly to CVS, by
folding repository changes into the working files with conflict
markers.  But, for @emph{both} text and binary files, Subversion also
always puts the old and new pristine repository revisions into
temporary files, and the pristine working copy revision in another
temporary file.

Thus, for any conflict, the user has four files readily at hand:

@enumerate
@item the original working copy file with local mods
@item the older repository file
@item the newest repository file
@item the merged file, with conflict markers
@end enumerate

and in a binary file conflict, the user has all but the last.

When the conflict has been resolved and the working copy is committed,
Subversion automatically removes the temporary pristine files.

A more general solution would allow plug-in merge resolution tools on
the client side; but this is not scheduled for the first release).
Note that users can use their own merge tools anyway, since all the
original files are available.
