[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [RFC] API for reading trees from repo or WC

From: Greg Stein <gstein_at_gmail.com>
Date: Fri, 7 Oct 2011 16:07:17 -0400

On Fri, Oct 7, 2011 at 09:56, Julian Foad <julian.foad_at_wandisco.com> wrote:
>  diff_tree_with_delta(tree1, delta)
>    Takes a reference to a base tree, and an svn_delta_editor_t type
> delta based on tree1, and reads dirs and files from tree1 as necessary
> to present the delta as a unidiff (or whatever kind of output).

You should be using Ev2 rather than the delta editor.

> /**
>  * A readable tree.  This object is used to perform read requests to a
>  * repository tree or a working-copy (base or working) tree or any other
>  * readable tree.
>  *
>  * @since New in 1.8.
>  */
> typedef struct svn_client_tree_t svn_client_tree_t;
> /* */
> typedef svn_io_dirent2_t svn_client_tree_dirent_t;
> /* V-table for #svn_client_tree_t.
>  *
>  * Paths are relpaths, relative to the tree root.
>  * Revision numbers and repository ids are #SVN_INVALID_REVNUM and NULL
>  * for an unversioned node (including a node that is a local add/copy/move
>  * in a WC working tree).
>  */
> typedef struct svn_client_tree__vtable_t

The vtable should be private/encapsulated. See how svn_editor_t
handles its vtable, along with the various callback-setters. The
code/feature-set is much easier to extend, and the API is much easier
to modify when the vtable is hidden.

> {
>  /* Fetch the node kind of the node at @a relpath.
>   * (### and other metadata? revnum? props?)
>   *
>   * Set @a *kind to the node kind.
>   */
>  svn_error_t *(*get_kind)(svn_client_tree_t *tree,
>                           svn_node_kind_t *kind,
>                           const char *relpath,
>                           apr_pool_t *scratch_pool);

relpath against what? I presume the root of the tree is defined at
construction time. Thus, all API calls are relative to that implied

>  /* Fetch the contents and properties of the file at @a relpath.
>   *
>   * If @a stream is non-NULL, set @a *stream to a readable stream yielding
>   * the contents of the file at @a relpath.  (### ? The stream
>   * handlers for @a stream may not perform any operations on @a tree.)
>   *
>   * If @a props is non-NULL, set @a *props to contain the regular
>   * versioned properties of the file (not 'wcprops', 'entryprops', etc.).
>   * The hash maps (const char *) names to (#svn_string_t *) values.
>   */
>  svn_error_t *(*get_file)(svn_client_tree_t *tree,
>                           svn_stream_t **stream,
>                           apr_hash_t **props,
>                           const char *relpath,
>                           apr_pool_t *result_pool,
>                           apr_pool_t *scratch_pool);

I would like to see the notion of a symlink be a first-order item in
this API. The hope is to move away from exposing svn:special and
treating all symlinks as their own type. (and yes, this kinda messes
with your get_kind using svn_node_kind_t)

>  /* Fetch the entries and properties of the directory at @a relpath.
>   *
>   * If @a dirents is non-NULL, set @a *dirents to contain all the entries
>   * of directory @a relpath.  The keys will be (<tt>const char *</tt>)
>   * entry names, and the values (#svn_client_tree_dirent_t *) dirents.
>   * Only the @c kind and @c filesize fields are filled in.

Just names are easiest. ie. return an array of child names. If you
start returning structures, then you're going to get into versioning
hell for those structures. They become giant gloms of random data.
(ref: the old svn_wc_entry_t, the various svn_info_t structures, and
the haphazard svn_wc_status_t structures).

>   * ### @c special would be useful too.

Screw special. Use kind properly.

I would suggest svn_kind_t. We can then get rid of svn_wc__db_kind_t,
and various APIs can be versioned from svn_node_kind_t over to the new

>   *
>   * If @a props is non-NULL, set @a *props to contain the regular
>   * versioned properties of the file (not 'wcprops', 'entryprops', etc.).
>   * The hash maps (const char *) names to (#svn_string_t *) values.
>   */
>  svn_error_t *(*get_dir)(svn_client_tree_t *tree,
>                          apr_hash_t **dirents,
>                          apr_hash_t **props,
>                          const char *relpath,
>                          apr_pool_t *result_pool,
>                          apr_pool_t *scratch_pool);
>  /* Push a sub-tree into an editor, as a delta against an empty tree.
>   * This is useful for efficiency when streaming a (sub-)tree from a
>   * remote source. */

I don't see the utility here. Every single node becomes an add_* call
into the Ev2 interface. Not very complicated, so I'm not sure how this
helps (or what the problem it is trying to solve).

> struct svn_client_tree_t
> {
>  const svn_client_tree__vtable_t *vtable;
>  /* Pool used to manage this session. */
>  apr_pool_t *pool;
>  /* Private data for the tree implementation. */
>  void *priv;
> };

This should be encapsulated. See svn_editor_t. And that would be
"baton" (we never call it "priv").


Received on 2011-10-07 22:07:48 CEST

This is an archived mail posted to the Subversion Dev mailing list.