Since this concerns the Subversion library, please re-send this message to 
d...@subversion.apache.org.

Kind regards,
Daniel

tisdag 18 juni 2024 kl. 10:09:53 UTC+2 skrev iceyu...@gmail.com:

> Hello,
>
> Recently, we encountered a bug while using mergeinfo in SVN. Here is an 
> example:
> Our source branch has the following branch changes (through copy or 
> rename) history:
>
>    - Branch 1: /products/xy1/develop/mos2/trunk, revision a-b
>    - Branch 2: /products/xy1/develop/mos2/server, revision b-c
>    - Branch 3: 
>    /products/xy1/develop/mos2/server/branches/zlp_20240306, revision c-d
>    
> From the current code, in the svn_client__mergeinfo_log function, when 
> constructing merge_source_fspaths, all the changed branches are added to 
> merge_source_fspaths: 
> ```
> for (hi = apr_hash_first(scratch_pool, source_history);
>   hi;
>   hi = apr_hash_next(hi))
> {
>  const char *key = apr_hash_this_key(hi);
>  svn_rangelist_t *subtree_merged_rangelist = apr_hash_this_val(hi);
>  svn_rangelist_t *intersecting_rangelist;
>
>  svn_pool_clear(iterpool);
>  SVN_ERR(svn_rangelist_intersect(&intersecting_rangelist,
>                                  youngest_rangelist,
>                                  subtree_merged_rangelist,
>                                  FALSE, iterpool));
>
>  APR_ARRAY_PUSH(merge_source_fspaths, const char *) = key;
>
>  if (intersecting_rangelist->nelts)
>    log_target = key;
> }
> ```
> In filter_log_entry_with_rangelist function, when searching for the 
> changed_path for each revision, there is some code based on 
> merge_source_fspaths to match the common prefix and calculate the relative 
> path as follows:
> ```
> for (i = 0; i merge_source_fspaths->nelts; i++)
> {
>  merge_source_fspath = APR_ARRAY_IDX(fleb->merge_source_fspaths,
>                                      i, const char *);
>
>  merge_source_rel_target
>    = svn_fspath__skip_ancestor(merge_source_fspath, path);
>    …
> ```
> When a revision has a changed_path such as 
> /products/xy1/develop/mos2/server/branches/zlp_20240306/engine/src/gameplay/mosprop/src/prop_desc.cpp,
>  
> its corresponding merge_source is 
> /products/xy1/develop/mos2/server/branches/zlp_20240306. However, due to 
> the fact that the for-loop does not guarantee order, if merge_source_fspath 
> first matches /products/xy1/develop/mos2/server, it will still proceed with 
> the subsequent processing because of the common prefix, eventually 
> obtaining an incorrect relative path merge_source_rel_target, leading to an 
> incorrect judgment in the subsequent steps.
>
> One modification approach is, since when calling 
> logs_for_mergeinfo_rangelist in the svn_client__mergeinfo_log function, the 
> revision range of master_inheritable_rangelist is used:
> ```
> --- a/ext/Subversion/subversion/libsvn_client/mergeinfo.c
> +++ b/ext/Subversion/subversion/libsvn_client/mergeinfo.c
> @@ -2139,6 +2139,7 @@ svn_client__mergeinfo_log(svn_boolean_t 
> finding_merged,
>           const char *key = apr_hash_this_key(hi);
>           svn_rangelist_t *subtree_merged_rangelist = 
> apr_hash_this_val(hi);
>           svn_rangelist_t *intersecting_rangelist;
> +          svn_rangelist_t *intersecting_rangelist_merge_source_filter;
>
>           svn_pool_clear(iterpool);
>           SVN_ERR(svn_rangelist_intersect(&intersecting_rangelist,
> @@ -2146,7 +2147,13 @@ svn_client__mergeinfo_log(svn_boolean_t 
> finding_merged,
>                                           subtree_merged_rangelist,
>                                           FALSE, iterpool));
>
> -          APR_ARRAY_PUSH(merge_source_fspaths, const char *) = key;
> +         
>  SVN_ERR(svn_rangelist_intersect(&intersecting_rangelist_merge_source_filter,
> +                                          master_inheritable_rangelist,
> +                                          subtree_merged_rangelist,
> +                                          FALSE, iterpool));
> +
> +          if (intersecting_rangelist_merge_source_filter->nelts)
> +            APR_ARRAY_PUSH(merge_source_fspaths, const char *) = key;
>
>           if (intersecting_rangelist->nelts)
>             log_target = key;
> ```
>

-- 
You received this message because you are subscribed to the Google Groups 
"TortoiseSVN" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to tortoisesvn+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/tortoisesvn/0e915e00-e00f-466e-8d01-e5aecade8e95n%40googlegroups.com.

Reply via email to