| @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{&}, @samp{<}, or @samp{'}, 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{&}, |
| @samp{<}, or @samp{'}, 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! |