1251881Speter/* 2251881Speter * mergeinfo.h : Client library-internal mergeinfo APIs. 3251881Speter * 4251881Speter * ==================================================================== 5251881Speter * Licensed to the Apache Software Foundation (ASF) under one 6251881Speter * or more contributor license agreements. See the NOTICE file 7251881Speter * distributed with this work for additional information 8251881Speter * regarding copyright ownership. The ASF licenses this file 9251881Speter * to you under the Apache License, Version 2.0 (the 10251881Speter * "License"); you may not use this file except in compliance 11251881Speter * with the License. You may obtain a copy of the License at 12251881Speter * 13251881Speter * http://www.apache.org/licenses/LICENSE-2.0 14251881Speter * 15251881Speter * Unless required by applicable law or agreed to in writing, 16251881Speter * software distributed under the License is distributed on an 17251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18251881Speter * KIND, either express or implied. See the License for the 19251881Speter * specific language governing permissions and limitations 20251881Speter * under the License. 21251881Speter * ==================================================================== 22251881Speter */ 23251881Speter 24251881Speter#ifndef SVN_LIBSVN_CLIENT_MERGEINFO_H 25251881Speter#define SVN_LIBSVN_CLIENT_MERGEINFO_H 26251881Speter 27251881Speter#include "svn_wc.h" 28251881Speter#include "svn_client.h" 29251881Speter#include "private/svn_client_private.h" 30251881Speter 31251881Speter 32251881Speter/*** Data Structures ***/ 33251881Speter 34251881Speter 35251881Speter/* Structure to store information about working copy paths that need special 36251881Speter consideration during a mergeinfo aware merge -- See the 37251881Speter 'THE CHILDREN_WITH_MERGEINFO ARRAY' meta comment and the doc string for the 38251881Speter function get_mergeinfo_paths() in libsvn_client/merge.c. 39251881Speter*/ 40251881Spetertypedef struct svn_client__merge_path_t 41251881Speter{ 42251881Speter const char *abspath; /* Absolute working copy path. */ 43251881Speter svn_boolean_t missing_child; /* ABSPATH has an immediate child which 44251881Speter is missing, but is not switched. */ 45251881Speter svn_boolean_t switched_child; /* ABSPATH has an immediate child which 46251881Speter is switched. */ 47251881Speter svn_boolean_t switched; /* ABSPATH is switched. */ 48251881Speter svn_boolean_t has_noninheritable; /* ABSPATH has svn:mergeinfo set on it 49251881Speter which includes non-inheritable 50251881Speter revision ranges. */ 51251881Speter svn_boolean_t absent; /* ABSPATH is absent from the WC, 52251881Speter probably due to authz 53251881Speter restrictions. */ 54251881Speter 55251881Speter svn_boolean_t child_of_noninheritable; /* ABSPATH has no explicit mergeinfo 56251881Speter itself but is the child of a 57251881Speter path with noniheritable 58251881Speter mergeinfo. */ 59251881Speter 60251881Speter /* The remaining ranges to be merged to ABSPATH. When describing a forward 61251881Speter merge this rangelist adheres to the rules for rangelists described in 62251881Speter svn_mergeinfo.h. However, when describing reverse merges this 63251881Speter rangelist can contain reverse merge ranges that are not sorted per 64251881Speter svn_sort_compare_ranges(), but rather are sorted such that the ranges 65251881Speter with the youngest start revisions come first. In both the forward and 66251881Speter reverse merge cases the ranges should never overlap. This rangelist 67251881Speter may be empty but should never be NULL unless ABSENT is true. */ 68251881Speter svn_rangelist_t *remaining_ranges; 69251881Speter 70251881Speter svn_mergeinfo_t pre_merge_mergeinfo; /* Explicit or inherited mergeinfo 71251881Speter on ABSPATH prior to a merge. 72251881Speter May be NULL. */ 73251881Speter svn_mergeinfo_t implicit_mergeinfo; /* Implicit mergeinfo on ABSPATH 74251881Speter prior to a merge. May be NULL. */ 75251881Speter svn_boolean_t inherited_mergeinfo; /* Whether PRE_MERGE_MERGEINFO was 76251881Speter explicit or inherited. */ 77251881Speter svn_boolean_t immediate_child_dir; /* ABSPATH is an immediate child 78251881Speter directory of the merge target, 79251881Speter has no explicit mergeinfo prior 80251881Speter to the merge, and the operational 81251881Speter depth of the merge is 82251881Speter svn_depth_immediates. */ 83251881Speter svn_boolean_t record_mergeinfo; /* Mergeinfo needs to be recorded 84251881Speter on ABSPATH to describe the 85251881Speter merge. */ 86251881Speter svn_boolean_t record_noninheritable; /* Non-inheritable mergeinfo needs to 87251881Speter be recorded on ABSPATH to describe 88251881Speter the merge. Implies RECORD_MERGEINFO 89251881Speter is true. */ 90251881Speter} svn_client__merge_path_t; 91251881Speter 92251881Speter/* Return a deep copy of the merge-path structure OLD, allocated in POOL. */ 93251881Spetersvn_client__merge_path_t * 94251881Spetersvn_client__merge_path_dup(const svn_client__merge_path_t *old, 95251881Speter apr_pool_t *pool); 96251881Speter 97251881Speter/* Create a new merge path structure, allocated in POOL. Initialize the 98251881Speter * 'abspath' member to a deep copy of ABSPATH and all other fields to zero 99251881Speter * bytes. */ 100251881Spetersvn_client__merge_path_t * 101251881Spetersvn_client__merge_path_create(const char *abspath, 102251881Speter apr_pool_t *pool); 103251881Speter 104251881Speter 105251881Speter 106251881Speter/*** Functions ***/ 107251881Speter 108251881Speter/* Find explicit or inherited WC mergeinfo for LOCAL_ABSPATH, and return it 109251881Speter in *MERGEINFO (NULL if no mergeinfo is set). Set *INHERITED to 110251881Speter whether the mergeinfo was inherited (TRUE or FALSE), if INHERITED is 111251881Speter non-null. 112251881Speter 113251881Speter This function will search for inherited mergeinfo in the parents of 114251881Speter LOCAL_ABSPATH only if the base revision of LOCAL_ABSPATH falls within 115251881Speter the range of the parent's last committed revision to the parent's base 116251881Speter revision (inclusive) or is LOCAL_ABSPATH is a local addition. If asking 117251881Speter for the inherited mergeinfo of an added path (i.e. one with no base 118251881Speter revision), that path may inherit mergeinfo from its nearest parent 119251881Speter with a base revision and explicit mergeinfo. 120251881Speter 121251881Speter INHERIT indicates whether explicit, explicit or inherited, or only 122251881Speter inherited mergeinfo for LOCAL_ABSPATH is retrieved. 123251881Speter 124251881Speter Don't look for inherited mergeinfo any higher than LIMIT_ABSPATH 125251881Speter (ignored if NULL) or beyond any switched path. 126251881Speter 127251881Speter Set *WALKED_PATH to the path climbed from LOCAL_ABSPATH to find inherited 128251881Speter mergeinfo, or "" if none was found. (ignored if NULL). 129251881Speter 130251881Speter If IGNORE_INVALID_MERGEINFO is true, then syntactically invalid explicit 131251881Speter mergeinfo on found on LOCAL_ABSPATH is ignored and *MERGEINFO is set to an 132251881Speter empty hash. If IGNORE_INVALID_MERGEINFO is false, then syntactically 133251881Speter invalid explicit mergeinfo on found on LOCAL_ABSPATH results in a 134251881Speter SVN_ERR_MERGEINFO_PARSE_ERROR error. Regardless of 135251881Speter IGNORE_INVALID_MERGEINFO, if LOCAL_ABSPATH inherits invalid mergeinfo, 136251881Speter then *MERGEINFO is always set to an empty hash and no parse error is 137251881Speter raised. */ 138251881Spetersvn_error_t * 139251881Spetersvn_client__get_wc_mergeinfo(svn_mergeinfo_t *mergeinfo, 140251881Speter svn_boolean_t *inherited, 141251881Speter svn_mergeinfo_inheritance_t inherit, 142251881Speter const char *local_abspath, 143251881Speter const char *limit_abspath, 144251881Speter const char **walked_path, 145251881Speter svn_boolean_t ignore_invalid_mergeinfo, 146251881Speter svn_client_ctx_t *ctx, 147251881Speter apr_pool_t *result_pool, 148251881Speter apr_pool_t *scratch_pool); 149251881Speter 150251881Speter/* If INCLUDE_DESCENDANTS is FALSE, behave exactly like 151251881Speter svn_client__get_wc_mergeinfo() except the mergeinfo for LOCAL_ABSPATH is 152251881Speter put in the mergeinfo catalog MERGEINFO_CAT, mapped from LOCAL_ABSPATH's 153251881Speter repository root-relative path. 154251881Speter 155251881Speter If INCLUDE_DESCENDANTS is true, then any subtrees under LOCAL_ABSPATH with 156251881Speter explicit mergeinfo are also included in MERGEINFO_CAT and again the 157251881Speter keys are the repository root-relative paths of the subtrees. If no 158251881Speter mergeinfo is found, then *MERGEINFO_CAT is set to NULL. */ 159251881Spetersvn_error_t * 160251881Spetersvn_client__get_wc_mergeinfo_catalog(svn_mergeinfo_catalog_t *mergeinfo_cat, 161251881Speter svn_boolean_t *inherited, 162251881Speter svn_boolean_t include_descendants, 163251881Speter svn_mergeinfo_inheritance_t inherit, 164251881Speter const char *local_abspath, 165251881Speter const char *limit_path, 166251881Speter const char **walked_path, 167251881Speter svn_boolean_t ignore_invalid_mergeinfo, 168251881Speter svn_client_ctx_t *ctx, 169251881Speter apr_pool_t *result_pool, 170251881Speter apr_pool_t *scratch_pool); 171251881Speter 172251881Speter/* Obtain any mergeinfo for URL from the repository, and set 173251881Speter it in *TARGET_MERGEINFO. 174251881Speter 175251881Speter INHERIT indicates whether explicit, explicit or inherited, or only 176251881Speter inherited mergeinfo for URL is obtained. 177251881Speter 178251881Speter If URL does not exist at REV, SVN_ERR_FS_NOT_FOUND or 179251881Speter SVN_ERR_RA_DAV_REQUEST_FAILED is returned and *TARGET_MERGEINFO 180251881Speter is untouched. 181251881Speter 182251881Speter If there is no mergeinfo available for URL, or if the server 183251881Speter doesn't support a mergeinfo capability and SQUELCH_INCAPABLE is 184251881Speter TRUE, set *TARGET_MERGEINFO to NULL. If the server doesn't support 185251881Speter a mergeinfo capability and SQUELCH_INCAPABLE is FALSE, return an 186251881Speter SVN_ERR_UNSUPPORTED_FEATURE error. 187251881Speter 188251881Speter RA_SESSION is an open RA session to the repository in which URL lives; 189251881Speter it may be temporarily reparented by this function. 190251881Speter*/ 191251881Spetersvn_error_t * 192251881Spetersvn_client__get_repos_mergeinfo(svn_mergeinfo_t *target_mergeinfo, 193251881Speter svn_ra_session_t *ra_session, 194251881Speter const char *url, 195251881Speter svn_revnum_t rev, 196251881Speter svn_mergeinfo_inheritance_t inherit, 197251881Speter svn_boolean_t squelch_incapable, 198251881Speter apr_pool_t *pool); 199251881Speter 200251881Speter/* If INCLUDE_DESCENDANTS is FALSE, behave exactly like 201251881Speter svn_client__get_repos_mergeinfo() except the mergeinfo for URL 202251881Speter is put in the mergeinfo catalog MERGEINFO_CAT, with the key being 203251881Speter the repository root-relative path of URL. 204251881Speter 205251881Speter If INCLUDE_DESCENDANTS is true, then any subtrees under URL 206251881Speter with explicit mergeinfo are also included in MERGEINFO_CAT. The 207251881Speter keys for the subtree mergeinfo are the repository root-relative 208251881Speter paths of the subtrees. If no mergeinfo is found, then 209251881Speter *TARGET_MERGEINFO_CAT is set to NULL. */ 210251881Spetersvn_error_t * 211251881Spetersvn_client__get_repos_mergeinfo_catalog(svn_mergeinfo_catalog_t *mergeinfo_cat, 212251881Speter svn_ra_session_t *ra_session, 213251881Speter const char *url, 214251881Speter svn_revnum_t rev, 215251881Speter svn_mergeinfo_inheritance_t inherit, 216251881Speter svn_boolean_t squelch_incapable, 217251881Speter svn_boolean_t include_descendants, 218251881Speter apr_pool_t *result_pool, 219251881Speter apr_pool_t *scratch_pool); 220251881Speter 221251881Speter/* Retrieve the direct mergeinfo for the TARGET_WCPATH from the WC's 222251881Speter mergeinfo prop, or that inherited from its nearest ancestor if the 223251881Speter target has no info of its own. 224251881Speter 225251881Speter If no mergeinfo can be obtained from the WC or REPOS_ONLY is TRUE, 226251881Speter get it from the repository. If the repository is contacted for mergeinfo 227251881Speter and RA_SESSION does not point to TARGET_WCPATH's URL, then it is 228251881Speter temporarily reparented. If RA_SESSION is NULL, then a temporary session 229251881Speter is opened as needed. 230251881Speter 231251881Speter Store any mergeinfo obtained for TARGET_WCPATH in 232251881Speter *TARGET_MERGEINFO, if no mergeinfo is found *TARGET_MERGEINFO is 233251881Speter NULL. 234251881Speter 235251881Speter Like svn_client__get_wc_mergeinfo(), this function considers no 236251881Speter inherited mergeinfo to be found in the WC when trying to crawl into 237251881Speter a parent path with a different working revision. 238251881Speter 239251881Speter INHERIT indicates whether explicit, explicit or inherited, or only 240251881Speter inherited mergeinfo for TARGET_WCPATH is retrieved. 241251881Speter 242251881Speter If FROM_REPOS is not NULL, then set *FROM_REPOS to true if 243251881Speter *TARGET_MERGEINFO is inherited and the repository was contacted to 244251881Speter obtain it. Set *FROM_REPOS to false otherwise. 245251881Speter 246251881Speter If TARGET_WCPATH inherited its mergeinfo from a working copy ancestor 247251881Speter or if it was obtained from the repository, set *INHERITED to TRUE, set it 248251881Speter to FALSE otherwise, if INHERITED is non-null. */ 249251881Spetersvn_error_t * 250251881Spetersvn_client__get_wc_or_repos_mergeinfo(svn_mergeinfo_t *target_mergeinfo, 251251881Speter svn_boolean_t *inherited, 252251881Speter svn_boolean_t *from_repos, 253251881Speter svn_boolean_t repos_only, 254251881Speter svn_mergeinfo_inheritance_t inherit, 255251881Speter svn_ra_session_t *ra_session, 256251881Speter const char *target_wcpath, 257251881Speter svn_client_ctx_t *ctx, 258251881Speter apr_pool_t *pool); 259251881Speter 260251881Speter/* If INCLUDE_DESCENDANTS is false then behaves exactly like 261251881Speter svn_client__get_wc_or_repos_mergeinfo() except the mergeinfo for 262251881Speter TARGET_WCPATH is put in the mergeinfo catalog 263251881Speter TARGET_MERGEINFO_CATALOG, mapped from TARGET_WCPATH's repository 264251881Speter root-relative path. 265251881Speter 266251881Speter IGNORE_INVALID_MERGEINFO behaves as per the argument of the same 267251881Speter name to svn_client__get_wc_mergeinfo(). It is applicable only if 268251881Speter the mergeinfo for TARGET_WCPATH is obtained from the working copy. 269251881Speter 270251881Speter If INCLUDE_DESCENDANTS is true, then any subtrees under 271251881Speter TARGET_WCPATH with explicit mergeinfo are also included in 272251881Speter TARGET_MERGEINFO_CATALOG and again the keys are the repository 273251881Speter root-relative paths of the subtrees. If no mergeinfo is found, 274251881Speter then *TARGET_MERGEINFO_CAT is set to NULL. */ 275251881Spetersvn_error_t * 276251881Spetersvn_client__get_wc_or_repos_mergeinfo_catalog( 277251881Speter svn_mergeinfo_catalog_t *target_mergeinfo_catalog, 278251881Speter svn_boolean_t *inherited, 279251881Speter svn_boolean_t *from_repos, 280251881Speter svn_boolean_t include_descendants, 281251881Speter svn_boolean_t repos_only, 282251881Speter svn_boolean_t ignore_invalid_mergeinfo, 283251881Speter svn_mergeinfo_inheritance_t inherit, 284251881Speter svn_ra_session_t *ra_session, 285251881Speter const char *target_wcpath, 286251881Speter svn_client_ctx_t *ctx, 287251881Speter apr_pool_t *result_pool, 288251881Speter apr_pool_t *scratch_pool); 289251881Speter 290251881Speter/* Set *MERGEINFO_P to a mergeinfo constructed solely from the 291251881Speter natural history of PATHREV. 292251881Speter 293251881Speter If RANGE_YOUNGEST and RANGE_OLDEST are valid, use them as inclusive 294251881Speter bounds on the revision ranges of returned mergeinfo. PATHREV->rev, 295251881Speter RANGE_YOUNGEST and RANGE_OLDEST are governed by the same rules as the 296251881Speter PEG_REVISION, START_REV, and END_REV parameters (respectively) of 297251881Speter svn_ra_get_location_segments(). 298251881Speter 299251881Speter If HAS_REV_ZERO_HISTORY is not NULL, then set *HAS_REV_ZERO_HISTORY to 300251881Speter TRUE if the natural history includes revision 0, else to FALSE. 301251881Speter 302251881Speter RA_SESSION is an open RA session to the repository of PATHREV; 303251881Speter it may be temporarily reparented by this function. 304251881Speter*/ 305251881Spetersvn_error_t * 306251881Spetersvn_client__get_history_as_mergeinfo(svn_mergeinfo_t *mergeinfo_p, 307251881Speter svn_boolean_t *has_rev_zero_history, 308251881Speter const svn_client__pathrev_t *pathrev, 309251881Speter svn_revnum_t range_youngest, 310251881Speter svn_revnum_t range_oldest, 311251881Speter svn_ra_session_t *ra_session, 312251881Speter svn_client_ctx_t *ctx, 313251881Speter apr_pool_t *pool); 314251881Speter 315251881Speter/* Parse any explicit mergeinfo on LOCAL_ABSPATH and store it in 316251881Speter *MERGEINFO. If no record of any mergeinfo exists, set *MERGEINFO to NULL. 317289180Speter Does not acount for inherited mergeinfo. 318289180Speter 319289180Speter Allocate the result deeply in @a result_pool. */ 320251881Spetersvn_error_t * 321251881Spetersvn_client__parse_mergeinfo(svn_mergeinfo_t *mergeinfo, 322251881Speter svn_wc_context_t *wc_ctx, 323251881Speter const char *local_abspath, 324251881Speter apr_pool_t *result_pool, 325251881Speter apr_pool_t *scratch_pool); 326251881Speter 327251881Speter/* Write MERGEINFO into the WC for LOCAL_ABSPATH. If MERGEINFO is NULL, 328251881Speter remove any SVN_PROP_MERGEINFO for LOCAL_ABSPATH. If MERGEINFO is empty, 329251881Speter record an empty property value (e.g. ""). If CTX->NOTIFY_FUNC2 is 330251881Speter not null call it with notification type svn_wc_notify_merge_record_info 331251881Speter if DO_NOTIFICATION is true. 332251881Speter 333251881Speter Use WC_CTX to access the working copy, and SCRATCH_POOL for any temporary 334251881Speter allocations. */ 335251881Spetersvn_error_t * 336251881Spetersvn_client__record_wc_mergeinfo(const char *local_abspath, 337251881Speter svn_mergeinfo_t mergeinfo, 338251881Speter svn_boolean_t do_notification, 339251881Speter svn_client_ctx_t *ctx, 340251881Speter apr_pool_t *scratch_pool); 341251881Speter 342251881Speter/* Write mergeinfo into the WC. 343251881Speter * 344251881Speter * For each path in RESULT_CATALOG, set the SVN_PROP_MERGEINFO 345251881Speter * property to represent the given mergeinfo, or remove the property 346251881Speter * if the given mergeinfo is null, and notify the change. Leave 347251881Speter * other paths unchanged. RESULT_CATALOG maps (const char *) WC paths 348251881Speter * to (svn_mergeinfo_t) mergeinfo. */ 349251881Spetersvn_error_t * 350251881Spetersvn_client__record_wc_mergeinfo_catalog(apr_hash_t *result_catalog, 351251881Speter svn_client_ctx_t *ctx, 352251881Speter apr_pool_t *scratch_pool); 353251881Speter 354251881Speter/* Elide any svn:mergeinfo set on TARGET_ABSPATH to its nearest working 355251881Speter copy (or possibly repository) ancestor with equivalent mergeinfo. 356251881Speter 357251881Speter If WC_ELISION_LIMIT_ABSPATH is NULL check up to the root of the 358251881Speter working copy or the nearest switched parent for an elision 359251881Speter destination, if none is found check the repository, otherwise check 360251881Speter as far as WC_ELISION_LIMIT_ABSPATH within the working copy. 361251881Speter 362251881Speter Elision occurs if: 363251881Speter 364251881Speter A) TARGET_ABSPATH has empty mergeinfo and no parent path with 365251881Speter explicit mergeinfo can be found in either the WC or the 366251881Speter repository (WC_ELISION_LIMIT_PATH must be NULL for this to 367251881Speter occur). 368251881Speter 369251881Speter B) TARGET_ABSPATH has empty mergeinfo and its nearest parent also 370251881Speter has empty mergeinfo. 371251881Speter 372251881Speter C) TARGET_ABSPATH has the same mergeinfo as its nearest parent 373251881Speter when that parent's mergeinfo is adjusted for the path 374251881Speter difference between the two, e.g.: 375251881Speter 376251881Speter TARGET_ABSPATH = A_COPY/D/H 377251881Speter TARGET_ABSPATH's mergeinfo = '/A/D/H:3' 378251881Speter TARGET_ABSPATH nearest parent = A_COPY 379251881Speter Parent's mergeinfo = '/A:3' 380251881Speter Path difference = 'D/H' 381251881Speter Parent's adjusted mergeinfo = '/A/D/H:3' 382251881Speter 383251881Speter If Elision occurs remove the svn:mergeinfo property from 384251881Speter TARGET_ABSPATH. */ 385251881Spetersvn_error_t * 386251881Spetersvn_client__elide_mergeinfo(const char *target_abspath, 387251881Speter const char *wc_elision_limit_abspath, 388251881Speter svn_client_ctx_t *ctx, 389251881Speter apr_pool_t *pool); 390251881Speter 391251881Speter/* Simplify a mergeinfo catalog, if possible, via elision. 392251881Speter 393251881Speter For each path in MERGEINFO_CATALOG, check if the path's mergeinfo can 394251881Speter elide to the path's nearest path-wise parent in MERGEINFO_CATALOG. If 395251881Speter so, remove that path from MERGEINFO_CATALOG. Elidability is determined 396251881Speter as per svn_client__elide_mergeinfo except that elision to the repository 397251881Speter is not considered. 398251881Speter 399251881Speter SCRATCH_POOL is used for temporary allocations. */ 400251881Spetersvn_error_t * 401251881Spetersvn_client__elide_mergeinfo_catalog(svn_mergeinfo_catalog_t mergeinfo_catalog, 402251881Speter apr_pool_t *scratch_pool); 403251881Speter 404251881Speter/* Set *MERGEINFO_CHANGES to TRUE if LOCAL_ABSPATH has locally modified 405251881Speter mergeinfo, set *MERGEINFO_CHANGES to FALSE otherwise. */ 406251881Spetersvn_error_t * 407251881Spetersvn_client__mergeinfo_status(svn_boolean_t *mergeinfo_changes, 408251881Speter svn_wc_context_t *wc_ctx, 409251881Speter const char *local_abspath, 410251881Speter apr_pool_t *scratch_pool); 411251881Speter 412251881Speter#endif /* SVN_LIBSVN_CLIENT_MERGEINFO_H */ 413