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/08/11 00:18:59 UTC

svn commit: r1371831 - in /subversion/branches/inheritable-props/subversion: include/private/ libsvn_client/ libsvn_wc/ tests/libsvn_wc/

Author: pburba
Date: Fri Aug 10 22:18:59 2012
New Revision: 1371831

URL: http://svn.apache.org/viewvc?rev=1371831&view=rev
Log:
On the inheritable-props branch: Atomically update cached iprops with
work queue items during update/switch editor drives.  Remove the temporary
svn_client__update_inheritable_props API.

* subversion/include/private/svn_wc_private.h

  (svn_wc__cache_iprops): Deleted, no callers.

  (svn_wc__get_update_editor,
   svn_wc__get_switch_editor): Add argument 

* subversion/libsvn_client/client.h

  (svn_client__update_inheritable_props): Delete.

  (svn_client__get_inheritable_props): New.

* subversion/libsvn_client/iprops.c

  (need_to_cache_iprops): Gracefully handle the case where we ask about a
   non-existant path.

  (svn_client__update_inheritable_props): Delete.

  (svn_client__get_inheritable_props):

* subversion/libsvn_client/switch.c (switch_internal):
* subversion/libsvn_client/update.c (update_internal):
  Grab inheritable properties from the repository
  for each WC root in the update target and pass these iprops to
  svn_wc__get_[update|switch]_editor so it can set the iprops along with
  the rest of the columns in the NODES table during the editor drive
  callbacks.  Also remove the call to the now defunct
  svn_client__update_inheritable_props.

* subversion/libsvn_wc/deprecated.c

  (svn_wc_get_update_editor4): Update call to svn_wc__get_update_editor.

  (svn_wc_get_switch_editor4): Update call to svn_wc__get_switch_editor.

* subversion/libsvn_wc/externals.c

  (close_edit): Update call to svn_wc__db_op_bump_revisions_post_update.

* subversion/libsvn_wc/update_editor.c

  (edit_baton): Add a new member to stash the set of iprops for all
   working copy roots in the update target.

  (close_directory): Pass along any iprops to
   svn_wc__db_base_add_directory.

  (close_edit): Pass along hash of WC root iprops to
   svn_wc__db_op_bump_revisions_post_update.

  (make_editor,
   svn_wc__get_update_editor,
   svn_wc__get_switch_editor):
   Add new argument corresponding to new edit baton member.

  (svn_wc__get_update_editor):

* subversion/libsvn_wc/wc-queries.sql

  (STMT_INSERT_NODE): Add inherited props parameter.

  (STMT_INSERT_IPROP): Rename to...

  (STMT_UPDATE_IPROP): ...this and remove op_depth parameter, op_depth
   is always zero for this statement.

* subversion/libsvn_wc/wc_db.c

  (insert_base_baton_t): Add a new member to stash base node's iprops.

  (insert_base_node): Bind iprops.

  (svn_wc__db_base_add_directory): Add new argument corresponding to new
   iprops.

  (svn_wc__db_cache_iprops): Deleted, no longer used by any callers.

  (db_op_set_rev_and_repos_relpath): Renamed to...

  (db_op_set_rev_repos_relpath_iprops): ...this.  Now handles setting iprops
   too.

  (bump_node_revision): Add an optional hash of iprops argument from which
   to set the node's inherited properties.

  (bump_revisions_baton_t): New hash of iprops member.

  (bump_revisions_post_update): Pass hash of iprops to bump_node_revision().

  (svn_wc__db_op_bump_revisions_post_update): Add an optional hash of iprops
   argument from which to set the node's inherited properties.

* subversion/libsvn_wc/wc_db.h

  (svn_wc__db_base_add_directory): Add new argument corresponding to new
   iprops.

  (svn_wc__db_cache_iprops): Deleted, no longer used by any callers.

  (svn_wc__db_op_bump_revisions_post_update): Add an optional hash of iprops
   argument from which to set the node's inherited properties.

* subversion/tests/libsvn_wc/db-test.c (test_inserting_nodes):
* subversion/tests/libsvn_wc/op-depth-test.c (svn_wc__db_base_add_directory):
  Update calls to svn_wc__db_base_add_directory.

Modified:
    subversion/branches/inheritable-props/subversion/include/private/svn_wc_private.h
    subversion/branches/inheritable-props/subversion/libsvn_client/client.h
    subversion/branches/inheritable-props/subversion/libsvn_client/iprops.c
    subversion/branches/inheritable-props/subversion/libsvn_client/switch.c
    subversion/branches/inheritable-props/subversion/libsvn_client/update.c
    subversion/branches/inheritable-props/subversion/libsvn_wc/deprecated.c
    subversion/branches/inheritable-props/subversion/libsvn_wc/externals.c
    subversion/branches/inheritable-props/subversion/libsvn_wc/props.c
    subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c
    subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.c
    subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.h
    subversion/branches/inheritable-props/subversion/tests/libsvn_wc/db-test.c
    subversion/branches/inheritable-props/subversion/tests/libsvn_wc/op-depth-test.c

Modified: subversion/branches/inheritable-props/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/include/private/svn_wc_private.h?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/inheritable-props/subversion/include/private/svn_wc_private.h Fri Aug 10 22:18:59 2012
@@ -924,21 +924,6 @@ svn_wc__prop_retrieve_recursive(apr_hash
                                 apr_pool_t *scratch_pool);
 
 /**
- * Cache the inherited properties @a inherited_props (a depth-first ordered
- * array of #svn_prop_inherited_item_t * structures) for the BASE node at
- * @a local_abspath.  @a inherited_props may be empty.  If there is no base
- * node at @a local_abspath, then do nothing.  If @a local_abspath is not in
- * the working copy, return @c SVN_ERR_WC_PATH_NOT_FOUND.
- *
- * Use @a scratch_pool for temporary allocations.
- */
-svn_error_t *
-svn_wc__cache_iprops(apr_array_header_t *inherited_props,
-                     svn_wc_context_t *wc_ctx,
-                     const char *local_abspath,
-                     apr_pool_t *scratch_pool);
-
-/**
  * Set @a *iprops_paths to a hash mapping const char * absolute working
  * copy paths to the same for each path in the working copy at or below
  * @a local_abspath, limited by @a depth, that has cached inherited
@@ -1492,6 +1477,15 @@ svn_wc__get_status_editor(const svn_delt
  * successful completion of the drive of this editor, will be
  * populated with the revision to which the working copy was updated.
  *
+ * @a wcroot_iprops is a hash mapping const char * absolute working copy
+ * paths which are working copy roots (at or under the target within the
+ * constraints dictated by @a depth) to depth-first ordered arrays of
+ * svn_prop_inherited_item_t * structures which represent the inherited
+ * properties for the base of those paths at @a target_revision.  After a
+ * successful drive of this editor, the base nodes for these paths will
+ * have their inherited properties cache updated with the values from
+ * @a wcroot_iprops.
+ *
  * If @a use_commit_times is TRUE, then all edited/added files will
  * have their working timestamp set to the last-committed-time.  If
  * FALSE, the working files will be touched with the 'now' time.
@@ -1533,6 +1527,7 @@ svn_wc__get_update_editor(const svn_delt
                           svn_wc_context_t *wc_ctx,
                           const char *anchor_abspath,
                           const char *target_basename,
+                          apr_hash_t *wcroot_iprops,
                           svn_boolean_t use_commit_times,
                           svn_depth_t depth,
                           svn_boolean_t depth_is_sticky,
@@ -1576,6 +1571,7 @@ svn_wc__get_switch_editor(const svn_delt
                           const char *anchor_abspath,
                           const char *target_basename,
                           const char *switch_url,
+                          apr_hash_t *wcroot_iprops,
                           svn_boolean_t use_commit_times,
                           svn_depth_t depth,
                           svn_boolean_t depth_is_sticky,

Modified: subversion/branches/inheritable-props/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_client/client.h?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_client/client.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_client/client.h Fri Aug 10 22:18:59 2012
@@ -564,24 +564,29 @@ svn_client__switch_internal(svn_revnum_t
 
 /*** Inheritable Properties ***/
 
-/* Fetch the inherited properties for the base of LOCAL_ABSPATH using
-   RA_SESSION and cache the results for all WC roots at or under
-   LOCAL_ABSPATH (limited by DEPTH).  If LOCAL_ABSPATH has no base then
-   do nothing.
+/* Fetch the inherited properties for the base of LOCAL_ABSPATH as well
+   as any WC roots under LOCAL_ABSPATH (as limited by DEPTH) using
+   RA_SESSION.  Store the results in *WCROOT_IPROPS, a hash mapping
+   const char * absolute working copy paths to depth-first ordered arrays
+   of svn_prop_inherited_item_t * structures.
+
+   If LOCAL_ABSPATH has no base then do nothing.
 
    RA_SESSION should be an open RA session pointing at the URL of PATH,
    or NULL, in which case this function will open its own temporary session.
 
-   ### IPROPS: This is a temporary private API.  Eventually this logic must
-   ### be run atomically as a work queue item in the update/switch editor
-   ### drive.
+   Allocate *WCROOT_IPROPS in RESULT_POOL, use SCRATCH_POOL for temporary
+   allocations.
 */
 svn_error_t *
-svn_client__update_inheritable_props(const char *local_abspath,
-                                     svn_depth_t depth,
-                                     svn_ra_session_t *ra_session,
-                                     svn_client_ctx_t *ctx,
-                                     apr_pool_t *scratch_pool);
+svn_client__get_inheritable_props(apr_hash_t **wcroot_iprops,
+                                  const char *local_abspath,
+                                  svn_revnum_t revision,
+                                  svn_depth_t depth,
+                                  svn_ra_session_t *ra_session,
+                                  svn_client_ctx_t *ctx,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool);
 
 /* ---------------------------------------------------------------- */
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_client/iprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_client/iprops.c?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_client/iprops.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_client/iprops.c Fri Aug 10 22:18:59 2012
@@ -50,12 +50,27 @@ need_to_cache_iprops(svn_boolean_t *need
                      apr_pool_t *scratch_pool)
 {
   svn_boolean_t is_wc_root;
+  svn_error_t *err;
 
   /* Our starting assumption. */
   *needs_cache = FALSE;
 
-  SVN_ERR(svn_wc_is_wc_root2(&is_wc_root, ctx->wc_ctx, abspath,
-                             scratch_pool));
+  err = svn_wc_is_wc_root2(&is_wc_root, ctx->wc_ctx, abspath,
+                           scratch_pool);
+
+  /* ABSPATH can't need a cache if it doesn't exist. */
+  if (err)
+    {
+      if (err->apr_err == SVN_ERR_ENTRY_NOT_FOUND)
+        {
+          svn_error_clear(err);
+          is_wc_root = FALSE;
+        }
+      else
+        {
+          return svn_error_trace(err);
+        }
+    }
 
   if (is_wc_root)
     {
@@ -75,16 +90,16 @@ need_to_cache_iprops(svn_boolean_t *need
 }
 
 svn_error_t *
-svn_client__update_inheritable_props(const char *local_abspath,
-                                     svn_depth_t depth,
-                                     svn_ra_session_t *ra_session,
-                                     svn_client_ctx_t *ctx,
-                                     apr_pool_t *scratch_pool)
+svn_client__get_inheritable_props(apr_hash_t **wcroot_iprops,
+                                  const char *local_abspath,
+                                  svn_revnum_t revision,
+                                  svn_depth_t depth,
+                                  svn_ra_session_t *ra_session,
+                                  svn_client_ctx_t *ctx,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool)
 {
-  svn_revnum_t revision;
-
-  SVN_ERR(svn_wc__node_get_base(&revision, NULL, NULL, NULL, ctx->wc_ctx,
-                                local_abspath, scratch_pool, scratch_pool));
+  *wcroot_iprops = apr_hash_make(result_pool);
 
   /* If we don't have a base revision for LOCAL_ABSPATH then it can't
      possibly be a working copy root, nor can it contain any WC roots
@@ -146,15 +161,19 @@ svn_client__update_inheritable_props(con
                 }
 
               SVN_ERR(svn_ra_get_inherited_props(ra_session, &inherited_props,
-                                                 "", revision, iterpool));
-              SVN_ERR(svn_wc__cache_iprops(inherited_props, ctx->wc_ctx,
-                                           child_abspath, iterpool));
+                                                 "", revision, result_pool));
+
+              if (old_session_url)
+                SVN_ERR(svn_ra_reparent(ra_session, old_session_url,
+                                        iterpool));
+
+              apr_hash_set(*wcroot_iprops,
+                           apr_pstrdup(result_pool, child_abspath),
+                           APR_HASH_KEY_STRING,
+                           inherited_props);
             }
         }
 
-      if (old_session_url)
-        SVN_ERR(svn_ra_reparent(ra_session, old_session_url, iterpool));
-
       svn_pool_destroy(iterpool);
     }
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_client/switch.c?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_client/switch.c Fri Aug 10 22:18:59 2012
@@ -79,6 +79,8 @@ switch_internal(svn_revnum_t *result_rev
   svn_revnum_t revnum;
   svn_error_t *err = SVN_NO_ERROR;
   const char *diff3_cmd;
+  apr_hash_t *wcroot_iprops;
+  apr_array_header_t *inherited_props;
   svn_boolean_t use_commit_times;
   svn_boolean_t sleep_here = FALSE;
   svn_boolean_t *use_sleep = timestamp_sleep ? timestamp_sleep : &sleep_here;
@@ -218,6 +220,12 @@ switch_internal(svn_revnum_t *result_rev
                                  svn_dirent_dirname(local_abspath, pool));
     }
 
+  SVN_ERR(svn_ra_get_inherited_props(ra_session, &inherited_props,
+                                     "", switch_loc->rev, pool));
+  wcroot_iprops = apr_hash_make(pool);
+  apr_hash_set(wcroot_iprops, local_abspath, APR_HASH_KEY_STRING,
+               inherited_props);
+
   SVN_ERR(svn_ra_reparent(ra_session, anchor_url, pool));
 
   /* Fetch the switch (update) editor.  If REVISION is invalid, that's
@@ -231,8 +239,8 @@ switch_internal(svn_revnum_t *result_rev
 
   SVN_ERR(svn_wc__get_switch_editor(&switch_editor, &switch_edit_baton,
                                     &revnum, ctx->wc_ctx, anchor_abspath,
-                                    target, switch_loc->url, use_commit_times,
-                                    depth,
+                                    target, switch_loc->url, wcroot_iprops,
+                                    use_commit_times, depth,
                                     depth_is_sticky, allow_unver_obstructions,
                                     server_supports_depth,
                                     diff3_cmd, preserved_exts,
@@ -296,10 +304,6 @@ switch_internal(svn_revnum_t *result_rev
                                            ctx, pool));
     }
 
-  /* Cache inherited props. */
-  SVN_ERR(svn_client__update_inheritable_props(local_abspath, depth,
-                                               ra_session, ctx, pool));
-
   /* Sleep to ensure timestamp integrity (we do this regardless of
      errors in the actual switch operation(s)). */
   if (sleep_here)

Modified: subversion/branches/inheritable-props/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_client/update.c?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_client/update.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_client/update.c Fri Aug 10 22:18:59 2012
@@ -202,6 +202,8 @@ update_internal(svn_revnum_t *result_rev
   svn_boolean_t clean_checkout = FALSE;
   svn_boolean_t is_not_present;
   const char *diff3_cmd;
+  apr_hash_t *wcroot_iprops;
+  svn_opt_revision_t opt_rev;
   svn_ra_session_t *ra_session;
   const char *preserved_exts_str;
   apr_array_header_t *preserved_exts;
@@ -351,10 +353,18 @@ update_internal(svn_revnum_t *result_rev
       anchor_loc->url = corrected_url;
     }
 
+  /* Resolve unspecified REVISION now, because we need to retrieve the
+     correct inherited props prior to the editor drive and we need to
+     use the same value of HEAD for both. */
+  opt_rev.kind = revision->kind;
+  opt_rev.value = revision->value;
+  if (opt_rev.kind == svn_opt_revision_unspecified)
+    opt_rev.kind = svn_opt_revision_head;
+
   /* ### todo: shouldn't svn_client__get_revision_number be able
      to take a URL as easily as a local path?  */
   SVN_ERR(svn_client__get_revision_number(&revnum, NULL, ctx->wc_ctx,
-                                          local_abspath, ra_session, revision,
+                                          local_abspath, ra_session, &opt_rev,
                                           pool));
 
   SVN_ERR(svn_ra_has_capability(ra_session, &server_supports_depth,
@@ -364,12 +374,31 @@ update_internal(svn_revnum_t *result_rev
   dfb.target_revision = revnum;
   dfb.anchor_url = anchor_loc->url;
 
+  err = svn_client__get_inheritable_props(&wcroot_iprops, local_abspath,
+                                          revnum, depth, ra_session, ctx,
+                                          pool, pool);
+
+  /* We might be trying to update to a non-existant path-rev. */
+  if (err)
+    {
+      if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
+        {
+          svn_error_clear(err);
+          err = NULL;
+        }
+      else
+        {
+          return svn_error_trace(err);
+        }
+    }
+
   /* Fetch the update editor.  If REVISION is invalid, that's okay;
      the RA driver will call editor->set_target_revision later on. */
   SVN_ERR(svn_wc__get_update_editor(&update_editor, &update_edit_baton,
                                     &revnum, ctx->wc_ctx, anchor_abspath,
-                                    target, use_commit_times, depth,
-                                    depth_is_sticky, allow_unver_obstructions,
+                                    target, wcroot_iprops, use_commit_times,
+                                    depth, depth_is_sticky,
+                                    allow_unver_obstructions,
                                     adds_as_modification,
                                     server_supports_depth,
                                     clean_checkout,
@@ -441,9 +470,6 @@ update_internal(svn_revnum_t *result_rev
       err = SVN_NO_ERROR;
       is_not_present = TRUE;
     }
-  if (! is_not_present)
-    SVN_ERR(svn_client__update_inheritable_props(local_abspath, depth,
-                                                 ra_session, ctx, pool));
 
   if (sleep_here)
     svn_io_sleep_for_timestamps(local_abspath, pool);

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/deprecated.c?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/deprecated.c Fri Aug 10 22:18:59 2012
@@ -3269,7 +3269,7 @@ svn_wc_get_update_editor4(const svn_delt
                               target_revision,
                               wc_ctx,
                               anchor_abspath,
-                              target_basename,
+                              target_basename, NULL,
                               use_commit_times,
                               depth, depth_is_sticky,
                               allow_unver_obstructions,
@@ -3455,7 +3455,7 @@ svn_wc_get_switch_editor4(const svn_delt
                               target_revision,
                               wc_ctx,
                               anchor_abspath, target_basename,
-                              switch_url,
+                              switch_url, NULL,
                               use_commit_times,
                               depth, depth_is_sticky,
                               allow_unver_obstructions,

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/externals.c?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/externals.c Fri Aug 10 22:18:59 2012
@@ -873,6 +873,7 @@ close_edit(void *edit_baton,
                                                        NULL, NULL, NULL,
                                                        *eb->target_revision,
                                                        apr_hash_make(pool),
+                                                       NULL,
                                                        pool));
     }
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/props.c?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/props.c Fri Aug 10 22:18:59 2012
@@ -2477,62 +2477,6 @@ svn_wc__get_iprops(apr_array_header_t **
 }
 
 svn_error_t *
-svn_wc__cache_iprops(apr_array_header_t *inherited_props,
-                     svn_wc_context_t *wc_ctx,
-                     const char *local_abspath,
-                     apr_pool_t *scratch_pool)
-{
-  if (inherited_props)
-    {
-      const char *repos_root_url;
-      svn_revnum_t revision;
-      svn_error_t *err = svn_wc__node_get_base(&revision, NULL,
-                                               &repos_root_url, NULL,
-                                               wc_ctx, local_abspath,
-                                               scratch_pool, scratch_pool);
-
-      /* Can't cache iprops for paths which aren't part of the WC. */
-      if (err)
-        {
-          if (err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY)
-            {
-              svn_error_clear(err);
-
-              /* Keep error for consistent with the other of the svn_wc__*
-                 private APIs. */
-              return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
-                                       _("The node '%s' was not found."),
-                                       svn_dirent_local_style(local_abspath,
-                                                              scratch_pool));
-            }
-          else
-            {
-              return svn_error_trace(err);
-            }
-        }
-
-      /* If there is no base node at LOCAL_ABSPATH there is nothing to do. */
-      if (SVN_IS_VALID_REVNUM(revision))
-        {
-          if (inherited_props->nelts)
-            {
-              SVN_ERR(svn_wc__db_cache_iprops(inherited_props, wc_ctx->db,
-                                              local_abspath, scratch_pool));
-            }
-          else
-            {
-              SVN_ERR(svn_wc__db_cache_iprops(
-                apr_array_make(scratch_pool, 0,
-                               sizeof(svn_prop_inherited_item_t *)),
-                wc_ctx->db, local_abspath, scratch_pool));
-            }
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
 svn_wc__get_cached_iprop_children(apr_hash_t **iprop_paths,
                                   svn_depth_t depth,
                                   svn_wc_context_t *wc_ctx,

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c Fri Aug 10 22:18:59 2012
@@ -170,6 +170,12 @@ struct edit_baton
      generated conflict files. */
   const apr_array_header_t *ext_patterns;
 
+  /* Hash mapping const char * absolute working copy paths to depth-first
+     ordered arrays of svn_prop_inherited_item_t * structures representing
+     the properties inherited by the base node at that working copy path.
+     May be NULL. */
+  apr_hash_t *wcroot_iprops;
+
   /* The revision we're targeting...or something like that.  This
      starts off as a pointer to the revision to which we are updating,
      or SVN_INVALID_REVNUM, but by the end of the edit, should be
@@ -2630,6 +2636,7 @@ close_directory(void *dir_baton,
   else
     {
       apr_hash_t *props;
+      apr_array_header_t *iprops = NULL;
 
       /* ### we know a base node already exists. it was created in
          ### open_directory or add_directory.  let's just preserve the
@@ -2689,6 +2696,22 @@ close_directory(void *dir_baton,
                                             scratch_pool);
         }
 
+      /* Any inherited props to be set set for this base node? */
+      if (eb->wcroot_iprops)
+        {
+          iprops = apr_hash_get(eb->wcroot_iprops, db->local_abspath,
+                                APR_HASH_KEY_STRING);
+
+          /* close_edit may also update iprops for switched nodes, catching
+             those for which close_directory is never called (e.g. a switch
+             with no changes).  So as a minor optimization we remove any
+             iprops from the hash so as not to set them again in
+             close_edit. */
+          if (iprops)
+            apr_hash_set(eb->wcroot_iprops, db->local_abspath,
+                         APR_HASH_KEY_STRING, NULL);
+        }
+
       /* Update the BASE data for the directory and mark the directory
          complete */
       SVN_ERR(svn_wc__db_base_add_directory(
@@ -2707,7 +2730,7 @@ close_directory(void *dir_baton,
                 conflict_skel,
                 (! db->shadowed) && new_base_props != NULL,
                 new_actual_props,
-                all_work_items,
+                iprops, all_work_items,
                 scratch_pool));
     }
 
@@ -4384,6 +4407,7 @@ close_edit(void *edit_baton,
                                                        eb->repos_uuid,
                                                        *(eb->target_revision),
                                                        eb->skipped_trees,
+                                                       eb->wcroot_iprops,
                                                        eb->pool));
 
       if (*eb->target_basename != '\0')
@@ -4457,6 +4481,7 @@ make_editor(svn_revnum_t *target_revisio
             svn_wc__db_t *db,
             const char *anchor_abspath,
             const char *target_basename,
+            apr_hash_t *wcroot_iprops,
             svn_boolean_t use_commit_times,
             const char *switch_url,
             svn_depth_t depth,
@@ -4522,6 +4547,7 @@ make_editor(svn_revnum_t *target_revisio
   eb->db                       = db;
   eb->target_basename          = target_basename;
   eb->anchor_abspath           = anchor_abspath;
+  eb->wcroot_iprops            = wcroot_iprops;
 
   SVN_ERR(svn_wc__db_get_wcroot(&eb->wcroot_abspath, db, anchor_abspath,
                                 edit_pool, scratch_pool));
@@ -4743,6 +4769,7 @@ svn_wc__get_update_editor(const svn_delt
                           svn_wc_context_t *wc_ctx,
                           const char *anchor_abspath,
                           const char *target_basename,
+                          apr_hash_t *wcroot_iprops,
                           svn_boolean_t use_commit_times,
                           svn_depth_t depth,
                           svn_boolean_t depth_is_sticky,
@@ -4766,7 +4793,7 @@ svn_wc__get_update_editor(const svn_delt
                           apr_pool_t *scratch_pool)
 {
   return make_editor(target_revision, wc_ctx->db, anchor_abspath,
-                     target_basename, use_commit_times,
+                     target_basename, wcroot_iprops, use_commit_times,
                      NULL, depth, depth_is_sticky, allow_unver_obstructions,
                      adds_as_modification, server_performs_filtering,
                      clean_checkout,
@@ -4787,6 +4814,7 @@ svn_wc__get_switch_editor(const svn_delt
                           const char *anchor_abspath,
                           const char *target_basename,
                           const char *switch_url,
+                          apr_hash_t *wcroot_iprops,
                           svn_boolean_t use_commit_times,
                           svn_depth_t depth,
                           svn_boolean_t depth_is_sticky,
@@ -4810,7 +4838,7 @@ svn_wc__get_switch_editor(const svn_delt
   SVN_ERR_ASSERT(switch_url && svn_uri_is_canonical(switch_url, scratch_pool));
 
   return make_editor(target_revision, wc_ctx->db, anchor_abspath,
-                     target_basename, use_commit_times,
+                     target_basename, wcroot_iprops, use_commit_times,
                      switch_url,
                      depth, depth_is_sticky, allow_unver_obstructions,
                      FALSE /* adds_as_modification */,

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql Fri Aug 10 22:18:59 2012
@@ -149,9 +149,10 @@ INSERT OR REPLACE INTO nodes (
   wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
   revision, presence, depth, kind, changed_revision, changed_date,
   changed_author, checksum, properties, translated_size, last_mod_time,
-  dav_cache, symlink_target, file_external, moved_to, moved_here)
+  dav_cache, symlink_target, file_external, moved_to, moved_here,
+  inherited_props)
 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14,
-        ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22)
+        ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23)
 
 -- STMT_SELECT_BASE_PRESENT
 SELECT local_relpath, kind FROM nodes n
@@ -1499,10 +1500,10 @@ WHERE wc_id = ?1
   AND local_relpath = ?2
   AND op_depth = ?3
 
--- STMT_INSERT_IPROP
+-- STMT_UPDATE_IPROP
 UPDATE nodes
-SET inherited_props = ?4
-WHERE (wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3)
+SET inherited_props = ?3
+WHERE (wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0)
 
 -- STMT_SELECT_INODES
 SELECT local_relpath FROM nodes

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.c?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.c Fri Aug 10 22:18:59 2012
@@ -176,6 +176,11 @@ typedef struct insert_base_baton_t {
   svn_boolean_t update_actual_props;
   const apr_hash_t *new_actual_props;
 
+  /* A depth-first ordered array of svn_prop_inherited_item_t *
+     structures representing the properties inherited by the base
+     node. */
+  apr_array_header_t *iprops;
+
   /* maybe we should copy information from a previous record? */
   svn_boolean_t keep_recorded_info;
 
@@ -831,6 +836,10 @@ insert_base_node(void *baton,
 
   SVN_ERR(svn_sqlite__bind_properties(stmt, 15, pibb->props,
                                       scratch_pool));
+
+  SVN_ERR(svn_sqlite__bind_iprops(stmt, 23, pibb->iprops,
+                                      scratch_pool));
+
   if (pibb->dav_cache)
     SVN_ERR(svn_sqlite__bind_properties(stmt, 18, pibb->dav_cache,
                                         scratch_pool));
@@ -1678,6 +1687,7 @@ svn_wc__db_base_add_directory(svn_wc__db
                               const svn_skel_t *conflict,
                               svn_boolean_t update_actual_props,
                               apr_hash_t *new_actual_props,
+                              apr_array_header_t *new_iprops,
                               const svn_skel_t *work_items,
                               apr_pool_t *scratch_pool)
 {
@@ -1712,6 +1722,7 @@ svn_wc__db_base_add_directory(svn_wc__db
   ibb.repos_relpath = repos_relpath;
   ibb.revision = revision;
 
+  ibb.iprops = new_iprops;
   ibb.props = props;
   ibb.changed_rev = changed_rev;
   ibb.changed_date = changed_date;
@@ -9416,32 +9427,6 @@ svn_wc__db_get_children_with_cached_ipro
 }
 
 svn_error_t *
-svn_wc__db_cache_iprops(apr_array_header_t *inherited_props,
-                        svn_wc__db_t *db,
-                        const char *local_abspath,
-                        apr_pool_t *scratch_pool)
-{
-  svn_wc__db_wcroot_t *wcroot;
-  svn_sqlite__stmt_t *stmt;
-  const char *local_relpath;
-  int op_depth;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
-                                                db, local_abspath,
-                                                scratch_pool, scratch_pool));
-  SVN_ERR(op_depth_of(&op_depth, wcroot, local_relpath));
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_INSERT_IPROP));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isd",
-                            wcroot->wc_id,
-                            local_relpath,
-                            op_depth));
-  SVN_ERR(svn_sqlite__bind_iprops(stmt, 4, inherited_props, scratch_pool));
-
-  return svn_error_trace(svn_sqlite__step_done(stmt));
-}
-
-svn_error_t *
 svn_wc__db_read_children_of_working_node(const apr_array_header_t **children,
                                          svn_wc__db_t *db,
                                          const char *local_abspath,
@@ -10284,19 +10269,21 @@ svn_wc__db_global_update(svn_wc__db_t *d
 #endif
 }
 
-/* Sets a base nodes revision and/or repository relative path. If
-   LOCAL_ABSPATH's rev (REV) is valid, set is revision and if SET_REPOS_RELPATH
-   is TRUE set its repository relative path to REPOS_RELPATH (and make sure its
-   REPOS_ID is still valid).
+/* Sets a base nodes revision, repository relative path, and/or inherited
+   propertis. If LOCAL_ABSPATH's rev (REV) is valid, set its revision.  If
+   SET_REPOS_RELPATH is TRUE set its repository relative path to REPOS_RELPATH
+   (and make sure its REPOS_ID is still valid).  If IPROPS is not NULL set its
+   inherited properties to IPROPS.
  */
 static svn_error_t *
-db_op_set_rev_and_repos_relpath(svn_wc__db_wcroot_t *wcroot,
-                                const char *local_relpath,
-                                svn_revnum_t rev,
-                                svn_boolean_t set_repos_relpath,
-                                const char *repos_relpath,
-                                apr_int64_t repos_id,
-                                apr_pool_t *scratch_pool)
+db_op_set_rev_repos_relpath_iprops(svn_wc__db_wcroot_t *wcroot,
+                                   const char *local_relpath,
+                                   apr_array_header_t *iprops,
+                                   svn_revnum_t rev,
+                                   svn_boolean_t set_repos_relpath,
+                                   const char *repos_relpath,
+                                   apr_int64_t repos_id,
+                                   apr_pool_t *scratch_pool)
 {
   svn_sqlite__stmt_t *stmt;
 
@@ -10328,6 +10315,17 @@ db_op_set_rev_and_repos_relpath(svn_wc__
       SVN_ERR(svn_sqlite__step_done(stmt));
     }
 
+  if (iprops)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_UPDATE_IPROP));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                wcroot->wc_id,
+                                local_relpath));
+      SVN_ERR(svn_sqlite__bind_iprops(stmt, 3, iprops, scratch_pool));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -10335,7 +10333,13 @@ db_op_set_rev_and_repos_relpath(svn_wc__
  *
  * Tweak the information for LOCAL_RELPATH in WCROOT.  If NEW_REPOS_RELPATH is
  * non-NULL update the entry to the new url specified by NEW_REPOS_RELPATH,
- * NEW_REPOS_ID..  If NEW_REV is valid, make this the node's working revision.
+ * NEW_REPOS_ID.  If NEW_REV is valid, make this the node's working revision.
+ *
+ * If WCROOT_IPROPS is not NULL it is a hash mapping const char * absolute
+ * working copy paths to depth-first ordered arrays of
+ * svn_prop_inherited_item_t * structures.  If the absoulte path equivalent
+ * of LOCAL_RELPATH exists in WCROOT_IPROPS, then set the hashed value as the
+ * node's inherited properties.
  *
  * Unless S_ROOT is TRUE the tweaks might cause the node for LOCAL_ABSPATH to
  * be removed from the WC; if IS_ROOT is TRUE this will not happen.
@@ -10348,6 +10352,7 @@ bump_node_revision(svn_wc__db_wcroot_t *
                    svn_revnum_t new_rev,
                    svn_depth_t depth,
                    apr_hash_t *exclude_relpaths,
+                   apr_hash_t *wcroot_iprops,
                    svn_boolean_t is_root,
                    svn_boolean_t skip_when_dir,
                    svn_wc__db_t *db,
@@ -10411,12 +10416,21 @@ bump_node_revision(svn_wc__db_wcroot_t *
 
   if (set_repos_relpath
       || (SVN_IS_VALID_REVNUM(new_rev) && new_rev != revision))
-    SVN_ERR(db_op_set_rev_and_repos_relpath(wcroot, local_relpath,
-                                            new_rev,
-                                            set_repos_relpath,
-                                            new_repos_relpath,
-                                            new_repos_id,
-                                            scratch_pool));
+    {
+      apr_array_header_t *iprops = NULL;
+      
+      if (wcroot_iprops)
+        iprops = apr_hash_get(wcroot_iprops,
+                              svn_dirent_join(wcroot->abspath, local_relpath,
+                                              scratch_pool),
+                              APR_HASH_KEY_STRING);
+      SVN_ERR(db_op_set_rev_repos_relpath_iprops(wcroot, local_relpath,
+                                                 iprops, new_rev,
+                                                 set_repos_relpath,
+                                                 new_repos_relpath,
+                                                 new_repos_id,
+                                                 scratch_pool));
+    }
 
   /* Early out */
   if (depth <= svn_depth_empty
@@ -10456,7 +10470,8 @@ bump_node_revision(svn_wc__db_wcroot_t *
       SVN_ERR(bump_node_revision(wcroot, child_local_relpath, new_repos_id,
                                  child_repos_relpath, new_rev,
                                  depth_below_here,
-                                 exclude_relpaths, FALSE /* is_root */,
+                                 exclude_relpaths, wcroot_iprops,
+                                 FALSE /* is_root */,
                                  (depth < svn_depth_immediates), db,
                                  iterpool));
     }
@@ -10476,6 +10491,7 @@ struct bump_revisions_baton_t
   const char *new_repos_uuid;
   svn_revnum_t new_revision;
   apr_hash_t *exclude_relpaths;
+  apr_hash_t *wcroot_iprops;
   svn_wc__db_t *db;
 };
 
@@ -10522,6 +10538,7 @@ bump_revisions_post_update(void *baton,
   SVN_ERR(bump_node_revision(wcroot, local_relpath, new_repos_id,
                              brb->new_repos_relpath, brb->new_revision,
                              brb->depth, brb->exclude_relpaths,
+                             brb->wcroot_iprops,
                              TRUE /* is_root */, FALSE, brb->db,
                              scratch_pool));
 
@@ -10537,6 +10554,7 @@ svn_wc__db_op_bump_revisions_post_update
                                          const char *new_repos_uuid,
                                          svn_revnum_t new_revision,
                                          apr_hash_t *exclude_relpaths,
+                                         apr_hash_t *wcroot_iprops,
                                          apr_pool_t *scratch_pool)
 {
   const char *local_relpath;
@@ -10560,6 +10578,7 @@ svn_wc__db_op_bump_revisions_post_update
   brb.new_repos_uuid = new_repos_uuid;
   brb.new_revision = new_revision;
   brb.exclude_relpaths = exclude_relpaths;
+  brb.wcroot_iprops = wcroot_iprops;
   brb.db = db;
 
   SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath,

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.h?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.h Fri Aug 10 22:18:59 2012
@@ -409,6 +409,10 @@ svn_wc__db_get_wcroot(const char **wcroo
    when the value of NEW_ACTUAL_PROPS matches NEW_PROPS, store NULL in
    ACTUAL, to mark the properties unmodified.
 
+   If NEW_IPROPS is not NULL, then it is a depth-first ordered array of
+   svn_prop_inherited_item_t * structures that is set as the base node's
+   inherited_properties.
+
    Any work items that are necessary as part of this node construction may
    be passed in WORK_ITEMS.
 
@@ -432,6 +436,7 @@ svn_wc__db_base_add_directory(svn_wc__db
                               const svn_skel_t *conflict,
                               svn_boolean_t update_actual_props,
                               apr_hash_t *new_actual_props,
+                              apr_array_header_t *new_iprops,
                               const svn_skel_t *work_items,
                               apr_pool_t *scratch_pool);
 
@@ -2118,19 +2123,6 @@ svn_wc__db_get_children_with_cached_ipro
                                            apr_pool_t *result_pool,
                                            apr_pool_t *scratch_pool);
 
-/* Cache inherited properites for a node in the BASE tree.
-
-   Cache the inherited properties INHERITED_PROPS (a depth-first ordered
-   array of svn_prop_inherited_item_t * structures) for the BASE node at
-   LOCAL_ABSPATH.
-
-   Use SCRATCH_POOL for temporary allocations. */
-svn_error_t *
-svn_wc__db_cache_iprops(apr_array_header_t *inherited_props,
-                        svn_wc__db_t *db,
-                        const char *local_abspath,
-                        apr_pool_t *scratch_pool);
-
 /** Obtain a mapping of const char * local_abspaths to const svn_string_t*
  * property values in *VALUES, of all PROPNAME properties on LOCAL_ABSPATH
  * and its descendants.
@@ -2442,6 +2434,12 @@ svn_wc__db_global_update(svn_wc__db_t *d
    EXCLUDE_RELPATHS is a hash containing const char *local_relpath.  Nodes
    for pathnames contained in EXCLUDE_RELPATHS are not touched by this
    function.  These pathnames should be paths relative to the wcroot.
+
+   If WCROOT_IPROPS is not NULL it is a hash mapping const char * absolute
+   working copy paths to depth-first ordered arrays of
+   svn_prop_inherited_item_t * structures.  If LOCAL_ABSPATH exists in
+   WCROOT_IPROPS, then set the hashed value as the node's inherited
+   properties.
 */
 svn_error_t *
 svn_wc__db_op_bump_revisions_post_update(svn_wc__db_t *db,
@@ -2452,6 +2450,7 @@ svn_wc__db_op_bump_revisions_post_update
                                          const char *new_repos_uuid,
                                          svn_revnum_t new_revision,
                                          apr_hash_t *exclude_relpaths,
+                                         apr_hash_t *wcroot_iprops,
                                          apr_pool_t *scratch_pool);
 
 

Modified: subversion/branches/inheritable-props/subversion/tests/libsvn_wc/db-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/tests/libsvn_wc/db-test.c?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/branches/inheritable-props/subversion/tests/libsvn_wc/db-test.c Fri Aug 10 22:18:59 2012
@@ -652,7 +652,7 @@ test_inserting_nodes(apr_pool_t *pool)
             props,
             1, TIME_1a, AUTHOR_1,
             children, svn_depth_infinity,
-            NULL, NULL, FALSE, NULL, NULL,
+            NULL, NULL, FALSE, NULL, NULL, NULL,
             pool));
 
   /* Replace an incomplete node with a file node. */

Modified: subversion/branches/inheritable-props/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/tests/libsvn_wc/op-depth-test.c?rev=1371831&r1=1371830&r2=1371831&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/inheritable-props/subversion/tests/libsvn_wc/op-depth-test.c Fri Aug 10 22:18:59 2012
@@ -1284,7 +1284,7 @@ base_dir_insert_remove(svn_test__sandbox
                                         "not-even-a-uuid", revision,
                                         apr_hash_make(b->pool), revision,
                                         0, NULL, NULL, svn_depth_infinity,
-                                        NULL, NULL, FALSE, NULL, NULL,
+                                        NULL, NULL, FALSE, NULL, NULL, NULL,
                                         b->pool));
 
   after = apr_palloc(b->pool, sizeof(*after) * (apr_size_t)(num_before + num_added + 1));