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 2010/01/05 17:22:32 UTC

svn commit: r896115 - in /subversion/trunk/subversion: include/private/svn_mergeinfo_private.h libsvn_client/merge.c libsvn_subr/mergeinfo.c libsvn_wc/props.c

Author: pburba
Date: Tue Jan  5 16:22:31 2010
New Revision: 896115

URL: http://svn.apache.org/viewvc?rev=896115&view=rev
Log:
Don't considered mergeinfo merge source paths containing '*' as 
automatically non-inheritable.

See http://svn.haxx.se/dev/archive-2010-01/0055.shtml

Found by: rhuijben

* subversion/include/private/svn_mergeinfo_private.h
 
  (svn_mergeinfo__is_noninheritable,
   svn_mergeinfo__string_has_noninheritable): New.

* subversion/libsvn_subr/mergeinfo.c

  (svn_mergeinfo__is_noninheritable,
   svn_mergeinfo__string_has_noninheritable): New.

* subversion/libsvn_client/merge.c

  (get_mergeinfo_walk_cb,
   record_mergeinfo_for_added_subtrees): Use new private APIs to detect
   non-inheritable mergeinfo, rather than overly-simplistic strstr() test
   for '*'.

* subversion/libsvn_wc/props.c

  (svn_wc_canonicalize_svn_prop): Ditto.

Modified:
    subversion/trunk/subversion/include/private/svn_mergeinfo_private.h
    subversion/trunk/subversion/libsvn_client/merge.c
    subversion/trunk/subversion/libsvn_subr/mergeinfo.c
    subversion/trunk/subversion/libsvn_wc/props.c

Modified: subversion/trunk/subversion/include/private/svn_mergeinfo_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_mergeinfo_private.h?rev=896115&r1=896114&r2=896115&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_mergeinfo_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_mergeinfo_private.h Tue Jan  5 16:22:31 2010
@@ -176,6 +176,20 @@
   svn_revnum_t oldest_rev,
   apr_pool_t *pool);
 
+/* If MERGEINFO is non-inheritable return TRUE, return FALSE otherwise.
+   MERGEINFO may be NULL or empty. */
+svn_boolean_t
+svn_mergeinfo__is_noninheritable(svn_mergeinfo_t mergeinfo,
+                                 apr_pool_t *scratch_pool);
+
+/* If MERGEINFO_STR is a string representation of non-inheritable mergeinfo
+   set *IS_NONINHERITABLE to TRUE, set it to FALSE otherwise.  MERGEINFO_STR
+   may be NULL or empty.  If MERGEINFO_STR cannot be parsed return
+   SVN_ERR_MERGEINFO_PARSE_ERROR. */
+svn_error_t *
+svn_mergeinfo__string_has_noninheritable(svn_boolean_t *is_noninheritable,
+                                         const char *mergeinfo_str,
+                                         apr_pool_t *scratch_pool);
 
 #ifdef __cplusplus
 }

Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=896115&r1=896114&r2=896115&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Tue Jan  5 16:22:31 2010
@@ -5245,9 +5245,10 @@
       child->switched = switched;
       child->absent = absent;
       child->scheduled_for_deletion = deleted;
-      if (propval
-          && strstr(propval->data, SVN_MERGEINFO_NONINHERITABLE_STR))
-        child->has_noninheritable = TRUE;
+
+      if (propval)
+        SVN_ERR(svn_mergeinfo__string_has_noninheritable(
+          &(child->has_noninheritable), propval->data, scratch_pool));
 
       /* A little trickery: If PATH doesn't have any mergeinfo or has
          only inheritable mergeinfo, we still describe it as having
@@ -7069,25 +7070,21 @@
     {
       const char *added_abspath = svn_apr_hash_index_key(hi);
       const char *dir_abspath;
-      const svn_string_t *added_path_parent_propval;
+      svn_mergeinfo_t parent_mergeinfo;
+      svn_boolean_t inherited;
 
       apr_pool_clear(iterpool);
       dir_abspath = svn_dirent_dirname(added_abspath, iterpool);
 
-      /* Rather than using svn_client__get_wc_mergeinfo() and analyzing the
-         mergeinfo it returns to determine if ADDED_PATH's parent has
-         non-inheritable mergeinfo, it is much simpler to just get the
-         svn_string_t representation of the svn:mergeinfo prop and look for
-         the '*' non-inheritable marker. */
-      SVN_ERR(svn_wc_prop_get2(&added_path_parent_propval,
-                               merge_b->ctx->wc_ctx, dir_abspath,
-                               SVN_PROP_MERGEINFO, iterpool, iterpool));
-      if (added_path_parent_propval
-          && strstr(added_path_parent_propval->data,
-                    SVN_MERGEINFO_NONINHERITABLE_STR))
+      /* Does ADDED_ABSPATH's immediate parent have non-inheritable
+         mergeinfo? */
+      SVN_ERR(svn_client__get_wc_mergeinfo(&parent_mergeinfo, &inherited,
+                                           svn_mergeinfo_explicit,
+                                           dir_abspath, NULL, NULL,
+                                           merge_b->ctx,
+                                           iterpool, iterpool));
+      if (svn_mergeinfo__is_noninheritable(parent_mergeinfo, iterpool))
         {
-          /* ADDED_PATH's immediate parent has non-inheritable
-             mergeinfo. */
           svn_client__merge_path_t *target_merge_path =
             APR_ARRAY_IDX(notify_b->children_with_mergeinfo, 0,
                           svn_client__merge_path_t *);

Modified: subversion/trunk/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/mergeinfo.c?rev=896115&r1=896114&r2=896115&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/trunk/subversion/libsvn_subr/mergeinfo.c Tue Jan  5 16:22:31 2010
@@ -2003,3 +2003,49 @@
     }
   return SVN_NO_ERROR;
 }
+
+svn_boolean_t
+svn_mergeinfo__is_noninheritable(svn_mergeinfo_t mergeinfo,
+                                 apr_pool_t *scratch_pool)
+{
+  if (mergeinfo)
+    {
+      apr_hash_index_t *hi;
+
+      for (hi = apr_hash_first(scratch_pool, mergeinfo);
+           hi;
+           hi = apr_hash_next(hi))
+        {
+          apr_array_header_t *rangelist = svn_apr_hash_index_val(hi);
+          int i;
+
+          for (i = 0; i < rangelist->nelts; i++)
+            {
+              svn_merge_range_t *range = APR_ARRAY_IDX(rangelist, i,
+                                                       svn_merge_range_t *);
+              if (!range->inheritable)
+                return TRUE;
+            }
+        }
+    }
+  return FALSE;
+}
+
+svn_error_t *
+svn_mergeinfo__string_has_noninheritable(svn_boolean_t *is_noninheritable,
+                                         const char *mergeinfo_str,
+                                         apr_pool_t *scratch_pool)
+{
+  *is_noninheritable = FALSE;
+
+  if (mergeinfo_str)
+    {
+      svn_mergeinfo_t mergeinfo;
+
+      SVN_ERR(svn_mergeinfo_parse(&mergeinfo, mergeinfo_str, scratch_pool));
+      *is_noninheritable = svn_mergeinfo__is_noninheritable(mergeinfo,
+                                                            scratch_pool);
+    }
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/trunk/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/props.c?rev=896115&r1=896114&r2=896115&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/props.c (original)
+++ subversion/trunk/subversion/libsvn_wc/props.c Tue Jan  5 16:22:31 2010
@@ -2444,16 +2444,16 @@
       apr_hash_t *mergeinfo;
       svn_string_t *new_value_str;
 
+      SVN_ERR(svn_mergeinfo_parse(&mergeinfo, propval->data, pool));
 
       /* Non-inheritable mergeinfo is only valid on directories. */
       if (kind != svn_node_dir
-          && strstr(propval->data, SVN_MERGEINFO_NONINHERITABLE_STR))
+          && svn_mergeinfo__is_noninheritable(mergeinfo, pool))
         return svn_error_createf(
           SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
           _("Cannot set non-inheritable mergeinfo on a non-directory ('%s')"),
           svn_dirent_local_style(path, pool));
 
-      SVN_ERR(svn_mergeinfo_parse(&mergeinfo, propval->data, pool));
       SVN_ERR(svn_mergeinfo_to_string(&new_value_str, mergeinfo, pool));
       new_value = svn_stringbuf_create_from_string(new_value_str, pool);
     }