Index: subversion/libsvn_ra/wrapper_template.h
===================================================================
--- subversion/libsvn_ra/wrapper_template.h (revision 17044)
+++ subversion/libsvn_ra/wrapper_template.h (working copy)
@@ -160,8 +160,8 @@
apr_hash_t **props,
apr_pool_t *pool)
{
- return VTBL.get_dir (session_baton, path, revision, dirents, fetched_rev,
- props, pool);
+ return VTBL.get_dir (session_baton, path, revision, SVN_DIRENT_ALL, dirents,
+ fetched_rev, props, pool);
}
struct compat_report_baton {
Index: subversion/libsvn_ra/ra_loader.c
===================================================================
--- subversion/libsvn_ra/ra_loader.c (revision 17044)
+++ subversion/libsvn_ra/ra_loader.c (working copy)
@@ -439,10 +439,23 @@
apr_hash_t **props,
apr_pool_t *pool)
{
- return session->vtable->get_dir (session, path, revision, dirents,
- fetched_rev, props, pool);
+ return session->vtable->get_dir (session, path, revision, SVN_DIRENT_ALL,
+ dirents, fetched_rev, props, pool);
}
+svn_error_t *svn_ra_get_dir2 (svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ apr_uint32_t dirent_fields,
+ apr_hash_t **dirents,
+ svn_revnum_t *fetched_rev,
+ apr_hash_t **props,
+ apr_pool_t *pool)
+{
+ return session->vtable->get_dir (session, path, revision, dirent_fields,
+ dirents, fetched_rev, props, pool);
+}
+
svn_error_t *svn_ra_do_update (svn_ra_session_t *session,
const svn_ra_reporter2_t **reporter,
void **report_baton,
Index: subversion/libsvn_ra/ra_loader.h
===================================================================
--- subversion/libsvn_ra/ra_loader.h (revision 17044)
+++ subversion/libsvn_ra/ra_loader.h (working copy)
@@ -99,6 +99,7 @@
svn_error_t *(*get_dir) (svn_ra_session_t *session,
const char *path,
svn_revnum_t revision,
+ apr_uint32_t dirent_fields,
apr_hash_t **dirents,
svn_revnum_t *fetched_rev,
apr_hash_t **props,
Index: subversion/include/svn_ra_svn.h
===================================================================
--- subversion/include/svn_ra_svn.h (revision 17044)
+++ subversion/include/svn_ra_svn.h (working copy)
@@ -42,6 +42,33 @@
/** Currently-defined capabilities. */
#define SVN_RA_SVN_CAP_EDIT_PIPELINE "edit-pipeline"
+/** ra_svn passes @c svn_dirent_t fields over the wire as a list of
+ * words, these are the values used to represent each field.
+ *
+ * @defgroup ra_svn_dirent_fields ra_svn dirent fields
+ * @{
+ */
+
+/** The ra_svn way of saying @c SVN_DIRENT_KIND. */
+#define SVN_RA_SVN_DIRENT_KIND "kind"
+
+/** The ra_svn way of saying @c SVN_DIRENT_SIZE. */
+#define SVN_RA_SVN_DIRENT_SIZE "size"
+
+/** The ra_svn way of saying @c SVN_DIRENT_HAS_PROPS. */
+#define SVN_RA_SVN_DIRENT_HAS_PROPS "has-props"
+
+/** The ra_svn way of saying @c SVN_DIRENT_CREATED_REV. */
+#define SVN_RA_SVN_DIRENT_CREATED_REV "created-rev"
+
+/** The ra_svn way of saying @c SVN_DIRENT_TIME. */
+#define SVN_RA_SVN_DIRENT_TIME "time"
+
+/** The ra_svn way of saying @c SVN_DIRENT_LAST_AUTHOR. */
+#define SVN_RA_SVN_DIRENT_LAST_AUTHOR "last-author"
+
+/** @} */
+
/** A value used to indicate an optional number element in a tuple that was
* not received.
*/
Index: subversion/include/svn_types.h
===================================================================
--- subversion/include/svn_types.h (revision 17044)
+++ subversion/include/svn_types.h (working copy)
@@ -199,7 +199,39 @@
svn_recursive
};
+/**
+ * It is sometimes convenient to indicate which parts of an @c svn_dirent_t
+ * object you are actually interested in, so that calculating and sending
+ * the data corresponding to the other fields can be avoided. These values
+ * can be used for that purpose.
+ *
+ * @defgroup svn_dirent_fields dirent fields
+ * @{
+ */
+/** An indication that you are interested in the @c kind field */
+#define SVN_DIRENT_KIND 0x00001
+
+/** An indication that you are interested in the @c size field */
+#define SVN_DIRENT_SIZE 0x00002
+
+/** An indication that you are interested in the @c has_props field */
+#define SVN_DIRENT_HAS_PROPS 0x00004
+
+/** An indication that you are interested in the @c created_rev field */
+#define SVN_DIRENT_CREATED_REV 0x00008
+
+/** An indication that you are interested in the @c time field */
+#define SVN_DIRENT_TIME 0x00010
+
+/** An indication that you are interested in the @c last_author field */
+#define SVN_DIRENT_LAST_AUTHOR 0x00020
+
+/** A combination of all the dirent fields */
+#define SVN_DIRENT_ALL ~((apr_uint32_t ) 0)
+
+/** @} */
+
/** A general subversion directory entry. */
typedef struct svn_dirent_t
{
Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h (revision 17044)
+++ subversion/include/svn_client.h (working copy)
@@ -2146,7 +2146,31 @@
* If @a recurse is true (and @a path_or_url is a directory) this will
* be a recursive operation.
*
+ * @a dirent_fields controls which fields in the @c svn_dirent_t's are
+ * filled in. To have them totally filled in use @c SVN_DIRENT_ALL,
+ * otherwise simply bitwise OR together the combination of @c SVN_DIRENT_
+ * fields you care about.
+ *
+ * @since New in 1.4.
+ */
+svn_error_t *
+svn_client_ls4 (apr_hash_t **dirents,
+ apr_hash_t **locks,
+ const char *path_or_url,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_boolean_t recurse,
+ apr_uint32_t dirent_fields,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+/**
+ * Same as svn_client_ls4(), but always passes @c SVN_DIRENT_ALL for
+ * the @a dirent_fields argument.
+ *
* @since New in 1.3.
+ *
+ * @deprecated Provided for backward compatibility with the 1.3 API.
*/
svn_error_t *
svn_client_ls3 (apr_hash_t **dirents,
Index: subversion/include/svn_ra.h
===================================================================
--- subversion/include/svn_ra.h (revision 17044)
+++ subversion/include/svn_ra.h (working copy)
@@ -657,6 +657,11 @@
* entry names (const char *), and the values dirents
* (@c svn_dirent_t *). Use @a pool for all allocations.
*
+ * @a dirent_fields controls which portions of the @c svn_dirent_t
+ * objects are filled in. To have them completely filled in just pass
+ * @c SVN_DIRENT_ALL, otherwise pass the bitwise OR of all the @c SVN_DIRENT_
+ * fields you would like to have returned to you.
+ *
* @a path is interpreted relative to the URL in @a session.
*
* If @a revision is @c SVN_INVALID_REVNUM (meaning 'head') and
@@ -671,7 +676,24 @@
* etc.) The keys are const char *, values are
* @c svn_string_t *.
*
+ * @since New in 1.4.
+ */
+svn_error_t *svn_ra_get_dir2 (svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ apr_uint32_t dirent_fields,
+ apr_hash_t **dirents,
+ svn_revnum_t *fetched_rev,
+ apr_hash_t **props,
+ apr_pool_t *pool);
+
+/**
+ * Similar to @c svn_ra_get_dir2, but with @c SVN_DIRENT_ALL for the
+ * @a dirent_fields parameter.
+ *
* @since New in 1.2.
+ *
+ * @deprecated Provided for compatibility with the 1.3 API.
*/
svn_error_t *svn_ra_get_dir (svn_ra_session_t *session,
const char *path,
Index: subversion/libsvn_ra_local/ra_plugin.c
===================================================================
--- subversion/libsvn_ra_local/ra_plugin.c (revision 17044)
+++ subversion/libsvn_ra_local/ra_plugin.c (working copy)
@@ -950,6 +950,7 @@
svn_ra_local__get_dir (svn_ra_session_t *session,
const char *path,
svn_revnum_t revision,
+ apr_uint32_t dirent_fields,
apr_hash_t **dirents,
svn_revnum_t *fetched_rev,
apr_hash_t **props,
@@ -1010,32 +1011,49 @@
apr_hash_this (hi, &key, NULL, &val);
entryname = (const char *) key;
fs_entry = (svn_fs_dirent_t *) val;
-
- /* node kind */
+
fullpath = svn_path_join (abs_path, entryname, subpool);
- entry->kind = fs_entry->kind;
-
- /* size */
- if (entry->kind == svn_node_dir)
- entry->size = 0;
- else
- SVN_ERR (svn_fs_file_length (&(entry->size), root,
- fullpath, subpool));
-
- /* has_props? */
- SVN_ERR (svn_fs_node_proplist (&prophash, root, fullpath, subpool));
- entry->has_props = (apr_hash_count (prophash)) ? TRUE : FALSE;
-
- /* created_rev & friends */
- SVN_ERR (svn_repos_get_committed_info (&(entry->created_rev),
- &datestring,
- &(entry->last_author),
- root, fullpath, subpool));
- if (datestring)
- SVN_ERR (svn_time_from_cstring (&(entry->time), datestring, pool));
- if (entry->last_author)
- entry->last_author = apr_pstrdup (pool, entry->last_author);
-
+
+ if (dirent_fields & SVN_DIRENT_KIND)
+ {
+ /* node kind */
+ entry->kind = fs_entry->kind;
+ }
+
+ if (dirent_fields & SVN_DIRENT_SIZE)
+ {
+ /* size */
+ if (entry->kind == svn_node_dir)
+ entry->size = 0;
+ else
+ SVN_ERR (svn_fs_file_length (&(entry->size), root,
+ fullpath, subpool));
+ }
+
+ if (dirent_fields & SVN_DIRENT_HAS_PROPS)
+ {
+ /* has_props? */
+ SVN_ERR (svn_fs_node_proplist (&prophash, root, fullpath,
+ subpool));
+ entry->has_props = (apr_hash_count (prophash)) ? TRUE : FALSE;
+ }
+
+ if ((dirent_fields & SVN_DIRENT_TIME)
+ || (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
+ || (dirent_fields & SVN_DIRENT_CREATED_REV))
+ {
+ /* created_rev & friends */
+ SVN_ERR (svn_repos_get_committed_info (&(entry->created_rev),
+ &datestring,
+ &(entry->last_author),
+ root, fullpath, subpool));
+ if (datestring)
+ SVN_ERR (svn_time_from_cstring (&(entry->time), datestring,
+ pool));
+ if (entry->last_author)
+ entry->last_author = apr_pstrdup (pool, entry->last_author);
+ }
+
/* Store. */
apr_hash_set (*dirents, entryname, APR_HASH_KEY_STRING, entry);
}
Index: subversion/libsvn_client/ls.c
===================================================================
--- subversion/libsvn_client/ls.c (revision 17044)
+++ subversion/libsvn_client/ls.c (working copy)
@@ -28,7 +28,8 @@
#include "svn_private_config.h"
static svn_error_t *
-get_dir_contents (apr_hash_t *dirents,
+get_dir_contents (apr_uint32_t dirent_fields,
+ apr_hash_t *dirents,
const char *dir,
svn_revnum_t rev,
svn_ra_session_t *ra_session,
@@ -41,8 +42,8 @@
apr_hash_index_t *hi;
/* Get the directory's entries, but not its props. */
- SVN_ERR (svn_ra_get_dir (ra_session, dir, rev, &tmpdirents,
- NULL, NULL, pool));
+ SVN_ERR (svn_ra_get_dir2 (ra_session, dir, rev, dirent_fields, &tmpdirents,
+ NULL, NULL, pool));
if (ctx->cancel_func)
SVN_ERR (ctx->cancel_func (ctx->cancel_baton));
@@ -64,20 +65,21 @@
apr_hash_set (dirents, path, APR_HASH_KEY_STRING, val);
if (recurse && the_ent->kind == svn_node_dir)
- SVN_ERR (get_dir_contents (dirents, path, rev, ra_session,
- recurse, ctx, pool));
+ SVN_ERR (get_dir_contents (dirent_fields, dirents, path, rev,
+ ra_session, recurse, ctx, pool));
}
return SVN_NO_ERROR;
}
svn_error_t *
-svn_client_ls3 (apr_hash_t **dirents,
+svn_client_ls4 (apr_hash_t **dirents,
apr_hash_t **locks,
const char *path_or_url,
const svn_opt_revision_t *peg_revision,
const svn_opt_revision_t *revision,
- svn_boolean_t recurse,
+ svn_boolean_t recurse,
+ apr_uint32_t dirent_fields,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
@@ -88,6 +90,10 @@
const char *repos_root;
const char *rel_path;
+ /* We use the kind field to determine if we should recurse, so we
+ always need it. */
+ dirent_fields |= SVN_DIRENT_KIND;
+
/* Get an RA plugin for this filesystem object. */
SVN_ERR (svn_client__ra_session_from_path (&ra_session, &rev,
&url, path_or_url, peg_revision,
@@ -105,8 +111,8 @@
{
*dirents = apr_hash_make (pool);
- SVN_ERR (get_dir_contents (*dirents, "", rev, ra_session, recurse,
- ctx, pool));
+ SVN_ERR (get_dir_contents (dirent_fields, *dirents, "", rev, ra_session,
+ recurse, ctx, pool));
}
else if (url_kind == svn_node_file)
{
@@ -184,6 +190,19 @@
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_client_ls3 (apr_hash_t **dirents,
+ apr_hash_t **locks,
+ const char *path_or_url,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_boolean_t recurse,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ return svn_client_ls4 (dirents, locks, path_or_url, peg_revision,
+ revision, recurse, SVN_DIRENT_ALL, ctx, pool);
+}
svn_error_t *
svn_client_ls2 (apr_hash_t **dirents,
Index: subversion/clients/cmdline/ls-cmd.c
===================================================================
--- subversion/clients/cmdline/ls-cmd.c (revision 17044)
+++ subversion/clients/cmdline/ls-cmd.c (working copy)
@@ -278,6 +278,7 @@
apr_array_header_t *targets;
int i;
apr_pool_t *subpool = svn_pool_create (pool);
+ apr_uint32_t dirent_fields;
SVN_ERR (svn_opt_args_to_target_array2 (&targets, os,
opt_state->targets, pool));
@@ -307,6 +308,11 @@
"mode"));
}
+ if (opt_state->verbose || opt_state->xml)
+ dirent_fields = SVN_DIRENT_ALL;
+ else
+ dirent_fields = SVN_DIRENT_KIND; /* the only thing we actually need... */
+
/* For each target, try to list it. */
for (i = 0; i < targets->nelts; i++)
{
@@ -324,12 +330,13 @@
SVN_ERR (svn_opt_parse_path (&peg_revision, &truepath, target,
subpool));
- SVN_ERR (svn_client_ls3 (&dirents,
+ SVN_ERR (svn_client_ls4 (&dirents,
(opt_state->xml || opt_state->verbose)
? &locks : NULL,
truepath, &peg_revision,
&(opt_state->start_revision),
- opt_state->recursive, ctx, subpool));
+ opt_state->recursive, dirent_fields,
+ ctx, subpool));
if (opt_state->xml)
SVN_ERR (print_dirents_xml (dirents, locks, truepath, ctx, subpool));
Index: subversion/libsvn_ra_svn/client.c
===================================================================
--- subversion/libsvn_ra_svn/client.c (revision 17044)
+++ subversion/libsvn_ra_svn/client.c (working copy)
@@ -1018,8 +1018,10 @@
return SVN_NO_ERROR;
}
-static svn_error_t *ra_svn_get_dir(svn_ra_session_t *session, const char *path,
- svn_revnum_t rev, apr_hash_t **dirents,
+static svn_error_t *ra_svn_get_dir(svn_ra_session_t *session,
+ const char *path, svn_revnum_t rev,
+ apr_uint32_t dirent_fields,
+ apr_hash_t **dirents,
svn_revnum_t *fetched_rev,
apr_hash_t **props,
apr_pool_t *pool)
@@ -1035,8 +1037,36 @@
apr_uint64_t size;
svn_dirent_t *dirent;
- SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "get-dir", "c(?r)bb", path,
- rev, (props != NULL), (dirents != NULL)));
+ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w(c(?r)bb(!", "get-dir", path,
+ rev, (props != NULL), (dirents != NULL)));
+ if (dirent_fields & SVN_DIRENT_KIND)
+ {
+ SVN_ERR(svn_ra_svn_write_word(conn, pool, SVN_RA_SVN_DIRENT_KIND));
+ }
+ if (dirent_fields & SVN_DIRENT_SIZE)
+ {
+ SVN_ERR(svn_ra_svn_write_word(conn, pool, SVN_RA_SVN_DIRENT_SIZE));
+ }
+ if (dirent_fields & SVN_DIRENT_HAS_PROPS)
+ {
+ SVN_ERR(svn_ra_svn_write_word(conn, pool, SVN_RA_SVN_DIRENT_HAS_PROPS));
+ }
+ if (dirent_fields & SVN_DIRENT_CREATED_REV)
+ {
+ SVN_ERR(svn_ra_svn_write_word(conn, pool,
+ SVN_RA_SVN_DIRENT_CREATED_REV));
+ }
+ if (dirent_fields & SVN_DIRENT_TIME)
+ {
+ SVN_ERR(svn_ra_svn_write_word(conn, pool, SVN_RA_SVN_DIRENT_TIME));
+ }
+ if (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
+ {
+ SVN_ERR(svn_ra_svn_write_word(conn, pool,
+ SVN_RA_SVN_DIRENT_LAST_AUTHOR));
+ }
+ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!))"));
+
SVN_ERR(handle_auth_request(sess_baton, pool));
SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "rll", &rev, &proplist,
&dirlist));
@@ -1075,7 +1105,6 @@
return SVN_NO_ERROR;
}
-
static svn_error_t *ra_svn_update(svn_ra_session_t *session,
const svn_ra_reporter2_t **reporter,
void **report_baton, svn_revnum_t rev,
Index: subversion/libsvn_ra_svn/protocol
===================================================================
--- subversion/libsvn_ra_svn/protocol (revision 17044)
+++ subversion/libsvn_ra_svn/protocol (working copy)
@@ -252,7 +252,8 @@
whether an error occurred during the sending of the file.
get-dir
- params: ( path:string [ rev:number ] want-props:bool want-contents:bool )
+ params: ( path:string [ rev:number ] want-props:bool want-contents:bool
+ [ dirent-field:string ... ] )
response: ( rev:number props:proplist ( entry:dirent ... ) )]
dirent: ( name:string kind:node-kind size:number has-props:bool
created-rev:number [ created-date:string ]
Index: subversion/libsvn_ra_dav/ra_dav.h
===================================================================
--- subversion/libsvn_ra_dav/ra_dav.h (revision 17044)
+++ subversion/libsvn_ra_dav/ra_dav.h (working copy)
@@ -240,6 +240,7 @@
svn_ra_session_t *session,
const char *path,
svn_revnum_t revision,
+ apr_uint32_t dirent_fields,
apr_hash_t **dirents,
svn_revnum_t *fetched_rev,
apr_hash_t **props,
Index: subversion/libsvn_ra_dav/fetch.c
===================================================================
--- subversion/libsvn_ra_dav/fetch.c (revision 17044)
+++ subversion/libsvn_ra_dav/fetch.c (working copy)
@@ -18,6 +18,8 @@
+#include
+
#define APR_WANT_STRFUNC
#include /* for strcmp() */
@@ -924,6 +926,7 @@
svn_error_t *svn_ra_dav__get_dir(svn_ra_session_t *session,
const char *path,
svn_revnum_t revision,
+ apr_uint32_t dirent_fields,
apr_hash_t **dirents,
svn_revnum_t *fetched_rev,
apr_hash_t **props,
@@ -963,11 +966,83 @@
if (dirents)
{
+ ne_propname *which_props;
+
+ /* if we didn't ask for the has_props field, we can get individual
+ properties. */
+ if ((SVN_DIRENT_HAS_PROPS & dirent_fields) == 0)
+ {
+ apr_size_t num_props = 1; /* start with one for the final NULL */
+
+ if (dirent_fields & SVN_DIRENT_KIND)
+ ++num_props;
+
+ if (dirent_fields & SVN_DIRENT_SIZE)
+ ++num_props;
+
+ if (dirent_fields & SVN_DIRENT_CREATED_REV)
+ ++num_props;
+
+ if (dirent_fields & SVN_DIRENT_TIME)
+ ++num_props;
+
+ if (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
+ ++num_props;
+
+ which_props = apr_pcalloc (pool, num_props * sizeof (ne_propname));
+
+ --num_props; /* damn zero based arrays... */
+
+ /* first, null out the end... */
+ which_props[num_props].nspace = NULL;
+ which_props[num_props--].name = NULL;
+
+ /* Now, go through and fill in the ones we care about, moving along
+ the array as we go. */
+
+ if (dirent_fields & SVN_DIRENT_KIND)
+ {
+ which_props[num_props].nspace = "DAV:";
+ which_props[num_props--].name = "resourcetype";
+ }
+
+ if (dirent_fields & SVN_DIRENT_SIZE)
+ {
+ which_props[num_props].nspace = "DAV:";
+ which_props[num_props--].name = "getcontentlength";
+ }
+
+ if (dirent_fields & SVN_DIRENT_CREATED_REV)
+ {
+ which_props[num_props].nspace = "DAV:";
+ which_props[num_props--].name = "version-name";
+ }
+
+ if (dirent_fields & SVN_DIRENT_TIME)
+ {
+ which_props[num_props].nspace = "DAV:";
+ which_props[num_props--].name = "creationdate";
+ }
+
+ if (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
+ {
+ which_props[num_props].nspace = "DAV:";
+ which_props[num_props--].name = "creator-displayname";
+ }
+
+ assert (num_props == -1);
+ }
+ else
+ {
+ /* get all props, since we need them all to do has_props */
+ which_props = NULL;
+ }
+
/* Just like Nautilus, Cadaver, or any other browser, we do a
PROPFIND on the directory of depth 1. */
SVN_ERR( svn_ra_dav__get_props(&resources, ras->sess,
final_url, NE_DEPTH_ONE,
- NULL, NULL /* all props */, pool) );
+ NULL, which_props, pool) );
/* Count the number of path components in final_url. */
final_url_n_components = svn_path_component_count(final_url);
@@ -1000,57 +1075,76 @@
continue;
entry = apr_pcalloc (pool, sizeof(*entry));
-
- /* node kind */
- entry->kind = resource->is_collection ? svn_node_dir : svn_node_file;
-
- /* size */
- propval = apr_hash_get(resource->propset,
- SVN_RA_DAV__PROP_GETCONTENTLENGTH,
- APR_HASH_KEY_STRING);
- if (propval == NULL)
- entry->size = 0;
- else
- entry->size = svn__atoui64(propval->data);
-
- /* does this resource contain any 'svn' or 'custom' properties,
- i.e. ones actually created and set by the user? */
- for (h = apr_hash_first (pool, resource->propset);
- h; h = apr_hash_next (h))
+
+ if (dirent_fields & SVN_DIRENT_KIND)
{
- const void *kkey;
- void *vval;
- apr_hash_this (h, &kkey, NULL, &vval);
+ /* node kind */
+ entry->kind = resource->is_collection ? svn_node_dir
+ : svn_node_file;
+ }
+
+ if (dirent_fields & SVN_DIRENT_SIZE)
+ {
+ /* size */
+ propval = apr_hash_get(resource->propset,
+ SVN_RA_DAV__PROP_GETCONTENTLENGTH,
+ APR_HASH_KEY_STRING);
+ if (propval == NULL)
+ entry->size = 0;
+ else
+ entry->size = svn__atoui64(propval->data);
+ }
+
+ if (dirent_fields & SVN_DIRENT_HAS_PROPS)
+ {
+ /* does this resource contain any 'svn' or 'custom' properties,
+ i.e. ones actually created and set by the user? */
+ for (h = apr_hash_first (pool, resource->propset);
+ h; h = apr_hash_next (h))
+ {
+ const void *kkey;
+ void *vval;
+ apr_hash_this (h, &kkey, NULL, &vval);
- if (strncmp((const char *)kkey, SVN_DAV_PROP_NS_CUSTOM,
- sizeof(SVN_DAV_PROP_NS_CUSTOM) - 1) == 0)
- entry->has_props = TRUE;
+ if (strncmp((const char *)kkey, SVN_DAV_PROP_NS_CUSTOM,
+ sizeof(SVN_DAV_PROP_NS_CUSTOM) - 1) == 0)
+ entry->has_props = TRUE;
- else if (strncmp((const char *)kkey, SVN_DAV_PROP_NS_SVN,
- sizeof(SVN_DAV_PROP_NS_SVN) - 1) == 0)
- entry->has_props = TRUE;
+ else if (strncmp((const char *)kkey, SVN_DAV_PROP_NS_SVN,
+ sizeof(SVN_DAV_PROP_NS_SVN) - 1) == 0)
+ entry->has_props = TRUE;
+ }
+ }
+
+ if (dirent_fields & SVN_DIRENT_CREATED_REV)
+ {
+ /* created_rev & friends */
+ propval = apr_hash_get(resource->propset,
+ SVN_RA_DAV__PROP_VERSION_NAME,
+ APR_HASH_KEY_STRING);
+ if (propval != NULL)
+ entry->created_rev = SVN_STR_TO_REV(propval->data);
}
-
- /* created_rev & friends */
- propval = apr_hash_get(resource->propset,
- SVN_RA_DAV__PROP_VERSION_NAME,
- APR_HASH_KEY_STRING);
- if (propval != NULL)
- entry->created_rev = SVN_STR_TO_REV(propval->data);
-
- propval = apr_hash_get(resource->propset,
- SVN_RA_DAV__PROP_CREATIONDATE,
- APR_HASH_KEY_STRING);
- if (propval != NULL)
- SVN_ERR( svn_time_from_cstring(&(entry->time),
- propval->data, pool) );
-
- propval = apr_hash_get(resource->propset,
- SVN_RA_DAV__PROP_CREATOR_DISPLAYNAME,
- APR_HASH_KEY_STRING);
- if (propval != NULL)
- entry->last_author = propval->data;
-
+
+ if (dirent_fields & SVN_DIRENT_TIME)
+ {
+ propval = apr_hash_get(resource->propset,
+ SVN_RA_DAV__PROP_CREATIONDATE,
+ APR_HASH_KEY_STRING);
+ if (propval != NULL)
+ SVN_ERR( svn_time_from_cstring(&(entry->time),
+ propval->data, pool) );
+ }
+
+ if (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
+ {
+ propval = apr_hash_get(resource->propset,
+ SVN_RA_DAV__PROP_CREATOR_DISPLAYNAME,
+ APR_HASH_KEY_STRING);
+ if (propval != NULL)
+ entry->last_author = propval->data;
+ }
+
apr_hash_set(*dirents,
svn_path_uri_decode(svn_path_basename(childname, pool),
pool),
@@ -1072,7 +1166,6 @@
}
-
/* ------------------------------------------------------------------------- */
svn_error_t *svn_ra_dav__get_latest_revnum(svn_ra_session_t *session,
Index: subversion/svnserve/serve.c
===================================================================
--- subversion/svnserve/serve.c (revision 17044)
+++ subversion/svnserve/serve.c (working copy)
@@ -1062,10 +1062,46 @@
svn_fs_root_t *root;
apr_pool_t *subpool;
svn_boolean_t want_props, want_contents;
+ apr_uint64_t dirent_fields;
+ apr_array_header_t *dirent_fields_list = NULL;
+ svn_ra_svn_item_t *elt;
+ int i;
- SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c(?r)bb", &path, &rev,
- &want_props, &want_contents));
+ SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c(?r)bb?l", &path, &rev,
+ &want_props, &want_contents,
+ &dirent_fields_list));
+ if (! dirent_fields_list)
+ {
+ dirent_fields = SVN_DIRENT_ALL;
+ }
+ else
+ {
+ dirent_fields = 0;
+
+ for (i = 0; i < dirent_fields_list->nelts; ++i)
+ {
+ elt = &APR_ARRAY_IDX(dirent_fields_list, i, svn_ra_svn_item_t);
+
+ if (elt->kind != SVN_RA_SVN_WORD)
+ return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+ "Dirent field not a string");
+
+ if (strcmp(SVN_RA_SVN_DIRENT_KIND, elt->u.word) == 0)
+ dirent_fields |= SVN_DIRENT_KIND;
+ else if (strcmp(SVN_RA_SVN_DIRENT_SIZE, elt->u.word) == 0)
+ dirent_fields |= SVN_DIRENT_SIZE;
+ else if (strcmp(SVN_RA_SVN_DIRENT_HAS_PROPS, elt->u.word) == 0)
+ dirent_fields |= SVN_DIRENT_HAS_PROPS;
+ else if (strcmp(SVN_RA_SVN_DIRENT_CREATED_REV, elt->u.word) == 0)
+ dirent_fields |= SVN_DIRENT_CREATED_REV;
+ else if (strcmp(SVN_RA_SVN_DIRENT_TIME, elt->u.word) == 0)
+ dirent_fields |= SVN_DIRENT_TIME;
+ else if (strcmp(SVN_RA_SVN_DIRENT_LAST_AUTHOR, elt->u.word) == 0)
+ dirent_fields |= SVN_DIRENT_LAST_AUTHOR;
+ }
+ }
+
full_path = svn_path_join(b->fs_path->data,
svn_path_canonicalize(path, pool), pool);
@@ -1102,30 +1138,48 @@
file_path = svn_path_join(full_path, name, subpool);
entry = apr_pcalloc(pool, sizeof(*entry));
- /* kind */
- entry->kind = fsent->kind;
+ if (dirent_fields & SVN_DIRENT_KIND)
+ {
+ /* kind */
+ entry->kind = fsent->kind;
+ }
- /* size */
- if (entry->kind == svn_node_dir)
- entry->size = 0;
- else
- SVN_CMD_ERR(svn_fs_file_length(&entry->size, root, file_path,
- subpool));
+ if (dirent_fields & SVN_DIRENT_SIZE)
+ {
+ /* size */
+ if (entry->kind == svn_node_dir)
+ entry->size = 0;
+ else
+ SVN_CMD_ERR(svn_fs_file_length(&entry->size, root, file_path,
+ subpool));
+ }
- /* has_props */
- SVN_CMD_ERR(svn_fs_node_proplist(&file_props, root, file_path,
- subpool));
- entry->has_props = (apr_hash_count(file_props) > 0) ? TRUE : FALSE;
+ if (dirent_fields & SVN_DIRENT_SIZE)
+ {
+ /* has_props */
+ SVN_CMD_ERR(svn_fs_node_proplist(&file_props, root, file_path,
+ subpool));
+ entry->has_props = (apr_hash_count(file_props) > 0) ? TRUE
+ : FALSE;
+ }
- /* created_rev, last_author, time */
- SVN_CMD_ERR(svn_repos_get_committed_info(&entry->created_rev, &cdate,
- &cauthor, root, file_path,
- subpool));
- entry->last_author = apr_pstrdup(pool, cauthor);
- if (cdate)
- SVN_CMD_ERR(svn_time_from_cstring(&entry->time, cdate, subpool));
- else
- entry->time = (time_t) -1;
+ if ((dirent_fields & SVN_DIRENT_LAST_AUTHOR)
+ || (dirent_fields & SVN_DIRENT_TIME)
+ || (dirent_fields & SVN_DIRENT_CREATED_REV))
+ {
+ /* created_rev, last_author, time */
+ SVN_CMD_ERR(svn_repos_get_committed_info(&entry->created_rev,
+ &cdate,
+ &cauthor, root,
+ file_path,
+ subpool));
+ entry->last_author = apr_pstrdup(pool, cauthor);
+ if (cdate)
+ SVN_CMD_ERR(svn_time_from_cstring(&entry->time, cdate,
+ subpool));
+ else
+ entry->time = (time_t) -1;
+ }
/* Store the entry. */
apr_hash_set(entries, name, APR_HASH_KEY_STRING, entry);