Subversion 1.6.16

svn_mergeinfo.h

Go to the documentation of this file.
00001 /**
00002  * @copyright
00003  * ====================================================================
00004  * Copyright (c) 2006-2008 CollabNet.  All rights reserved.
00005  *
00006  * This software is licensed as described in the file COPYING, which
00007  * you should have received as part of this distribution.  The terms
00008  * are also available at http://subversion.tigris.org/license-1.html.
00009  * If newer versions of this license are posted there, you may use a
00010  * newer version instead, at your option.
00011  *
00012  * This software consists of voluntary contributions made by many
00013  * individuals.  For exact contribution history, see the revision
00014  * history and logs, available at http://subversion.tigris.org/.
00015  * ====================================================================
00016  * @endcopyright
00017  *
00018  * @file svn_mergeinfo.h
00019  * @brief mergeinfo handling and processing
00020  */
00021 
00022 
00023 #ifndef SVN_MERGEINFO_H
00024 #define SVN_MERGEINFO_H
00025 
00026 #include <apr_pools.h>
00027 #include <apr_tables.h>  /* for apr_array_header_t */
00028 #include <apr_hash.h>
00029 
00030 #include "svn_types.h"
00031 #include "svn_string.h"  /* for svn_string_t */
00032 
00033 
00034 #ifdef __cplusplus
00035 extern "C" {
00036 #endif /* __cplusplus */
00037 
00038 /** Overview of the @c SVN_PROP_MERGEINFO property.
00039  *
00040  * Merge history is stored in the @c SVN_PROP_MERGEINFO property of files
00041  * and directories.  The @c SVN_PROP_MERGEINFO property on a path stores the
00042  * complete list of changes merged to that path, either directly or via the
00043  * path's parent, grand-parent, etc..  A path may have empty mergeinfo which
00044  * means that nothing has been merged to that path or all previous merges
00045  * to the path were reversed.  Note that a path may have no mergeinfo, this
00046  * is not the same as empty mergeinfo.
00047  *
00048  * Every path in a tree may have @c SVN_PROP_MERGEINFO set, but if the
00049  * @c SVN_PROP_MERGEINFO for a path is equivalent to the
00050  * @c SVN_PROP_MERGEINFO for its parent, then the @c SVN_PROP_MERGEINFO on
00051  * the path will 'elide' (be removed) from the path as a post step to any
00052  * merge.  If a path's parent does not have any @c SVN_PROP_MERGEINFO set,
00053  * the path's mergeinfo can elide to its nearest grand-parent,
00054  * great-grand-parent, etc. that has equivalent @c SVN_PROP_MERGEINFO set
00055  * on it.
00056  *
00057  * If a path has no @c SVN_PROP_MERGEINFO of its own, it inherits mergeinfo
00058  * from its nearest parent that has @c SVN_PROP_MERGEINFO set.  The
00059  * exception to this is @c SVN_PROP_MERGEINFO with non-ineritable revision
00060  * ranges.  These non-inheritable ranges apply only to the path which they
00061  * are set on.
00062  *
00063  * Due to Subversion's allowance for mixed revision working copies, both
00064  * elision and inheritance within the working copy presume the path
00065  * between a path and its nearest parent with mergeinfo is at the same
00066  * working revision.  If this is not the case then neither inheritance nor
00067  * elision can occur.
00068  *
00069  * The value of the @c SVN_PROP_MERGEINFO property is either an empty string
00070  * (representing empty mergeinfo) or a non-empty string consisting of
00071  * a path, a colon, and comma separated revision list, containing one or more
00072  * revision or revision ranges. Revision range start and end points are
00073  * separated by "-".  Revisions and revision ranges may have the optional
00074  * @c SVN_MERGEINFO_NONINHERITABLE_STR suffix to signify a non-inheritable
00075  * revision/revision range.
00076  *
00077  * @c SVN_PROP_MERGEINFO Value Grammar:
00078  *
00079  *   Token             Definition
00080  *   -----             ----------
00081  *   revisionrange     REVISION1 "-" REVISION2
00082  *   revisioneelement  (revisionrange | REVISION)"*"?
00083  *   rangelist         revisioneelement (COMMA revisioneelement)*
00084  *   revisionline      PATHNAME COLON rangelist
00085  *   top               "" | (revisionline (NEWLINE revisionline))*
00086  *
00087  * The PATHNAME is the source of a merge and the rangelist the revision(s)
00088  * merged to the path @c SVN_PROP_MERGEINFO is set on directly or indirectly
00089  * via inheritance.  PATHNAME must always exist at the specified rangelist
00090  * and thus a single merge may result in multiple revisionlines if the source
00091  * was renamed.
00092  *
00093  * Rangelists must be sorted from lowest to highest revision and cannot
00094  * contain overlapping revisionlistelements.  REVISION1 must be less than
00095  * REVISION2.  Consecutive single revisions that can be represented by a
00096  * revisionrange are allowed however (e.g. '5,6,7,8,9-12' or '5-12' are
00097  * both acceptable).
00098  */
00099 
00100 /* Suffix for SVN_PROP_MERGEINFO revision ranges indicating a given
00101    range is non-inheritable. */
00102 #define SVN_MERGEINFO_NONINHERITABLE_STR "*"
00103 
00104 /** Terminology for data structures that contain mergeinfo.
00105  *
00106  * Subversion commonly uses several data structures to represent
00107  * mergeinfo in RAM:
00108  *
00109  * (a) Strings (@c svn_string_t *) containing "unparsed mergeinfo".
00110  *
00111  * (b) A "rangelist".  An array (@c apr_array_header_t *) of non-overlapping
00112  *     merge ranges (@c svn_merge_range_t *), sorted as said by
00113  *     @c svn_sort_compare_ranges().  An empty range list is represented by
00114  *     an empty array.  Unless specifically noted otherwise, all APIs require
00115  *     rangelists that describe only forward ranges, i.e. the range's start
00116  *     revision is less than its end revision.
00117  *
00118  * (c) @c svn_mergeinfo_t, called "mergeinfo".  A hash mapping merge
00119  *     source paths (@c const char *, starting with slashes) to
00120  *     non-empty rangelist arrays.  A @c NULL hash is used to represent
00121  *     no mergeinfo and an empty hash is used to represent empty
00122  *     mergeinfo.
00123  *
00124  * (d) @c svn_mergeinfo_catalog_t, called a "mergeinfo catalog".  A hash
00125  *     mapping paths (@c const char *, starting with slashes) to
00126  *     @c svn_mergeinfo_t.
00127  *
00128  * Both @c svn_mergeinfo_t and @c svn_mergeinfo_catalog_t are just
00129  * typedefs for @c apr_hash_t *; there is no static type-checking, and
00130  * you still use standard @c apr_hash_t functions to interact with
00131  * them.
00132  *
00133  * Note that while the keys of mergeinfos are always relative to the
00134  * repository root, the keys of a catalog may be relative to something
00135  * else, such as an RA session root.
00136  */
00137 
00138 typedef apr_hash_t *svn_mergeinfo_t;
00139 typedef apr_hash_t *svn_mergeinfo_catalog_t;
00140 
00141 /** Parse the mergeinfo from @a input into @a *mergeinfo.  If no
00142  * mergeinfo is available, return an empty mergeinfo (never @c NULL).
00143  * Perform temporary allocations in @a pool.
00144  *
00145  * If @a input is not a grammatically correct @c SVN_PROP_MERGEINFO
00146  * property, contains overlapping revision ranges of differing
00147  * inheritability, or revision ranges with a start revision greater
00148  * than or equal to its end revision, or contains paths mapped to empty
00149  * revision ranges, then return  @c SVN_ERR_MERGEINFO_PARSE_ERROR.
00150  * Unordered revision ranges are  allowed, but will be sorted when
00151  * placed into @a *mergeinfo.  Overlapping revision ranges of the same
00152  * inheritability are also allowed, but will be combined into a single
00153  * range when placed into @a *mergeinfo.
00154  *
00155  * @a input may contain relative merge source paths, but these are
00156  * converted to absolute paths in @a *mergeinfo.
00157  *
00158  * @since New in 1.5.
00159  */
00160 svn_error_t *
00161 svn_mergeinfo_parse(svn_mergeinfo_t *mergeinfo, const char *input,
00162                     apr_pool_t *pool);
00163 
00164 /** Calculate the delta between two mergeinfos, @a mergefrom and @a mergeto
00165  * (which may be @c NULL), and place the result in @a *deleted and @a
00166  * *added (neither output argument may be @c NULL).
00167  *
00168  * @a consider_inheritance determines how the rangelists in the two
00169  * hashes are compared for equality.  If @a consider_inheritance is FALSE,
00170  * then the start and end revisions of the @c svn_merge_range_t's being
00171  * compared are the only factors considered when determining equality.
00172  *
00173  *  e.g. '/trunk: 1,3-4*,5' == '/trunk: 1,3-5'
00174  *
00175  * If @a consider_inheritance is TRUE, then the inheritability of the
00176  * @c svn_merge_range_t's is also considered and must be the same for two
00177  * otherwise identical ranges to be judged equal.
00178  *
00179  *  e.g. '/trunk: 1,3-4*,5' != '/trunk: 1,3-5'
00180  *       '/trunk: 1,3-4*,5' == '/trunk: 1,3-4*,5'
00181  *       '/trunk: 1,3-4,5'  == '/trunk: 1,3-4,5'
00182  *
00183  * @since New in 1.5.
00184  */
00185 svn_error_t *
00186 svn_mergeinfo_diff(svn_mergeinfo_t *deleted, svn_mergeinfo_t *added,
00187                    svn_mergeinfo_t mergefrom, svn_mergeinfo_t mergeto,
00188                    svn_boolean_t consider_inheritance,
00189                    apr_pool_t *pool);
00190 
00191 /** Merge one mergeinfo, @a changes, into another mergeinfo @a
00192  * mergeinfo.
00193  *
00194  * When intersecting rangelists for a path are merged, the inheritability of
00195  * the resulting svn_merge_range_t depends on the inheritability of the
00196  * operands.  If two non-inheritable ranges are merged the result is always
00197  * non-inheritable, in all other cases the resulting range is inheritable.
00198  *
00199  *  e.g. '/A: 1,3-4'  merged with '/A: 1,3,4*,5' --> '/A: 1,3-5'
00200  *       '/A: 1,3-4*' merged with '/A: 1,3,4*,5' --> '/A: 1,3,4*,5'
00201  *
00202  * @since New in 1.5.
00203  */
00204 svn_error_t *
00205 svn_mergeinfo_merge(svn_mergeinfo_t mergeinfo, svn_mergeinfo_t changes,
00206                     apr_pool_t *pool);
00207 
00208 /** Removes @a eraser (the subtrahend) from @a whiteboard (the
00209  * minuend), and places the resulting difference in @a *mergeinfo.
00210  *
00211  * @since New in 1.5.
00212  */
00213 svn_error_t *
00214 svn_mergeinfo_remove(svn_mergeinfo_t *mergeinfo, svn_mergeinfo_t eraser,
00215                      svn_mergeinfo_t whiteboard, apr_pool_t *pool);
00216 
00217 /** Calculate the delta between two rangelists consisting of @c
00218  * svn_merge_range_t * elements (sorted in ascending order), @a from
00219  * and @a to, and place the result in @a *deleted and @a *added
00220  * (neither output argument will ever be @c NULL).
00221  *
00222  * @a consider_inheritance determines how to account for the inheritability
00223  * of the two rangelist's ranges when calculating the diff,
00224  * as described for svn_mergeinfo_diff().
00225  *
00226  * @since New in 1.5.
00227  */
00228 svn_error_t *
00229 svn_rangelist_diff(apr_array_header_t **deleted, apr_array_header_t **added,
00230                    apr_array_header_t *from, apr_array_header_t *to,
00231                    svn_boolean_t consider_inheritance,
00232                    apr_pool_t *pool);
00233 
00234 /** Merge two rangelists consisting of @c svn_merge_range_t *
00235  * elements, @a *rangelist and @a changes, placing the results in
00236  * @a *rangelist.  Either rangelist may be empty.
00237  *
00238  * When intersecting rangelists are merged, the inheritability of
00239  * the resulting svn_merge_range_t depends on the inheritability of the
00240  * operands: see svn_mergeinfo_merge().
00241  *
00242  * Note: @a *rangelist and @a changes must be sorted as said by @c
00243  * svn_sort_compare_ranges().  @a *rangelist is guaranteed to remain
00244  * in sorted order and be compacted to the minimal number of ranges
00245  * needed to represent the merged result.
00246  *
00247  * @since New in 1.5.
00248  */
00249 svn_error_t *
00250 svn_rangelist_merge(apr_array_header_t **rangelist,
00251                     apr_array_header_t *changes,
00252                     apr_pool_t *pool);
00253 
00254 /** Removes @a eraser (the subtrahend) from @a whiteboard (the
00255  * minuend), and places the resulting difference in @a output.
00256  *
00257  * Note: @a eraser and @a whiteboard must be sorted as said by @c
00258  * svn_sort_compare_ranges().  @a output is guaranteed to be in sorted
00259  * order.
00260  *
00261  * @a consider_inheritance determines how to account for the
00262  * @c svn_merge_range_t inheritable field when comparing @a whiteboard's
00263  * and @a *eraser's rangelists for equality.  @see svn_mergeinfo_diff().
00264  *
00265  * @since New in 1.5.
00266  */
00267 svn_error_t *
00268 svn_rangelist_remove(apr_array_header_t **output, apr_array_header_t *eraser,
00269                      apr_array_header_t *whiteboard,
00270                      svn_boolean_t consider_inheritance,
00271                      apr_pool_t *pool);
00272 
00273 /** Find the intersection of two mergeinfos, @a mergeinfo1 and @a
00274  * mergeinfo2, and place the result in @a *mergeinfo, which is (deeply)
00275  * allocated in @a pool.
00276  *
00277  * @since New in 1.5.
00278  */
00279 svn_error_t *
00280 svn_mergeinfo_intersect(svn_mergeinfo_t *mergeinfo,
00281                         svn_mergeinfo_t mergeinfo1,
00282                         svn_mergeinfo_t mergeinfo2,
00283                         apr_pool_t *pool);
00284 
00285 /** Find the intersection of two rangelists consisting of @c
00286  * svn_merge_range_t * elements, @a rangelist1 and @a rangelist2, and
00287  * place the result in @a *rangelist (which is never @c NULL).
00288  *
00289  * @a consider_inheritance determines how to account for the inheritability
00290  * of the two rangelist's ranges when calculating the intersection,
00291  * @see svn_mergeinfo_diff().  If @a consider_inheritance is FALSE then
00292  * ranges with different inheritance can intersect, but the the resulting
00293  * @a *rangelist is non-inheritable only if the corresponding ranges from
00294  * both @a rangelist1 and @a rangelist2 are non-inheritable.
00295  * If @a consider_inheritance is TRUE, then ranges with different
00296  * inheritance can never intersect.
00297  *
00298  * Note: @a rangelist1 and @a rangelist2 must be sorted as said by @c
00299  * svn_sort_compare_ranges(). @a *rangelist is guaranteed to be in sorted
00300  * order.
00301  * @since New in 1.5.
00302  */
00303 svn_error_t *
00304 svn_rangelist_intersect(apr_array_header_t **rangelist,
00305                         apr_array_header_t *rangelist1,
00306                         apr_array_header_t *rangelist2,
00307                         svn_boolean_t consider_inheritance,
00308                         apr_pool_t *pool);
00309 
00310 /** Reverse @a rangelist, and the @c start and @c end fields of each
00311  * range in @a rangelist, in place.
00312  *
00313  * TODO(miapi): Is this really a valid function?  Rangelists that
00314  * aren't sorted, or rangelists containing reverse ranges, are
00315  * generally not valid in mergeinfo code.  Can we rewrite the two
00316  * places where this is used?
00317  *
00318  * @since New in 1.5.
00319  */
00320 svn_error_t *
00321 svn_rangelist_reverse(apr_array_header_t *rangelist, apr_pool_t *pool);
00322 
00323 /** Take an array of svn_merge_range_t *'s in @a rangelist, and convert it
00324  * back to a text format rangelist in @a output.  If @a rangelist contains
00325  * no elements, sets @a output to the empty string.
00326  *
00327  * @since New in 1.5.
00328  */
00329 svn_error_t *
00330 svn_rangelist_to_string(svn_string_t **output,
00331                         const apr_array_header_t *rangelist,
00332                         apr_pool_t *pool);
00333 
00334 /** Return a deep copy of @c svn_merge_range_t *'s in @a rangelist excluding
00335  * all non-inheritable @c svn_merge_range_t.  If @a start and @a end are valid
00336  * revisions and @a start is less than or equal to @a end, then exclude only the
00337  * non-inheritable revision ranges that intersect inclusively with the range
00338  * defined by @a start and @a end.  If @a rangelist contains no elements, return
00339  * an empty array.  Allocate the copy in @a pool.
00340  *
00341  * @since New in 1.5.
00342  */
00343 svn_error_t *
00344 svn_rangelist_inheritable(apr_array_header_t **inheritable_rangelist,
00345                           apr_array_header_t *rangelist,
00346                           svn_revnum_t start,
00347                           svn_revnum_t end,
00348                           apr_pool_t *pool);
00349 
00350 /** Return a deep copy of @a mergeinfo, excluding all non-inheritable
00351  * @c svn_merge_range_t.  If @a start and @a end are valid revisions
00352  * and @a start is less than or equal to @a end, then exclude only the
00353  * non-inheritable revisions that intersect inclusively with the range
00354  * defined by @a start and @a end.  If @a path is not NULL remove
00355  * non-inheritable ranges only for @a path.  If all ranges are removed
00356  * for a given path then remove that path as well.  If all paths are
00357  * removed or @a rangelist is empty then set @a *inheritable_rangelist
00358  * to an empty array.  Allocate the copy in @a pool.
00359  *
00360  * @since New in 1.5.
00361  */
00362 svn_error_t *
00363 svn_mergeinfo_inheritable(svn_mergeinfo_t *inheritable_mergeinfo,
00364                           svn_mergeinfo_t mergeinfo,
00365                           const char *path,
00366                           svn_revnum_t start,
00367                           svn_revnum_t end,
00368                           apr_pool_t *pool);
00369 
00370 /** Take a mergeinfo in MERGEINPUT, and convert it back to unparsed
00371  *  mergeinfo in *OUTPUT.  If INPUT contains no elements, return the
00372  *  empty string.
00373  *
00374  * @a mergeinput may contain relative merge source paths, but these are
00375  * converted to absolute paths in @a *output.
00376  *
00377  * @since New in 1.5.
00378 */
00379 svn_error_t *
00380 svn_mergeinfo_to_string(svn_string_t **output,
00381                         svn_mergeinfo_t mergeinput,
00382                         apr_pool_t *pool);
00383 
00384 /** Take a hash of mergeinfo in @a mergeinfo, and sort the rangelists
00385  * associated with each key (in place).
00386  *
00387  * TODO(miapi): mergeinfos should *always* be sorted.  This should be
00388  * a private function.
00389  *
00390  * @since New in 1.5
00391  */
00392 svn_error_t *
00393 svn_mergeinfo_sort(svn_mergeinfo_t mergeinfo, apr_pool_t *pool);
00394 
00395 /** Return a deep copy of @a mergeinfo_catalog, allocated in @a pool.
00396  *
00397  * @since New in 1.6.
00398  */
00399 svn_mergeinfo_catalog_t
00400 svn_mergeinfo_catalog_dup(svn_mergeinfo_catalog_t mergeinfo_catalog,
00401                           apr_pool_t *pool);
00402 
00403 /** Return a deep copy of @a mergeinfo, allocated in @a pool.
00404  *
00405  * @since New in 1.5.
00406  */
00407 svn_mergeinfo_t
00408 svn_mergeinfo_dup(svn_mergeinfo_t mergeinfo, apr_pool_t *pool);
00409 
00410 /** Return a deep copy of @a rangelist, allocated in @a pool.
00411  *
00412  * @since New in 1.5.
00413  */
00414 apr_array_header_t *
00415 svn_rangelist_dup(apr_array_header_t *rangelist, apr_pool_t *pool);
00416 
00417 
00418 /**
00419  * The three ways to request mergeinfo affecting a given path.
00420  *
00421  * @since New in 1.5.
00422  */
00423 typedef enum
00424 {
00425   /** Explicit mergeinfo only. */
00426   svn_mergeinfo_explicit,
00427 
00428   /** Explicit mergeinfo, or if that doesn't exist, the inherited
00429       mergeinfo from a target's nearest (path-wise, not history-wise)
00430       ancestor. */
00431   svn_mergeinfo_inherited,
00432 
00433   /** Mergeinfo on target's nearest (path-wise, not history-wise)
00434       ancestor, regardless of whether target has explict mergeinfo. */
00435   svn_mergeinfo_nearest_ancestor
00436 } svn_mergeinfo_inheritance_t;
00437 
00438 /** Return a constant string expressing @a inherit as an English word,
00439  * i.e., "explicit" (default), "inherited", or "nearest_ancestor".
00440  * The string is not localized, as it may be used for client<->server
00441  * communications.
00442  *
00443  * @since New in 1.5.
00444  */
00445 const char *
00446 svn_inheritance_to_word(svn_mergeinfo_inheritance_t inherit);
00447 
00448 
00449 /** Return the appropriate @c svn_mergeinfo_inheritance_t for @a word.
00450  * @a word is as returned from svn_inheritance_to_word().  Defaults to
00451  * @c svn_mergeinfo_explicit.
00452  *
00453  * @since New in 1.5.
00454  */
00455 svn_mergeinfo_inheritance_t
00456 svn_inheritance_from_word(const char *word);
00457 
00458 
00459 #ifdef __cplusplus
00460 }
00461 #endif /* __cplusplus */
00462 
00463 #endif /* SVN_MERGEINFO_H */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines