summaryrefslogtreecommitdiffstats
path: root/subversion/libsvn_subr/mergeinfo.c
diff options
context:
space:
mode:
authorsvnmir <svnmir@FreeBSD.org>2015-08-09 04:37:48 +0000
committersvnmir <svnmir@FreeBSD.org>2015-08-09 04:37:48 +0000
commit91308aec6ca93cab82659cd43b3f6a83d366350b (patch)
tree78a13bd0acf7405df6eb6ca94a4e354d124065a6 /subversion/libsvn_subr/mergeinfo.c
parent0d1e05fe9c6027aaf742eb9b8b05f4dbefb92e2e (diff)
downloadFreeBSD-src-91308aec6ca93cab82659cd43b3f6a83d366350b.zip
FreeBSD-src-91308aec6ca93cab82659cd43b3f6a83d366350b.tar.gz
Vendor import subversion-1.8.14
Diffstat (limited to 'subversion/libsvn_subr/mergeinfo.c')
-rw-r--r--subversion/libsvn_subr/mergeinfo.c67
1 files changed, 58 insertions, 9 deletions
diff --git a/subversion/libsvn_subr/mergeinfo.c b/subversion/libsvn_subr/mergeinfo.c
index 63496ae..131fe59 100644
--- a/subversion/libsvn_subr/mergeinfo.c
+++ b/subversion/libsvn_subr/mergeinfo.c
@@ -611,6 +611,43 @@ svn_rangelist__parse(svn_rangelist_t **rangelist,
return SVN_NO_ERROR;
}
+/* Return TRUE, if all ranges in RANGELIST are in ascending order and do
+ * not overlap and are not adjacent.
+ *
+ * ### Can yield false negatives: ranges of differing inheritance are
+ * allowed to be adjacent.
+ *
+ * If this returns FALSE, you probaly want to qsort() the
+ * ranges and then call svn_rangelist__combine_adjacent_ranges().
+ */
+static svn_boolean_t
+is_rangelist_normalized(svn_rangelist_t *rangelist)
+{
+ int i;
+ svn_merge_range_t **ranges = (svn_merge_range_t **)rangelist->elts;
+
+ for (i = 0; i < rangelist->nelts-1; ++i)
+ if (ranges[i]->end >= ranges[i+1]->start)
+ return FALSE;
+
+ return TRUE;
+}
+
+svn_error_t *
+svn_rangelist__canonicalize(svn_rangelist_t *rangelist,
+ apr_pool_t *scratch_pool)
+{
+ if (! is_rangelist_normalized(rangelist))
+ {
+ qsort(rangelist->elts, rangelist->nelts, rangelist->elt_size,
+ svn_sort_compare_ranges);
+
+ SVN_ERR(svn_rangelist__combine_adjacent_ranges(rangelist, scratch_pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_rangelist__combine_adjacent_ranges(svn_rangelist_t *rangelist,
apr_pool_t *scratch_pool)
@@ -692,15 +729,11 @@ parse_revision_line(const char **input, const char *end, svn_mergeinfo_t hash,
if (*input != end)
*input = *input + 1;
- /* Sort the rangelist, combine adjacent ranges into single ranges,
- and make sure there are no overlapping ranges. */
- if (rangelist->nelts > 1)
- {
- qsort(rangelist->elts, rangelist->nelts, rangelist->elt_size,
- svn_sort_compare_ranges);
-
- SVN_ERR(svn_rangelist__combine_adjacent_ranges(rangelist, scratch_pool));
- }
+ /* Sort the rangelist, combine adjacent ranges into single ranges, and
+ make sure there are no overlapping ranges. Luckily, most data in
+ svn:mergeinfo will already be in normalized form and this will be quick.
+ */
+ SVN_ERR(svn_rangelist__canonicalize(rangelist, scratch_pool));
/* Handle any funky mergeinfo with relative merge source paths that
might exist due to issue #3547. It's possible that this issue allowed
@@ -1973,6 +2006,22 @@ svn_mergeinfo_sort(svn_mergeinfo_t input, apr_pool_t *pool)
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_mergeinfo__canonicalize_ranges(svn_mergeinfo_t mergeinfo,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_index_t *hi;
+
+ for (hi = apr_hash_first(scratch_pool, mergeinfo); hi; hi = apr_hash_next(hi))
+ {
+ apr_array_header_t *rl = svn__apr_hash_index_val(hi);
+
+ SVN_ERR(svn_rangelist__canonicalize(rl, scratch_pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
svn_mergeinfo_catalog_t
svn_mergeinfo_catalog_dup(svn_mergeinfo_catalog_t mergeinfo_catalog,
apr_pool_t *pool)
OpenPOWER on IntegriCloud