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.