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/7f230f3e-1d64-4c4c-924d-990645df6dacn%40googlegroups.com.