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