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); }
