summaryrefslogtreecommitdiff
path: root/subversion/include/svn_mergeinfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/include/svn_mergeinfo.h')
-rw-r--r--subversion/include/svn_mergeinfo.h612
1 files changed, 612 insertions, 0 deletions
diff --git a/subversion/include/svn_mergeinfo.h b/subversion/include/svn_mergeinfo.h
new file mode 100644
index 0000000000000..ada70a200964f
--- /dev/null
+++ b/subversion/include/svn_mergeinfo.h
@@ -0,0 +1,612 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ *
+ * @file svn_mergeinfo.h
+ * @brief mergeinfo handling and processing
+ */
+
+
+#ifndef SVN_MERGEINFO_H
+#define SVN_MERGEINFO_H
+
+#include <apr_pools.h>
+#include <apr_tables.h> /* for apr_array_header_t */
+#include <apr_hash.h>
+
+#include "svn_types.h"
+#include "svn_string.h" /* for svn_string_t */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** Overview of the @c SVN_PROP_MERGEINFO property.
+ *
+ * Merge history is stored in the @c SVN_PROP_MERGEINFO property of files
+ * and directories. The @c SVN_PROP_MERGEINFO property on a path stores the
+ * complete list of changes merged to that path, either directly or via the
+ * path's parent, grand-parent, etc.. A path may have empty mergeinfo which
+ * means that nothing has been merged to that path or all previous merges
+ * to the path were reversed. Note that a path may have no mergeinfo, this
+ * is not the same as empty mergeinfo.
+ *
+ * Every path in a tree may have @c SVN_PROP_MERGEINFO set, but if the
+ * @c SVN_PROP_MERGEINFO for a path is equivalent to the
+ * @c SVN_PROP_MERGEINFO for its parent, then the @c SVN_PROP_MERGEINFO on
+ * the path will 'elide' (be removed) from the path as a post step to any
+ * merge. If a path's parent does not have any @c SVN_PROP_MERGEINFO set,
+ * the path's mergeinfo can elide to its nearest grand-parent,
+ * great-grand-parent, etc. that has equivalent @c SVN_PROP_MERGEINFO set
+ * on it.
+ *
+ * If a path has no @c SVN_PROP_MERGEINFO of its own, it inherits mergeinfo
+ * from its nearest parent that has @c SVN_PROP_MERGEINFO set. The
+ * exception to this is @c SVN_PROP_MERGEINFO with non-inheritable revision
+ * ranges. These non-inheritable ranges apply only to the path which they
+ * are set on.
+ *
+ * Due to Subversion's allowance for mixed revision working copies, both
+ * elision and inheritance within the working copy presume the path
+ * between a path and its nearest parent with mergeinfo is at the same
+ * working revision. If this is not the case then neither inheritance nor
+ * elision can occur.
+ *
+ * The value of the @c SVN_PROP_MERGEINFO property is either an empty string
+ * (representing empty mergeinfo) or a non-empty string consisting of
+ * a path, a colon, and comma separated revision list, containing one or more
+ * revision or revision ranges. Revision range start and end points are
+ * separated by "-". Revisions and revision ranges may have the optional
+ * @c SVN_MERGEINFO_NONINHERITABLE_STR suffix to signify a non-inheritable
+ * revision/revision range.
+ *
+ * @c SVN_PROP_MERGEINFO Value Grammar:
+ *
+ * Token Definition
+ * ----- ----------
+ * revisionrange REVISION1 "-" REVISION2
+ * revisioneelement (revisionrange | REVISION)"*"?
+ * rangelist revisioneelement (COMMA revisioneelement)*
+ * revisionline PATHNAME COLON rangelist
+ * top "" | (revisionline (NEWLINE revisionline))*
+ *
+ * The PATHNAME is the source of a merge and the rangelist the revision(s)
+ * merged to the path @c SVN_PROP_MERGEINFO is set on directly or indirectly
+ * via inheritance. PATHNAME must always exist at the specified rangelist
+ * and thus a single merge may result in multiple revisionlines if the source
+ * was renamed.
+ *
+ * Rangelists must be sorted from lowest to highest revision and cannot
+ * contain overlapping revisionlistelements. REVISION1 must be less than
+ * REVISION2. Consecutive single revisions that can be represented by a
+ * revisionrange are allowed however (e.g. '5,6,7,8,9-12' or '5-12' are
+ * both acceptable).
+ */
+
+/* Suffix for SVN_PROP_MERGEINFO revision ranges indicating a given
+ range is non-inheritable. */
+#define SVN_MERGEINFO_NONINHERITABLE_STR "*"
+
+/** Terminology for data structures that contain mergeinfo.
+ *
+ * Subversion commonly uses several data structures to represent
+ * mergeinfo in RAM:
+ *
+ * (a) Strings (@c svn_string_t *) containing "unparsed mergeinfo".
+ *
+ * (b) @c svn_rangelist_t, called a "rangelist". An array of non-
+ * overlapping merge ranges (@c svn_merge_range_t *), sorted as said by
+ * @c svn_sort_compare_ranges(). An empty range list is represented by
+ * an empty array. Unless specifically noted otherwise, all APIs require
+ * rangelists that describe only forward ranges, i.e. the range's start
+ * revision is less than its end revision.
+ *
+ * (c) @c svn_mergeinfo_t, called "mergeinfo". A hash mapping merge
+ * source paths (@c const char *, starting with slashes) to
+ * non-empty rangelist arrays. A @c NULL hash is used to represent
+ * no mergeinfo and an empty hash is used to represent empty
+ * mergeinfo.
+ *
+ * (d) @c svn_mergeinfo_catalog_t, called a "mergeinfo catalog". A hash
+ * mapping paths (@c const char *) to @c svn_mergeinfo_t.
+ *
+ * Both @c svn_mergeinfo_t and @c svn_mergeinfo_catalog_t are just
+ * typedefs for @c apr_hash_t *; there is no static type-checking, and
+ * you still use standard @c apr_hash_t functions to interact with
+ * them.
+ *
+ * Note that while the keys of mergeinfos are always absolute from the
+ * repository root, the keys of a catalog may be relative to something
+ * else, such as an RA session root.
+ */
+
+typedef apr_array_header_t svn_rangelist_t;
+typedef apr_hash_t *svn_mergeinfo_t;
+typedef apr_hash_t *svn_mergeinfo_catalog_t;
+
+/** Parse the mergeinfo from @a input into @a *mergeinfo. If no
+ * mergeinfo is available, return an empty mergeinfo (never @c NULL).
+ * Perform temporary allocations in @a pool.
+ *
+ * If @a input is not a grammatically correct @c SVN_PROP_MERGEINFO
+ * property, contains overlapping revision ranges of differing
+ * inheritability, or revision ranges with a start revision greater
+ * than or equal to its end revision, or contains paths mapped to empty
+ * revision ranges, then return @c SVN_ERR_MERGEINFO_PARSE_ERROR.
+ * Unordered revision ranges are allowed, but will be sorted when
+ * placed into @a *mergeinfo. Overlapping revision ranges of the same
+ * inheritability are also allowed, but will be combined into a single
+ * range when placed into @a *mergeinfo.
+ *
+ * @a input may contain relative merge source paths, but these are
+ * converted to absolute paths in @a *mergeinfo.
+ *
+ * @since New in 1.5.
+ */
+svn_error_t *
+svn_mergeinfo_parse(svn_mergeinfo_t *mergeinfo, const char *input,
+ apr_pool_t *pool);
+
+/** Calculate the delta between two mergeinfos, @a mergefrom and @a mergeto
+ * (either or both of which may be @c NULL meaning an empty mergeinfo).
+ * Place the result in @a *deleted and @a *added (neither output argument
+ * may be @c NULL), both allocated in @a result_pool. The resulting
+ * @a *deleted and @a *added will not be null.
+ *
+ * @a consider_inheritance determines how the rangelists in the two
+ * hashes are compared for equality. If @a consider_inheritance is FALSE,
+ * then the start and end revisions of the @c svn_merge_range_t's being
+ * compared are the only factors considered when determining equality.
+ *
+ * e.g. '/trunk: 1,3-4*,5' == '/trunk: 1,3-5'
+ *
+ * If @a consider_inheritance is TRUE, then the inheritability of the
+ * @c svn_merge_range_t's is also considered and must be the same for two
+ * otherwise identical ranges to be judged equal.
+ *
+ * e.g. '/trunk: 1,3-4*,5' != '/trunk: 1,3-5'
+ * '/trunk: 1,3-4*,5' == '/trunk: 1,3-4*,5'
+ * '/trunk: 1,3-4,5' == '/trunk: 1,3-4,5'
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_mergeinfo_diff2(svn_mergeinfo_t *deleted, svn_mergeinfo_t *added,
+ svn_mergeinfo_t mergefrom, svn_mergeinfo_t mergeto,
+ svn_boolean_t consider_inheritance,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** Similar to svn_mergeinfo_diff2(), but users only one pool.
+ *
+ * @deprecated Provided for backward compatibility with the 1.7 API.
+ * @since New in 1.5.
+ */
+SVN_DEPRECATED
+svn_error_t *
+svn_mergeinfo_diff(svn_mergeinfo_t *deleted, svn_mergeinfo_t *added,
+ svn_mergeinfo_t mergefrom, svn_mergeinfo_t mergeto,
+ svn_boolean_t consider_inheritance,
+ apr_pool_t *pool);
+
+/** Merge a shallow copy of one mergeinfo, @a changes, into another mergeinfo
+ * @a mergeinfo.
+ *
+ * Rangelists for merge source paths common to @a changes and @a mergeinfo may
+ * result in new rangelists; these are allocated in @a result_pool.
+ * Temporary allocations are made in @a scratch_pool.
+ *
+ * When intersecting rangelists for a path are merged, the inheritability of
+ * the resulting svn_merge_range_t depends on the inheritability of the
+ * operands. If two non-inheritable ranges are merged the result is always
+ * non-inheritable, in all other cases the resulting range is inheritable.
+ *
+ * e.g. '/A: 1,3-4' merged with '/A: 1,3,4*,5' --> '/A: 1,3-5'
+ * '/A: 1,3-4*' merged with '/A: 1,3,4*,5' --> '/A: 1,3,4*,5'
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_mergeinfo_merge2(svn_mergeinfo_t mergeinfo,
+ svn_mergeinfo_t changes,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** Like svn_mergeinfo_merge2, but uses only one pool.
+ *
+ * @deprecated Provided for backward compatibility with the 1.5 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
+svn_mergeinfo_merge(svn_mergeinfo_t mergeinfo,
+ svn_mergeinfo_t changes,
+ apr_pool_t *pool);
+
+/** Combine one mergeinfo catalog, @a changes_catalog, into another mergeinfo
+ * catalog @a mergeinfo_catalog. If both catalogs have mergeinfo for the same
+ * key, use svn_mergeinfo_merge() to combine the mergeinfos.
+ *
+ * Additions to @a mergeinfo_catalog are deep copies allocated in
+ * @a result_pool. Temporary allocations are made in @a scratch_pool.
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_mergeinfo_catalog_merge(svn_mergeinfo_catalog_t mergeinfo_catalog,
+ svn_mergeinfo_catalog_t changes_catalog,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** Like svn_mergeinfo_remove2, but always considers inheritance.
+ *
+ * @deprecated Provided for backward compatibility with the 1.6 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
+svn_mergeinfo_remove(svn_mergeinfo_t *mergeinfo, svn_mergeinfo_t eraser,
+ svn_mergeinfo_t whiteboard, apr_pool_t *pool);
+
+/** Removes @a eraser (the subtrahend) from @a whiteboard (the
+ * minuend), and places the resulting difference in @a *mergeinfo.
+ * Allocates @a *mergeinfo in @a result_pool. Temporary allocations
+ * will be performed in @a scratch_pool.
+ *
+ * @a consider_inheritance determines how to account for the inheritability
+ * of the two mergeinfo's ranges when calculating the range equivalence,
+ * as described for svn_mergeinfo_diff().
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_mergeinfo_remove2(svn_mergeinfo_t *mergeinfo,
+ svn_mergeinfo_t eraser,
+ svn_mergeinfo_t whiteboard,
+ svn_boolean_t consider_inheritance,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** Calculate the delta between two rangelists consisting of @c
+ * svn_merge_range_t * elements (sorted in ascending order), @a from
+ * and @a to, and place the result in @a *deleted and @a *added
+ * (neither output argument will ever be @c NULL).
+ *
+ * @a consider_inheritance determines how to account for the inheritability
+ * of the two rangelist's ranges when calculating the diff,
+ * as described for svn_mergeinfo_diff().
+ *
+ * @since New in 1.5.
+ */
+svn_error_t *
+svn_rangelist_diff(svn_rangelist_t **deleted, svn_rangelist_t **added,
+ const svn_rangelist_t *from, const svn_rangelist_t *to,
+ svn_boolean_t consider_inheritance,
+ apr_pool_t *pool);
+
+/** Merge two rangelists consisting of @c svn_merge_range_t *
+ * elements, @a rangelist and @a changes, placing the results in
+ * @a rangelist. New elements added to @a rangelist are allocated
+ * in @a result_pool. Either rangelist may be empty.
+ *
+ * When intersecting rangelists are merged, the inheritability of
+ * the resulting svn_merge_range_t depends on the inheritability of the
+ * operands: see svn_mergeinfo_merge().
+ *
+ * Note: @a rangelist and @a changes must be sorted as said by @c
+ * svn_sort_compare_ranges(). @a rangelist is guaranteed to remain
+ * in sorted order and be compacted to the minimal number of ranges
+ * needed to represent the merged result.
+ *
+ * If the original rangelist contains non-collapsed adjacent ranges,
+ * the final result is not guaranteed to be compacted either.
+ *
+ * Use @a scratch_pool for temporary allocations.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_rangelist_merge2(svn_rangelist_t *rangelist,
+ const svn_rangelist_t *changes,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** Like svn_rangelist_merge2(), but with @a rangelist as an input/output
+ * argument. This function always allocates a new rangelist in @a pool and
+ * returns its result in @a *rangelist. It does not modify @a *rangelist
+ * in place. If not used carefully, this function can use up a lot of memory
+ * if called in a loop.
+ *
+ * It performs an extra adjacent range compaction round to make sure non
+ * collapsed input ranges are compacted in the result.
+ *
+ * @since New in 1.5.
+ * @deprecated Provided for backward compatibility with the 1.7 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
+svn_rangelist_merge(svn_rangelist_t **rangelist,
+ const svn_rangelist_t *changes,
+ apr_pool_t *pool);
+
+/** Removes @a eraser (the subtrahend) from @a whiteboard (the
+ * minuend), and places the resulting difference in @a output.
+ *
+ * Note: @a eraser and @a whiteboard must be sorted as said by @c
+ * svn_sort_compare_ranges(). @a output is guaranteed to be in sorted
+ * order.
+ *
+ * @a consider_inheritance determines how to account for the
+ * @c svn_merge_range_t inheritable field when comparing @a whiteboard's
+ * and @a *eraser's rangelists for equality. @see svn_mergeinfo_diff().
+ *
+ * @since New in 1.5.
+ */
+svn_error_t *
+svn_rangelist_remove(svn_rangelist_t **output, const svn_rangelist_t *eraser,
+ const svn_rangelist_t *whiteboard,
+ svn_boolean_t consider_inheritance,
+ apr_pool_t *pool);
+
+/** Find the intersection of two mergeinfos, @a mergeinfo1 and @a
+ * mergeinfo2, and place the result in @a *mergeinfo, which is (deeply)
+ * allocated in @a result_pool. Temporary allocations will be performed
+ * in @a scratch_pool.
+ *
+ * @a consider_inheritance determines how to account for the inheritability
+ * of the two mergeinfo's ranges when calculating the range equivalence,
+ * @see svn_rangelist_intersect().
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_mergeinfo_intersect2(svn_mergeinfo_t *mergeinfo,
+ svn_mergeinfo_t mergeinfo1,
+ svn_mergeinfo_t mergeinfo2,
+ svn_boolean_t consider_inheritance,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** Like svn_mergeinfo_intersect2, but always considers inheritance.
+ *
+ * @deprecated Provided for backward compatibility with the 1.6 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
+svn_mergeinfo_intersect(svn_mergeinfo_t *mergeinfo,
+ svn_mergeinfo_t mergeinfo1,
+ svn_mergeinfo_t mergeinfo2,
+ apr_pool_t *pool);
+
+/** Find the intersection of two rangelists consisting of @c
+ * svn_merge_range_t * elements, @a rangelist1 and @a rangelist2, and
+ * place the result in @a *rangelist (which is never @c NULL).
+ *
+ * @a consider_inheritance determines how to account for the inheritability
+ * of the two rangelist's ranges when calculating the intersection,
+ * @see svn_mergeinfo_diff(). If @a consider_inheritance is FALSE then
+ * ranges with different inheritance can intersect, but the resulting
+ * @a *rangelist is non-inheritable only if the corresponding ranges from
+ * both @a rangelist1 and @a rangelist2 are non-inheritable.
+ * If @a consider_inheritance is TRUE, then ranges with different
+ * inheritance can never intersect.
+ *
+ * Note: @a rangelist1 and @a rangelist2 must be sorted as said by @c
+ * svn_sort_compare_ranges(). @a *rangelist is guaranteed to be in sorted
+ * order.
+ * @since New in 1.5.
+ */
+svn_error_t *
+svn_rangelist_intersect(svn_rangelist_t **rangelist,
+ const svn_rangelist_t *rangelist1,
+ const svn_rangelist_t *rangelist2,
+ svn_boolean_t consider_inheritance,
+ apr_pool_t *pool);
+
+/** Reverse @a rangelist, and the @c start and @c end fields of each
+ * range in @a rangelist, in place.
+ *
+ * TODO(miapi): Is this really a valid function? Rangelists that
+ * aren't sorted, or rangelists containing reverse ranges, are
+ * generally not valid in mergeinfo code. Can we rewrite the two
+ * places where this is used?
+ *
+ * @since New in 1.5.
+ */
+svn_error_t *
+svn_rangelist_reverse(svn_rangelist_t *rangelist, apr_pool_t *pool);
+
+/** Take an array of svn_merge_range_t *'s in @a rangelist, and convert it
+ * back to a text format rangelist in @a output. If @a rangelist contains
+ * no elements, sets @a output to the empty string.
+ *
+ * @since New in 1.5.
+ */
+svn_error_t *
+svn_rangelist_to_string(svn_string_t **output,
+ const svn_rangelist_t *rangelist,
+ apr_pool_t *pool);
+
+/** Return a deep copy of @c svn_merge_range_t *'s in @a rangelist excluding
+ * all non-inheritable @c svn_merge_range_t if @a inheritable is TRUE or
+ * excluding all inheritable @c svn_merge_range_t otherwise. If @a start and
+ * @a end are valid revisions and @a start is less than or equal to @a end,
+ * then exclude only the non-inheritable revision ranges that intersect
+ * inclusively with the range defined by @a start and @a end. If
+ * @a rangelist contains no elements, return an empty array. Allocate the
+ * copy in @a result_pool, use @a scratch_pool for temporary allocations.
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_rangelist_inheritable2(svn_rangelist_t **inheritable_rangelist,
+ const svn_rangelist_t *rangelist,
+ svn_revnum_t start,
+ svn_revnum_t end,
+ svn_boolean_t inheritable,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** Like svn_rangelist_inheritable2, but always finds inheritable ranges.
+ *
+ * @since New in 1.5.
+ * @deprecated Provided for backward compatibility with the 1.6 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
+svn_rangelist_inheritable(svn_rangelist_t **inheritable_rangelist,
+ const svn_rangelist_t *rangelist,
+ svn_revnum_t start,
+ svn_revnum_t end,
+ apr_pool_t *pool);
+
+/** Return a deep copy of @a mergeinfo, excluding all non-inheritable
+ * @c svn_merge_range_t if @a inheritable is TRUE or excluding all
+ * inheritable @c svn_merge_range_t otherwise. If @a start and @a end
+ * are valid revisions and @a start is less than or equal to @a end,
+ * then exclude only the non-inheritable revisions that intersect
+ * inclusively with the range defined by @a start and @a end. If @a path
+ * is not NULL remove non-inheritable ranges only for @a path. If all
+ * ranges are removed for a given path then remove that path as well.
+ * If all paths are removed or @a rangelist is empty then set
+ * @a *inheritable_rangelist to an empty array. Allocate the copy in
+ * @a result_pool, use @a scratch_pool for temporary allocations.
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_mergeinfo_inheritable2(svn_mergeinfo_t *inheritable_mergeinfo,
+ svn_mergeinfo_t mergeinfo,
+ const char *path,
+ svn_revnum_t start,
+ svn_revnum_t end,
+ svn_boolean_t inheritable,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** Like svn_mergeinfo_inheritable2, but always finds inheritable mergeinfo.
+ *
+ * @since New in 1.5.
+ * @deprecated Provided for backward compatibility with the 1.6 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
+svn_mergeinfo_inheritable(svn_mergeinfo_t *inheritable_mergeinfo,
+ svn_mergeinfo_t mergeinfo,
+ const char *path,
+ svn_revnum_t start,
+ svn_revnum_t end,
+ apr_pool_t *pool);
+
+/** Take a mergeinfo in @a mergeinput, and convert it to unparsed
+ * mergeinfo. Set @a *output to the result, allocated in @a pool.
+ * If @a input contains no elements, set @a *output to the empty string.
+ *
+ * @a mergeinput may contain relative merge source paths, but these are
+ * converted to absolute paths in @a *output.
+ *
+ * @since New in 1.5.
+*/
+svn_error_t *
+svn_mergeinfo_to_string(svn_string_t **output,
+ svn_mergeinfo_t mergeinput,
+ apr_pool_t *pool);
+
+/** Take a hash of mergeinfo in @a mergeinfo, and sort the rangelists
+ * associated with each key (in place).
+ *
+ * TODO(miapi): mergeinfos should *always* be sorted. This should be
+ * a private function.
+ *
+ * @since New in 1.5
+ */
+svn_error_t *
+svn_mergeinfo_sort(svn_mergeinfo_t mergeinfo, apr_pool_t *pool);
+
+/** Return a deep copy of @a mergeinfo_catalog, allocated in @a pool.
+ *
+ * @since New in 1.6.
+ */
+svn_mergeinfo_catalog_t
+svn_mergeinfo_catalog_dup(svn_mergeinfo_catalog_t mergeinfo_catalog,
+ apr_pool_t *pool);
+
+/** Return a deep copy of @a mergeinfo, allocated in @a pool.
+ *
+ * @since New in 1.5.
+ */
+svn_mergeinfo_t
+svn_mergeinfo_dup(svn_mergeinfo_t mergeinfo, apr_pool_t *pool);
+
+/** Return a deep copy of @a rangelist, allocated in @a pool.
+ *
+ * @since New in 1.5.
+ */
+svn_rangelist_t *
+svn_rangelist_dup(const svn_rangelist_t *rangelist, apr_pool_t *pool);
+
+
+/**
+ * The three ways to request mergeinfo affecting a given path.
+ *
+ * @since New in 1.5.
+ */
+typedef enum svn_mergeinfo_inheritance_t
+{
+ /** Explicit mergeinfo only. */
+ svn_mergeinfo_explicit,
+
+ /** Explicit mergeinfo, or if that doesn't exist, the inherited
+ mergeinfo from a target's nearest (path-wise, not history-wise)
+ ancestor. */
+ svn_mergeinfo_inherited,
+
+ /** Mergeinfo inherited from a target's nearest (path-wise, not
+ history-wise) ancestor, regardless of whether target has explicit
+ mergeinfo. */
+ svn_mergeinfo_nearest_ancestor
+} svn_mergeinfo_inheritance_t;
+
+/** Return a constant string expressing @a inherit as an English word,
+ * i.e., "explicit" (default), "inherited", or "nearest_ancestor".
+ * The string is not localized, as it may be used for client<->server
+ * communications.
+ *
+ * @since New in 1.5.
+ */
+const char *
+svn_inheritance_to_word(svn_mergeinfo_inheritance_t inherit);
+
+
+/** Return the appropriate @c svn_mergeinfo_inheritance_t for @a word.
+ * @a word is as returned from svn_inheritance_to_word(). Defaults to
+ * @c svn_mergeinfo_explicit.
+ *
+ * @since New in 1.5.
+ */
+svn_mergeinfo_inheritance_t
+svn_inheritance_from_word(const char *word);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SVN_MERGEINFO_H */