You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2012/12/10 23:48:28 UTC
svn commit: r1419856 - /subversion/trunk/subversion/libsvn_client/merge.c
Author: pburba
Date: Mon Dec 10 22:48:27 2012
New Revision: 1419856
URL: http://svn.apache.org/viewvc?rev=1419856&view=rev
Log:
Partial fix for issue #4269 'subtree mergeinfo can degrade automatic merge
performance'.
This can buy substantial merge performance improvements in some limited
circumstances, see
http://subversion.tigris.org/issues/show_bug.cgi?id=4269#desc5
* subversion/libsvn_client/merge.c
(remove_noop_subtree_ranges): If possible, limit the requested log to a
subtree of the merge source, potentially giving a quicker turnaround.
Modified:
subversion/trunk/subversion/libsvn_client/merge.c
Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1419856&r1=1419855&r2=1419856&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Mon Dec 10 22:48:27 2012
@@ -8511,6 +8511,8 @@ remove_noop_subtree_ranges(const merge_s
svn_merge_range_t *youngest_gap_rev;
svn_rangelist_t *inoperative_ranges;
apr_pool_t *iterpool;
+ const char *longest_common_subtree_ancestor = NULL;
+ svn_error_t *err;
assert(session_url_is(ra_session, source->loc2->url, scratch_pool));
@@ -8549,6 +8551,19 @@ remove_noop_subtree_ranges(const merge_s
svn_pool_clear(iterpool);
+ /* Issue #4269: Keep track of the longest common ancestor of all the
+ subtrees which require merges. This may be a child of
+ TARGET->ABSPATH, which will allow us to narrow the log request
+ below. */
+ if (child->remaining_ranges && child->remaining_ranges->nelts)
+ {
+ if (longest_common_subtree_ancestor)
+ longest_common_subtree_ancestor = svn_dirent_get_longest_ancestor(
+ longest_common_subtree_ancestor, child->abspath, scratch_pool);
+ else
+ longest_common_subtree_ancestor = child->abspath;
+ }
+
/* CHILD->REMAINING_RANGES will be NULL if child is absent. */
if (child->remaining_ranges && child->remaining_ranges->nelts)
SVN_ERR(svn_rangelist_merge2(subtree_remaining_ranges,
@@ -8589,24 +8604,53 @@ remove_noop_subtree_ranges(const merge_s
sizeof(svn_revnum_t *));
log_gap_baton.pool = svn_pool_create(scratch_pool);
+ /* Find the longest common ancestor of all subtrees relative to
+ RA_SESSION's URL. */
+ if (longest_common_subtree_ancestor)
+ longest_common_subtree_ancestor =
+ svn_dirent_skip_ancestor(target->abspath,
+ longest_common_subtree_ancestor);
+ else
+ longest_common_subtree_ancestor = "";
+
/* Invoke the svn_log_entry_receiver_t receiver log_noop_revs() from
oldest to youngest. The receiver is optimized to add ranges to
log_gap_baton.merged_ranges and log_gap_baton.operative_ranges, but
requires that the revs arrive oldest to youngest -- see log_noop_revs()
and rangelist_merge_revision(). */
- SVN_ERR(get_log(ra_session, "", oldest_gap_rev->start + 1,
- youngest_gap_rev->end, TRUE,
- log_noop_revs, &log_gap_baton, scratch_pool));
-
- inoperative_ranges = svn_rangelist__initialize(oldest_gap_rev->start,
- youngest_gap_rev->end,
- TRUE, scratch_pool);
- SVN_ERR(svn_rangelist_remove(&(inoperative_ranges),
- log_gap_baton.operative_ranges,
- inoperative_ranges, FALSE, scratch_pool));
+ err = get_log(ra_session, longest_common_subtree_ancestor,
+ oldest_gap_rev->start + 1, youngest_gap_rev->end, TRUE,
+ log_noop_revs, &log_gap_baton, scratch_pool);
+
+ /* It's possible that the only subtrees with mergeinfo in TARGET don't have
+ any corresponding subtree in SOURCE between SOURCE->REV1 < SOURCE->REV2.
+ So it's also possible that we may ask for the logs of non-existent paths.
+ If we do, then assume that no subtree requires any ranges that are not
+ already required by the TARGET. */
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_FS_NOT_FOUND
+ && longest_common_subtree_ancestor[0] != '\0')
+ return svn_error_trace(err);
- SVN_ERR(svn_rangelist_merge2(log_gap_baton.merged_ranges, inoperative_ranges,
- scratch_pool, scratch_pool));
+ /* Asked about a non-existent subtree in SOURCE. */
+ svn_error_clear(err);
+ log_gap_baton.merged_ranges =
+ svn_rangelist__initialize(oldest_gap_rev->start,
+ youngest_gap_rev->end,
+ TRUE, scratch_pool);
+ }
+ else
+ {
+ inoperative_ranges = svn_rangelist__initialize(oldest_gap_rev->start,
+ youngest_gap_rev->end,
+ TRUE, scratch_pool);
+ SVN_ERR(svn_rangelist_remove(&(inoperative_ranges),
+ log_gap_baton.operative_ranges,
+ inoperative_ranges, FALSE, scratch_pool));
+ SVN_ERR(svn_rangelist_merge2(log_gap_baton.merged_ranges, inoperative_ranges,
+ scratch_pool, scratch_pool));
+ }
for (i = 1; i < children_with_mergeinfo->nelts; i++)
{