blob: c1e465f24ea45679283d0dd82c3cbac8fb218cc9 [file] [log] [blame]
@node Client
@chapter Client
The Subversion client is built on three libraries. One operates
strictly on the working copy and does not talk to the repository.
Another talks to the repository but never changes the working copy. The
last library uses the first two to provide operations such as
@code{commit} and @code{update}, that both talk to the repository and
change the working copy.
The initial client is a Unix-style command-line tool (like standard
CVS), but it should be easy to write a GUI client as well, based on the
same libraries. The libraries capture the core Subversion
functionality, segregating it from user interface concerns.
This chapter describes the libraries, and the physical layout of working
copies.
@menu
* Deltas::
* Working copies and the working copy library::
* The repository access library::
* The client operation library::
@end menu
@c -----------------------------------------------------------------------
@node Deltas
@section Deltas
A delta is a data structure that compactly describes the differences
between two arbitrary directory trees. Deltas can also carry ancestry
information, indicating how the files in one tree are related to files
in the other tree, if this is available. Finally, deltas can describe
changes to file meta-information, like permission bits, creation dates,
and so on. Both the working copy and repository access libraries
operate on deltas.
Deltas use three distinct structures:
@itemize @bullet
@item
@dfn{text deltas}, which describe changes to a string of bytes, like the
contents of a file,
@item
@dfn{property deltas}, which describe changes to a list of named
properties, perhaps using text deltas, and
@item
@dfn{tree deltas} proper, which describe changes to directory trees.
@end itemize
The term @dfn{delta} without qualification generally means a tree delta,
unless some other meaning is clear from context.
@menu
* Text Deltas::
* Property Deltas::
* Tree Deltas::
* Skeltas::
@end menu
@c -----------------------------------------------------------------------
@node Text Deltas
@subsection Text Deltas
A text delta describes the difference between two strings of bytes, the
@dfn{source} string and the @dfn{target} string. Given a source string
and a target string, we can compute a text delta; given a source string
and a delta, we can reconstruct the target string. However, note that
deltas are not invertible: you cannot always reconstruct the source
string given the target string and delta.
The standard Unix ``diff'' format is one possible representation for
text deltas; however, diffs are not ideal for internal use by a version
control system, for several reasons:
@itemize @bullet
@item
Diffs are line-oriented, which makes them human-readable, but sometimes
makes them perform poorly on binary files.
@item
Diffs represent a series of replacements, exchanging selected ranges of
the old text with new text; again, this is easy for humans to read, but
it is more expensive to compute and less compact than some alternatives.
@end itemize
Instead, Subversion uses the VDelta format, as described in @cite{Hunt,
J. J., Vo, K.-P., and Tichy, W. F. An empirical study of delta
algorithms. Lecture Notes in Computer Science 1167 (July 1996), 49-66.}
David Korn and Kiem-Phong Vo have submitted an Internet Draft, titled
``The VCDIFF Generic Differencing and Compression Data Format,''
describing an improvement to VDelta which we may adopt.
The concrete form of a text delta, used for transmitting such deltas
over the net, is a well-formed XML element, having the following form:
@example
<text-delta>@var{data}</text-delta>
@end example
Here, @var{data} is the raw VDelta data, escaped appropriately for XML
character data.
@c -----------------------------------------------------------------------
@node Property Deltas
@subsection Property Deltas
A property delta describes changes to a property list, of the sort
associated with files, directories, and directory entries, and version
numbers. A property delta can record creating, deleting, and changing
the text of any number of properties.
A property delta is an unordered set of name/change pairs. No two
pairs within a given property delta have the same name. A pair's name
indicates the property affected, and the change indicates what happens
to its value. There are two kinds of changes:
@table @code
@item set @var{value}
Change the value of the named property to the byte string @var{value}.
If there is no property with the given name, one is added to the
property list.
@item delete
Remove the named property from the property list.
@end table
At the moment, the @code{set} command can either create or change a
property value. However, this simplification means that the server
cannot distinguish between a client which believes it is creating a
value afresh, and a client which believes it is changing the value of an
existing property. It may simplify conflict detection to divide
@code{set} into two separate @code{add} and @code{change} operations.
In the future, we may add a @code{vdelta} change, which specifies a
change to an existing property's value as a VDelta-format text delta.
This would give us a compact way to describe small changes to large
property values.
The concrete form of a property delta, used for transmitting such deltas
over the net, is a well-formed XML element, having the following form:
@example
<property-delta>@var{change}@dots{}</property-delta>
@end example
Each @var{change} in a property delta has one of the following forms:
@example
<set name='@var{name}'>@var{value}</set>
<delete name='@var{name}'/>
@end example
The @var{name} attribute of a @code{set} or @code{delete} element gives
the name of the property to change. The @var{value} of a @code{set}
element gives the new value of the property.
If either the property name or the property value contains the
characters @samp{&}, @samp{<}, or @samp{'}, they should be replaced with
the sequences @samp{&#38}, @samp{&#60}, or @samp{&#39}, respectively.
@c -----------------------------------------------------------------------
@node Tree Deltas
@subsection Tree Deltas
A tree delta describes changes between two directory trees, the
@dfn{source tree} and the @dfn{target tree}. Tree deltas can describe
copies, renames, and deletions of files and directories, changes to file
contents, and changes to property lists. A tree delta can also carry
information about how the files in the target tree are derived from the
files in the source tree, if this information is available.
The format for tree deltas described here is easy to compute from a
Subversion working directory, and easy to apply to a Subversion
repository. Furthermore, the size of a tree delta in this format is
independent of the commands used to produce the target tree --- it
depends only on the degree of difference between the source and target
trees.
A tree delta is interpreted in the context of three parameters:
@itemize @bullet
@item
@var{source-root}, the name of the directory to which this complete
tree delta applies,
@item
@var{version}, indicating a particular version of @dots{}
@item
@var{source-dir}, which is a directory in the source tree that we are
currently modifying to yield @dots{}
@item
@dots{} @dfn{target-dir} --- the directory we're constructing.
@end itemize
When we start interpreting a tree delta, @var{source-root},
@var{source-dir}, and @var{target-dir} are all equal. As we walk the
tree delta, @var{target-dir} walks the tree we are constructing, and
@var{source-dir} walks the corresponding portion of the source tree,
which we use as the original. @var{Source-root} remains constant as we
walk the delta; we may use it to choose new source trees.
A tree delta is a list of changes of the form
@example
<tree-delta>@var{change}@dots{}</tree-delta>
@end example
which describe how to edit the contents of @var{source-dir} to yield
@var{target-dir}. There are three kinds of changes:
@table @code
@item <delete name='@var{name}'/>
@var{Source-dir} has an entry named @var{name}, which is not present in
@var{target-dir}.
@item <new name='@var{name}'>@var{content}</new>
@var{target-dir} has an entry named @var{name}, which is not present in
@var{source-dir}; @var{content} describes the file or directory to which
the new directory entry refers.
@item <replace name='@var{name}'>@var{content}</replace>
Both @var{source-dir} and @var{target-dir} have an entry named
@var{name}, which has changed; @var{content} describes the new file or
directory.
@end table
Any entries in @var{source-dir} whose names aren't mentioned are assumed
to appear unchanged in @var{target-dir}. Thus, an empty
@code{tree-delta} element indicates that @var{target-dir} is identical
to @var{source-dir}.
In the change descriptions above, each @var{content} takes one of the
following forms:
@table @code
@item <file @var{ancestor}>@var{prop-delta} @var{text-delta}</file>
The given @var{target-dir} entry refers to a file, @var{f}.
@var{Ancestor} indicates which file in the source tree @var{f} is
derived from, if any.
@var{Prop-delta} is a property delta describing how @var{f}'s properties
differ from that ancestor; it may be omitted, indicating that the
properties are unchanged.
@var{Text-delta} is a text delta describing how to construct @var{f}
from that ancestor; it may also be omitted, indicating that @var{f}'s
text is identical to its ancestor's.
@item <file @var{ancestor}/>
An abbreviation for @code{<file @var{ancestor}></file>} --- a file
element with no property or text delta, thus describing a file identical
to its ancestor.
@item <directory @var{ancestor}>@var{prop-delta} @var{tree-delta}</directory>
The given @var{target-dir} entry refers to a subdirectory, @var{sub}.
@var{Ancestor} indicates which directory in the source tree @var{sub} is
derived from, if any.
@var{Prop-delta} is a property delta describing how @var{sub}'s
properties differ from that ancestor; it may be omitted, indicating that
the properties are unchanged.
@var{Tree-delta} describes how to construct @var{sub} from that
ancestor; it may be omitted, indicating that the directory is identical
to its ancestor. @var{Tree-delta} should be interpreted with a new
@var{target-dir} of @file{@var{target-dir}/@var{name}}.
Since @var{tree-delta} is itself a complete tree delta structure, tree
deltas are themselves trees, whose structure is a subgraph of the target
tree.
@item <directory @var{ancestor}/>
An abbreviation for @code{<directory @var{ancestor}></directory>} --- a
directory element with no property or tree delta, thus describing a
directory identical to its ancestor.
@end table
The @var{content} of a @code{new} or @code{replace} tag may also contain
a property delta, describing changes to the properties of that
@emph{directory entry}.
In the @code{file} and @code{directory} elements described above, each
@var{ancestor} has one of the following forms:
@table @code
@item ancestor='@var{path}'
The ancestor of the new or changed file or directory is
@file{@var{source-root}/@var{path}}, in @var{version}. When this
appears as an attribute of a @code{file} element, the element's text
delta should be applied to @file{@var{source-root}/@var{path}}. When
this appears as an attribute of a @code{directory} element,
@file{@var{source-root}/@var{path}} should be the new @var{source-dir}
for interpreting that element's tree delta.
@item new='true'
This indicates that the file or directory has no ancestor in the source
tree. When followed by a @var{text-delta}, that delta should be applied
to the empty file to yield the new text; when followed by a
@var{tree-delta}, that delta should be evaluated as if @var{source-dir}
were an imaginary empty directory.
@item @var{nothing}
If neither an @code{ancestor} nor a @code{new} attribute is given, this
is an abbreviation for @code{ancestor='@var{source-dir}/@var{name}'},
with the same version number. This makes the common case --- files or
directories modified in place --- more compact.
@end table
If the @var{ancestor} spec is not @code{new='true'}, it may also contain
the text @code{version='@var{v}'}, indicating a new value for
@var{version}, in which we should find the ancestor.
If a filename or path appearing as a @var{name} or @var{path} in the
description above contains the characters @samp{&}, @samp{<}, or
@samp{'}, they should be replaced with the sequences @samp{&#38},
@samp{&#60}, or @samp{&#39}, respectively.
Suppose we have the following source tree:
@example
/dir1/file1
file2
dir2/file3
file4
dir3/file5
file6
@end example
If we edit the contents of @file{/dir1/file1}, we can describe the
effect on the tree with the following tree delta, to be applied to the
root:
@example
<tree-delta>
<replace name='dir1'>
<directory>
<tree-delta>
<replace name='file1'>
<file>@var{text-delta}</file>
</replace>
</tree-delta>
</directory>
</replace>
</tree-delta>
@end example
The outer @code{tree-delta} element describes the changes made to the root
directory. Within the root directory, there are changes in @file{dir1},
described by the nested @code{tree-delta}. Within @file{/dir1}, there are
changes in @file{file1}, described by the @var{text-delta}.
If we had edited both @file{/dir1/file1} and @file{/dir1/file2}, then
there would simply be two @code{replace} elements in the inner
@code{tree-delta}.
As another example, starting from the same source tree, suppose we
rename @file{/dir1/file1} to @file{/dir1/file8}:
@example
<tree-delta>
<replace name='dir1'>
<directory>
<tree-delta>
<delete name='file1'/>
<new name='file8'>
<file ancestor='/dir1/file1'/>
</new>
</tree-delta>
</directory>
</replace>
</tree-delta>
@end example
As above, the inner @code{tdelta} describes how @file{/dir1} has
changed: the entry for @file{/dir1/file1} has disappeared, but there is
a new entry, @file{/dir1/file8}, which is derived from and textually
identical to @file{/dir1/file1} in the source directory. This is just
an indirect way of describing the rename.
Why is it necessary to be so indirect? Consider the delta representing
the result of:
@enumerate
@item
renaming @file{/dir1/file1} to @file{/dir1/tmp},
@item
renaming @file{/dir1/file2} to @file{/dir1/file1}, and
@item
renaming @file{/dir1/tmp} to @file{/dir1/file2}
@end enumerate
(in other words, exchanging @file{file1} and @file{file2}):
@example
<tree-delta>
<replace name='dir1'>
<directory>
<tree-delta>
<replace name='file1'>
<file ancestor='/dir1/file2'/>
</replace>
<replace name='file2'>
<file ancestor='/dir1/file1'/>
</replace>
</tree-delta>
</directory>
</replace>
</tree-delta>
@end example
The indirectness allows the tree delta to capture an arbitrary
rearrangement without resorting to temporary filenames.
Another example, starting from the same source tree:
@enumerate
@item
rename @file{/dir1/dir2} to @file{/dir1/dir4},
@item
rename @file{/dir1/dir3} to @file{/dir1/dir2}, and
@item
move @file{file3} from @var{/dir1/dir4} to @var{/dir1/dir2}.
@end enumerate
Note that @file{file3}'s path has remained the same, even though the
directories around it have changed. Here is the tree delta:
@example
<tree-delta>
<replace name='dir1'>
<directory>
<tree-delta>
<replace name='dir2'>
<directory ancestor='/dir1/dir3'>
<tree-delta>
<new name='file3'>
<file ancestor='/dir1/dir2/file3'/>
</new>
</tree-delta>
</directory>
</replace>
<delete name='dir3'/>
<new name='dir4'>
<directory ancestor='/dir1/dir2'>
<tree-delta>
<delete name='file3'/>
</tree-delta>
</directory>
</new>
</tree-delta>
</directory>
</replace>
</tree-delta>
@end example
In other words:
@itemize @bullet
@item
@file{/dir1} has changed;
@item
the new directory @file{/dir1/dir2} is derived from the old
@file{/dir1/dir3}, and contains a new entry @file{file3}, derived from
the old @file{/dir1/dir2/file3};
@item
there is no longer any @file{/dir1/dir3}; and
@item
the new directory @file{/dir1/dir4} is derived from the old
@file{/dir1/dir2}, except that its entry for @file{file3} is now gone.
@end itemize
Some more possible maneuvers, left as exercises for the reader:
@itemize @bullet
@item
Delete @file{dir2}, and then create a file named @file{dir2}.
@item
Rename @file{/dir1/dir2} to @file{/dir1/dir4}; move @file{file2} into
@file{/dir1/dir4}; and move @file{file3} into @var{/dir1/dir3}.
@item
Move @file{dir2} into @file{dir3}, and move @file{dir3} into @file{/}.
@end itemize
@node Skeltas
@subsection Skeltas
It is sometimes useful to represent a set of changes to a tree, just as
a tree delta does, without providing any text deltas. Text deltas are
often large and expensive to compute, and tree deltas can be useful
without them. For example, one can detect whether two changes conflict
--- whether they change the same file, for example --- without knowing
exactly how the conflicting files changed.
A @dfn{Skelta} is a simply tree delta in which all text deltas are
omitted --- it is a ``skeleton delta''. The @code{svn commit} command
uses skeltas to provide early notice of conflicts: first, the client
transmits a skelta to the server, which can check for textual conflicts
and reject the user's commit, before the client takes the time to
transmit the (possibly large) textual changes.
@c -----------------------------------------------------------------------
@node Working copies and the working copy library
@section Working copies and the working copy library
Working copies are client-side directory trees containing both versioned
data and Subversion administrative files. The functions in the working
copy management library are the only functions in Subversion which
operate on these trees.
@menu
* The layout of working copies::
* The working copy management library::
@end menu
@c -----------------------------------------------------------------------
@node The layout of working copies
@subsection The layout of working copies
This section gives an overview of how working copies are arranged
physically, but is not a full specification of working copy layout.
As with CVS, Subversion working copies are simply directory trees with
special administrative subdirectories, in this case named "SVN" instead
of "CVS":
@example
@group
myproj
/ | \
_____________/ | \______________
/ | \
SVN src doc
___/ | \___ /|\ ___/ \___
| | | / | \ | |
base ... ... / | \ myproj.texi SVN
/ | \ ___/ | \___
____/ | \____ | | |
| | | base ... ...
SVN foo.c bar.c |
___/ | \___ |
| | | |
base ... ... myproj.texi
___/ \___
| |
foo.c bar.c
@end group
@end example
Each @file{dir/SVN/} directory records the files in @file{dir}, their
version numbers and property lists, pristine versions of all the files
(for client-side delta generation), the repository from which @file{dir}
came, and any local changes (such as uncommitted adds, deletes, and
renames) that affect @file{dir}.
Although often it would often be possible to deduce certain information
(such as the origin repository) by examining parent directories, this is
avoided in favor of making each directory be as much a self-contained
unit as possible.
For example, immediately after a checkout the administrative information
for the entire working tree @emph{could} be stored in one top-level
file. But subdirectories instead keep track of their own version
information. This would be necessary anyway once the user starts
committing new versions for particular files, and it also makes it
easier for the user to prune a big, complete tree into a small subtree
and still have a valid working copy.
The SVN subdir contains:
@itemize @bullet
@item
A @file{base} directory, containing the pristine repository versions of
the files in the corresponding working directory.
@item
A @file{versions} file, the first entry of which records the version
number of this directory (and, by implication, the version number of any
files not otherwise mentioned). The remaining entries are for files at
other versions.
It may help to think of this file as the functional equivalent of the
CVS/Entries file.
@item
A @file{properties} file, recording properties for this directory and
all directory entries and files it contains. Although this information
could be stored in the @file{versions} file, it is sufficiently
separable to warrant its own file; very often one wants to look up a
version without looking up a property, and vice-versa.
@item
A @file{changes} file, recording uncommitted changes to and from this
directory (adds, removes, renames).
@item
A @file{lock} file, whose presence implies that some client is currently
operating on the adminstrative area.
@item
A @file{tmp} directory.
@end itemize
The formats of these files are not specified yet.
@c -----------------------------------------------------------------------
@node The working copy management library
@subsection The working copy management library
@itemize @bullet
@item
@b{Requires:}
@itemize
@item
a working copy
@end itemize
@item
@b{Provides:}
@itemize
@item
ability to manipulate the working copy's versioned data
@item
ability to manipulate the working copy's administrative files
@end itemize
@end itemize
This library performs "offline" operations on the working copy.
Note that the interface as given here is incomplete. This section
concentrates on functions meant to be used in conjunction with the
repository access library, such as routines to produce deltas and make
committable changes. But functions used most often @emph{within} the
working copy library itself, and only rarely outside it, are left
unspecified here. For example, there is a @w{@code{ver_t
wc_base_version (path)}} function, and a @w{@code{ver_t wc_lock (path)}}
function, but they are not part of the conceptual interface this section
describes.
In the function names and descriptions below, the term @dfn{node} refers
to any kind of object in a Subversion tree. At the moment, Subversion
trees can only contain files and directories, but we will eventually add
symlinks and other interesting creatures; these are all nodes.
@table @code
@item skelta_t wc_make_skelta (pathlist)
Returns a skelta -- a delta object describing the changes to
@emph{paths} but not including the actual content of the changes (i.e.,
the vdeltas). In other words, this is how you get a list of all local
modifications.
A @emph{pathlist} contains directories or files; directories may be
entered recursively. Multiple paths must be support because of
scenarios like the following:
@example
$ ls
src/ foo/ other/ bar/ baz/ README Makefile
$ svn commit foo/ bar/ baz/qux.c
@end example
The commit is atomic, and covers some but not all of the subdirectories
available. Therefore, it must be possible to request a delta for any
subset of the working tree. Although some files and directories outside
that subset might also have been modified, the delta will not include
those changes.
@item delta_t wc_fill_skelta (skelta)
Turns @emph{skelta} into a delta by generating the appropriate vdiffs
and pdiffs, and placing them into the skelta.
@item delta_t wc_make_delta (pathlist)
Equivalent to
@example
wc_fill_skelta (make_skelta (pathlist))
@end example
@item bool wc_apply_delta (delta)
Applies @emph{delta} to the working copy.
@item bool wc_add (path)
Add the file @emph{path} (i.e., tweak the administrative files
appropriately).
@item bool wc_delete (path)
Remove this file.
@item bool wc_rename (old_path, new_path)
Move/rename this file (within the working copy, of course).
@item bool wc_copy (src_path, dest_path)
Copy this file (within the working copy).
@item str_t wc_get_node_prop (path, propname)
Return local value of @emph{propname} for the file or directory
@emph{path}.
@item str_t wc_get_dirent_prop (path, propname)
Return local value of @emph{propname} for the directory entry @emph{path}.
@item proplist_t wc_get_node_proplist (path)
Return all properties (names and values) of file or directory
@emph{path}, in a hash table.
@item proplist_t wc_get_dirent_proplist (path)
Return all properties (names and values) of directory entry @emph{path},
in a hash table.
@item proplist_t wc_get_node_propnames (path)
Return all property names for file or directory @emph{path}.
@item proplist_t wc_get_dirent_propnames (path)
Return all property names for a directory entry.
@end table
@c -----------------------------------------------------------------------
@node The repository access library
@section The repository access library
@itemize @bullet
@item
@b{Requires:}
@itemize
@item
network access to a Subversion server
@end itemize
@item
@b{Provides:}
@itemize
@item
the ability to interact with a repository
@end itemize
@end itemize
This library performs operations involving communication with the
repository.
@subsection Reading History
@table @code
@item ver_t ra_latest (repos, user)
Report the latest version number for @emph{repos}.
@item prop_t ra_get_ver_prop (repos, user, ver, propname)
Return the value of @emph{propname} on @emph{ver}.
@item proplist_t ra_get_ver_proplist (repos, user, ver)
Return all properties (names and values) of @emph{ver}.
@item proplist_t ra_get_ver_propnames (repos, user, ver)
Return all property keys for a @emph{ver}.
@end table
@subsection Reading Nodes
@table @code
@item node_t ra_read (repos, user, ver, path)
Return a node from the repository.
If @emph{path} is a file, returns full contents of the file.
If @emph{path} is a directory, returns a list of dir_entries.
@c todo: explain nodes, explain lazy reading
@item str_t ra_get_node_prop (repos, user, ver, path, propname)
Return value of @emph{propname} for @emph{path} in @emph{repos}.
@item str_t ra_get_dirent_prop (repos, user, ver, path, propname)
Return value of @emph{propname} for the directory entry @emph{path} in
@emph{repos}.
@item proplist_t ra_get_node_proplist (repos, ver, path)
Return all properties (names and values) of @emph{path} in @emph{repos}.
@item proplist_t ra_get_dirent_proplist (repos, user, ver, path)
Return all properties (names and values) of directory entry @emph{path}
in @emph{repos}.
@item proplist_t ra_get_node_propnames (repos, user, ver, path)
Return all property names for @emph{path} in @emph{repos}.
@item proplist_t ra_get_dirent_propnames (repos, user, ver, path)
Return all property names for directory entry @emph{path} in @emph{repos}
@end table
@subsection Difference Queries
@table @code
@item skelta_t ra_get_status (repos, user, skelta)
Return status (up-to-date or not) for the files mentioned in @emph{skelta}.
@item delta_t ra_get_update (repos, user, skelta)
Return changes for files mentioned in @emph{skelta}. Like
@code{ra_get_status}, but returns filled delta instead of a skelta.
@item delta_t ra_get_delta (repos, user, ver1, path1, ver2, path2)
Return delta between two trees in @emph{repos}.@*
@item diff_t ra_get_diff (repos, user, ver1, path1, ver2, path2)
@c todo: skelta vs file diff list problem, talk w/ Jim
Return a text diff between versions in @emph{repos}.
(This must be done server side, the client doesn't have enough
information to make the diff.)
@end table
@subsection Writing
@table @code
@item token_t ra_submit (repos, user, skelta)
Submit @emph{skelta} for approval (see @pxref{Locking}).
@item ver_t ra_write (repos, user, delta, token)
Write previously-approved @emph{delta} into the repository.@*
Returns the @emph{repos}'s new version number.@*
This @emph{delta} and @emph{token} must correspond to the @emph{skelta}
and @emph{token} of a previous @code{submit()} call.
@item bool ra_abandon (repos, user, token)
Abandon the commit identified by token. For example, a user might
interrupt the client between calls to @code{submit()} and
@code{write()}, and the server would want to know the commit has been
abandoned so it can clear out its pool of approved changes.
@end table
@c -----------------------------------------------------------------------
@node The client operation library
@section The client operation library
@itemize @bullet
@item
@b{Requires:}
@itemize
@item
the working copy management library
@item
the repository access library
@end itemize
@item
@b{Provides:}
@itemize
@item
all client-side Subversion commands
@end itemize
@end itemize
These functions correspond to user-level client commands.
They are listed here to show how it is possible to implement them using
the libraries given above, not to explain what they do. Their behavior
corresponds to the CVS operations of the same names.
@table @code
@item bool add (path)
Passes @emph{path} to @code{wc_add()}.
@item bool checkout (repos, ver, path)
todo: discuss serialized delta vs lazy reading
@item bool commit (pathlist, log_msg)
Make a skelta with @code{wc_make_skelta()}, @code{ra_submit()} it to
the repository for approval. If an approval token is forthcoming, use
@code{wc_fill_skelta()} to produce a delta, along with the
@emph{log_msg} as a property change on the version, and send it and the
token back to the repository via @code{ra_write()}. Else if no
approval, then @code{abandon()} the commit.
@item bool diff (pathlist)
A Subversion diff, like a CVS diff, can involve information available
only to the server, or client, or both:
@enumerate
@item @w{@b{diff locally modified file against its base version}}@*
Just run diff locally.
@item @w{@b{diff local file against a repository-only version}}@*
Call @code{ra_get_delta()}, then @code{wc_apply_delta()} to the
pristine base version to get the new file (result probably stored in
@file{SVN/tmp/}, of course), then run diff on the local file and the
new file.
@item @w{@b{diff two repository-only versions}}@*
Call @code{ra_get_diff()}.
@end enumerate
@item bool import (pathlist)
A special case of @code{add()}, which see.
@item bool log (ver)
Call @code{ra_get_ver_prop()} with the appropriate property name.
@item bool rename (old_path, new_path)
Pass through to @code{wc_rename()}.
@item bool remove (pathlist)
Pass through to @code{wc_delete()}.
@item bool branch (branchname, pathlist)
Uses @code{wc_copy()} (see @pxref{Model}).
@item bool tag (tagname, pathlist)
Same as @code{branch()}, and may also set properties marking this as a
read-only clone, so it behaves like a CVS tag.
@item bool status (pathlist)
Call @code{ra_get_status()}.
@item bool update (pathlist)
Call @code{ra_get_update()}, passing result to
@code{wc_apply_delta()}. (There may be streamy variants of these so
the application of a delta doesn't need to wait for the entire delta to
have arrived.)
@end table
@c todo: can't wait to add `annotate' to this list!