You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2012/03/15 22:31:46 UTC

svn commit: r1301211 [1/2] - in /subversion/branches/inheritable-props/subversion: include/ libsvn_client/ libsvn_fs/ libsvn_fs_base/ libsvn_fs_fs/ libsvn_ra/ libsvn_ra_local/ libsvn_ra_neon/ libsvn_ra_serf/ libsvn_ra_svn/ libsvn_subr/ svn/

Author: pburba
Date: Thu Mar 15 21:31:45 2012
New Revision: 1301211

URL: http://svn.apache.org/viewvc?rev=1301211&view=rev
Log:
On the inheritable-props branch: Some initial basic functionality.

Rev a few new APIs to allow 'svn pg' and 'svn pl' to find inherited
properties on URL targets (with an FSFS back-end):

  svn_proplist_receiver_t
  svn_client_propget4
  svn_client_proplist3
  svn_fs_node_proplist2
  svn_ra_get_dir3
  svn_ra_get_dir2

* subversion/include/svn_client.h

  (svn_proplist_receiver2_t,
   svn_client_propget5,
   svn_client_proplist4): New.

  (svn_proplist_receiver_t,
   svn_client_propget4,
   svn_client_proplist3): Deprecated.

* subversion/include/svn_fs.h

  (svn_fs_node_proplist2): New.

  (svn_fs_node_proplist): Deprecated.

* subversion/include/svn_props.h

  (svn_prop_inherited_item_t,
   svn_prop_inherited_item_dup,
   svn_prop_inherited_array_dup): New.

* subversion/include/svn_ra.h

  (svn_ra_get_file2,
   svn_ra_get_dir3): New.

  (svn_ra_get_file,
   svn_ra_get_dir2): Deprecated.

* subversion/libsvn_client/deprecated.c

  (svn_client_propget4,
   svn_client_proplist3): Deprecated implementations moved here
   from prop_commands.c.

  (proplist_wrapper_receiver,
   wrap_proplist_receiver): New helpers for svn_client_proplist3.

* subversion/libsvn_client/prop_commands.c
 
  (remote_propget): Support option to get inherited props.  Use standard
   pool argument names.

  (svn_client_propget5): New (doesn't yet support getting inherited props
   from the WC).

  (call_receiver): Update to reflect new svn_proplist_receiver2_t.

  (remote_proplist): Support option to get inherited props.  Update doc
   string, we don't use svn_client_proplist_item_t anymore.  Use standard
   pool argument names.

  (svn_client_proplist4): New (doesn't yet support getting inherited props
   from the WC).

* subversion/libsvn_client/revisions.c

  (svn_client__get_revision_number): Minor comment tweak to reflect that
   svn_client_proplist4 is the latest API.

* subversion/libsvn_fs/fs-loader.c

  (svn_fs_node_proplist2): New.

  (svn_fs_node_proplist): Deprecated.

* subversion/libsvn_fs/fs-loader.h

  (root_vtable_t.node_proplist): Update to reflect changes to 
svn_fs_node_proplist.

* subversion/libsvn_fs_base/tree.c

  (base_node_proplist): Update signature to reflect changes to
   svn_fs_node_proplist, but no BDB implementation yet.

* subversion/libsvn_fs_fs/tree.c

  (fs_node_proplist): Update to reflect changes to svn_fs_node_proplist.

* subversion/libsvn_ra/deprecated

  (svn_ra_get_file,
   svn_ra_get_dir,
   svn_ra_get_dir2): Deprecated implementations moved here from ra_loader.c.

* subversion/libsvn_ra/ra_loader.c

  (svn_ra_get_file2,
   svn_ra_get_dir3): New.

* subversion/libsvn_ra/ra_loader.h

  (svn_ra__vtable_t.get_file,
   svn_ra__vtable_t.get_dir): Update to reflect latest svn_ra_get_file* and
   svn_ra_get_dir* APIs.

* subversion/libsvn_ra/wrapper_template.h

  (compat_get_file,
   compat_get_dir): Pass null for inherited_properties.

* subversion/libsvn_ra_local/ra_plugin.c

  (get_node_props): Support option to get inherited props.

  (svn_ra_local__get_file,
   svn_ra_local__get_dir): Update to reflect latest svn_ra_get_file* and
   svn_ra_get_dir* APIs.

* subversion/libsvn_ra_neon/fetch.c
  
  (svn_ra_neon__get_file,
   svn_ra_neon__get_dir): Update signatures to reflect latest
   svn_ra_get_file* and svn_ra_get_dir* APIs (not implemented yet).

* subversion/libsvn_ra_neon/ra_neon.h

  (svn_ra_neon__get_file,
   svn_ra_neon__get_dir): Update signature to reflect latest
   svn_ra_get_file* and svn_ra_get_dir* APIs.

* subversion/libsvn_ra_serf/ra_serf.h

  (svn_ra_serf__get_file): Update signature to reflect latest
   svn_ra_get_file API.

* subversion/libsvn_ra_serf/serf.c

  (svn_ra_serf__get_dir): Update signature to reflect latest svn_ra_get_dir
   API (not yet implemented).

* subversion/libsvn_ra_serf/update.c

  (svn_ra_serf__get_file): Update signature to reflect latest svn_ra_get_file
   API (not yet implemented).

* subversion/libsvn_ra_svn/client.c

  (ra_svn_get_file,
   ra_svn_get_dir): Update signatures to reflect latest
   svn_ra_get_file* and svn_ra_get_dir* APIs (not implemented yet).

* subversion/libsvn_subr/properties.c

  (svn_prop_inherited_item_dup,
   svn_prop_inherited_array_dup): New.

* subversion/svn/cl.h

  (svn_cl__opt_state_t): Add option for --show-inherited-props.

* subversion/svn/main.c

  (svn_cl__longopt_t): Add identifier for --show-inherited-props.

  (svn_cl__options): Add option code and description for
   --show-inherited-props.

* subversion/svn/propget-cmd.c

  (print_single_prop): New, factored out of print_properties.

  (print_properties): Add support to print inherited properties.

  (svn_cl__propget): Implement --show-inherited-props (no --xml output yet).

* subversion/svn/proplist-cmd.c

  (proplist_receiver_xml): Update signature to match
   svn_proplist_receiver2_t, no implementation yet.

  (proplist_receiver): Implement svn_proplist_receiver2_t.

  (svn_cl__proplist): Implement --show-inherited-props (no --xml output yet).

Modified:
    subversion/branches/inheritable-props/subversion/include/svn_client.h
    subversion/branches/inheritable-props/subversion/include/svn_fs.h
    subversion/branches/inheritable-props/subversion/include/svn_props.h
    subversion/branches/inheritable-props/subversion/include/svn_ra.h
    subversion/branches/inheritable-props/subversion/libsvn_client/deprecated.c
    subversion/branches/inheritable-props/subversion/libsvn_client/prop_commands.c
    subversion/branches/inheritable-props/subversion/libsvn_client/revisions.c
    subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.c
    subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.h
    subversion/branches/inheritable-props/subversion/libsvn_fs_base/tree.c
    subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c
    subversion/branches/inheritable-props/subversion/libsvn_ra/deprecated.c
    subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c
    subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.h
    subversion/branches/inheritable-props/subversion/libsvn_ra/wrapper_template.h
    subversion/branches/inheritable-props/subversion/libsvn_ra_local/ra_plugin.c
    subversion/branches/inheritable-props/subversion/libsvn_ra_neon/fetch.c
    subversion/branches/inheritable-props/subversion/libsvn_ra_neon/ra_neon.h
    subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h
    subversion/branches/inheritable-props/subversion/libsvn_ra_serf/serf.c
    subversion/branches/inheritable-props/subversion/libsvn_ra_serf/update.c
    subversion/branches/inheritable-props/subversion/libsvn_ra_svn/client.c
    subversion/branches/inheritable-props/subversion/libsvn_subr/properties.c
    subversion/branches/inheritable-props/subversion/svn/cl.h
    subversion/branches/inheritable-props/subversion/svn/main.c
    subversion/branches/inheritable-props/subversion/svn/propget-cmd.c
    subversion/branches/inheritable-props/subversion/svn/proplist-cmd.c

Modified: subversion/branches/inheritable-props/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/include/svn_client.h?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/include/svn_client.h (original)
+++ subversion/branches/inheritable-props/subversion/include/svn_client.h Thu Mar 15 21:31:45 2012
@@ -355,10 +355,30 @@ typedef struct svn_client_proplist_item_
 } svn_client_proplist_item_t;
 
 /**
- * The callback invoked by svn_client_proplist3().  Each invocation
- * provides the regular properties of @a path which is either a WC path or
- * a URL.  @a prop_hash maps property names (char *) to property
-   values (svn_string_t *).  Use @a pool for all temporary allocation.
+ * The callback invoked by svn_client_proplist4().  Each invocation
+ * provides the regular and/or inherited properties of @a path, which is
+ * either a working copy path or a URL.  If @a prop_hash is not @c NULL, then
+ * it maps explicit <tt>const char *</tt> property names to
+ * <tt>svn_string_t *</tt> explicit property values.  If @a inherited_props
+ * is not @c NULL, then it is a depth-first ordered array of
+ * #svn_prop_inherited_item_t * structures representing the
+ * properties inherited by @a path.  Use @a scratch_pool for all temporary
+ * allocations.
+ *
+ * @since New in 1.8.
+ */
+typedef svn_error_t *(*svn_proplist_receiver2_t)(
+  void *baton,
+  const char *path,
+  apr_hash_t *prop_hash,
+  apr_array_header_t *inherited_props,
+  apr_pool_t *scratch_pool);
+
+/**
+ * Similar to #svn_proplist_receiver2_t, but doesn't return inherited
+ * properties.
+ *
+ * @deprecated Provided for backward compatibility with the 1.7 API.
  *
  * @since New in 1.5.
  */
@@ -4569,9 +4589,20 @@ svn_client_revprop_set(const char *propn
 
 /**
  * Set @a *props to a hash table whose keys are absolute paths or URLs
- * of items on which property @a propname is set, and whose values are
- * `#svn_string_t *' representing the property value for @a propname
- * at that path.
+ * of items on which property @a propname is explicitly set, and whose
+ * values are <tt>svn_string_t *</tt> representing the property value for
+ * @a propname at that path.
+ *
+ * If @a inherited_props is not @c NULL, then set @a *inherited_props to a
+ * depth-first ordered array of #svn_prop_inherited_item_t * structures
+ * representing the properties inherited by @a target.  If @a target is a
+ * working copy path, then properties inherited by @a target as far as the
+ * root of the working copy are obtained from the working copy's actual
+ * property values.  Properties inherited from above the working copy root
+ * come from the inherited properties cache.  If @a target is a URL, then
+ * the inherited properties come from the repository.  If @a inherited_props
+ * is not @c NULL and no inheritable properties are found, then set
+ * @a *inherited_props to an empty array.
  *
  * Allocate @a *props, its keys, and its values in @a pool, use
  * @a scratch_pool for temporary allocations.
@@ -4611,8 +4642,30 @@ svn_client_revprop_set(const char *propn
  * This function returns SVN_ERR_UNVERSIONED_RESOURCE when it is called on
  * unversioned nodes.
  *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_client_propget5(apr_hash_t **props,
+                    apr_array_header_t **inherited_props,
+                    const char *propname,
+                    const char *target,  /* abspath or URL */
+                    const svn_opt_revision_t *peg_revision,
+                    const svn_opt_revision_t *revision,
+                    svn_revnum_t *actual_revnum,
+                    svn_depth_t depth,
+                    const apr_array_header_t *changelists,
+                    svn_client_ctx_t *ctx,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool);
+
+/**
+ * Similar to svn_client_propget5 but doesn't support the retrieval of the
+ * properties inherited by @a target.
+ *
  * @since New in 1.7.
+ * @deprecated Provided for backward compatibility with the 1.8 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_client_propget4(apr_hash_t **props,
                     const char *propname,
@@ -4706,22 +4759,22 @@ svn_client_revprop_get(const char *propn
                        apr_pool_t *pool);
 
 /**
- * Invoke @a receiver with @a receiver_baton to return the regular properties
- * of @a target, a URL or working copy path.  @a receiver will be called
- * for each path encountered.
+ * Invoke @a receiver with @a receiver_baton to return the regular explicit, and
+ * possibly the inherited, properties of @a target, a URL or working copy path.
+ * @a receiver will be called for each path encountered.
  *
  * @a target is a WC path or a URL.
  *
- * If @a revision->kind is #svn_opt_revision_unspecified, then get
- * properties from the working copy, if @a target is a working copy
- * path, or from the repository head if @a target is a URL.  Else get
- * the properties as of @a revision.  The actual node revision
- * selected is determined by the path as it exists in @a peg_revision.
- * If @a peg_revision->kind is #svn_opt_revision_unspecified, then it
- * defaults to #svn_opt_revision_head for URLs or
- * #svn_opt_revision_working for WC targets.  Use the authentication
- * baton cached in @a ctx for authentication if contacting the
- * repository.
+ * If @a revision->kind is #svn_opt_revision_unspecified, then get the
+ * explicit (and possibly the inherited) properties from the working copy,
+ * if @a target is a working copy path, or from the repository head if
+ * @a target is a URL.  Else get the properties as of @a revision.
+ * The actual node revision selected is determined by the path as it exists
+ * in @a peg_revision.  If @a peg_revision->kind is
+ * #svn_opt_revision_unspecified, then it defaults to #svn_opt_revision_head
+ * for URLs or #svn_opt_revision_working for WC targets.  Use the
+ * authentication baton cached in @a ctx for authentication if contacting
+ * the repository.
  *
  * If @a depth is #svn_depth_empty, list only the properties of
  * @a target itself.  If @a depth is #svn_depth_files, and
@@ -4739,10 +4792,43 @@ svn_client_revprop_get(const char *propn
  * of one of those changelists.  If @a changelists is empty (or
  * altogether @c NULL), no changelist filtering occurs.
  *
+ * If @a get_target_inherited_props is true, then also return any inherited
+ * properties when @a receiver is called for @a target.  If @a target is a
+ * working copy path, then properties inherited by @a target as far as the
+ * root of the working copy are obtained from the working copy's actual
+ * property values.  Properties inherited from above the working copy
+ * root come from the inherited properties cache.  If @a target is a URL,
+ * then the inherited properties come from the repository.
+ * If @a get_target_inherited_props is false, then no inherited properties
+ * are returned to @a receiver.
+ *
  * If @a target is not found, return the error #SVN_ERR_ENTRY_NOT_FOUND.
  *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_client_proplist4(const char *target,
+                     const svn_opt_revision_t *peg_revision,
+                     const svn_opt_revision_t *revision,
+                     svn_depth_t depth,
+                     const apr_array_header_t *changelists,
+                     svn_boolean_t get_target_inherited_props,
+                     svn_proplist_receiver2_t receiver,
+                     void *receiver_baton,
+                     svn_client_ctx_t *ctx,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool);
+
+/**
+ * Similar to svn_client_proplist4(), except that the @a receiver type is
+ * a #svn_proplist_receiver_t and there is no support for finding the
+ * inherited properties for @a target and there is no separate scratch pool.
+ *
  * @since New in 1.5.
+ *
+ * @deprecated Provided for backward compatibility with the 1.8 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_client_proplist3(const char *target,
                      const svn_opt_revision_t *peg_revision,

Modified: subversion/branches/inheritable-props/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/include/svn_fs.h?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/include/svn_fs.h (original)
+++ subversion/branches/inheritable-props/subversion/include/svn_fs.h Thu Mar 15 21:31:45 2012
@@ -1400,12 +1400,34 @@ svn_fs_node_prop(svn_string_t **value_p,
                  apr_pool_t *pool);
 
 
-/** Set @a *table_p to the entire property list of @a path in @a root,
- * as an APR hash table allocated in @a pool.  The resulting table maps
+/** If @a table_p is not null, then set @a *table_p to the entire property
+ * list of @a path in @a root.  The resulting table maps
  * property names to pointers to #svn_string_t objects containing the
  * property value.
+ *
+ * If @a inherited_values is not @c NULL, then set @a *inherited_values to
+ * a depth-first ordered array of #svn_prop_inherited_item_t * structures
+ * (the path_or_url members of which are relative filesystem paths)
+ * representing the properties inherited by @a path.  If @a inherited_values
+ * is not @c NULL and no properties are inherited, then set
+ * @a *inherited_values to an empty array.
+ *
+ * @since New in 1.8.
  */
 svn_error_t *
+svn_fs_node_proplist2(apr_hash_t **table_p,
+                      apr_array_header_t **inherited_props,
+                      svn_fs_root_t *root,
+                      const char *path,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool);
+
+/**
+ * Similar to svn_fs_node_proplist2 but doesn't support the retrieval of
+ * the properties inherited by @a path and doesn't use a scratch pool.
+ *
+ * @deprecated Provided for backward compatibility with the 1.8 API. */
+svn_error_t *
 svn_fs_node_proplist(apr_hash_t **table_p,
                      svn_fs_root_t *root,
                      const char *path,

Modified: subversion/branches/inheritable-props/subversion/include/svn_props.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/include/svn_props.h?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/include/svn_props.h (original)
+++ subversion/branches/inheritable-props/subversion/include/svn_props.h Thu Mar 15 21:31:45 2012
@@ -85,6 +85,46 @@ svn_prop_array_dup(const apr_array_heade
                    apr_pool_t *pool);
 
 
+/** A structure to represent inherited properties.
+ *
+ * @since New in 1.8.
+ */
+typedef struct svn_prop_inherited_item_t
+{
+  /** The absolute working copy path, relative filesystem path, or URL from
+   * which the properties in @a prop_hash are inherited. */
+  const char *path_or_url;
+
+  /** A hash of (const char *) inherited property names, and (svn_string_t *)
+   * property values. */
+  apr_hash_t *prop_hash;
+
+} svn_prop_inherited_item_t;
+
+
+/**
+ * Return a deep copy of @a inherited_prop, allocated in @a result_pool.
+ * Use @a scratch_pool for temporary allocations.
+ * @since New in 1.8.
+ */
+svn_prop_inherited_item_t *
+svn_prop_inherited_item_dup(const svn_prop_inherited_item_t *inherited_prop,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
+
+
+/**
+ * Return a deep copy the array @a prop_array of svn_prop_inherited_item_t *
+ * items in @a result_pool.  Use @a scratch_pool for temporary allocations.
+ *
+ * @since New in 1.8.
+ */
+apr_array_header_t *
+svn_prop_inherited_array_dup(const apr_array_header_t *prop_array,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool);
+
+
 /**
  * Given a hash (keys <tt>const char *</tt> and values <tt>const
  * svn_string_t</tt>) of properties, returns an array of svn_prop_t

Modified: subversion/branches/inheritable-props/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/include/svn_ra.h?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/include/svn_ra.h (original)
+++ subversion/branches/inheritable-props/subversion/include/svn_ra.h Thu Mar 15 21:31:45 2012
@@ -938,11 +938,37 @@ svn_ra_get_commit_editor(svn_ra_session_
  * etc.)  The keys are <tt>const char *</tt>, values are
  * <tt>@c svn_string_t *</tt>.
  *
+ * If @a inherited_props is not @c NULL, then set @a *inherited_props to a
+ * depth-first ordered array of #svn_prop_inherited_item_t * structures
+ * representing the properties inherited by @a path at @a revision (or the
+ * 'head' revision if @a revision is @c SVN_INVALID_REVNUM.  If
+ * @a inherited_props is not @c NULL and no inheritable properties are found,
+ * then set @a *inherited_props to an empty array.
+ *
  * The stream handlers for @a stream may not perform any RA
  * operations using @a session.
  *
- * @since New in 1.2.
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_ra_get_file2(svn_ra_session_t *session,
+                 const char *path,
+                 svn_revnum_t revision,
+                 svn_stream_t *stream,
+                 svn_revnum_t *fetched_rev,
+                 apr_hash_t **props,
+                 apr_array_header_t **inherited_props,
+                 apr_pool_t *pool);
+
+/**
+ * Similar to @c svn_ra_get_file2, but does not support the retrieval of
+ * inherited properties.
+ *
+ * @since New in 1.8.
+ *
+ * @deprecated Provided for compatibility with the 1.2 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_ra_get_file(svn_ra_session_t *session,
                 const char *path,
@@ -977,8 +1003,35 @@ svn_ra_get_file(svn_ra_session_t *sessio
  * etc.)  The keys are <tt>const char *</tt>, values are
  * <tt>@c svn_string_t *</tt>.
  *
+ * If @a inherited_props is not @c NULL, then set @a *inherited_props to a
+ * depth-first ordered array of #svn_prop_inherited_item_t * structures
+ * representing the properties inherited by @a path at @a revision (or the
+ * 'head' revision if @a revision is @c SVN_INVALID_REVNUM.  If
+ * @a inherited_props is not @c NULL and no inheritable properties are found,
+ * then set @a *inherited_props to an empty array.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_ra_get_dir3(svn_ra_session_t *session,
+                apr_hash_t **dirents,
+                svn_revnum_t *fetched_rev,
+                apr_hash_t **props,
+                apr_array_header_t **inherited_props,
+                const char *path,
+                svn_revnum_t revision,
+                apr_uint32_t dirent_fields,
+                apr_pool_t *pool);
+
+/**
+ * Similar to @c svn_ra_get_dir3, but does not support the retrieval of
+ * inherited properties.
+ *
  * @since New in 1.4.
+ *
+ * @deprecated Provided for compatibility with the 1.8 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_ra_get_dir2(svn_ra_session_t *session,
                 apr_hash_t **dirents,

Modified: subversion/branches/inheritable-props/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_client/deprecated.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_client/deprecated.c Thu Mar 15 21:31:45 2012
@@ -1687,6 +1687,26 @@ svn_client_revprop_set(const char *propn
 }
 
 svn_error_t *
+svn_client_propget4(apr_hash_t **props,
+                    const char *propname,
+                    const char *target,
+                    const svn_opt_revision_t *peg_revision,
+                    const svn_opt_revision_t *revision,
+                    svn_revnum_t *actual_revnum,
+                    svn_depth_t depth,
+                    const apr_array_header_t *changelists,
+                    svn_client_ctx_t *ctx,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(svn_client_propget5(props, NULL, propname, target,
+                                             peg_revision, revision,
+                                             actual_revnum, depth,
+                                             changelists, ctx,
+                                             result_pool, scratch_pool));
+}
+
+svn_error_t *
 svn_client_propget3(apr_hash_t **props,
                     const char *propname,
                     const char *path_or_url,
@@ -1826,6 +1846,70 @@ svn_client_proplist_item_dup(const svn_c
   return new_item;
 }
 
+/* Baton for use with wrap_proplist_receiver */
+struct proplist_receiver_wrapper_baton {
+  void *baton;
+  svn_proplist_receiver_t receiver;
+};
+
+/* This implements svn_client_proplist_receiver2_t */
+static svn_error_t *
+proplist_wrapper_receiver(void *baton,
+                          const char *path,
+                          apr_hash_t *prop_hash,
+                          apr_array_header_t *inherited_props,
+                          apr_pool_t *pool)
+{
+  struct proplist_receiver_wrapper_baton *plrwb = baton;
+
+  if (plrwb->receiver)
+    return plrwb->receiver(plrwb->baton, path, prop_hash, pool);
+
+  return SVN_NO_ERROR;
+}
+
+static void
+wrap_proplist_receiver(svn_proplist_receiver2_t *receiver2,
+                       void **receiver2_baton,
+                       svn_proplist_receiver_t receiver,
+                       void *receiver_baton,
+                       apr_pool_t *pool)
+{
+  struct proplist_receiver_wrapper_baton *plrwb = apr_palloc(pool,
+                                                             sizeof(*plrwb));
+
+  /* Set the user provided old format callback in the baton. */
+  plrwb->baton = receiver_baton;
+  plrwb->receiver = receiver;
+
+  *receiver2_baton = plrwb;
+  *receiver2 = proplist_wrapper_receiver;
+}
+
+svn_error_t *
+svn_client_proplist3(const char *target,
+                     const svn_opt_revision_t *peg_revision,
+                     const svn_opt_revision_t *revision,
+                     svn_depth_t depth,
+                     const apr_array_header_t *changelists,
+                     svn_proplist_receiver_t receiver,
+                     void *receiver_baton,
+                     svn_client_ctx_t *ctx,
+                     apr_pool_t *pool)
+{
+
+  svn_proplist_receiver2_t receiver2;
+  void *receiver2_baton;
+
+  wrap_proplist_receiver(&receiver2, &receiver2_baton, receiver, receiver_baton,
+                         pool);
+
+  return svn_error_trace(svn_client_proplist4(target, peg_revision, revision,
+                                              depth, changelists, FALSE,
+                                              receiver2, receiver2_baton,
+                                              ctx, pool, pool));
+}
+
 /* Receiver baton used by proplist2() */
 struct proplist_receiver_baton {
   apr_array_header_t *props;

Modified: subversion/branches/inheritable-props/subversion/libsvn_client/prop_commands.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_client/prop_commands.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_client/prop_commands.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_client/prop_commands.c Thu Mar 15 21:31:45 2012
@@ -598,17 +598,24 @@ pristine_or_working_props(apr_hash_t **p
  * SESSION.  Store the value ('svn_string_t *') in PROPS, under the
  * path key "TARGET_PREFIX/TARGET_RELATIVE" ('const char *').
  *
+ * If INHERITED_PROPS is not null, then set *INHERITED_PROPS to a
+ * depth-first ordered array of svn_prop_inherited_item_t * structures
+ * representing the PROPNAME properties inherited by the target.  If
+ * INHERITABLE_PROPS in not null and no inheritable properties are found,
+ * then set *INHERITED_PROPS to an empty array.
+ *
  * Recurse according to DEPTH, similarly to svn_client_propget3().
  *
  * KIND is the kind of the node at "TARGET_PREFIX/TARGET_RELATIVE".
  * Yes, caller passes this; it makes the recursion more efficient :-).
  *
- * Allocate the keys and values in PERM_POOL, but do all temporary
- * work in WORK_POOL.  The two pools can be the same; recursive
- * calls may use a different WORK_POOL, however.
+ * Allocate PROPS and *INHERITED_PROPS in RESULT_POOL, but do all temporary
+ * work in SCRATCH_POOL.  The two pools can be the same; recursive
+ * calls may use a different SCRATCH_POOL, however.
  */
 static svn_error_t *
 remote_propget(apr_hash_t *props,
+               apr_array_header_t **inherited_props,
                const char *propname,
                const char *target_prefix,
                const char *target_relative,
@@ -616,26 +623,29 @@ remote_propget(apr_hash_t *props,
                svn_revnum_t revnum,
                svn_ra_session_t *ra_session,
                svn_depth_t depth,
-               apr_pool_t *perm_pool,
-               apr_pool_t *work_pool)
+               apr_pool_t *result_pool,
+               apr_pool_t *scratch_pool)
 {
   apr_hash_t *dirents;
   apr_hash_t *prop_hash;
   const svn_string_t *val;
   const char *target_full_url =
-    svn_path_url_add_component2(target_prefix, target_relative, work_pool);
+    svn_path_url_add_component2(target_prefix, target_relative,
+                                scratch_pool);
 
   if (kind == svn_node_dir)
     {
-      SVN_ERR(svn_ra_get_dir2(ra_session,
+      SVN_ERR(svn_ra_get_dir3(ra_session,
                               (depth >= svn_depth_files ? &dirents : NULL),
-                              NULL, &prop_hash, target_relative, revnum,
-                              SVN_DIRENT_KIND, work_pool));
+                              NULL, &prop_hash, inherited_props,
+                              target_relative, revnum, SVN_DIRENT_KIND,
+                              scratch_pool));
     }
   else if (kind == svn_node_file)
     {
-      SVN_ERR(svn_ra_get_file(ra_session, target_relative, revnum,
-                              NULL, NULL, &prop_hash, work_pool));
+      SVN_ERR(svn_ra_get_file2(ra_session, target_relative, revnum,
+                               NULL, NULL, &prop_hash, inherited_props,
+                               scratch_pool));
     }
   else if (kind == svn_node_none)
     {
@@ -650,10 +660,42 @@ remote_propget(apr_hash_t *props,
                                target_full_url);
     }
 
+  /* Make a copy of any inherited PROPNAME properties in RESULT_POOL. */
+  if (inherited_props)
+    {
+      int i;
+      apr_array_header_t *final_iprops =
+        apr_array_make(result_pool, 1, sizeof(svn_prop_inherited_item_t *));
+
+      for (i = 0; i < (*inherited_props)->nelts; i++)
+        {
+          svn_prop_inherited_item_t *iprop =
+            APR_ARRAY_IDX((*inherited_props), i, svn_prop_inherited_item_t *);
+          svn_string_t *iprop_val = apr_hash_get(iprop->prop_hash, propname,
+                                                 APR_HASH_KEY_STRING);
+
+          if (iprop_val)
+            {
+              svn_prop_inherited_item_t *new_iprop =
+                apr_palloc(result_pool, sizeof(*new_iprop));
+              new_iprop->path_or_url =
+                apr_pstrdup(result_pool, iprop->path_or_url);
+              new_iprop->prop_hash = apr_hash_make(result_pool);
+              apr_hash_set(new_iprop->prop_hash,
+                           apr_pstrdup(result_pool, propname),
+                           APR_HASH_KEY_STRING,
+                           svn_string_dup(iprop_val, result_pool));
+              APR_ARRAY_PUSH(final_iprops, svn_prop_inherited_item_t *) =
+                new_iprop;
+            }
+        }
+      *inherited_props = final_iprops;
+    }
+
   if ((val = apr_hash_get(prop_hash, propname, APR_HASH_KEY_STRING)))
     {
-      apr_hash_set(props, apr_pstrdup(perm_pool, target_full_url),
-                   APR_HASH_KEY_STRING, svn_string_dup(val, perm_pool));
+      apr_hash_set(props, apr_pstrdup(result_pool, target_full_url),
+                   APR_HASH_KEY_STRING, svn_string_dup(val, result_pool));
     }
 
   if (depth >= svn_depth_files
@@ -661,9 +703,9 @@ remote_propget(apr_hash_t *props,
       && apr_hash_count(dirents) > 0)
     {
       apr_hash_index_t *hi;
-      apr_pool_t *iterpool = svn_pool_create(work_pool);
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
-      for (hi = apr_hash_first(work_pool, dirents);
+      for (hi = apr_hash_first(scratch_pool, dirents);
            hi;
            hi = apr_hash_next(hi))
         {
@@ -683,7 +725,7 @@ remote_propget(apr_hash_t *props,
           new_target_relative = svn_relpath_join(target_relative, this_name,
                                                  iterpool);
 
-          SVN_ERR(remote_propget(props,
+          SVN_ERR(remote_propget(props, NULL,
                                  propname,
                                  target_prefix,
                                  new_target_relative,
@@ -691,7 +733,7 @@ remote_propget(apr_hash_t *props,
                                  revnum,
                                  ra_session,
                                  depth_below_here,
-                                 perm_pool, iterpool));
+                                 result_pool, iterpool));
         }
 
       svn_pool_destroy(iterpool);
@@ -780,7 +822,8 @@ get_prop_from_wc(apr_hash_t *props,
 
 /* Note: this implementation is very similar to svn_client_proplist. */
 svn_error_t *
-svn_client_propget4(apr_hash_t **props,
+svn_client_propget5(apr_hash_t **props,
+                    apr_array_header_t **inherited_props,
                     const char *propname,
                     const char *target,
                     const svn_opt_revision_t *peg_revision,
@@ -859,7 +902,7 @@ svn_client_propget4(apr_hash_t **props,
 
       SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, scratch_pool));
 
-      SVN_ERR(remote_propget(*props, propname, url, "",
+      SVN_ERR(remote_propget(*props, inherited_props, propname, url, "",
                              kind, revnum, ra_session,
                              depth, result_pool, scratch_pool));
     }
@@ -895,19 +938,24 @@ svn_client_revprop_get(const char *propn
 }
 
 
-/* Call RECEIVER for the given PATH and PROP_HASH.
+/* Call RECEIVER for the given PATH and its PROP_HASH and/or
+ * INHERITED_PROPERTIES.
  *
- * If PROP_HASH is null or has zero count, do nothing.
+ * If PROP_HASH is null or has zero count or INHERITED_PROPERTIES is null,
+ * then do nothing.
  */
 static svn_error_t*
 call_receiver(const char *path,
               apr_hash_t *prop_hash,
-              svn_proplist_receiver_t receiver,
+              apr_array_header_t *inherited_properties,
+              svn_proplist_receiver2_t receiver,
               void *receiver_baton,
-              apr_pool_t *pool)
+              apr_pool_t *scratch_pool)
 {
-  if (prop_hash && apr_hash_count(prop_hash))
-    SVN_ERR(receiver(receiver_baton, path, prop_hash, pool));
+  if ((prop_hash && apr_hash_count(prop_hash))
+      || inherited_properties)
+    SVN_ERR(receiver(receiver_baton, path, prop_hash, inherited_properties,
+                     scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -915,20 +963,23 @@ call_receiver(const char *path,
 
 /* Helper for the remote case of svn_client_proplist.
  *
- * Push a new 'svn_client_proplist_item_t *' item onto PROPLIST,
- * containing the properties for "TARGET_PREFIX/TARGET_RELATIVE" in
- * REVNUM, obtained using RA_LIB and SESSION.  The item->node_name
- * will be "TARGET_PREFIX/TARGET_RELATIVE", and the value will be a
- * hash mapping 'const char *' property names onto 'svn_string_t *'
- * property values.
+ * Call RECEIVER for paths at or under "TARGET_PREFIX/TARGET_RELATIVE@REVNUM"
+ * (obtained using RA_SESSION) which have regular properties.  If
+ * GET_TARGET_INHERITED_PROPS is true, then also send the target's inherited
+ * properties to the callback.
  *
- * Allocate the new item and its contents in POOL.
- * Do all looping, recursion, and temporary work in SCRATCHPOOL.
+ * The 'path' and keys for 'prop_hash' and 'inherited_prop' arguments to
+ * RECEIVER are all URLs.
+ * 
+ * RESULT_POOL is used to allocated the 'path', 'prop_hash', and
+ * 'inherited_prop' arguments to RECEIVER.  SCRATCH_POOL is used for all
+ * other (temporary) allocations.
  *
  * KIND is the kind of the node at "TARGET_PREFIX/TARGET_RELATIVE".
  *
  * If the target is a directory, only fetch properties for the files
- * and directories at depth DEPTH.
+ * and directories at depth DEPTH.  DEPTH has not effect on inherited
+ * properties.
  */
 static svn_error_t *
 remote_proplist(const char *target_prefix,
@@ -936,29 +987,37 @@ remote_proplist(const char *target_prefi
                 svn_node_kind_t kind,
                 svn_revnum_t revnum,
                 svn_ra_session_t *ra_session,
+                svn_boolean_t get_target_inherited_props,
                 svn_depth_t depth,
-                svn_proplist_receiver_t receiver,
+                svn_proplist_receiver2_t receiver,
                 void *receiver_baton,
-                apr_pool_t *pool,
-                apr_pool_t *scratchpool)
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
 {
   apr_hash_t *dirents;
   apr_hash_t *prop_hash, *final_hash;
   apr_hash_index_t *hi;
   const char *target_full_url =
-    svn_path_url_add_component2(target_prefix, target_relative, scratchpool);
+    svn_path_url_add_component2(target_prefix, target_relative, scratch_pool);
+  apr_array_header_t *inherited_props;
 
   if (kind == svn_node_dir)
     {
-      SVN_ERR(svn_ra_get_dir2(ra_session,
-                              (depth > svn_depth_empty) ? &dirents : NULL,
-                              NULL, &prop_hash, target_relative, revnum,
-                              SVN_DIRENT_KIND, scratchpool));
+      SVN_ERR(svn_ra_get_dir3(
+        ra_session,
+        (depth > svn_depth_empty) ? &dirents : NULL,
+        NULL, &prop_hash,
+        get_target_inherited_props ? &inherited_props : NULL,
+        target_relative, revnum,
+        SVN_DIRENT_KIND, scratch_pool));
     }
   else if (kind == svn_node_file)
     {
-      SVN_ERR(svn_ra_get_file(ra_session, target_relative, revnum,
-                              NULL, NULL, &prop_hash, scratchpool));
+      SVN_ERR(svn_ra_get_file2(
+        ra_session, target_relative, revnum,
+        NULL, NULL, &prop_hash,
+        get_target_inherited_props ? &inherited_props : NULL,
+        scratch_pool));
     }
   else
     {
@@ -969,9 +1028,9 @@ remote_proplist(const char *target_prefi
 
   /* Filter out non-regular properties, since the RA layer returns all
      kinds.  Copy regular properties keys/vals from the prop_hash
-     allocated in SCRATCHPOOL to the "final" hash allocated in POOL. */
-  final_hash = apr_hash_make(pool);
-  for (hi = apr_hash_first(scratchpool, prop_hash);
+     allocated in SCRATCH_POOL to the "final" hash allocated in POOL. */
+  final_hash = apr_hash_make(result_pool);
+  for (hi = apr_hash_first(scratch_pool, prop_hash);
        hi;
        hi = apr_hash_next(hi))
     {
@@ -984,21 +1043,30 @@ remote_proplist(const char *target_prefi
 
       if (prop_kind == svn_prop_regular_kind)
         {
-          name = apr_pstrdup(pool, name);
-          value = svn_string_dup(value, pool);
+          name = apr_pstrdup(result_pool, name);
+          value = svn_string_dup(value, result_pool);
           apr_hash_set(final_hash, name, klen, value);
         }
     }
 
-  SVN_ERR(call_receiver(target_full_url, final_hash, receiver, receiver_baton,
-                        pool));
+
+  if (get_target_inherited_props)
+    {
+      inherited_props = svn_prop_inherited_array_dup(inherited_props,
+                                                     result_pool,
+                                                     scratch_pool);
+    }
+
+  SVN_ERR(call_receiver(target_full_url, final_hash,
+                        get_target_inherited_props ? inherited_props : NULL,
+                        receiver, receiver_baton, result_pool));
 
   if (depth > svn_depth_empty
       && (kind == svn_node_dir) && (apr_hash_count(dirents) > 0))
     {
-      apr_pool_t *subpool = svn_pool_create(scratchpool);
+      apr_pool_t *subpool = svn_pool_create(scratch_pool);
 
-      for (hi = apr_hash_first(scratchpool, dirents);
+      for (hi = apr_hash_first(scratch_pool, dirents);
            hi;
            hi = apr_hash_next(hi))
         {
@@ -1024,10 +1092,11 @@ remote_proplist(const char *target_prefi
                                       this_ent->kind,
                                       revnum,
                                       ra_session,
+                                      FALSE,
                                       depth_below_here,
                                       receiver,
                                       receiver_baton,
-                                      pool,
+                                      result_pool,
                                       subpool));
             }
         }
@@ -1043,7 +1112,7 @@ remote_proplist(const char *target_prefi
 struct recursive_proplist_receiver_baton
 {
   svn_wc_context_t *wc_ctx;  /* Working copy context. */
-  svn_proplist_receiver_t wrapped_receiver;  /* Proplist receiver to call. */
+  svn_proplist_receiver2_t wrapped_receiver;  /* Proplist receiver to call. */
   void *wrapped_receiver_baton;    /* Baton for the proplist receiver. */
 
   /* Anchor, anchor_abspath pair for converting to relative paths */
@@ -1074,19 +1143,22 @@ recursive_proplist_receiver(void *baton,
     path = local_abspath;
 
   return svn_error_trace(b->wrapped_receiver(b->wrapped_receiver_baton,
-                                             path, props, scratch_pool));
+                                             path, props, NULL,
+                                             scratch_pool));
 }
 
 svn_error_t *
-svn_client_proplist3(const char *path_or_url,
+svn_client_proplist4(const char *path_or_url,
                      const svn_opt_revision_t *peg_revision,
                      const svn_opt_revision_t *revision,
                      svn_depth_t depth,
                      const apr_array_header_t *changelists,
-                     svn_proplist_receiver_t receiver,
+                     svn_boolean_t get_target_inherited_props,
+                     svn_proplist_receiver2_t receiver,
                      void *receiver_baton,
                      svn_client_ctx_t *ctx,
-                     apr_pool_t *pool)
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
 {
   const char *url;
 
@@ -1106,13 +1178,14 @@ svn_client_proplist3(const char *path_or
       apr_hash_t *changelist_hash = NULL;
       const char *local_abspath;
 
-      SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url, pool));
+      SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url,
+                                      scratch_pool));
 
       pristine = ((revision->kind == svn_opt_revision_committed)
                   || (revision->kind == svn_opt_revision_base));
 
       SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, local_abspath, FALSE,
-                               pool));
+                               scratch_pool));
 
       if (kind == svn_node_unknown || kind == svn_node_none)
         {
@@ -1121,12 +1194,12 @@ svn_client_proplist3(const char *path_or
           return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                                    _("'%s' is not under version control"),
                                    svn_dirent_local_style(local_abspath,
-                                                          pool));
+                                                          scratch_pool));
         }
 
       if (changelists && changelists->nelts)
         SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash,
-                                           changelists, pool));
+                                           changelists, scratch_pool));
 
       /* Fetch, recursively or not. */
       if (kind == svn_node_dir)
@@ -1153,17 +1226,18 @@ svn_client_proplist3(const char *path_or
                                               FALSE, pristine, changelists,
                                               recursive_proplist_receiver, &rb,
                                               ctx->cancel_func,
-                                              ctx->cancel_baton, pool));
+                                              ctx->cancel_baton, result_pool));
         }
       else if (svn_wc__changelist_match(ctx->wc_ctx, local_abspath,
-                                        changelist_hash, pool))
+                                        changelist_hash, scratch_pool))
         {
           apr_hash_t *hash;
 
           SVN_ERR(pristine_or_working_props(&hash, ctx->wc_ctx, local_abspath,
-                                            pristine, pool, pool));
-          SVN_ERR(call_receiver(path_or_url, hash,
-                                receiver, receiver_baton, pool));
+                                            pristine, result_pool,
+                                            scratch_pool));
+          SVN_ERR(call_receiver(path_or_url, hash, NULL,
+                                receiver, receiver_baton, scratch_pool));
 
         }
     }
@@ -1171,20 +1245,20 @@ svn_client_proplist3(const char *path_or
     {
       svn_ra_session_t *ra_session;
       svn_node_kind_t kind;
-      apr_pool_t *subpool = svn_pool_create(pool);
       svn_revnum_t revnum;
 
       /* Get an RA session for this URL. */
       SVN_ERR(svn_client__ra_session_from_path(&ra_session, &revnum,
                                                &url, path_or_url, NULL,
                                                peg_revision,
-                                               revision, ctx, pool));
+                                               revision, ctx, result_pool));
 
-      SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, pool));
+      SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, result_pool));
 
-      SVN_ERR(remote_proplist(url, "", kind, revnum, ra_session, depth,
-                              receiver, receiver_baton, pool, subpool));
-      svn_pool_destroy(subpool);
+      SVN_ERR(remote_proplist(url, "", kind, revnum, ra_session,
+                              get_target_inherited_props, depth,
+                              receiver, receiver_baton, result_pool,
+                              scratch_pool));
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/inheritable-props/subversion/libsvn_client/revisions.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_client/revisions.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_client/revisions.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_client/revisions.c Thu Mar 15 21:31:45 2012
@@ -96,7 +96,7 @@ svn_client__get_revision_number(svn_revn
                                                scratch_pool);
 
         /* Return the same error as older code did (before and at r935091).
-           At least svn_client_proplist3 promises SVN_ERR_ENTRY_NOT_FOUND. */
+           At least svn_client_proplist4 promises SVN_ERR_ENTRY_NOT_FOUND. */
         if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
           {
             svn_error_clear(err);

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.c Thu Mar 15 21:31:45 2012
@@ -905,11 +905,25 @@ svn_fs_node_prop(svn_string_t **value_p,
 }
 
 svn_error_t *
+svn_fs_node_proplist2(apr_hash_t **table_p,
+                      apr_array_header_t **inherited_props,
+                      svn_fs_root_t *root,
+                      const char *path,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(root->vtable->node_proplist(table_p, inherited_props,
+                                                     root, path,
+                                                     result_pool, scratch_pool));
+}
+
+
+svn_error_t *
 svn_fs_node_proplist(apr_hash_t **table_p, svn_fs_root_t *root,
                      const char *path, apr_pool_t *pool)
 {
-  return svn_error_trace(root->vtable->node_proplist(table_p, root, path,
-                                                     pool));
+  return svn_error_trace(root->vtable->node_proplist(table_p, NULL, root,
+                                                     path, pool, pool));
 }
 
 svn_error_t *

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.h?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.h Thu Mar 15 21:31:45 2012
@@ -271,8 +271,11 @@ typedef struct root_vtable_t
   svn_error_t *(*node_prop)(svn_string_t **value_p, svn_fs_root_t *root,
                             const char *path, const char *propname,
                             apr_pool_t *pool);
-  svn_error_t *(*node_proplist)(apr_hash_t **table_p, svn_fs_root_t *root,
-                                const char *path, apr_pool_t *pool);
+  svn_error_t *(*node_proplist)(apr_hash_t **table_p,
+                                apr_array_header_t **inherited_props,
+                                svn_fs_root_t *root,
+                                const char *path, apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool);
   svn_error_t *(*change_node_prop)(svn_fs_root_t *root, const char *path,
                                    const char *name,
                                    const svn_string_t *value,

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_base/tree.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs_base/tree.c Thu Mar 15 21:31:45 2012
@@ -1244,9 +1244,11 @@ txn_body_node_proplist(void *baton, trai
 
 static svn_error_t *
 base_node_proplist(apr_hash_t **table_p,
+                   apr_array_header_t **inherited_props,
                    svn_fs_root_t *root,
                    const char *path,
-                   apr_pool_t *pool)
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
 {
   apr_hash_t *table;
   struct node_proplist_args args;
@@ -1255,8 +1257,10 @@ base_node_proplist(apr_hash_t **table_p,
   args.root = root;
   args.path = path;
 
+  /* ### TODO: Get inherited props. */
+
   SVN_ERR(svn_fs_base__retry_txn(root->fs, txn_body_node_proplist, &args,
-                                 FALSE, pool));
+                                 FALSE, result_pool));
 
   *table_p = table;
   return SVN_NO_ERROR;

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c Thu Mar 15 21:31:45 2012
@@ -995,21 +995,59 @@ fs_node_prop(svn_string_t **value_p,
 
 
 /* Set *TABLE_P to the entire property list of PATH under ROOT, as an
-   APR hash table allocated in POOL.  The resulting property table
+   APR hash table allocated in RESULT_POOL.  The resulting property table
    maps property names to pointers to svn_string_t objects containing
-   the property value. */
+   the property value.
+
+   If INHERITED_PROPS is not null, then set *INHERITED_PROPS to a depth-first
+   ordered array of svn_prop_inherited_item_t * structures (the path_or_url
+   members of which are relative filesystem paths), allocated in RESULT_POOL,
+   representing the properties inherited by PATH.  If INHERITED_PROPS is not
+   null and no properties are inherited, then set *INHERITED_PROPS to an
+   empty array.
+ */
 static svn_error_t *
 fs_node_proplist(apr_hash_t **table_p,
+                 apr_array_header_t **inherited_props,
                  svn_fs_root_t *root,
                  const char *path,
-                 apr_pool_t *pool)
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
 {
   apr_hash_t *table;
   dag_node_t *node;
 
-  SVN_ERR(get_dag(&node, root, path, pool));
-  SVN_ERR(svn_fs_fs__dag_get_proplist(&table, node, pool));
-  *table_p = table ? table : apr_hash_make(pool);
+  SVN_ERR(get_dag(&node, root, path, scratch_pool));
+  SVN_ERR(svn_fs_fs__dag_get_proplist(&table, node, result_pool));
+  *table_p = table ? table : apr_hash_make(result_pool);
+
+  /* If the caller requested PATH's inherited properties, then walk from
+     PATH to the repository root to gather PATH's inherited props. */
+  if (inherited_props)
+    {
+      const char *parent_path = path;
+      apr_hash_t *parent_properties;
+
+      *inherited_props = apr_array_make(result_pool, 1,
+                                        sizeof(svn_prop_inherited_item_t *));
+      while (!(parent_path[0] == '/' && parent_path[1] == '\0'))
+        {
+          parent_path = svn_fspath__dirname(parent_path, scratch_pool);
+          SVN_ERR(get_dag(&node, root, parent_path, scratch_pool));
+          SVN_ERR(svn_fs_fs__dag_get_proplist(&parent_properties, node,
+                                              result_pool));
+          if (parent_properties && apr_hash_count(parent_properties))
+            {
+              svn_prop_inherited_item_t *i_props =
+                apr_pcalloc(result_pool, sizeof(*i_props));
+              i_props->path_or_url =
+                apr_pstrdup(result_pool, parent_path + 1);
+              i_props->prop_hash = parent_properties;
+              APR_ARRAY_PUSH(*inherited_props,
+                             svn_prop_inherited_item_t *) = i_props;
+            }
+        }
+    }
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra/deprecated.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra/deprecated.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra/deprecated.c Thu Mar 15 21:31:45 2012
@@ -417,3 +417,43 @@ svn_error_t *svn_ra_do_status(svn_ra_ses
                                     SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
                                     status_editor, status_baton, pool);
 }
+
+svn_error_t *svn_ra_get_file(svn_ra_session_t *session,
+                             const char *path,
+                             svn_revnum_t revision,
+                             svn_stream_t *stream,
+                             svn_revnum_t *fetched_rev,
+                             apr_hash_t **props,
+                             apr_pool_t *pool)
+{
+  SVN_ERR_ASSERT(*path != '/');
+  return session->vtable->get_file(session, path, revision, stream,
+                                   fetched_rev, props, NULL, pool);
+}
+
+svn_error_t *svn_ra_get_dir(svn_ra_session_t *session,
+                            const char *path,
+                            svn_revnum_t revision,
+                            apr_hash_t **dirents,
+                            svn_revnum_t *fetched_rev,
+                            apr_hash_t **props,
+                            apr_pool_t *pool)
+{
+  SVN_ERR_ASSERT(*path != '/');
+  return session->vtable->get_dir(session, dirents, fetched_rev, props, NULL,
+                                  path, revision, SVN_DIRENT_ALL, pool);
+}
+
+svn_error_t *svn_ra_get_dir2(svn_ra_session_t *session,
+                             apr_hash_t **dirents,
+                             svn_revnum_t *fetched_rev,
+                             apr_hash_t **props,
+                             const char *path,
+                             svn_revnum_t revision,
+                             apr_uint32_t dirent_fields,
+                             apr_pool_t *pool)
+{
+  SVN_ERR_ASSERT(*path != '/');
+  return session->vtable->get_dir(session, dirents, fetched_rev, props, NULL,
+                                  path, revision, dirent_fields, pool);
+}

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c Thu Mar 15 21:31:45 2012
@@ -733,44 +733,35 @@ svn_error_t *svn_ra_get_commit_editor3(s
                                             lock_tokens, keep_locks, pool);
 }
 
-svn_error_t *svn_ra_get_file(svn_ra_session_t *session,
-                             const char *path,
-                             svn_revnum_t revision,
-                             svn_stream_t *stream,
-                             svn_revnum_t *fetched_rev,
-                             apr_hash_t **props,
-                             apr_pool_t *pool)
+svn_error_t *svn_ra_get_file2(svn_ra_session_t *session,
+                              const char *path,
+                              svn_revnum_t revision,
+                              svn_stream_t *stream,
+                              svn_revnum_t *fetched_rev,
+                              apr_hash_t **props,
+                              apr_array_header_t **inherited_props,
+                              apr_pool_t *pool)
 {
   SVN_ERR_ASSERT(*path != '/');
   return session->vtable->get_file(session, path, revision, stream,
-                                   fetched_rev, props, pool);
-}
-
-svn_error_t *svn_ra_get_dir(svn_ra_session_t *session,
-                            const char *path,
-                            svn_revnum_t revision,
-                            apr_hash_t **dirents,
-                            svn_revnum_t *fetched_rev,
-                            apr_hash_t **props,
-                            apr_pool_t *pool)
-{
-  SVN_ERR_ASSERT(*path != '/');
-  return session->vtable->get_dir(session, dirents, fetched_rev, props,
-                                  path, revision, SVN_DIRENT_ALL, pool);
+                                   fetched_rev, props, inherited_props, pool);
 }
 
-svn_error_t *svn_ra_get_dir2(svn_ra_session_t *session,
-                             apr_hash_t **dirents,
-                             svn_revnum_t *fetched_rev,
-                             apr_hash_t **props,
-                             const char *path,
-                             svn_revnum_t revision,
-                             apr_uint32_t dirent_fields,
-                             apr_pool_t *pool)
+svn_error_t *
+svn_ra_get_dir3(svn_ra_session_t *session,
+                apr_hash_t **dirents,
+                svn_revnum_t *fetched_rev,
+                apr_hash_t **props,
+                apr_array_header_t **inherited_props,
+                const char *path,
+                svn_revnum_t revision,
+                apr_uint32_t dirent_fields,
+                apr_pool_t *pool)
 {
   SVN_ERR_ASSERT(*path != '/');
   return session->vtable->get_dir(session, dirents, fetched_rev, props,
-                                  path, revision, dirent_fields, pool);
+                                  inherited_props, path, revision,
+                                  dirent_fields, pool);
 }
 
 svn_error_t *svn_ra_get_mergeinfo(svn_ra_session_t *session,

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.h?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.h Thu Mar 15 21:31:45 2012
@@ -108,19 +108,21 @@ typedef struct svn_ra__vtable_t {
                                     apr_hash_t *lock_tokens,
                                     svn_boolean_t keep_locks,
                                     apr_pool_t *pool);
-  /* See svn_ra_get_file(). */
+  /* See svn_ra_get_file2(). */
   svn_error_t *(*get_file)(svn_ra_session_t *session,
                            const char *path,
                            svn_revnum_t revision,
                            svn_stream_t *stream,
                            svn_revnum_t *fetched_rev,
                            apr_hash_t **props,
+                           apr_array_header_t **inherited_props,
                            apr_pool_t *pool);
-  /* See svn_ra_get_dir2(). */
+  /* See svn_ra_get_dir3(). */
   svn_error_t *(*get_dir)(svn_ra_session_t *session,
                           apr_hash_t **dirents,
                           svn_revnum_t *fetched_rev,
                           apr_hash_t **props,
+                          apr_array_header_t **inherited_props,
                           const char *path,
                           svn_revnum_t revision,
                           apr_uint32_t dirent_fields,

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra/wrapper_template.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra/wrapper_template.h?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra/wrapper_template.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra/wrapper_template.h Thu Mar 15 21:31:45 2012
@@ -179,7 +179,7 @@ static svn_error_t *compat_get_file(void
                                     apr_pool_t *pool)
 {
   return VTBL.get_file(session_baton, path, revision, stream, fetched_rev,
-                       props, pool);
+                       props, NULL, pool);
 }
 
 static svn_error_t *compat_get_dir(void *session_baton,
@@ -191,7 +191,7 @@ static svn_error_t *compat_get_dir(void 
                                    apr_pool_t *pool)
 {
   return VTBL.get_dir(session_baton, dirents, fetched_rev, props,
-                      path, revision, SVN_DIRENT_ALL, pool);
+                      NULL, path, revision, SVN_DIRENT_ALL, pool);
 }
 
 /** Reporter compat code. **/

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_local/ra_plugin.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_local/ra_plugin.c Thu Mar 15 21:31:45 2012
@@ -1011,6 +1011,7 @@ svn_ra_local__stat(svn_ra_session_t *ses
 
 static svn_error_t *
 get_node_props(apr_hash_t **props,
+               apr_array_header_t **inherited_props,
                svn_ra_local__session_baton_t *sess,
                svn_fs_root_t *root,
                const char *path,
@@ -1020,7 +1021,22 @@ get_node_props(apr_hash_t **props,
   const char *cmt_date, *cmt_author;
 
   /* Create a hash with props attached to the fs node. */
-  SVN_ERR(svn_fs_node_proplist(props, root, path, pool));
+  SVN_ERR(svn_fs_node_proplist2(props, inherited_props, root, path, pool,
+                                pool));
+
+  /* Turn FS-path keys into URLs. */
+  if (inherited_props)
+    {
+      int i;
+
+      for (i = 0; i < (*inherited_props)->nelts; i++)
+        {
+          svn_prop_inherited_item_t *i_props =
+            APR_ARRAY_IDX(*inherited_props, i, svn_prop_inherited_item_t *);
+          i_props->path_or_url = svn_path_url_add_component2(
+            sess->repos_url, i_props->path_or_url, pool);
+        }
+    }
 
   /* Now add some non-tweakable metadata to the hash as well... */
 
@@ -1059,6 +1075,7 @@ svn_ra_local__get_file(svn_ra_session_t 
                        svn_stream_t *stream,
                        svn_revnum_t *fetched_rev,
                        apr_hash_t **props,
+                       apr_array_header_t **inherited_props,
                        apr_pool_t *pool)
 {
   svn_fs_root_t *root;
@@ -1116,8 +1133,9 @@ svn_ra_local__get_file(svn_ra_session_t 
     }
 
   /* Handle props if requested. */
-  if (props)
-    SVN_ERR(get_node_props(props, sess, root, abs_path, pool));
+  if (props || inherited_props)
+    SVN_ERR(get_node_props(props, inherited_props, sess, root, abs_path,
+                           pool));
 
   return SVN_NO_ERROR;
 }
@@ -1130,6 +1148,7 @@ svn_ra_local__get_dir(svn_ra_session_t *
                       apr_hash_t **dirents,
                       svn_revnum_t *fetched_rev,
                       apr_hash_t **props,
+                      apr_array_header_t **inherited_props,
                       const char *path,
                       svn_revnum_t revision,
                       apr_uint32_t dirent_fields,
@@ -1227,8 +1246,9 @@ svn_ra_local__get_dir(svn_ra_session_t *
     }
 
   /* Handle props if requested. */
-  if (props)
-    SVN_ERR(get_node_props(props, sess, root, abs_path, pool));
+  if (props || inherited_props)
+    SVN_ERR(get_node_props(props, inherited_props, sess, root, abs_path,
+                           pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_neon/fetch.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_neon/fetch.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_neon/fetch.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_neon/fetch.c Thu Mar 15 21:31:45 2012
@@ -654,12 +654,14 @@ static const ne_propname restype_checksu
   { NULL }
 };
 
+/* ### TODO: Implement INHERITED_PROPS. */
 svn_error_t *svn_ra_neon__get_file(svn_ra_session_t *session,
                                    const char *path,
                                    svn_revnum_t revision,
                                    svn_stream_t *stream,
                                    svn_revnum_t *fetched_rev,
                                    apr_hash_t **props,
+                                   apr_array_header_t **inherited_props,
                                    apr_pool_t *pool)
 {
   svn_ra_neon__resource_t *rsrc;
@@ -774,10 +776,12 @@ svn_error_t *svn_ra_neon__get_file(svn_r
   return SVN_NO_ERROR;
 }
 
+/* ### TODO: Implement INHERITED_PROPS. */
 svn_error_t *svn_ra_neon__get_dir(svn_ra_session_t *session,
                                   apr_hash_t **dirents,
                                   svn_revnum_t *fetched_rev,
                                   apr_hash_t **props,
+                                  apr_array_header_t **inherited_props,
                                   const char *path,
                                   svn_revnum_t revision,
                                   apr_uint32_t dirent_fields,

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_neon/ra_neon.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_neon/ra_neon.h?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_neon/ra_neon.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_neon/ra_neon.h Thu Mar 15 21:31:45 2012
@@ -294,12 +294,14 @@ svn_error_t * svn_ra_neon__get_file(svn_
                                     svn_stream_t *stream,
                                     svn_revnum_t *fetched_rev,
                                     apr_hash_t **props,
+                                    apr_array_header_t **inherited_props,
                                     apr_pool_t *pool);
 
 svn_error_t *svn_ra_neon__get_dir(svn_ra_session_t *session,
                                   apr_hash_t **dirents,
                                   svn_revnum_t *fetched_rev,
                                   apr_hash_t **props,
+                                  apr_array_header_t **inherited_props,
                                   const char *path,
                                   svn_revnum_t revision,
                                   apr_uint32_t dirent_fields,

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h Thu Mar 15 21:31:45 2012
@@ -1330,6 +1330,7 @@ svn_ra_serf__get_file(svn_ra_session_t *
                       svn_stream_t *stream,
                       svn_revnum_t *fetched_rev,
                       apr_hash_t **props,
+                      apr_array_header_t **inherited_props,
                       apr_pool_t *pool);
 
 svn_error_t *

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_serf/serf.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_serf/serf.c Thu Mar 15 21:31:45 2012
@@ -954,6 +954,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
                      apr_hash_t **dirents,
                      svn_revnum_t *fetched_rev,
                      apr_hash_t **ret_props,
+                     apr_array_header_t **inherited_props,
                      const char *rel_path,
                      svn_revnum_t revision,
                      apr_uint32_t dirent_fields,

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_serf/update.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_serf/update.c Thu Mar 15 21:31:45 2012
@@ -2783,6 +2783,7 @@ svn_ra_serf__get_file(svn_ra_session_t *
                       svn_stream_t *stream,
                       svn_revnum_t *fetched_rev,
                       apr_hash_t **props,
+                      apr_array_header_t **inherited_props,
                       apr_pool_t *pool)
 {
   svn_ra_serf__session_t *session = ra_session->priv;

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_svn/client.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_svn/client.c Thu Mar 15 21:31:45 2012
@@ -1013,6 +1013,7 @@ static svn_error_t *ra_svn_get_file(svn_
                                     svn_revnum_t rev, svn_stream_t *stream,
                                     svn_revnum_t *fetched_rev,
                                     apr_hash_t **props,
+                                    apr_array_header_t **inherited_props,
                                     apr_pool_t *pool)
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
@@ -1089,6 +1090,7 @@ static svn_error_t *ra_svn_get_dir(svn_r
                                    apr_hash_t **dirents,
                                    svn_revnum_t *fetched_rev,
                                    apr_hash_t **props,
+                                   apr_array_header_t **inherited_props,
                                    const char *path,
                                    svn_revnum_t rev,
                                    apr_uint32_t dirent_fields,

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/properties.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/properties.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/properties.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/properties.c Thu Mar 15 21:31:45 2012
@@ -385,3 +385,51 @@ svn_prop_get_value(apr_hash_t *props,
 
   return NULL;
 }
+
+svn_prop_inherited_item_t *
+svn_prop_inherited_item_dup(const svn_prop_inherited_item_t *inherited_prop,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  apr_hash_index_t *hi;
+  svn_prop_inherited_item_t *new_iprop = apr_palloc(result_pool,
+                                                    sizeof(*new_iprop));
+
+  new_iprop->path_or_url = apr_pstrdup(
+    result_pool, inherited_prop->path_or_url);
+  new_iprop->prop_hash = apr_hash_make(result_pool);
+
+  for (hi = apr_hash_first(scratch_pool, inherited_prop->prop_hash);
+       hi;
+       hi = apr_hash_next(hi))
+    {
+      const char *name = svn__apr_hash_index_key(hi);
+      svn_string_t *value = svn__apr_hash_index_val(hi);
+      apr_hash_set(new_iprop->prop_hash,
+                   apr_pstrdup(result_pool, name),
+                   APR_HASH_KEY_STRING,
+                   svn_string_dup(value, result_pool));
+    }
+
+  return new_iprop;
+}
+
+apr_array_header_t *
+svn_prop_inherited_array_dup(const apr_array_header_t *prop_array,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
+{
+  int i;
+  apr_array_header_t *new_array = apr_array_make(
+    result_pool, prop_array->nelts, sizeof(svn_prop_inherited_item_t *));
+
+  for (i = 0; i < prop_array->nelts; ++i)
+    {
+      svn_prop_inherited_item_t *elt =
+        APR_ARRAY_IDX(prop_array, i, svn_prop_inherited_item_t *);
+
+      elt = svn_prop_inherited_item_dup(elt, result_pool, scratch_pool);
+      APR_ARRAY_PUSH(new_array, svn_prop_inherited_item_t *) = elt;
+    }
+  return new_array;
+}

Modified: subversion/branches/inheritable-props/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/svn/cl.h?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/svn/cl.h (original)
+++ subversion/branches/inheritable-props/subversion/svn/cl.h Thu Mar 15 21:31:45 2012
@@ -233,6 +233,7 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t use_patch_diff_format; /* Output compatible with GNU patch */
   svn_boolean_t allow_mixed_rev; /* Allow operation on mixed-revision WC */
   svn_boolean_t include_externals; /* Recurses (in)to file & dir externals */
+  svn_boolean_t show_inherited_props; /* get inherited properties */
 } svn_cl__opt_state_t;
 
 

Modified: subversion/branches/inheritable-props/subversion/svn/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/svn/main.c?rev=1301211&r1=1301210&r2=1301211&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/svn/main.c (original)
+++ subversion/branches/inheritable-props/subversion/svn/main.c Thu Mar 15 21:31:45 2012
@@ -127,6 +127,7 @@ typedef enum svn_cl__longopt_t {
   opt_use_patch_diff_format,
   opt_allow_mixed_revisions,
   opt_include_externals,
+  opt_show_inherited_props,
 } svn_cl__longopt_t;
 
 
@@ -366,6 +367,8 @@ const apr_getopt_option_t svn_cl__option
                        "recursion. This does not include externals with a\n"
                        "                             "
                        "fixed revision. (See the svn:externals property)")},
+  {"show-inherited-props", opt_show_inherited_props, 0,
+                       N_("retrieve target's inherited properties")},
 
   /* Long-opt Aliases
    *
@@ -1148,7 +1151,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "  redirecting a binary property value to a file, but available only\n"
      "  if you supply a single TARGET to a non-recursive propget operation).\n"),
     {'v', 'R', opt_depth, 'r', opt_revprop, opt_strict, opt_xml,
-     opt_changelist } },
+     opt_changelist, opt_show_inherited_props } },
 
   { "proplist", svn_cl__proplist, {"plist", "pl"}, N_
     ("List all properties on files, dirs, or revisions.\n"
@@ -1159,7 +1162,8 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "     revision the target is first looked up.\n"
      "  2. Lists unversioned remote props on repos revision.\n"
      "     TARGET only determines which repository to access.\n"),
-    {'v', 'R', opt_depth, 'r', 'q', opt_revprop, opt_xml, opt_changelist } },
+    {'v', 'R', opt_depth, 'r', 'q', opt_revprop, opt_xml, opt_changelist,
+     opt_show_inherited_props} },
 
   { "propset", svn_cl__propset, {"pset", "ps"}, N_
     ("Set the value of a property on files, dirs, or revisions.\n"
@@ -2114,6 +2118,9 @@ main(int argc, const char *argv[])
       case opt_include_externals:
         opt_state.include_externals = TRUE;
         break;
+      case opt_show_inherited_props:
+        opt_state.show_inherited_props = TRUE;
+        break;
       default:
         /* Hmmm. Perhaps this would be a good place to squirrel away
            opts that commands like svn diff might need. Hmmm indeed. */