Author: pburba Date: Thu Aug 11 19:16:24 2011 New Revision: 1156750 URL: http://svn.apache.org/viewvc?rev=1156750&view=rev Log: More fixes for issue #3986 'svn_client_mergeinfo_log API broken with WC target which inherits mergeinfo from repos'.
Prior to this change svn_client__get_repos_mergeinfo_catalog promised a a mergeinfo catalog with a key relative to RA_SESSION's session URL for the target, but keys relative to the *root* of the repository for the subtrees. It actually only ever did the latter...which caused some obvious problems for one of its two callers, svn_client__get_wc_or_repos_mergeinfo_catalog, which might call either svn_client__get_wc_mergeinfo_catalog or svn_client__get_repos_mergeinfo_catalog and return a catalog keyed on either repos-root-relative paths or session-relative-paths. Ouch. Both of these functions are now consistent, returning a catalog keyed on root-relative paths. * subversion/libsvn_client/mergeinfo.c (svn_client__get_repos_mergeinfo_catalog): Make the mergeinfo catalog returned by this function consistent with svn_client__get_wc_mergeinfo_catalog; the keys to the catalog are now relative to the root of the repository, rather than relative to the root of the RA session passed in. (svn_client__get_wc_or_repos_mergeinfo_catalog): Account for change in mergeinfo catalog keys provided by svn_client__get_repos_mergeinfo_catalog. (get_mergeinfo): Stop changing mergeinfo catalog keys from relative to the session URL to relative to the root of the repository, svn_client__get_wc_or_repos_mergeinfo_catalog does this itself now. * subversion/libsvn_client/mergeinfo.h (svn_client__get_repos_mergeinfo_catalog): Update doc string. * subversion/tests/cmdline/mergeinfo_tests.py (wc_target_inherits_mergeinfo_from_repos): Remove XFail decorator and comments. Modified: subversion/trunk/subversion/libsvn_client/mergeinfo.c subversion/trunk/subversion/libsvn_client/mergeinfo.h subversion/trunk/subversion/tests/cmdline/mergeinfo_tests.py Modified: subversion/trunk/subversion/libsvn_client/mergeinfo.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/mergeinfo.c?rev=1156750&r1=1156749&r2=1156750&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_client/mergeinfo.c (original) +++ subversion/trunk/subversion/libsvn_client/mergeinfo.c Thu Aug 11 19:16:24 2011 @@ -476,28 +476,66 @@ svn_client__get_repos_mergeinfo_catalog( apr_pool_t *scratch_pool) { svn_error_t *err; - svn_mergeinfo_t repos_mergeinfo; + svn_mergeinfo_t repos_mergeinfo_cat; apr_array_header_t *rel_paths = apr_array_make(scratch_pool, 1, sizeof(rel_path)); APR_ARRAY_PUSH(rel_paths, const char *) = rel_path; /* Fetch the mergeinfo. */ - err = svn_ra_get_mergeinfo2(ra_session, &repos_mergeinfo, rel_paths, rev, - inherit, validate_inherited_mergeinfo, + err = svn_ra_get_mergeinfo2(ra_session, &repos_mergeinfo_cat, rel_paths, + rev, inherit, validate_inherited_mergeinfo, include_descendants, result_pool); if (err) { if (squelch_incapable && err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE) { svn_error_clear(err); - repos_mergeinfo = NULL; + *mergeinfo_cat = NULL; } else return svn_error_trace(err); } - *mergeinfo_cat = repos_mergeinfo; + if (repos_mergeinfo_cat == NULL) + { + *mergeinfo_cat = NULL; + } + else + { + const char *repos_root; + const char *session_url; + + SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, scratch_pool)); + SVN_ERR(svn_ra_get_session_url(ra_session, &session_url, scratch_pool)); + + if (strcmp(repos_root, session_url) == 0) + { + *mergeinfo_cat = repos_mergeinfo_cat; + } + else + { + apr_hash_index_t *hi; + svn_mergeinfo_catalog_t rekeyed_mergeinfo_cat = + apr_hash_make(result_pool); + + for (hi = apr_hash_first(scratch_pool, repos_mergeinfo_cat); + hi; + hi = apr_hash_next(hi)) + { + const char *path = + svn_path_url_add_component2(session_url, + svn__apr_hash_index_key(hi), + scratch_pool); + SVN_ERR(svn_ra_get_path_relative_to_root(ra_session, &path, + path, + result_pool)); + apr_hash_set(rekeyed_mergeinfo_cat, path, APR_HASH_KEY_STRING, + svn__apr_hash_index_val(hi)); + } + *mergeinfo_cat = rekeyed_mergeinfo_cat; + } + } return SVN_NO_ERROR; } @@ -653,7 +691,8 @@ svn_client__get_wc_or_repos_mergeinfo_ca result_pool, scratch_pool)); if (target_mergeinfo_cat_repos - && apr_hash_get(target_mergeinfo_cat_repos, "", + && apr_hash_get(target_mergeinfo_cat_repos, + repos_relpath, APR_HASH_KEY_STRING)) { *inherited = TRUE; @@ -1109,41 +1148,11 @@ get_mergeinfo(svn_mergeinfo_catalog_t *m if (use_url) { - svn_mergeinfo_catalog_t tmp_catalog; - rev = peg_rev; SVN_ERR(svn_client__get_repos_mergeinfo_catalog( - &tmp_catalog, ra_session, "", rev, svn_mergeinfo_inherited, + mergeinfo_catalog, ra_session, "", rev, svn_mergeinfo_inherited, FALSE, include_descendants, TRUE, result_pool, scratch_pool)); - - /* If we're not querying the root of the repository, the catalog - we fetched will be keyed on paths relative to the session - URL. But our caller is expecting repository relpaths. So we - do a little dance... */ - if (tmp_catalog && (strcmp(url, *repos_root) != 0)) - { - apr_hash_index_t *hi; - - *mergeinfo_catalog = apr_hash_make(result_pool); - - for (hi = apr_hash_first(scratch_pool, tmp_catalog); - hi; hi = apr_hash_next(hi)) - { - /* session-relpath -> repos-url -> repos-relpath */ - const char *path = - svn_path_url_add_component2(url, svn__apr_hash_index_key(hi), - scratch_pool); - SVN_ERR(svn_ra_get_path_relative_to_root(ra_session, &path, path, - result_pool)); - apr_hash_set(*mergeinfo_catalog, path, APR_HASH_KEY_STRING, - svn__apr_hash_index_val(hi)); - } - } - else - { - *mergeinfo_catalog = tmp_catalog; - } } else /* ! svn_path_is_url() */ { Modified: subversion/trunk/subversion/libsvn_client/mergeinfo.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/mergeinfo.h?rev=1156750&r1=1156749&r2=1156750&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_client/mergeinfo.h (original) +++ subversion/trunk/subversion/libsvn_client/mergeinfo.h Thu Aug 11 19:16:24 2011 @@ -186,7 +186,7 @@ svn_client__get_repos_mergeinfo(svn_ra_s /* If INCLUDE_DESCENDANTS is FALSE, behave exactly like svn_client__get_repos_mergeinfo() except the mergeinfo for REL_PATH is put in the mergeinfo catalog MERGEINFO_CAT, with the key being - REL_PATH itself. + the repository root-relative path of REL_PATH. If INCLUDE_DESCENDANTS is true, then any subtrees under REL_PATH with explicit mergeinfo are also included in MERGEINFO_CAT. The Modified: subversion/trunk/subversion/tests/cmdline/mergeinfo_tests.py URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/mergeinfo_tests.py?rev=1156750&r1=1156749&r2=1156750&view=diff ============================================================================== --- subversion/trunk/subversion/tests/cmdline/mergeinfo_tests.py (original) +++ subversion/trunk/subversion/tests/cmdline/mergeinfo_tests.py Thu Aug 11 19:16:24 2011 @@ -553,17 +553,12 @@ def wc_target_inherits_mergeinfo_from_re '--show-revs', 'eligible', '-R') # Merged : Non-recursive - # - # Currently this fails because r7 is not shown as merged, despite the fact - # that the target inherits it from ^/A_COPY svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['7'], sbox.repo_url + '/A/D', subtree_wc, '--show-revs', 'merged') # Merged : Recursive - # - # Currently this fails because r7 is again missing. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['5','7'], sbox.repo_url + '/A/D', subtree_wc,