subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pbu...@apache.org
Subject svn commit: r1393257 - in /subversion/branches/auto-props-sdc/subversion: include/svn_props.h libsvn_client/add.c libsvn_client/client.h libsvn_client/commit.c
Date Wed, 03 Oct 2012 02:23:46 GMT
Author: pburba
Date: Wed Oct  3 02:23:46 2012
New Revision: 1393257

URL: http://svn.apache.org/viewvc?rev=1393257&view=rev
Log:
On the auto-props-sdc branch: Implement svn:config:auto-props, an inherited
property which well-behaved clients use to set auto-props in addition to
the existing config file auto-props.

Currently svn:config:auto-props override config file auto-props and
svn:config:auto-props inherited from nearer path-wise parents override those
inherited from more distant parents.

Note: There is one known test failure with this change: schedule_tests.py 11
"'svn add' should traverse already-versioned dirs".

* subversion/include/svn_props.h

  (SVN_CONFIG_PROP_PREFIX,
   SVN_CONFIG_PROP_AUTO_PROPS): New defines for 'svn:config:auto-props'.

* subversion/libsvn_client/add.c

  (auto_props_baton_t,
   auto_props_enumerator): Delete.

  (svn_client__get_auto_props): Delete, effectively replaced by
   get_auto_props_for_pattern and svn_client__get_paths_auto_props.

  (get_auto_props_for_pattern): New, gets previously cached auto-props
   for a given path.

  (svn_client__get_paths_auto_props): New, gets all possible auto-props,
   rather than the previous method whereby svn_client__get_auto_props was
   called for every imported/added path.

  (add_file): Replace call to svn_client__get_auto_props with
   its replacement svn_client__get_paths_auto_props. Add a new hash arg
   that contains all the possible autoprops.

  (add_dir_recursive): Add a new hash arg that contains all the possible
   autoprops and pass it along recursively and to add_file().

  (collect_auto_props_baton_t,
   all_auto_props_collector): New svn_config_enumerator2_t baton and
   callback.

  (svn_client__get_all_auto_props): New, gets all config file auto props and
   explicit/inherited svn:config:auto-props for a WC path or URL.

  (add): Gather all config file auto props and explicit/inherited once and
   pass the results to add_dir_recursive and add_file.

* subversion/libsvn_client/client.h

  (svn_client__get_auto_props): Delete.

  (svn_client__get_paths_auto_props,
   svn_client__get_all_auto_props): New.

* subversion/libsvn_client/commit.c

  (import_ctx_t): Add a new hash member to track all config file auto-props
   and svn:config:auto-props.

  (import_file): Replace svn_client__get_auto_props with
   svn_client__get_paths_auto_props.

  (import): Add an argument corresponding to the new import_ctx_t member.

  (svn_client_import5): Get all auto-props at start of import.

Modified:
    subversion/branches/auto-props-sdc/subversion/include/svn_props.h
    subversion/branches/auto-props-sdc/subversion/libsvn_client/add.c
    subversion/branches/auto-props-sdc/subversion/libsvn_client/client.h
    subversion/branches/auto-props-sdc/subversion/libsvn_client/commit.c

Modified: subversion/branches/auto-props-sdc/subversion/include/svn_props.h
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/include/svn_props.h?rev=1393257&r1=1393256&r2=1393257&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/include/svn_props.h (original)
+++ subversion/branches/auto-props-sdc/subversion/include/svn_props.h Wed Oct  3 02:23:46
2012
@@ -384,6 +384,11 @@ svn_prop_name_is_valid(const char *prop_
  */
 #define SVN_PROP_MERGEINFO SVN_PROP_PREFIX "mergeinfo"
 
+/** Prefix for all Subersion configurable inhertiable properties. */
+#define SVN_CONFIG_PROP_PREFIX SVN_PROP_PREFIX "config:"
+
+/** Merge info property used to record a resource's merge history. */
+#define SVN_CONFIG_PROP_AUTO_PROPS SVN_CONFIG_PROP_PREFIX "auto-props"
 
 /** Meta-data properties.
  *

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_client/add.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_client/add.c?rev=1393257&r1=1393256&r2=1393257&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_client/add.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_client/add.c Wed Oct  3 02:23:46
2012
@@ -56,27 +56,6 @@
 
 /*** Code. ***/
 
-/* This structure is used as baton for enumerating the config entries
-   in the auto-props section.
-*/
-typedef struct auto_props_baton_t
-{
-  /* the file name for which properties are searched */
-  const char *filename;
-
-  /* when this flag is set the hash contains svn:executable */
-  svn_boolean_t have_executable;
-
-  /* when mimetype is not NULL is set the hash contains svn:mime-type */
-  const char *mimetype;
-
-  /* the hash table for storing the property name/value pairs */
-  apr_hash_t *properties;
-
-  /* a pool used for allocating memory */
-  apr_pool_t *pool;
-} auto_props_baton_t;
-
 /* Remove leading and trailing white space from a C string, in place. */
 static void
 trim_string(char **pstr)
@@ -160,109 +139,83 @@ split_props(apr_array_header_t **props,
    listed in VALUE into BATON->properties.
    BATON must point to an auto_props_baton_t.
 */
-static svn_boolean_t
-auto_props_enumerator(const char *name,
-                      const char *value,
-                      void *baton,
-                      apr_pool_t *pool)
+static void
+get_auto_props_for_pattern(apr_hash_t *properties,
+                           const char **mimetype,
+                           svn_boolean_t *have_executable,
+                           const char *filename,
+                           const char *pattern,
+                           apr_hash_t *propvals,
+                           apr_pool_t *scratch_pool,
+                           apr_pool_t *result_pool)
 {
-  int i;
-  auto_props_baton_t *autoprops = baton;
-  apr_array_header_t *props;
-
-  /* nothing to do here without a value */
-  if (*value == 0)
-    return TRUE;
+  apr_hash_index_t *hi;
 
   /* check if filename matches and return if it doesn't */
-  if (apr_fnmatch(name, autoprops->filename, APR_FNM_CASE_BLIND) == APR_FNM_NOMATCH)
-    return TRUE;
-
-  split_props(&props, value, autoprops->pool);
-
-  for (i = 0; i < props->nelts; i++)
-    {
-      size_t len;
-      const char *this_value;
-      char *property = APR_ARRAY_IDX(props, i, char *);
-      char *equal_sign = strchr(property, '=');
-
-      if (equal_sign)
-        {
-          *equal_sign = '\0';
-          equal_sign++;
-          trim_string(&equal_sign);
-          unquote_string(&equal_sign);
-          this_value = equal_sign;
-        }
-      else
-        {
-          this_value = "";
-        }
-      trim_string(&property);
-      len = strlen(property);
-
-      if (len > 0)
-        {
-          svn_string_t *propval = apr_palloc(autoprops->pool,
+  if (apr_fnmatch(pattern, filename,
+                  APR_FNM_CASE_BLIND) == APR_FNM_NOMATCH)
+    return;
+
+  for (hi = apr_hash_first(scratch_pool, propvals);
+       hi != NULL;
+       hi = apr_hash_next(hi))
+    {
+      const char *propname = svn__apr_hash_index_key(hi);
+      const char *propval = svn__apr_hash_index_val(hi);
+      svn_string_t *propval_str = apr_palloc(result_pool,
                                              sizeof(*propval));
-          propval->data = this_value;
-          propval->len = strlen(this_value);
+      propval_str->data = propval;
+      propval_str->len = strlen(propval);
 
-          apr_hash_set(autoprops->properties, property, len, propval);
-          if (strcmp(property, SVN_PROP_MIME_TYPE) == 0)
-            autoprops->mimetype = this_value;
-          else if (strcmp(property, SVN_PROP_EXECUTABLE) == 0)
-            autoprops->have_executable = TRUE;
-        }
+      apr_hash_set(properties, propname, APR_HASH_KEY_STRING,
+                   propval_str);
+      if (strcmp(propname, SVN_PROP_MIME_TYPE) == 0)
+        *mimetype = propval;
+      else if (strcmp(propname, SVN_PROP_EXECUTABLE) == 0)
+        *have_executable = TRUE;
     }
-  return TRUE;
 }
 
 svn_error_t *
-svn_client__get_auto_props(apr_hash_t **properties,
-                           const char **mimetype,
-                           const char *path,
-                           svn_magic__cookie_t *magic_cookie,
-                           svn_client_ctx_t *ctx,
-                           apr_pool_t *pool)
+svn_client__get_paths_auto_props(apr_hash_t **properties,
+                                 const char **mimetype,
+                                 const char *path,
+                                 svn_magic__cookie_t *magic_cookie,
+                                 apr_hash_t *autoprops,
+                                 svn_client_ctx_t *ctx,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool)
 {
-  svn_config_t *cfg;
-  svn_boolean_t use_autoprops;
-  auto_props_baton_t autoprops;
-
-  /* initialisation */
-  autoprops.properties = apr_hash_make(pool);
-  autoprops.filename = svn_dirent_basename(path, pool);
-  autoprops.pool = pool;
-  autoprops.mimetype = NULL;
-  autoprops.have_executable = FALSE;
-  *properties = autoprops.properties;
-
-  cfg = ctx->config ? apr_hash_get(ctx->config, SVN_CONFIG_CATEGORY_CONFIG,
-                                   APR_HASH_KEY_STRING) : NULL;
+  apr_hash_index_t *hi;
+  svn_boolean_t have_executable;
 
-  /* check that auto props is enabled */
-  SVN_ERR(svn_config_get_bool(cfg, &use_autoprops,
-                              SVN_CONFIG_SECTION_MISCELLANY,
-                              SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS, FALSE));
+  *properties = apr_hash_make(result_pool);
+  *mimetype = NULL;
 
-  /* search for auto props */
-  if (use_autoprops)
-    svn_config_enumerate2(cfg, SVN_CONFIG_SECTION_AUTO_PROPS,
-                          auto_props_enumerator, &autoprops, pool);
+  for (hi = apr_hash_first(scratch_pool, autoprops);
+       hi != NULL;
+       hi = apr_hash_next(hi))
+    {
+      const char *pattern = svn__apr_hash_index_key(hi);
+      apr_hash_t *propvals = svn__apr_hash_index_val(hi);
+
+      get_auto_props_for_pattern(*properties, mimetype, &have_executable,
+                                 svn_dirent_basename(path, scratch_pool),
+                                 pattern, propvals, result_pool,
+                                 scratch_pool);
+    }
 
   /* if mimetype has not been set check the file */
-  if (! autoprops.mimetype)
+  if (! *mimetype)
     {
-      SVN_ERR(svn_io_detect_mimetype2(&autoprops.mimetype, path,
-                                      ctx->mimetypes_map, pool));
+      SVN_ERR(svn_io_detect_mimetype2(mimetype, path, ctx->mimetypes_map,
+                                      result_pool));
 
       /* If we got no mime-type, or if it is "application/octet-stream",
        * try to get the mime-type from libmagic. */
       if (magic_cookie &&
-          (!autoprops.mimetype ||
-           strcmp(autoprops.mimetype, "application/octet-stream") == 0))
+          (!*mimetype ||
+           strcmp(*mimetype, "application/octet-stream") == 0))
         {
           const char *magic_mimetype;
 
@@ -275,29 +228,29 @@ svn_client__get_auto_props(apr_hash_t **
           * returns "text/plain" for them. */
           SVN_ERR(svn_magic__detect_binary_mimetype(&magic_mimetype,
                                                     path, magic_cookie,
-                                                    pool, pool));
+                                                    result_pool,
+                                                    scratch_pool));
           if (magic_mimetype)
-            autoprops.mimetype = magic_mimetype;
+            *mimetype = magic_mimetype;
         }
 
-      if (autoprops.mimetype)
-        apr_hash_set(autoprops.properties, SVN_PROP_MIME_TYPE,
+      if (*mimetype)
+        apr_hash_set(*properties, SVN_PROP_MIME_TYPE,
                      strlen(SVN_PROP_MIME_TYPE),
-                     svn_string_create(autoprops.mimetype, pool));
+                     svn_string_create(*mimetype, result_pool));
     }
 
   /* if executable has not been set check the file */
-  if (! autoprops.have_executable)
+  if (! have_executable)
     {
       svn_boolean_t executable = FALSE;
-      SVN_ERR(svn_io_is_file_executable(&executable, path, pool));
+      SVN_ERR(svn_io_is_file_executable(&executable, path, scratch_pool));
       if (executable)
-        apr_hash_set(autoprops.properties, SVN_PROP_EXECUTABLE,
+        apr_hash_set(*properties, SVN_PROP_EXECUTABLE,
                      strlen(SVN_PROP_EXECUTABLE),
-                     svn_string_create_empty(pool));
+                     svn_string_create_empty(result_pool));
     }
 
-  *mimetype = autoprops.mimetype;
   return SVN_NO_ERROR;
 }
 
@@ -305,6 +258,7 @@ svn_client__get_auto_props(apr_hash_t **
 static svn_error_t *
 add_file(const char *local_abspath,
          svn_magic__cookie_t *magic_cookie,
+         apr_hash_t *autoprops,
          svn_client_ctx_t *ctx,
          apr_pool_t *pool)
 {
@@ -324,8 +278,9 @@ add_file(const char *local_abspath,
     /* This may fail on write-only files:
        we open them to estimate file type.
        That's why we postpone the add until after this step. */
-    SVN_ERR(svn_client__get_auto_props(&properties, &mimetype, local_abspath,
-                                       magic_cookie, ctx, pool));
+    SVN_ERR(svn_client__get_paths_auto_props(&properties, &mimetype,
+                                             local_abspath, magic_cookie,
+                                             autoprops, ctx, pool, pool));
 
   /* Add the file */
   SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, local_abspath,
@@ -408,6 +363,7 @@ add_dir_recursive(const char *dir_abspat
                   svn_boolean_t force,
                   svn_boolean_t no_ignore,
                   svn_magic__cookie_t *magic_cookie,
+                  apr_hash_t *config_autoprops,
                   svn_client_ctx_t *ctx,
                   apr_pool_t *scratch_pool)
 {
@@ -475,12 +431,13 @@ add_dir_recursive(const char *dir_abspat
 
           SVN_ERR(add_dir_recursive(abspath, depth_below_here,
                                     force, no_ignore, magic_cookie,
-                                    ctx, iterpool));
+                                    config_autoprops, ctx, iterpool));
         }
       else if ((dirent->kind == svn_node_file || dirent->special)
                && depth >= svn_depth_files)
         {
-          err = add_file(abspath, magic_cookie, ctx, iterpool);
+          err = add_file(abspath, magic_cookie, config_autoprops, ctx,
+                         iterpool);
           if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
             svn_error_clear(err);
           else
@@ -494,6 +451,210 @@ add_dir_recursive(const char *dir_abspat
   return SVN_NO_ERROR;
 }
 
+/* This structure is used as baton for collecting the config entries
+   in the auto-props section and any inherited svn:config:auto-props
+   properties.
+*/
+typedef struct collect_auto_props_baton_t
+{
+  /* the hash table for storing the property name/value pairs */
+  apr_hash_t *autoprops;
+
+  /* a pool used for allocating memory */
+  apr_pool_t *result_pool;
+} collect_auto_props_baton_t;
+
+/* Implements svn_config_enumerator2_t callback.
+
+   For one auto-props config entry (NAME, VALUE), stash a copy of
+   NAME and VALUE, allocated in BATON->POOL, in BATON->AUTOPROP.
+   BATON must point to an collect_auto_props_baton_t.
+*/
+static svn_boolean_t
+all_auto_props_collector(const char *name,
+                         const char *value,
+                         void *baton,
+                         apr_pool_t *pool)
+{
+  collect_auto_props_baton_t *autoprops_baton = baton;
+  apr_array_header_t *autoprops;
+  int i;
+
+  /* nothing to do here without a value */
+  if (*value == 0)
+    return TRUE;
+
+  split_props(&autoprops, value, pool);
+
+  for (i = 0; i < autoprops->nelts; i ++)
+    {
+      size_t len;
+      const char *this_value;
+      char *property = APR_ARRAY_IDX(autoprops, i, char *);
+      char *equal_sign = strchr(property, '=');
+
+      if (equal_sign)
+        {
+          *equal_sign = '\0';
+          equal_sign++;
+          trim_string(&equal_sign);
+          unquote_string(&equal_sign);
+          this_value = equal_sign;
+        }
+      else
+        {
+          this_value = "";
+        }
+      trim_string(&property);
+      len = strlen(property);
+
+      if (len > 0)
+        {
+          svn_string_t *propval =
+            svn_string_create(this_value, autoprops_baton->result_pool);
+          apr_hash_t *pattern_hash = apr_hash_get(autoprops_baton->autoprops,
+                                                  name, APR_HASH_KEY_STRING);
+          if (!pattern_hash)
+            {
+              pattern_hash = apr_hash_make(autoprops_baton->result_pool);
+              apr_hash_set(autoprops_baton->autoprops,
+                           apr_pstrdup(autoprops_baton->result_pool, name),
+                           APR_HASH_KEY_STRING, pattern_hash);
+            }
+          apr_hash_set(pattern_hash,
+                       apr_pstrdup(autoprops_baton->result_pool, property),
+                       APR_HASH_KEY_STRING, propval->data);
+        }
+    }
+  return TRUE;
+}
+
+svn_error_t *
+svn_client__get_all_auto_props(apr_hash_t **autoprops,
+                               const char *path_or_url,
+                               svn_client_ctx_t *ctx,
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool)
+{
+  int i;
+  apr_array_header_t *inherited_config_auto_props;
+  apr_hash_t *props;
+  svn_opt_revision_t rev;
+  svn_string_t *config_auto_prop;
+  svn_boolean_t use_autoprops;
+  collect_auto_props_baton_t autoprops_baton;
+  svn_config_t *cfg = ctx->config ? apr_hash_get(ctx->config,
+                                                 SVN_CONFIG_CATEGORY_CONFIG,
+                                                 APR_HASH_KEY_STRING) : NULL;
+  *autoprops = apr_hash_make(result_pool);
+  autoprops_baton.result_pool = result_pool;
+  autoprops_baton.autoprops = *autoprops;
+
+  /* Are "traditional" auto-props enabled?  If so grab them from the
+    config.  This is our starting set auto-props, which may be overriden
+    by svn:config:auto-props. */
+  SVN_ERR(svn_config_get_bool(cfg, &use_autoprops,
+                              SVN_CONFIG_SECTION_MISCELLANY,
+                              SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS, FALSE));
+  if (use_autoprops)
+    svn_config_enumerate2(cfg, SVN_CONFIG_SECTION_AUTO_PROPS,
+                          all_auto_props_collector, &autoprops_baton,
+                          scratch_pool);
+
+  /* Convert the config file setting (if any) into a hash mapping file
+     patterns to as hash of prop-->val mappings. */
+  if (svn_path_is_url(path_or_url))
+    rev.kind = svn_opt_revision_head;
+  else
+    rev.kind = svn_opt_revision_working;
+
+  SVN_ERR(svn_client_propget5(&props, &inherited_config_auto_props,
+                              SVN_CONFIG_PROP_AUTO_PROPS, path_or_url, &rev,
+                              &rev, NULL, svn_depth_empty, NULL, ctx,
+                              scratch_pool, scratch_pool));
+
+  /* Stash any explicit PROPS for PARENT_PATH into the inherited props array,
+     since these are actually inherited props for LOCAL_ABSPATH. */
+  config_auto_prop = apr_hash_get(props, path_or_url, APR_HASH_KEY_STRING);
+
+  if (config_auto_prop)
+    {
+      svn_prop_inherited_item_t *new_iprop =
+        apr_palloc(scratch_pool, sizeof(*new_iprop));
+      new_iprop->path_or_url = path_or_url;
+      new_iprop->prop_hash = apr_hash_make(scratch_pool);
+      apr_hash_set(new_iprop->prop_hash,
+                   SVN_CONFIG_PROP_AUTO_PROPS,
+                   APR_HASH_KEY_STRING,
+                   config_auto_prop);
+      APR_ARRAY_PUSH(inherited_config_auto_props,
+                     svn_prop_inherited_item_t *) = new_iprop;
+    }
+
+  for (i = 0; i < inherited_config_auto_props->nelts; i++)
+    {
+      apr_hash_index_t *hi;
+      svn_prop_inherited_item_t *elt = APR_ARRAY_IDX(
+        inherited_config_auto_props, i, svn_prop_inherited_item_t *);
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+      for (hi = apr_hash_first(scratch_pool, elt->prop_hash);
+           hi;
+           hi = apr_hash_next(hi))
+        {
+          const svn_string_t *propval = svn__apr_hash_index_val(hi);
+          const char *ch = propval->data;
+          svn_stringbuf_t *config_auto_prop_pattern;
+          svn_stringbuf_t *config_auto_prop_val;
+
+          svn_pool_clear(iterpool);
+
+          config_auto_prop_pattern = svn_stringbuf_create_empty(iterpool);
+          config_auto_prop_val = svn_stringbuf_create_empty(iterpool);
+
+          /* Parse svn:config:auto-props value. */
+          while (*ch != '\0')
+            {
+              svn_stringbuf_setempty(config_auto_prop_pattern);
+              svn_stringbuf_setempty(config_auto_prop_val);
+
+              /* Parse the file pattern. */
+              while (*ch != '\0' && *ch != '=' && *ch != '\n')
+                {
+                  svn_stringbuf_appendbyte(config_auto_prop_pattern, *ch);
+                  ch++;
+                }
+
+              svn_stringbuf_strip_whitespace(config_auto_prop_pattern);
+
+              /* Parse the auto-prop group. */
+              while (*ch != '\0' && *ch != '\n')
+                {
+                  svn_stringbuf_appendbyte(config_auto_prop_val, *ch);
+                  ch++;
+                }
+
+              /* Strip leading '=' and whitespace from auto-prop group. */
+              if (config_auto_prop_val->data[0] == '=')
+                svn_stringbuf_remove(config_auto_prop_val, 0, 1);
+              svn_stringbuf_strip_whitespace(config_auto_prop_val);
+
+              all_auto_props_collector(config_auto_prop_pattern->data,
+                                       config_auto_prop_val->data,
+                                       &autoprops_baton,
+                                       scratch_pool);
+
+              /* Skip to next line if any. */
+              while (*ch != '\0' && *ch != '\n')
+                ch++;
+              if (*ch == '\n')
+                ch++;
+            }
+          svn_pool_destroy(iterpool);
+        }
+    }
+  return SVN_NO_ERROR;
+}
 
 /* The main logic of the public svn_client_add4.
  *
@@ -512,6 +673,7 @@ add(const char *local_abspath,
   svn_node_kind_t kind;
   svn_error_t *err;
   svn_magic__cookie_t *magic_cookie;
+  apr_hash_t *config_autoprops;
 
   svn_magic__init(&magic_cookie, scratch_pool);
 
@@ -528,6 +690,11 @@ add(const char *local_abspath,
                                           local_abspath, NULL);
       components = svn_path_decompose(child_relpath, scratch_pool);
       iterpool = svn_pool_create(scratch_pool);
+
+      SVN_ERR(svn_client__get_all_auto_props(&config_autoprops,
+                                             existing_parent_abspath, ctx,
+                                             scratch_pool, iterpool));
+
       for (i = 0; i < components->nelts - 1; i++)
         {
           const char *component;
@@ -554,6 +721,13 @@ add(const char *local_abspath,
         }
       svn_pool_destroy(iterpool);
     }
+  else
+    {
+      SVN_ERR(svn_client__get_all_auto_props(
+        &config_autoprops,
+        svn_dirent_dirname(local_abspath, scratch_pool),
+        ctx, scratch_pool, scratch_pool));
+    }
 
   SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
   if (kind == svn_node_dir)
@@ -562,10 +736,12 @@ add(const char *local_abspath,
          and pass depth along no matter what it is, so that the
          target's depth will be set correctly. */
       err = add_dir_recursive(local_abspath, depth, force, no_ignore,
-                              magic_cookie, ctx, scratch_pool);
+                              magic_cookie, config_autoprops, ctx,
+                              scratch_pool);
     }
   else if (kind == svn_node_file)
-    err = add_file(local_abspath, magic_cookie, ctx, scratch_pool);
+    err = add_file(local_abspath, magic_cookie, config_autoprops, ctx,
+                   scratch_pool);
   else if (kind == svn_node_none)
     {
       svn_boolean_t tree_conflicted;

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_client/client.h?rev=1393257&r1=1393256&r2=1393257&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_client/client.h (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_client/client.h Wed Oct  3 02:23:46
2012
@@ -360,21 +360,44 @@ svn_client__ra_make_cb_baton(svn_wc_cont
 
 /*** Add/delete ***/
 
-/* Read automatic properties matching PATH from CTX->config.
+/* Read automatic properties matching PATH from AUTOPROPS.  AUTOPROPS
+   is is a hash as per svn_client__get_all_auto_props.
    Set *PROPERTIES to a hash containing propname/value pairs
-   (const char * keys mapping to svn_string_t * values), or if
-   auto-props are disabled, set *PROPERTIES to NULL.
+   (const char * keys mapping to svn_string_t * values).  *PROPERTIES
+   may be an empty hash, but will not be NULL.
    Set *MIMETYPE to the mimetype, if any, or to NULL.
    If MAGIC_COOKIE is not NULL and no mime-type can be determined
    via CTX->config try to detect the mime-type with libmagic.
-   Allocate the hash table, keys, values, and mimetype in POOL. */
-svn_error_t *svn_client__get_auto_props(apr_hash_t **properties,
-                                        const char **mimetype,
-                                        const char *path,
-                                        svn_magic__cookie_t *magic_cookie,
-                                        svn_client_ctx_t *ctx,
-                                        apr_pool_t *pool);
-
+   Allocate the *PROPERTIES and its contents as well as *MIMETYPE, in
+   RESULT_POOL.  Use SCRATCH_POOL for temporary allocations. */
+svn_error_t *svn_client__get_paths_auto_props(
+  apr_hash_t **properties,
+  const char **mimetype,
+  const char *path,
+  svn_magic__cookie_t *magic_cookie,
+  apr_hash_t *autoprops,
+  svn_client_ctx_t *ctx,
+  apr_pool_t *result_pool,
+  apr_pool_t *scratch_pool);
+
+/* Gather all auto-props from CTX->config (or none if auto-props are
+   disabled) and all svn:config:auto-props explicitly set on or inherited
+   by PATH_OR_URL.  If PATH_OR_URL is a URL ask for the properties @HEAD,
+   if it is a WC path as for the working properties.  Store both types of
+   auto-props in *AUTOPROPS, a hash mapping const char * file patterns to
+   another hash which maps const char * property names to const char *
+   property values.  If a given property name exists for the same pattern
+   in both the config file and in an a svn:config:auto-props property,
+   the latter overrides the former.  If a given property name exists for
+   the same pattern in two diffrent inherited svn:config:auto-props, then
+   the closer path-wise property overrides the more distant.
+   svn:config:auto-props explicitly set on PATH_OR_URL have the highest
+   precedence and override inherited props and config file settings. */
+svn_error_t *svn_client__get_all_auto_props(apr_hash_t **autoprops,
+                                            const char *path_or_url,
+                                            svn_client_ctx_t *ctx,
+                                            apr_pool_t *result_pool,
+                                            apr_pool_t *scratch_pool);
 
 /* The main logic for client deletion from a working copy. Deletes PATH
    from CTX->WC_CTX.  If PATH (or any item below a directory PATH) is

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_client/commit.c?rev=1393257&r1=1393256&r2=1393257&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_client/commit.c Wed Oct  3 02:23:46
2012
@@ -75,6 +75,13 @@ typedef struct import_ctx_t
 
   /* A magic cookie for mime-type detection. */
   svn_magic__cookie_t *magic_cookie;
+
+  /* Collection of all possible configuration file dictated auto-props and
+     svn:config:autoprops.  A hash mapping const char * file patterns to a
+     second hash which maps const char * property names to const char *
+     property values.  Properties which don't have a value, e.g. svn:executable,
+     simply map the property name to an empty string. */
+  apr_hash_t *autoprops;
 } import_ctx_t;
 
 
@@ -219,9 +226,11 @@ import_file(const svn_delta_editor_t *ed
   if (! dirent->special)
     {
       /* add automatic properties */
-      SVN_ERR(svn_client__get_auto_props(&properties, &mimetype, local_abspath,
-                                         import_ctx->magic_cookie,
-                                         ctx, pool));
+      SVN_ERR(svn_client__get_paths_auto_props(&properties, &mimetype,
+                                               local_abspath,
+                                               import_ctx->magic_cookie,
+                                               import_ctx->autoprops,
+                                               ctx, pool, pool));
     }
   else
     properties = apr_hash_make(pool);
@@ -590,6 +599,10 @@ import_dir(const svn_delta_editor_t *edi
  * EXCLUDES is a hash whose keys are absolute paths to exclude from
  * the import (values are unused).
  *
+ * AUTOPROPS is hash of all config file autoprops and svn:config:auto-props
+ * inherited by the import target, see the IMPORT_CTX member of the same
+ * name.
+ *
  * If NO_IGNORE is FALSE, don't import files or directories that match
  * ignore patterns.
  *
@@ -610,6 +623,7 @@ import(const char *local_abspath,
        void *edit_baton,
        svn_depth_t depth,
        apr_hash_t *excludes,
+       apr_hash_t *autoprops,
        svn_boolean_t no_ignore,
        svn_boolean_t ignore_unknown_node_types,
        svn_client_import_filter_func_t filter_callback,
@@ -624,6 +638,7 @@ import(const char *local_abspath,
   import_ctx_t *import_ctx = apr_pcalloc(pool, sizeof(*import_ctx));
   const svn_io_dirent2_t *dirent;
 
+  import_ctx->autoprops = autoprops;
   svn_magic__init(&import_ctx->magic_cookie, pool);
 
   /* Get a root dir baton.  We pass an invalid revnum to open_root
@@ -822,7 +837,8 @@ get_ra_editor(const svn_delta_editor_t *
   return SVN_NO_ERROR;
 }
 
-
+
+
 /*** Public Interfaces. ***/
 
 svn_error_t *
@@ -853,6 +869,7 @@ svn_client_import5(const char *path,
   const char *dir;
   apr_hash_t *commit_revprops;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_hash_t *autoprops;
 
   if (svn_path_is_url(path))
     return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
@@ -964,10 +981,15 @@ svn_client_import5(const char *path,
                                     commit_baton, NULL, TRUE,
                                     scratch_pool));
 
+  /* Get inherited svn:config:auto-props for the location we
+     are importing to. */
+  SVN_ERR(svn_client__get_all_auto_props(&autoprops, url, ctx,
+                                         scratch_pool, iterpool));
+
   /* If an error occurred during the commit, abort the edit and return
      the error.  We don't even care if the abort itself fails.  */
   if ((err = import(local_abspath, new_entries, editor, edit_baton,
-                    depth, excludes, no_ignore,
+                    depth, excludes, autoprops, no_ignore,
                     ignore_unknown_node_types,
                     filter_callback, filter_baton,
                     ctx, iterpool)))



Mime
View raw message