Index: subversion/include/private/svn_mergeinfo_private.h =================================================================== --- subversion/include/private/svn_mergeinfo_private.h (revision 943236) +++ subversion/include/private/svn_mergeinfo_private.h (working copy) @@ -212,6 +212,21 @@ svn_boolean_t inheritable, apr_pool_t *result_pool); +/* Adjust in-place MERGEINFO's rangelists by OFFSET. If OFFSET is negative + and would adjust any part of MERGEINFO's source revisions to 0 or less, + then those revisions are dropped. If all the source revisions for a merge + source path are dropped, then the path itself is dropped. If all merge + source paths are dropped, then *ADJUSTED_MERGEINFO is set to an empty + hash. *ADJUSTED_MERGEINFO is allocated in RESULT_POOL. SCRATCH_POOL is + used for any temporary allocations. */ +svn_error_t * +svn_mergeinfo__adjust_mergeinfo_rangelists(svn_mergeinfo_t *adjusted_mergeinfo, + svn_mergeinfo_t mergeinfo, + svn_revnum_t offset, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + #ifdef __cplusplus } #endif /* __cplusplus */ Index: subversion/libsvn_repos/load.c =================================================================== --- subversion/libsvn_repos/load.c (revision 943236) +++ subversion/libsvn_repos/load.c (working copy) @@ -278,11 +278,31 @@ apr_pool_t *pool) { apr_pool_t *subpool = svn_pool_create(pool); - apr_hash_t *mergeinfo; - apr_hash_t *final_mergeinfo = apr_hash_make(subpool); + svn_mergeinfo_t mergeinfo, predates_stream_mergeinfo; + svn_mergeinfo_t final_mergeinfo = apr_hash_make(subpool); apr_hash_index_t *hi; SVN_ERR(svn_mergeinfo_parse(&mergeinfo, initial_val->data, subpool)); + + if (rb->pb->oldest_old_rev > 1) + { + SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges( + &predates_stream_mergeinfo, mergeinfo, + rb->pb->oldest_old_rev - 1, 0, + TRUE, subpool, subpool)); + SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges( + &mergeinfo, mergeinfo, + rb->pb->oldest_old_rev - 1, 0, + FALSE, subpool, subpool)); + SVN_ERR(svn_mergeinfo__adjust_mergeinfo_rangelists( + &predates_stream_mergeinfo, predates_stream_mergeinfo, + -rb->rev_offset, subpool, subpool)); + } + else + { + predates_stream_mergeinfo = NULL; + } + for (hi = apr_hash_first(subpool, mergeinfo); hi; hi = apr_hash_next(hi)) { const char *merge_source; @@ -348,6 +368,11 @@ apr_hash_set(final_mergeinfo, merge_source, APR_HASH_KEY_STRING, rangelist); } + + if (predates_stream_mergeinfo) + SVN_ERR(svn_mergeinfo_merge(final_mergeinfo, predates_stream_mergeinfo, + subpool)); + SVN_ERR(svn_mergeinfo_sort(final_mergeinfo, subpool)); /* Mergeinfo revision sources for r0 and r1 are invalid; you can't merge r0 @@ -1053,6 +1078,10 @@ SVN_ERR(svn_stream_printf(pb->outstream, pool, _("<<< Started new transaction, based on " "original revision %ld\n"), rb->rev)); + + /* Stash the oldest "old" revision committed from the load stream. */ + if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev)) + pb->oldest_old_rev = rb->rev; } /* If we're parsing revision 0, only the revision are (possibly) @@ -1411,10 +1440,6 @@ return svn_error_return(err); } - /* Stash the oldest "old" revision committed from the load stream. */ - if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev)) - pb->oldest_old_rev = *old_rev; - /* Run post-commit hook, if so commanded. */ if (pb->use_post_commit_hook) { Index: subversion/libsvn_subr/mergeinfo.c =================================================================== --- subversion/libsvn_subr/mergeinfo.c (revision 943236) +++ subversion/libsvn_subr/mergeinfo.c (working copy) @@ -1998,6 +1998,58 @@ return SVN_NO_ERROR; } +svn_error_t * +svn_mergeinfo__adjust_mergeinfo_rangelists(svn_mergeinfo_t *adjusted_mergeinfo, + svn_mergeinfo_t mergeinfo, + svn_revnum_t offset, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + apr_hash_index_t *hi; + *adjusted_mergeinfo = apr_hash_make(result_pool); + + if (mergeinfo) + { + for (hi = apr_hash_first(scratch_pool, mergeinfo); + hi; + hi = apr_hash_next(hi)) + { + int i; + const char *path = svn__apr_hash_index_key(hi); + apr_array_header_t *rangelist = svn__apr_hash_index_val(hi); + apr_array_header_t *adjusted_rangelist = + apr_array_make(result_pool, rangelist->nelts, + sizeof(svn_merge_range_t *)); + + for (i = 0; i < rangelist->nelts; i++) + { + svn_merge_range_t *range = + APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *); + + if (range->start + offset > 0 && range->end + offset > 0) + { + if (range->start + offset < 0) + range->start = 0; + else + range->start = range->start + offset; + + if (range->end + offset < 0) + range->end = 0; + else + range->end = range->end + offset; + APR_ARRAY_PUSH(adjusted_rangelist, svn_merge_range_t *) = + range; + } + } + + if (adjusted_rangelist->nelts) + apr_hash_set(*adjusted_mergeinfo, apr_pstrdup(result_pool, path), + APR_HASH_KEY_STRING, adjusted_rangelist); + } + } + return SVN_NO_ERROR; +} + svn_boolean_t svn_mergeinfo__is_noninheritable(svn_mergeinfo_t mergeinfo, apr_pool_t *scratch_pool) Index: subversion/tests/cmdline/svnadmin_tests.py =================================================================== --- subversion/tests/cmdline/svnadmin_tests.py (revision 943236) +++ subversion/tests/cmdline/svnadmin_tests.py (working copy) @@ -1070,6 +1070,7 @@ load_and_verify_dumpstream(sbox, [], [], None, open(dump_file_r11_13).read(), '--ignore-uuid') + #raise svntest.Failure("PTB") load_and_verify_dumpstream(sbox, [], [], None, open(dump_file_r14_15).read(), '--ignore-uuid') @@ -1162,28 +1163,6 @@ # Check the resulting mergeinfo. We expect the exact same results # as Part 3. - # - # Currently this fails because our current logic mapping mergeinfo revs - # in the load stream to their new values based on the offset of the - # target repository is quite flawed. Right now this is the resulting - # mergeinfo: - # - # Properties on 'svnadmin_tests-21\Projects\Project-X\branches\B1\B - # svn:mergeinfo - # /Projects/Project-X/branches/B2/B/E:11-12 - # /Projects/Project-X/trunk/B/E:5-6,8-9 - # Properties on 'svnadmin_tests-21\Projects\Project-X\branches\B1': - # svn:mergeinfo - # /Projects/Project-X/branches/B2:11-18 - # ^^ - # The *only* correct rev here! - # /Projects/Project-X/trunk:6,9 - # Properties on 'svnadmin_tests-21\Projects\Project-X\branches\B2': - # svn:mergeinfo - # /Projects/Project-X/trunk:9 - # - # See http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16 for - # more info. svntest.actions.run_and_verify_svn(None, expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url) @@ -1215,7 +1194,7 @@ create_in_repo_subdir, SkipUnless(verify_with_invalid_revprops, svntest.main.is_fs_type_fsfs), - XFail(dont_drop_valid_mergeinfo_during_incremental_loads), + dont_drop_valid_mergeinfo_during_incremental_loads, ] if __name__ == '__main__':