2 * mergeinfo.h : Client library-internal mergeinfo APIs.
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
21 * ====================================================================
24 #ifndef SVN_LIBSVN_CLIENT_MERGEINFO_H
25 #define SVN_LIBSVN_CLIENT_MERGEINFO_H
28 #include "svn_client.h"
29 #include "private/svn_client_private.h"
32 /*** Data Structures ***/
35 /* Structure to store information about working copy paths that need special
36 consideration during a mergeinfo aware merge -- See the
37 'THE CHILDREN_WITH_MERGEINFO ARRAY' meta comment and the doc string for the
38 function get_mergeinfo_paths() in libsvn_client/merge.c.
40 typedef struct svn_client__merge_path_t
42 const char *abspath; /* Absolute working copy path. */
43 svn_boolean_t missing_child; /* ABSPATH has an immediate child which
44 is missing, but is not switched. */
45 svn_boolean_t switched_child; /* ABSPATH has an immediate child which
47 svn_boolean_t switched; /* ABSPATH is switched. */
48 svn_boolean_t has_noninheritable; /* ABSPATH has svn:mergeinfo set on it
49 which includes non-inheritable
51 svn_boolean_t absent; /* ABSPATH is absent from the WC,
55 svn_boolean_t child_of_noninheritable; /* ABSPATH has no explicit mergeinfo
56 itself but is the child of a
57 path with noniheritable
60 /* The remaining ranges to be merged to ABSPATH. When describing a forward
61 merge this rangelist adheres to the rules for rangelists described in
62 svn_mergeinfo.h. However, when describing reverse merges this
63 rangelist can contain reverse merge ranges that are not sorted per
64 svn_sort_compare_ranges(), but rather are sorted such that the ranges
65 with the youngest start revisions come first. In both the forward and
66 reverse merge cases the ranges should never overlap. This rangelist
67 may be empty but should never be NULL unless ABSENT is true. */
68 svn_rangelist_t *remaining_ranges;
70 svn_mergeinfo_t pre_merge_mergeinfo; /* Explicit or inherited mergeinfo
71 on ABSPATH prior to a merge.
73 svn_mergeinfo_t implicit_mergeinfo; /* Implicit mergeinfo on ABSPATH
74 prior to a merge. May be NULL. */
75 svn_boolean_t inherited_mergeinfo; /* Whether PRE_MERGE_MERGEINFO was
76 explicit or inherited. */
77 svn_boolean_t scheduled_for_deletion; /* ABSPATH is scheduled for
79 svn_boolean_t immediate_child_dir; /* ABSPATH is an immediate child
80 directory of the merge target,
81 has no explicit mergeinfo prior
82 to the merge, and the operational
84 svn_depth_immediates. */
85 svn_boolean_t record_mergeinfo; /* Mergeinfo needs to be recorded
86 on ABSPATH to describe the
88 svn_boolean_t record_noninheritable; /* Non-inheritable mergeinfo needs to
89 be recorded on ABSPATH to describe
90 the merge. Implies RECORD_MERGEINFO
92 } svn_client__merge_path_t;
94 /* Return a deep copy of the merge-path structure OLD, allocated in POOL. */
95 svn_client__merge_path_t *
96 svn_client__merge_path_dup(const svn_client__merge_path_t *old,
99 /* Create a new merge path structure, allocated in POOL. Initialize the
100 * 'abspath' member to a deep copy of ABSPATH and all other fields to zero
102 svn_client__merge_path_t *
103 svn_client__merge_path_create(const char *abspath,
110 /* Find explicit or inherited WC mergeinfo for LOCAL_ABSPATH, and return it
111 in *MERGEINFO (NULL if no mergeinfo is set). Set *INHERITED to
112 whether the mergeinfo was inherited (TRUE or FALSE), if INHERITED is
115 This function will search for inherited mergeinfo in the parents of
116 LOCAL_ABSPATH only if the base revision of LOCAL_ABSPATH falls within
117 the range of the parent's last committed revision to the parent's base
118 revision (inclusive) or is LOCAL_ABSPATH is a local addition. If asking
119 for the inherited mergeinfo of an added path (i.e. one with no base
120 revision), that path may inherit mergeinfo from its nearest parent
121 with a base revision and explicit mergeinfo.
123 INHERIT indicates whether explicit, explicit or inherited, or only
124 inherited mergeinfo for LOCAL_ABSPATH is retrieved.
126 Don't look for inherited mergeinfo any higher than LIMIT_ABSPATH
127 (ignored if NULL) or beyond any switched path.
129 Set *WALKED_PATH to the path climbed from LOCAL_ABSPATH to find inherited
130 mergeinfo, or "" if none was found. (ignored if NULL).
132 If IGNORE_INVALID_MERGEINFO is true, then syntactically invalid explicit
133 mergeinfo on found on LOCAL_ABSPATH is ignored and *MERGEINFO is set to an
134 empty hash. If IGNORE_INVALID_MERGEINFO is false, then syntactically
135 invalid explicit mergeinfo on found on LOCAL_ABSPATH results in a
136 SVN_ERR_MERGEINFO_PARSE_ERROR error. Regardless of
137 IGNORE_INVALID_MERGEINFO, if LOCAL_ABSPATH inherits invalid mergeinfo,
138 then *MERGEINFO is always set to an empty hash and no parse error is
141 svn_client__get_wc_mergeinfo(svn_mergeinfo_t *mergeinfo,
142 svn_boolean_t *inherited,
143 svn_mergeinfo_inheritance_t inherit,
144 const char *local_abspath,
145 const char *limit_abspath,
146 const char **walked_path,
147 svn_boolean_t ignore_invalid_mergeinfo,
148 svn_client_ctx_t *ctx,
149 apr_pool_t *result_pool,
150 apr_pool_t *scratch_pool);
152 /* If INCLUDE_DESCENDANTS is FALSE, behave exactly like
153 svn_client__get_wc_mergeinfo() except the mergeinfo for LOCAL_ABSPATH is
154 put in the mergeinfo catalog MERGEINFO_CAT, mapped from LOCAL_ABSPATH's
155 repository root-relative path.
157 If INCLUDE_DESCENDANTS is true, then any subtrees under LOCAL_ABSPATH with
158 explicit mergeinfo are also included in MERGEINFO_CAT and again the
159 keys are the repository root-relative paths of the subtrees. If no
160 mergeinfo is found, then *MERGEINFO_CAT is set to NULL. */
162 svn_client__get_wc_mergeinfo_catalog(svn_mergeinfo_catalog_t *mergeinfo_cat,
163 svn_boolean_t *inherited,
164 svn_boolean_t include_descendants,
165 svn_mergeinfo_inheritance_t inherit,
166 const char *local_abspath,
167 const char *limit_path,
168 const char **walked_path,
169 svn_boolean_t ignore_invalid_mergeinfo,
170 svn_client_ctx_t *ctx,
171 apr_pool_t *result_pool,
172 apr_pool_t *scratch_pool);
174 /* Obtain any mergeinfo for URL from the repository, and set
175 it in *TARGET_MERGEINFO.
177 INHERIT indicates whether explicit, explicit or inherited, or only
178 inherited mergeinfo for URL is obtained.
180 If URL does not exist at REV, SVN_ERR_FS_NOT_FOUND or
181 SVN_ERR_RA_DAV_REQUEST_FAILED is returned and *TARGET_MERGEINFO
184 If there is no mergeinfo available for URL, or if the server
185 doesn't support a mergeinfo capability and SQUELCH_INCAPABLE is
186 TRUE, set *TARGET_MERGEINFO to NULL. If the server doesn't support
187 a mergeinfo capability and SQUELCH_INCAPABLE is FALSE, return an
188 SVN_ERR_UNSUPPORTED_FEATURE error.
190 RA_SESSION is an open RA session to the repository in which URL lives;
191 it may be temporarily reparented by this function.
194 svn_client__get_repos_mergeinfo(svn_mergeinfo_t *target_mergeinfo,
195 svn_ra_session_t *ra_session,
198 svn_mergeinfo_inheritance_t inherit,
199 svn_boolean_t squelch_incapable,
202 /* If INCLUDE_DESCENDANTS is FALSE, behave exactly like
203 svn_client__get_repos_mergeinfo() except the mergeinfo for URL
204 is put in the mergeinfo catalog MERGEINFO_CAT, with the key being
205 the repository root-relative path of URL.
207 If INCLUDE_DESCENDANTS is true, then any subtrees under URL
208 with explicit mergeinfo are also included in MERGEINFO_CAT. The
209 keys for the subtree mergeinfo are the repository root-relative
210 paths of the subtrees. If no mergeinfo is found, then
211 *TARGET_MERGEINFO_CAT is set to NULL. */
213 svn_client__get_repos_mergeinfo_catalog(svn_mergeinfo_catalog_t *mergeinfo_cat,
214 svn_ra_session_t *ra_session,
217 svn_mergeinfo_inheritance_t inherit,
218 svn_boolean_t squelch_incapable,
219 svn_boolean_t include_descendants,
220 apr_pool_t *result_pool,
221 apr_pool_t *scratch_pool);
223 /* Retrieve the direct mergeinfo for the TARGET_WCPATH from the WC's
224 mergeinfo prop, or that inherited from its nearest ancestor if the
225 target has no info of its own.
227 If no mergeinfo can be obtained from the WC or REPOS_ONLY is TRUE,
228 get it from the repository. If the repository is contacted for mergeinfo
229 and RA_SESSION does not point to TARGET_WCPATH's URL, then it is
230 temporarily reparented. If RA_SESSION is NULL, then a temporary session
233 Store any mergeinfo obtained for TARGET_WCPATH in
234 *TARGET_MERGEINFO, if no mergeinfo is found *TARGET_MERGEINFO is
237 Like svn_client__get_wc_mergeinfo(), this function considers no
238 inherited mergeinfo to be found in the WC when trying to crawl into
239 a parent path with a different working revision.
241 INHERIT indicates whether explicit, explicit or inherited, or only
242 inherited mergeinfo for TARGET_WCPATH is retrieved.
244 If FROM_REPOS is not NULL, then set *FROM_REPOS to true if
245 *TARGET_MERGEINFO is inherited and the repository was contacted to
246 obtain it. Set *FROM_REPOS to false otherwise.
248 If TARGET_WCPATH inherited its mergeinfo from a working copy ancestor
249 or if it was obtained from the repository, set *INHERITED to TRUE, set it
250 to FALSE otherwise, if INHERITED is non-null. */
252 svn_client__get_wc_or_repos_mergeinfo(svn_mergeinfo_t *target_mergeinfo,
253 svn_boolean_t *inherited,
254 svn_boolean_t *from_repos,
255 svn_boolean_t repos_only,
256 svn_mergeinfo_inheritance_t inherit,
257 svn_ra_session_t *ra_session,
258 const char *target_wcpath,
259 svn_client_ctx_t *ctx,
262 /* If INCLUDE_DESCENDANTS is false then behaves exactly like
263 svn_client__get_wc_or_repos_mergeinfo() except the mergeinfo for
264 TARGET_WCPATH is put in the mergeinfo catalog
265 TARGET_MERGEINFO_CATALOG, mapped from TARGET_WCPATH's repository
268 IGNORE_INVALID_MERGEINFO behaves as per the argument of the same
269 name to svn_client__get_wc_mergeinfo(). It is applicable only if
270 the mergeinfo for TARGET_WCPATH is obtained from the working copy.
272 If INCLUDE_DESCENDANTS is true, then any subtrees under
273 TARGET_WCPATH with explicit mergeinfo are also included in
274 TARGET_MERGEINFO_CATALOG and again the keys are the repository
275 root-relative paths of the subtrees. If no mergeinfo is found,
276 then *TARGET_MERGEINFO_CAT is set to NULL. */
278 svn_client__get_wc_or_repos_mergeinfo_catalog(
279 svn_mergeinfo_catalog_t *target_mergeinfo_catalog,
280 svn_boolean_t *inherited,
281 svn_boolean_t *from_repos,
282 svn_boolean_t include_descendants,
283 svn_boolean_t repos_only,
284 svn_boolean_t ignore_invalid_mergeinfo,
285 svn_mergeinfo_inheritance_t inherit,
286 svn_ra_session_t *ra_session,
287 const char *target_wcpath,
288 svn_client_ctx_t *ctx,
289 apr_pool_t *result_pool,
290 apr_pool_t *scratch_pool);
292 /* Set *MERGEINFO_P to a mergeinfo constructed solely from the
293 natural history of PATHREV.
295 If RANGE_YOUNGEST and RANGE_OLDEST are valid, use them as inclusive
296 bounds on the revision ranges of returned mergeinfo. PATHREV->rev,
297 RANGE_YOUNGEST and RANGE_OLDEST are governed by the same rules as the
298 PEG_REVISION, START_REV, and END_REV parameters (respectively) of
299 svn_ra_get_location_segments().
301 If HAS_REV_ZERO_HISTORY is not NULL, then set *HAS_REV_ZERO_HISTORY to
302 TRUE if the natural history includes revision 0, else to FALSE.
304 RA_SESSION is an open RA session to the repository of PATHREV;
305 it may be temporarily reparented by this function.
308 svn_client__get_history_as_mergeinfo(svn_mergeinfo_t *mergeinfo_p,
309 svn_boolean_t *has_rev_zero_history,
310 const svn_client__pathrev_t *pathrev,
311 svn_revnum_t range_youngest,
312 svn_revnum_t range_oldest,
313 svn_ra_session_t *ra_session,
314 svn_client_ctx_t *ctx,
317 /* Parse any explicit mergeinfo on LOCAL_ABSPATH and store it in
318 *MERGEINFO. If no record of any mergeinfo exists, set *MERGEINFO to NULL.
319 Does not acount for inherited mergeinfo.
321 Allocate the result deeply in @a result_pool. */
323 svn_client__parse_mergeinfo(svn_mergeinfo_t *mergeinfo,
324 svn_wc_context_t *wc_ctx,
325 const char *local_abspath,
326 apr_pool_t *result_pool,
327 apr_pool_t *scratch_pool);
329 /* Write MERGEINFO into the WC for LOCAL_ABSPATH. If MERGEINFO is NULL,
330 remove any SVN_PROP_MERGEINFO for LOCAL_ABSPATH. If MERGEINFO is empty,
331 record an empty property value (e.g. ""). If CTX->NOTIFY_FUNC2 is
332 not null call it with notification type svn_wc_notify_merge_record_info
333 if DO_NOTIFICATION is true.
335 Use WC_CTX to access the working copy, and SCRATCH_POOL for any temporary
338 svn_client__record_wc_mergeinfo(const char *local_abspath,
339 svn_mergeinfo_t mergeinfo,
340 svn_boolean_t do_notification,
341 svn_client_ctx_t *ctx,
342 apr_pool_t *scratch_pool);
344 /* Write mergeinfo into the WC.
346 * For each path in RESULT_CATALOG, set the SVN_PROP_MERGEINFO
347 * property to represent the given mergeinfo, or remove the property
348 * if the given mergeinfo is null, and notify the change. Leave
349 * other paths unchanged. RESULT_CATALOG maps (const char *) WC paths
350 * to (svn_mergeinfo_t) mergeinfo. */
352 svn_client__record_wc_mergeinfo_catalog(apr_hash_t *result_catalog,
353 svn_client_ctx_t *ctx,
354 apr_pool_t *scratch_pool);
356 /* Elide any svn:mergeinfo set on TARGET_ABSPATH to its nearest working
357 copy (or possibly repository) ancestor with equivalent mergeinfo.
359 If WC_ELISION_LIMIT_ABSPATH is NULL check up to the root of the
360 working copy or the nearest switched parent for an elision
361 destination, if none is found check the repository, otherwise check
362 as far as WC_ELISION_LIMIT_ABSPATH within the working copy.
366 A) TARGET_ABSPATH has empty mergeinfo and no parent path with
367 explicit mergeinfo can be found in either the WC or the
368 repository (WC_ELISION_LIMIT_PATH must be NULL for this to
371 B) TARGET_ABSPATH has empty mergeinfo and its nearest parent also
374 C) TARGET_ABSPATH has the same mergeinfo as its nearest parent
375 when that parent's mergeinfo is adjusted for the path
376 difference between the two, e.g.:
378 TARGET_ABSPATH = A_COPY/D/H
379 TARGET_ABSPATH's mergeinfo = '/A/D/H:3'
380 TARGET_ABSPATH nearest parent = A_COPY
381 Parent's mergeinfo = '/A:3'
382 Path difference = 'D/H'
383 Parent's adjusted mergeinfo = '/A/D/H:3'
385 If Elision occurs remove the svn:mergeinfo property from
388 svn_client__elide_mergeinfo(const char *target_abspath,
389 const char *wc_elision_limit_abspath,
390 svn_client_ctx_t *ctx,
393 /* Simplify a mergeinfo catalog, if possible, via elision.
395 For each path in MERGEINFO_CATALOG, check if the path's mergeinfo can
396 elide to the path's nearest path-wise parent in MERGEINFO_CATALOG. If
397 so, remove that path from MERGEINFO_CATALOG. Elidability is determined
398 as per svn_client__elide_mergeinfo except that elision to the repository
401 SCRATCH_POOL is used for temporary allocations. */
403 svn_client__elide_mergeinfo_catalog(svn_mergeinfo_catalog_t mergeinfo_catalog,
404 apr_pool_t *scratch_pool);
406 /* Set *MERGEINFO_CHANGES to TRUE if LOCAL_ABSPATH has locally modified
407 mergeinfo, set *MERGEINFO_CHANGES to FALSE otherwise. */
409 svn_client__mergeinfo_status(svn_boolean_t *mergeinfo_changes,
410 svn_wc_context_t *wc_ctx,
411 const char *local_abspath,
412 apr_pool_t *scratch_pool);
414 #endif /* SVN_LIBSVN_CLIENT_MERGEINFO_H */