OSDN Git Service

Success build TortoiseMerge.
[tortoisegit/TortoiseGitJp.git] / src / TortoiseMerge / svninclude / svn_mergeinfo.h
1 /**\r
2  * @copyright\r
3  * ====================================================================\r
4  * Copyright (c) 2006-2008 CollabNet.  All rights reserved.\r
5  *\r
6  * This software is licensed as described in the file COPYING, which\r
7  * you should have received as part of this distribution.  The terms\r
8  * are also available at http://subversion.tigris.org/license-1.html.\r
9  * If newer versions of this license are posted there, you may use a\r
10  * newer version instead, at your option.\r
11  *\r
12  * This software consists of voluntary contributions made by many\r
13  * individuals.  For exact contribution history, see the revision\r
14  * history and logs, available at http://subversion.tigris.org/.\r
15  * ====================================================================\r
16  * @endcopyright\r
17  *\r
18  * @file svn_mergeinfo.h\r
19  * @brief mergeinfo handling and processing\r
20  */\r
21 \r
22 \r
23 #ifndef SVN_MERGEINFO_H\r
24 #define SVN_MERGEINFO_H\r
25 \r
26 #include <apr_pools.h>\r
27 #include <apr_tables.h>  /* for apr_array_header_t */\r
28 #include <apr_hash.h>\r
29 \r
30 #include "svn_types.h"\r
31 #include "svn_string.h"  /* for svn_string_t */\r
32 \r
33 \r
34 #ifdef __cplusplus\r
35 extern "C" {\r
36 #endif /* __cplusplus */\r
37 \r
38 /** Overview of the @c SVN_PROP_MERGEINFO property.\r
39  *\r
40  * Merge history is stored in the @c SVN_PROP_MERGEINFO property of files\r
41  * and directories.  The @c SVN_PROP_MERGEINFO property on a path stores the\r
42  * complete list of changes merged to that path, either directly or via the\r
43  * path's parent, grand-parent, etc..  A path may have empty mergeinfo which\r
44  * means that nothing has been merged to that path or all previous merges\r
45  * to the path were reversed.  Note that a path may have no mergeinfo, this\r
46  * is not the same as empty mergeinfo.\r
47  *\r
48  * Every path in a tree may have @c SVN_PROP_MERGEINFO set, but if the\r
49  * @c SVN_PROP_MERGEINFO for a path is equivalent to the\r
50  * @c SVN_PROP_MERGEINFO for its parent, then the @c SVN_PROP_MERGEINFO on\r
51  * the path will 'elide' (be removed) from the path as a post step to any\r
52  * merge.  If a path's parent does not have any @c SVN_PROP_MERGEINFO set,\r
53  * the path's mergeinfo can elide to its nearest grand-parent,\r
54  * great-grand-parent, etc. that has equivalent @c SVN_PROP_MERGEINFO set\r
55  * on it.\r
56  *\r
57  * If a path has no @c SVN_PROP_MERGEINFO of its own, it inherits mergeinfo\r
58  * from its nearest parent that has @c SVN_PROP_MERGEINFO set.  The\r
59  * exception to this is @c SVN_PROP_MERGEINFO with non-ineritable revision\r
60  * ranges.  These non-inheritable ranges apply only to the path which they\r
61  * are set on.\r
62  *\r
63  * Due to Subversion's allowance for mixed revision working copies, both\r
64  * elision and inheritance within the working copy presume the path\r
65  * between a path and its nearest parent with mergeinfo is at the same\r
66  * working revision.  If this is not the case then neither inheritance nor\r
67  * elision can occur.\r
68  *\r
69  * The value of the @c SVN_PROP_MERGEINFO property is either an empty string\r
70  * (representing empty mergeinfo) or a non-empty string consisting of\r
71  * a path, a colon, and comma separated revision list, containing one or more\r
72  * revision or revision ranges. Revision range start and end points are\r
73  * separated by "-".  Revisions and revision ranges may have the optional\r
74  * @c SVN_MERGEINFO_NONINHERITABLE_STR suffix to signify a non-inheritable\r
75  * revision/revision range.\r
76  *\r
77  * @c SVN_PROP_MERGEINFO Value Grammar:\r
78  *\r
79  *   Token             Definition\r
80  *   -----             ----------\r
81  *   revisionrange     REVISION1 "-" REVISION2\r
82  *   revisioneelement  (revisionrange | REVISION)"*"?\r
83  *   rangelist         revisioneelement (COMMA revisioneelement)*\r
84  *   revisionline      PATHNAME COLON rangelist\r
85  *   top               "" | (revisionline (NEWLINE revisionline))*\r
86  *\r
87  * The PATHNAME is the source of a merge and the rangelist the revision(s)\r
88  * merged to the path @c SVN_PROP_MERGEINFO is set on directly or indirectly\r
89  * via inheritance.  PATHNAME must always exist at the specified rangelist\r
90  * and thus a single merge may result in multiple revisionlines if the source\r
91  * was renamed.\r
92  *\r
93  * Rangelists must be sorted from lowest to highest revision and cannot\r
94  * contain overlapping revisionlistelements.  REVISION1 must be less than\r
95  * REVISION2.  Consecutive single revisions that can be represented by a\r
96  * revisionrange are allowed however (e.g. '5,6,7,8,9-12' or '5-12' are\r
97  * both acceptable).\r
98  */\r
99 \r
100 /* Suffix for SVN_PROP_MERGEINFO revision ranges indicating a given\r
101    range is non-inheritable. */\r
102 #define SVN_MERGEINFO_NONINHERITABLE_STR "*"\r
103 \r
104 /** Terminology for data structures that contain mergeinfo.\r
105  *\r
106  * Subversion commonly uses several data structures to represent\r
107  * mergeinfo in RAM:\r
108  *\r
109  * (a) Strings (@c svn_string_t *) containing "unparsed mergeinfo".\r
110  *\r
111  * (b) A "rangelist".  An array (@c apr_array_header_t *) of non-overlapping\r
112  *     merge ranges (@c svn_merge_range_t *), sorted as said by\r
113  *     @c svn_sort_compare_ranges().  An empty range list is represented by\r
114  *     an empty array.  Unless specifically noted otherwise, all APIs require\r
115  *     rangelists that describe only forward ranges, i.e. the range's start\r
116  *     revision is less than its end revision.\r
117  *\r
118  * (c) @c svn_mergeinfo_t, called "mergeinfo".  A hash mapping merge\r
119  *     source paths (@c const char *, starting with slashes) to\r
120  *     non-empty rangelist arrays.  A @c NULL hash is used to represent\r
121  *     no mergeinfo and an empty hash is used to represent empty\r
122  *     mergeinfo.\r
123  *\r
124  * (d) @c svn_mergeinfo_catalog_t, called a "mergeinfo catalog".  A hash\r
125  *     mapping paths (@c const char *, starting with slashes) to\r
126  *     @c svn_mergeinfo_t.\r
127  *\r
128  * Both @c svn_mergeinfo_t and @c svn_mergeinfo_catalog_t are just\r
129  * typedefs for @c apr_hash_t *; there is no static type-checking, and\r
130  * you still use standard @c apr_hash_t functions to interact with\r
131  * them.\r
132  *\r
133  * Note that while the keys of mergeinfos are always relative to the\r
134  * repository root, the keys of a catalog may be relative to something\r
135  * else, such as an RA session root.\r
136  */\r
137 \r
138 typedef apr_hash_t *svn_mergeinfo_t;\r
139 typedef apr_hash_t *svn_mergeinfo_catalog_t;\r
140 \r
141 /** Parse the mergeinfo from @a input into @a *mergeinfo.  If no\r
142  * mergeinfo is available, return an empty mergeinfo (never @c NULL).\r
143  * Perform temporary allocations in @a pool.\r
144  *\r
145  * If @a input is not a grammatically correct @c SVN_PROP_MERGEINFO\r
146  * property, contains overlapping revision ranges of differing\r
147  * inheritability, or revision ranges with a start revision greater\r
148  * than or equal to its end revision, or contains paths mapped to empty\r
149  * revision ranges, then return  @c SVN_ERR_MERGEINFO_PARSE_ERROR.\r
150  * Unordered revision ranges are  allowed, but will be sorted when\r
151  * placed into @a *mergeinfo.  Overlapping revision ranges of the same\r
152  * inheritability are also allowed, but will be combined into a single\r
153  * range when placed into @a *mergeinfo.\r
154  *\r
155  * @since New in 1.5.\r
156  */\r
157 svn_error_t *\r
158 svn_mergeinfo_parse(svn_mergeinfo_t *mergeinfo, const char *input,\r
159                     apr_pool_t *pool);\r
160 \r
161 /** Calculate the delta between two mergeinfos, @a mergefrom and @a mergeto\r
162  * (which may be @c NULL), and place the result in @a *deleted and @a\r
163  * *added (neither output argument may be @c NULL).\r
164  *\r
165  * @a consider_inheritance determines how the rangelists in the two\r
166  * hashes are compared for equality.  If @a consider_inheritance is FALSE,\r
167  * then the start and end revisions of the @c svn_merge_range_t's being\r
168  * compared are the only factors considered when determining equality.\r
169  *\r
170  *  e.g. '/trunk: 1,3-4*,5' == '/trunk: 1,3-5'\r
171  *\r
172  * If @a consider_inheritance is TRUE, then the inheritability of the\r
173  * @c svn_merge_range_t's is also considered and must be the same for two\r
174  * otherwise identical ranges to be judged equal.\r
175  *\r
176  *  e.g. '/trunk: 1,3-4*,5' != '/trunk: 1,3-5'\r
177  *       '/trunk: 1,3-4*,5' == '/trunk: 1,3-4*,5'\r
178  *       '/trunk: 1,3-4,5'  == '/trunk: 1,3-4,5'\r
179  *\r
180  * @since New in 1.5.\r
181  */\r
182 svn_error_t *\r
183 svn_mergeinfo_diff(svn_mergeinfo_t *deleted, svn_mergeinfo_t *added,\r
184                    svn_mergeinfo_t mergefrom, svn_mergeinfo_t mergeto,\r
185                    svn_boolean_t consider_inheritance,\r
186                    apr_pool_t *pool);\r
187 \r
188 /** Merge one mergeinfo, @a changes, into another mergeinfo @a\r
189  * mergeinfo.\r
190  *\r
191  * When intersecting rangelists for a path are merged, the inheritability of\r
192  * the resulting svn_merge_range_t depends on the inheritability of the\r
193  * operands.  If two non-inheritable ranges are merged the result is always\r
194  * non-inheritable, in all other cases the resulting range is inheritable.\r
195  *\r
196  *  e.g. '/A: 1,3-4'  merged with '/A: 1,3,4*,5' --> '/A: 1,3-5'\r
197  *       '/A: 1,3-4*' merged with '/A: 1,3,4*,5' --> '/A: 1,3,4*,5'\r
198  *\r
199  * @since New in 1.5.\r
200  */\r
201 svn_error_t *\r
202 svn_mergeinfo_merge(svn_mergeinfo_t mergeinfo, svn_mergeinfo_t changes,\r
203                     apr_pool_t *pool);\r
204 \r
205 /** Removes @a eraser (the subtrahend) from @a whiteboard (the\r
206  * minuend), and places the resulting difference in @a *mergeinfo.\r
207  *\r
208  * @since New in 1.5.\r
209  */\r
210 svn_error_t *\r
211 svn_mergeinfo_remove(svn_mergeinfo_t *mergeinfo, svn_mergeinfo_t eraser,\r
212                      svn_mergeinfo_t whiteboard, apr_pool_t *pool);\r
213 \r
214 /** Calculate the delta between two rangelists consisting of @c\r
215  * svn_merge_range_t * elements (sorted in ascending order), @a from\r
216  * and @a to, and place the result in @a *deleted and @a *added\r
217  * (neither output argument will ever be @c NULL).\r
218  *\r
219  * @a consider_inheritance determines how to account for the inheritability\r
220  * of the two rangelist's ranges when calculating the diff,\r
221  * as described for svn_mergeinfo_diff().\r
222  *\r
223  * @since New in 1.5.\r
224  */\r
225 svn_error_t *\r
226 svn_rangelist_diff(apr_array_header_t **deleted, apr_array_header_t **added,\r
227                    apr_array_header_t *from, apr_array_header_t *to,\r
228                    svn_boolean_t consider_inheritance,\r
229                    apr_pool_t *pool);\r
230 \r
231 /** Merge two rangelists consisting of @c svn_merge_range_t *\r
232  * elements, @a *rangelist and @a changes, placing the results in\r
233  * @a *rangelist.  Either rangelist may be empty.\r
234  *\r
235  * When intersecting rangelists are merged, the inheritability of\r
236  * the resulting svn_merge_range_t depends on the inheritability of the\r
237  * operands: see svn_mergeinfo_merge().\r
238  *\r
239  * Note: @a *rangelist and @a changes must be sorted as said by @c\r
240  * svn_sort_compare_ranges().  @a *rangelist is guaranteed to remain\r
241  * in sorted order and be compacted to the minimal number of ranges\r
242  * needed to represent the merged result.\r
243  *\r
244  * @since New in 1.5.\r
245  */\r
246 svn_error_t *\r
247 svn_rangelist_merge(apr_array_header_t **rangelist,\r
248                     apr_array_header_t *changes,\r
249                     apr_pool_t *pool);\r
250 \r
251 /** Removes @a eraser (the subtrahend) from @a whiteboard (the\r
252  * minuend), and places the resulting difference in @a output.\r
253  *\r
254  * Note: @a eraser and @a whiteboard must be sorted as said by @c\r
255  * svn_sort_compare_ranges().  @a output is guaranteed to be in sorted\r
256  * order.\r
257  *\r
258  * @a consider_inheritance determines how to account for the\r
259  * @c svn_merge_range_t inheritable field when comparing @a whiteboard's\r
260  * and @a *eraser's rangelists for equality.  @see svn_mergeinfo_diff().\r
261  *\r
262  * @since New in 1.5.\r
263  */\r
264 svn_error_t *\r
265 svn_rangelist_remove(apr_array_header_t **output, apr_array_header_t *eraser,\r
266                      apr_array_header_t *whiteboard,\r
267                      svn_boolean_t consider_inheritance,\r
268                      apr_pool_t *pool);\r
269 \r
270 /** Find the intersection of two mergeinfos, @a mergeinfo1 and @a\r
271  * mergeinfo2, and place the result in @a *mergeinfo, which is (deeply)\r
272  * allocated in @a pool.\r
273  *\r
274  * @since New in 1.5.\r
275  */\r
276 svn_error_t *\r
277 svn_mergeinfo_intersect(svn_mergeinfo_t *mergeinfo,\r
278                         svn_mergeinfo_t mergeinfo1,\r
279                         svn_mergeinfo_t mergeinfo2,\r
280                         apr_pool_t *pool);\r
281 \r
282 /** Find the intersection of two rangelists consisting of @c\r
283  * svn_merge_range_t * elements, @a rangelist1 and @a rangelist2, and\r
284  * place the result in @a *rangelist (which is never @c NULL).\r
285  *\r
286  * @a consider_inheritance determines how to account for the inheritability\r
287  * of the two rangelist's ranges when calculating the intersection,\r
288  * @see svn_mergeinfo_diff().\r
289  *\r
290  * Note: @a rangelist1 and @a rangelist2 must be sorted as said by @c\r
291  * svn_sort_compare_ranges(). @a *rangelist is guaranteed to be in sorted\r
292  * order.\r
293  * @since New in 1.5.\r
294  */\r
295 svn_error_t *\r
296 svn_rangelist_intersect(apr_array_header_t **rangelist,\r
297                         apr_array_header_t *rangelist1,\r
298                         apr_array_header_t *rangelist2,\r
299                         svn_boolean_t consider_inheritance,\r
300                         apr_pool_t *pool);\r
301 \r
302 /** Reverse @a rangelist, and the @c start and @c end fields of each\r
303  * range in @a rangelist, in place.\r
304  *\r
305  * TODO(miapi): Is this really a valid function?  Rangelists that\r
306  * aren't sorted, or rangelists containing reverse ranges, are\r
307  * generally not valid in mergeinfo code.  Can we rewrite the two\r
308  * places where this is used?\r
309  *\r
310  * @since New in 1.5.\r
311  */\r
312 svn_error_t *\r
313 svn_rangelist_reverse(apr_array_header_t *rangelist, apr_pool_t *pool);\r
314 \r
315 /** Take an array of svn_merge_range_t *'s in @a rangelist, and convert it\r
316  * back to a text format rangelist in @a output.  If @a rangelist contains\r
317  * no elements, sets @a output to the empty string.\r
318  *\r
319  * @since New in 1.5.\r
320  */\r
321 svn_error_t *\r
322 svn_rangelist_to_string(svn_string_t **output,\r
323                         const apr_array_header_t *rangelist,\r
324                         apr_pool_t *pool);\r
325 \r
326 /** Return a deep copy of @c svn_merge_range_t *'s in @a rangelist excluding\r
327  * all non-inheritable @c svn_merge_range_t.  If @a start and @a end are valid\r
328  * revisions and @a start is less than or equal to @a end, then exclude only the\r
329  * non-inheritable revision ranges that intersect inclusively with the range\r
330  * defined by @a start and @a end.  If @a rangelist contains no elements, return\r
331  * an empty array.  Allocate the copy in @a pool.\r
332  *\r
333  * @since New in 1.5.\r
334  */\r
335 svn_error_t *\r
336 svn_rangelist_inheritable(apr_array_header_t **inheritable_rangelist,\r
337                           apr_array_header_t *rangelist,\r
338                           svn_revnum_t start,\r
339                           svn_revnum_t end,\r
340                           apr_pool_t *pool);\r
341 \r
342 /** Return a deep copy of @a mergeinfo, excluding all non-inheritable\r
343  * @c svn_merge_range_t.  If @a start and @a end are valid revisions\r
344  * and @a start is less than or equal to @a end, then exclude only the\r
345  * non-inheritable revisions that intersect inclusively with the range\r
346  * defined by @a start and @a end.  If @a path is not NULL remove\r
347  * non-inheritable ranges only for @a path.  If all ranges are removed\r
348  * for a given path then remove that path as well.  If all paths are\r
349  * removed or @a rangelist is empty then set @a *inheritable_rangelist\r
350  * to an empty array.  Allocate the copy in @a pool.\r
351  *\r
352  * @since New in 1.5.\r
353  */\r
354 svn_error_t *\r
355 svn_mergeinfo_inheritable(svn_mergeinfo_t *inheritable_mergeinfo,\r
356                           svn_mergeinfo_t mergeinfo,\r
357                           const char *path,\r
358                           svn_revnum_t start,\r
359                           svn_revnum_t end,\r
360                           apr_pool_t *pool);\r
361 \r
362 /** Take a mergeinfo in MERGEINPUT, and convert it back to unparsed\r
363  *  mergeinfo in *OUTPUT.  If INPUT contains no elements, return the\r
364  *  empty string.\r
365  *\r
366  * @since New in 1.5.\r
367 */\r
368 svn_error_t *\r
369 svn_mergeinfo_to_string(svn_string_t **output,\r
370                         svn_mergeinfo_t mergeinput,\r
371                         apr_pool_t *pool);\r
372 \r
373 /** Take a hash of mergeinfo in @a mergeinfo, and sort the rangelists\r
374  * associated with each key (in place).\r
375  *\r
376  * TODO(miapi): mergeinfos should *always* be sorted.  This should be\r
377  * a private function.\r
378  *\r
379  * @since New in 1.5\r
380  */\r
381 svn_error_t *\r
382 svn_mergeinfo_sort(svn_mergeinfo_t mergeinfo, apr_pool_t *pool);\r
383 \r
384 /** Return a deep copy of @a mergeinfo_catalog, allocated in @a pool.\r
385  *\r
386  * @since New in 1.6.\r
387  */\r
388 svn_mergeinfo_catalog_t\r
389 svn_mergeinfo_catalog_dup(svn_mergeinfo_catalog_t mergeinfo_catalog,\r
390                           apr_pool_t *pool);\r
391 \r
392 /** Return a deep copy of @a mergeinfo, allocated in @a pool.\r
393  *\r
394  * @since New in 1.5.\r
395  */\r
396 svn_mergeinfo_t\r
397 svn_mergeinfo_dup(svn_mergeinfo_t mergeinfo, apr_pool_t *pool);\r
398 \r
399 /** Return a deep copy of @a rangelist, allocated in @a pool.\r
400  *\r
401  * @since New in 1.5.\r
402  */\r
403 apr_array_header_t *\r
404 svn_rangelist_dup(apr_array_header_t *rangelist, apr_pool_t *pool);\r
405 \r
406 \r
407 /**\r
408  * The three ways to request mergeinfo affecting a given path.\r
409  *\r
410  * @since New in 1.5.\r
411  */\r
412 typedef enum\r
413 {\r
414   /** Explicit mergeinfo only. */\r
415   svn_mergeinfo_explicit,\r
416 \r
417   /** Explicit mergeinfo, or if that doesn't exist, the inherited\r
418       mergeinfo from a target's nearest (path-wise, not history-wise)\r
419       ancestor. */\r
420   svn_mergeinfo_inherited,\r
421 \r
422   /** Mergeinfo on target's nearest (path-wise, not history-wise)\r
423       ancestor, regardless of whether target has explict mergeinfo. */\r
424   svn_mergeinfo_nearest_ancestor\r
425 } svn_mergeinfo_inheritance_t;\r
426 \r
427 /** Return a constant string expressing @a inherit as an English word,\r
428  * i.e., "explicit" (default), "inherited", or "nearest_ancestor".\r
429  * The string is not localized, as it may be used for client<->server\r
430  * communications.\r
431  *\r
432  * @since New in 1.5.\r
433  */\r
434 const char *\r
435 svn_inheritance_to_word(svn_mergeinfo_inheritance_t inherit);\r
436 \r
437 \r
438 /** Return the appropriate @c svn_mergeinfo_inheritance_t for @a word.\r
439  * @a word is as returned from svn_inheritance_to_word().  Defaults to\r
440  * @c svn_mergeinfo_explicit.\r
441  *\r
442  * @since New in 1.5.\r
443  */\r
444 svn_mergeinfo_inheritance_t\r
445 svn_inheritance_from_word(const char *word);\r
446 \r
447 \r
448 #ifdef __cplusplus\r
449 }\r
450 #endif /* __cplusplus */\r
451 \r
452 #endif /* SVN_MERGEINFO_H */\r