1 /*
2  * client.h :  shared stuff internal to the client library.
3  *
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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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
20  *    under the License.
21  * ====================================================================
22  */
23 
24 
25 
26 #ifndef SVN_LIBSVN_CLIENT_H
27 #define SVN_LIBSVN_CLIENT_H
28 
29 
30 #include <apr_pools.h>
31 
32 #include "svn_types.h"
33 #include "svn_opt.h"
34 #include "svn_string.h"
35 #include "svn_error.h"
36 #include "svn_ra.h"
37 #include "svn_client.h"
38 
39 #include "private/svn_magic.h"
40 #include "private/svn_client_private.h"
41 #include "private/svn_diff_tree.h"
42 #include "private/svn_editor.h"
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif /* __cplusplus */
47 
48 
49 /* Private client context.
50  *
51  * This is what is actually allocated by svn_client_create_context2(),
52  * which then returns the address of the public_ctx member. */
53 typedef struct svn_client__private_ctx_t
54 {
55   /* Reserved field, always zero, to detect misuse of the private
56      context as a public client context. */
57   apr_uint64_t magic_null;
58 
59   /* Reserved field, always set to a known magic number, to identify
60      this struct as the private client context. */
61   apr_uint64_t magic_id;
62 
63   /* Total number of bytes transferred over network across all RA sessions. */
64   apr_off_t total_progress;
65 
66   /* The public context. */
67   svn_client_ctx_t public_ctx;
68 } svn_client__private_ctx_t;
69 
70 
71 /* Given a public client context CTX, return the private context
72    within which it is allocated. */
73 svn_client__private_ctx_t *
74 svn_client__get_private_ctx(svn_client_ctx_t *ctx);
75 
76 /* Set *ORIGINAL_REPOS_RELPATH and *ORIGINAL_REVISION to the original location
77    that served as the source of the copy from which PATH_OR_URL at REVISION was
78    created, or NULL and SVN_INVALID_REVNUM (respectively) if PATH_OR_URL at
79    REVISION was not the result of a copy operation.
80 
81    If RA_SESSION is not NULL it is an existing session to the repository that
82    might be reparented temporarily to obtain the information.
83    */
84 svn_error_t *
85 svn_client__get_copy_source(const char **original_repos_relpath,
86                             svn_revnum_t *original_revision,
87                             const char *path_or_url,
88                             const svn_opt_revision_t *revision,
89                             svn_ra_session_t *ra_session,
90                             svn_client_ctx_t *ctx,
91                             apr_pool_t *result_pool,
92                             apr_pool_t *scratch_pool);
93 
94 /* Set *START_URL and *START_REVISION (and maybe *END_URL
95    and *END_REVISION) to the revisions and repository URLs of one
96    (or two) points of interest along a particular versioned resource's
97    line of history.  PATH as it exists in "peg revision"
98    REVISION identifies that line of history, and START and END
99    specify the point(s) of interest (typically the revisions referred
100    to as the "operative range" for a given operation) along that history.
101 
102    START_REVISION and/or END_REVISION may be NULL if not wanted.
103    END may be NULL or of kind svn_opt_revision_unspecified (in either case
104    END_URL and END_REVISION are not touched by the function);
105    START and REVISION may not.
106 
107    If PATH is a WC path and REVISION is of kind svn_opt_revision_working,
108    then look at the PATH's copy-from URL instead of its base URL.
109 
110    RA_SESSION should be an open RA session pointing at the URL of PATH,
111    or NULL, in which case this function will open its own temporary session.
112 
113    A NOTE ABOUT FUTURE REPORTING:
114 
115    If either START or END are greater than REVISION, then do a
116    sanity check (since we cannot search future history yet): verify
117    that PATH in the future revision(s) is the "same object" as the
118    one pegged by REVISION.  In other words, all three objects must
119    be connected by a single line of history which exactly passes
120    through PATH at REVISION.  If this sanity check fails, return
121    SVN_ERR_CLIENT_UNRELATED_RESOURCES.  If PATH doesn't exist in the future
122    revision, SVN_ERR_FS_NOT_FOUND may also be returned.
123 
124    CTX is the client context baton.
125 
126    Use POOL for all allocations.  */
127 svn_error_t *
128 svn_client__repos_locations(const char **start_url,
129                             svn_revnum_t *start_revision,
130                             const char **end_url,
131                             svn_revnum_t *end_revision,
132                             svn_ra_session_t *ra_session,
133                             const char *path,
134                             const svn_opt_revision_t *revision,
135                             const svn_opt_revision_t *start,
136                             const svn_opt_revision_t *end,
137                             svn_client_ctx_t *ctx,
138                             apr_pool_t *pool);
139 
140 /* Trace a line of history of a particular versioned resource back to a
141  * specific revision.
142  *
143  * Set *OP_LOC_P to the location that the object PEG_LOC had in
144  * revision OP_REVNUM.
145  *
146  * RA_SESSION is an open RA session to the correct repository; it may be
147  * temporarily reparented inside this function. */
148 svn_error_t *
149 svn_client__repos_location(svn_client__pathrev_t **op_loc_p,
150                            svn_ra_session_t *ra_session,
151                            const svn_client__pathrev_t *peg_loc,
152                            svn_revnum_t op_revnum,
153                            svn_client_ctx_t *ctx,
154                            apr_pool_t *result_pool,
155                            apr_pool_t *scratch_pool);
156 
157 
158 /* Set *SEGMENTS to an array of svn_location_segment_t * objects, each
159    representing a reposition location segment for the history of URL
160    in PEG_REVISION
161    between END_REVISION and START_REVISION, ordered from oldest
162    segment to youngest.  *SEGMENTS may be empty but it will never
163    be NULL.
164 
165    This is basically a thin de-stream-ifying wrapper around the
166    svn_ra_get_location_segments() interface, which see for the rules
167    governing PEG_REVISION, START_REVISION, and END_REVISION.
168 
169    RA_SESSION is an RA session open to the repository of URL; it may be
170    temporarily reparented within this function.
171 
172    CTX is the client context baton.
173 
174    Use POOL for all allocations.  */
175 svn_error_t *
176 svn_client__repos_location_segments(apr_array_header_t **segments,
177                                     svn_ra_session_t *ra_session,
178                                     const char *url,
179                                     svn_revnum_t peg_revision,
180                                     svn_revnum_t start_revision,
181                                     svn_revnum_t end_revision,
182                                     svn_client_ctx_t *ctx,
183                                     apr_pool_t *pool);
184 
185 
186 /* Find the common ancestor of two locations in a repository.
187    Ancestry is determined by the 'copy-from' relationship and the normal
188    successor relationship.
189 
190    Set *ANCESTOR_P to the location of the youngest common ancestor of
191    LOC1 and LOC2.  If the locations have no common ancestor (including if
192    they don't have the same repository root URL), set *ANCESTOR_P to NULL.
193 
194    If SESSION is not NULL, use it for retrieving the common ancestor instead
195    of creating a new session.
196 
197    Use the authentication baton cached in CTX to authenticate against
198    the repository.  Use POOL for all allocations.
199 
200    See also svn_client__calc_youngest_common_ancestor() to find youngest
201    common ancestor for already fetched history-as-mergeinfo information.
202 
203 */
204 svn_error_t *
205 svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
206                                          const svn_client__pathrev_t *loc1,
207                                          const svn_client__pathrev_t *loc2,
208                                          svn_ra_session_t *session,
209                                          svn_client_ctx_t *ctx,
210                                          apr_pool_t *result_pool,
211                                          apr_pool_t *scratch_pool);
212 
213 /* Find the common ancestor of two locations in a repository using already
214    fetched history-as-mergeinfo information.
215 
216    Ancestry is determined by the 'copy-from' relationship and the normal
217    successor relationship.
218 
219    Set *ANCESTOR_P to the location of the youngest common ancestor of
220    LOC1 and LOC2.  If the locations have no common ancestor (including if
221    they don't have the same repository root URL), set *ANCESTOR_P to NULL.
222 
223    HISTORY1, HAS_REV_ZERO_HISTORY1, HISTORY2, HAS_REV_ZERO_HISTORY2 are
224    history-as-mergeinfo information as returned by
225    svn_client__get_history_as_mergeinfo() for LOC1 and LOC2 respectively.
226 
227    See also svn_client__get_youngest_common_ancestor().
228 
229 */
230 svn_error_t *
231 svn_client__calc_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
232                                           const svn_client__pathrev_t *loc1,
233                                           apr_hash_t *history1,
234                                           svn_boolean_t has_rev_zero_history1,
235                                           const svn_client__pathrev_t *loc2,
236                                           apr_hash_t *history2,
237                                           svn_boolean_t has_rev_zero_history2,
238                                           apr_pool_t *result_pool,
239                                           apr_pool_t *scratch_pool);
240 
241 /* Ensure that RA_SESSION's session URL matches SESSION_URL,
242    reparenting that session if necessary.
243    Store the previous session URL in *OLD_SESSION_URL (so that if the
244    reparenting is meant to be temporary, the caller can reparent the
245    session back to where it was).
246 
247    If SESSION_URL is NULL, treat this as a magic value meaning "point
248    the RA session to the root of the repository".
249 
250    NOTE: The typical usage pattern for this functions is:
251 
252        const char *old_session_url;
253        SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
254                                                  ra_session,
255                                                  new_session_url,
256                                                  pool);
257 
258        [...]
259 
260        SVN_ERR(svn_ra_reparent(ra_session, old_session_url, pool));
261 */
262 svn_error_t *
263 svn_client__ensure_ra_session_url(const char **old_session_url,
264                                   svn_ra_session_t *ra_session,
265                                   const char *session_url,
266                                   apr_pool_t *pool);
267 
268 /* ---------------------------------------------------------------- */
269 
270 
271 /*** RA callbacks ***/
272 
273 
274 /* CTX is of type "svn_client_ctx_t *". */
275 #define SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx) \
276         ((ctx)->log_msg_func3 || (ctx)->log_msg_func2 || (ctx)->log_msg_func)
277 
278 /* Open an RA session, returning it in *RA_SESSION or a corrected URL
279    in *CORRECTED_URL.  (This function mirrors svn_ra_open4(), which
280    see, regarding the interpretation and handling of these two parameters.)
281 
282    The root of the session is specified by BASE_URL and BASE_DIR_ABSPATH.
283 
284    Additional control parameters:
285 
286       - COMMIT_ITEMS is an array of svn_client_commit_item_t *
287         structures, present only for working copy commits, NULL otherwise.
288 
289       - WRITE_DAV_PROPS indicates that the RA layer can clear and write
290         the DAV properties in the working copy of BASE_DIR_ABSPATH.
291 
292       - READ_DAV_PROPS indicates that the RA layer should not attempt to
293         modify the WC props directly, but is still allowed to read them.
294 
295    BASE_DIR_ABSPATH may be NULL if the RA operation does not correspond to a
296    working copy (in which case, WRITE_DAV_PROPS and READ_DAV_PROPS must be
297    FALSE.
298 
299    If WRITE_DAV_PROPS and READ_DAV_PROPS are both FALSE the working copy may
300    still be used for locating pristine files via their SHA1.
301 
302    The calling application's authentication baton is provided in CTX,
303    and allocations related to this session are performed in POOL.
304 
305    NOTE: The reason for the _internal suffix of this function's name is to
306    avoid confusion with the public API svn_client_open_ra_session(). */
307 svn_error_t *
308 svn_client__open_ra_session_internal(svn_ra_session_t **ra_session,
309                                      const char **corrected_url,
310                                      const char *base_url,
311                                      const char *base_dir_abspath,
312                                      const apr_array_header_t *commit_items,
313                                      svn_boolean_t write_dav_props,
314                                      svn_boolean_t read_dav_props,
315                                      svn_client_ctx_t *ctx,
316                                      apr_pool_t *result_pool,
317                                      apr_pool_t *scratch_pool);
318 
319 
320 svn_error_t *
321 svn_client__ra_provide_base(svn_stream_t **contents,
322                             svn_revnum_t *revision,
323                             void *baton,
324                             const char *repos_relpath,
325                             apr_pool_t *result_pool,
326                             apr_pool_t *scratch_pool);
327 
328 
329 svn_error_t *
330 svn_client__ra_provide_props(apr_hash_t **props,
331                              svn_revnum_t *revision,
332                              void *baton,
333                              const char *repos_relpath,
334                              apr_pool_t *result_pool,
335                              apr_pool_t *scratch_pool);
336 
337 
338 svn_error_t *
339 svn_client__ra_get_copysrc_kind(svn_node_kind_t *kind,
340                                 void *baton,
341                                 const char *repos_relpath,
342                                 svn_revnum_t src_revision,
343                                 apr_pool_t *scratch_pool);
344 
345 
346 void *
347 svn_client__ra_make_cb_baton(svn_wc_context_t *wc_ctx,
348                              apr_hash_t *relpath_map,
349                              apr_pool_t *result_pool);
350 
351 /* ---------------------------------------------------------------- */
352 
353 
354 /*** Add/delete ***/
355 
356 /* If AUTOPROPS is not null: Then read automatic properties matching PATH
357    from AUTOPROPS.  AUTOPROPS is is a hash as per
358    svn_client__get_all_auto_props.  Set *PROPERTIES to a hash containing
359    propname/value pairs (const char * keys mapping to svn_string_t * values).
360 
361    If AUTOPROPS is null then set *PROPERTIES to an empty hash.
362 
363    If *MIMETYPE is null or "application/octet-stream" then check AUTOPROPS
364    for a matching svn:mime-type.  If AUTOPROPS is null or no match is found
365    and MAGIC_COOKIE is not NULL, then then try to detect the mime-type with
366    libmagic.  If a mimetype is found then add it to *PROPERTIES and set
367    *MIMETYPE to the mimetype value or NULL otherwise.
368 
369    Allocate the *PROPERTIES and its contents as well as *MIMETYPE, in
370    RESULT_POOL.  Use SCRATCH_POOL for temporary allocations. */
371 svn_error_t *svn_client__get_paths_auto_props(
372   apr_hash_t **properties,
373   const char **mimetype,
374   const char *path,
375   svn_magic__cookie_t *magic_cookie,
376   apr_hash_t *autoprops,
377   svn_client_ctx_t *ctx,
378   apr_pool_t *result_pool,
379   apr_pool_t *scratch_pool);
380 
381 /* Gather all auto-props from CTX->config (or none if auto-props are
382    disabled) and all svn:auto-props explicitly set on or inherited
383    by PATH_OR_URL.
384 
385    If PATH_OR_URL is an unversioned WC path then gather the
386    svn:auto-props inherited by PATH_OR_URL's nearest versioned
387    parent.
388 
389    If PATH_OR_URL is a URL ask for the properties @HEAD, if it is a WC
390    path as sfor the working properties.
391 
392    Store both types of auto-props in *AUTOPROPS, a hash mapping const
393    char * file patterns to another hash which maps const char * property
394    names to const char *property values.
395 
396    If a given property name exists for the same pattern in both the config
397    file and in an a svn:auto-props property, the latter overrides the
398    former.  If a given property name exists for the same pattern in two
399    different inherited svn:auto-props, then the closer path-wise
400    property overrides the more distant. svn:auto-props explicitly set
401    on PATH_OR_URL have the highest precedence and override inherited props
402    and config file settings.
403 
404    Allocate *AUTOPROPS in RESULT_POOL.  Use SCRATCH_POOL for temporary
405    allocations. */
406 svn_error_t *svn_client__get_all_auto_props(apr_hash_t **autoprops,
407                                             const char *path_or_url,
408                                             svn_client_ctx_t *ctx,
409                                             apr_pool_t *result_pool,
410                                             apr_pool_t *scratch_pool);
411 
412 /* The main logic for client deletion from a working copy. Deletes PATH
413    from CTX->WC_CTX.  If PATH (or any item below a directory PATH) is
414    modified the delete will fail and return an error unless FORCE or KEEP_LOCAL
415    is TRUE.
416 
417    If KEEP_LOCAL is TRUE then PATH is only scheduled from deletion from the
418    repository and a local copy of PATH will be kept in the working copy.
419 
420    If DRY_RUN is TRUE all the checks are made to ensure that the delete can
421    occur, but the working copy is not modified.  If NOTIFY_FUNC is not
422    null, it is called with NOTIFY_BATON for each file or directory deleted. */
423 svn_error_t *
424 svn_client__wc_delete(const char *local_abspath,
425                       svn_boolean_t force,
426                       svn_boolean_t dry_run,
427                       svn_boolean_t keep_local,
428                       svn_wc_notify_func2_t notify_func,
429                       void *notify_baton,
430                       svn_client_ctx_t *ctx,
431                       apr_pool_t *pool);
432 
433 
434 /* Like svn_client__wc_delete(), but deletes multiple TARGETS efficiently. */
435 svn_error_t *
436 svn_client__wc_delete_many(const apr_array_header_t *targets,
437                            svn_boolean_t force,
438                            svn_boolean_t dry_run,
439                            svn_boolean_t keep_local,
440                            svn_wc_notify_func2_t notify_func,
441                            void *notify_baton,
442                            svn_client_ctx_t *ctx,
443                            apr_pool_t *pool);
444 
445 
446 /* Make LOCAL_ABSPATH and add it to the working copy, optionally making all
447    the intermediate parent directories if MAKE_PARENTS is TRUE. */
448 svn_error_t *
449 svn_client__make_local_parents(const char *local_abspath,
450                                svn_boolean_t make_parents,
451                                svn_client_ctx_t *ctx,
452                                apr_pool_t *pool);
453 
454 /* ---------------------------------------------------------------- */
455 
456 
457 /*** Checkout, update and switch ***/
458 
459 /* Update a working copy LOCAL_ABSPATH to REVISION, and (if not NULL) set
460    RESULT_REV to the update revision.
461 
462    If DEPTH is svn_depth_unknown, then use whatever depth is already
463    set for LOCAL_ABSPATH, or @c svn_depth_infinity if LOCAL_ABSPATH does
464    not exist.
465 
466    Else if DEPTH is svn_depth_infinity, then update fully recursively
467    (resetting the existing depth of the working copy if necessary).
468    Else if DEPTH is svn_depth_files, update all files under LOCAL_ABSPATH (if
469    any), but exclude any subdirectories.  Else if DEPTH is
470    svn_depth_immediates, update all files and include immediate
471    subdirectories (at svn_depth_empty).  Else if DEPTH is
472    svn_depth_empty, just update LOCAL_ABSPATH; if LOCAL_ABSPATH is a
473    directory, that means touching only its properties not its entries.
474 
475    If DEPTH_IS_STICKY is set and DEPTH is not svn_depth_unknown, then
476    in addition to updating LOCAL_ABSPATH, also set its sticky ambient depth
477    value to DEPTH.
478 
479    If IGNORE_EXTERNALS is true, do no externals processing.
480 
481    Set *TIMESTAMP_SLEEP to TRUE if a sleep is required; otherwise do not
482    change *TIMESTAMP_SLEEP.  The output will be valid even if the function
483    returns an error.
484 
485    If ALLOW_UNVER_OBSTRUCTIONS is TRUE, unversioned children of LOCAL_ABSPATH
486    that obstruct items added from the repos are tolerated; if FALSE,
487    these obstructions cause the update to fail.
488 
489    If ADDS_AS_MODIFICATION is TRUE, local additions are handled as
490    modifications on added nodes.
491 
492    If INNERUPDATE is true, no anchor check is performed on the update target.
493 
494    If MAKE_PARENTS is true, allow the update to calculate and checkout
495    (with depth=empty) any parent directories of the requested update
496    target which are missing from the working copy.
497 
498    If RA_SESSION is NOT NULL, it may be used to avoid creating a new
499    session. The session may point to a different URL after returning.
500 
501    NOTE:  You may not specify both INNERUPDATE and MAKE_PARENTS as true.
502 */
503 svn_error_t *
504 svn_client__update_internal(svn_revnum_t *result_rev,
505                             svn_boolean_t *timestamp_sleep,
506                             const char *local_abspath,
507                             const svn_opt_revision_t *revision,
508                             svn_depth_t depth,
509                             svn_boolean_t depth_is_sticky,
510                             svn_boolean_t ignore_externals,
511                             svn_boolean_t allow_unver_obstructions,
512                             svn_boolean_t adds_as_modification,
513                             svn_boolean_t make_parents,
514                             svn_boolean_t innerupdate,
515                             svn_ra_session_t *ra_session,
516                             svn_client_ctx_t *ctx,
517                             apr_pool_t *pool);
518 
519 /* Checkout into LOCAL_ABSPATH a working copy of URL at REVISION, and (if not
520    NULL) set RESULT_REV to the checked out revision.
521 
522    If DEPTH is svn_depth_infinity, then check out fully recursively.
523    Else if DEPTH is svn_depth_files, checkout all files under LOCAL_ABSPATH (if
524    any), but not subdirectories.  Else if DEPTH is
525    svn_depth_immediates, check out all files and include immediate
526    subdirectories (at svn_depth_empty).  Else if DEPTH is
527    svn_depth_empty, just check out LOCAL_ABSPATH, with none of its entries.
528 
529    DEPTH must be a definite depth, not (e.g.) svn_depth_unknown.
530 
531    If IGNORE_EXTERNALS is true, do no externals processing.
532 
533    Set *TIMESTAMP_SLEEP to TRUE if a sleep is required; otherwise do not
534    change *TIMESTAMP_SLEEP.  The output will be valid even if the function
535    returns an error.
536 
537    If ALLOW_UNVER_OBSTRUCTIONS is TRUE,
538    unversioned children of LOCAL_ABSPATH that obstruct items added from
539    the repos are tolerated; if FALSE, these obstructions cause the checkout
540    to fail.
541 
542    If RA_SESSION is NOT NULL, it may be used to avoid creating a new
543    session. The session may point to a different URL after returning.
544    */
545 svn_error_t *
546 svn_client__checkout_internal(svn_revnum_t *result_rev,
547                               svn_boolean_t *timestamp_sleep,
548                               const char *URL,
549                               const char *local_abspath,
550                               const svn_opt_revision_t *peg_revision,
551                               const svn_opt_revision_t *revision,
552                               svn_depth_t depth,
553                               svn_boolean_t ignore_externals,
554                               svn_boolean_t allow_unver_obstructions,
555                               svn_ra_session_t *ra_session,
556                               svn_client_ctx_t *ctx,
557                               apr_pool_t *pool);
558 
559 /* Switch a working copy PATH to URL@PEG_REVISION at REVISION, and (if not
560    NULL) set RESULT_REV to the switch revision. A write lock will be
561    acquired and released if not held. Only switch as deeply as DEPTH
562    indicates.
563 
564    Set *TIMESTAMP_SLEEP to TRUE if a sleep is required; otherwise do not
565    change *TIMESTAMP_SLEEP.  The output will be valid even if the function
566    returns an error.
567 
568    If IGNORE_EXTERNALS is true, don't process externals.
569 
570    If ALLOW_UNVER_OBSTRUCTIONS is TRUE, unversioned children of PATH
571    that obstruct items added from the repos are tolerated; if FALSE,
572    these obstructions cause the switch to fail.
573 
574    DEPTH and DEPTH_IS_STICKY behave as for svn_client__update_internal().
575 
576    If IGNORE_ANCESTRY is true, don't perform a common ancestry check
577    between the PATH and URL; otherwise, do, and return
578    SVN_ERR_CLIENT_UNRELATED_RESOURCES if they aren't related.
579 */
580 svn_error_t *
581 svn_client__switch_internal(svn_revnum_t *result_rev,
582                             const char *path,
583                             const char *url,
584                             const svn_opt_revision_t *peg_revision,
585                             const svn_opt_revision_t *revision,
586                             svn_depth_t depth,
587                             svn_boolean_t depth_is_sticky,
588                             svn_boolean_t ignore_externals,
589                             svn_boolean_t allow_unver_obstructions,
590                             svn_boolean_t ignore_ancestry,
591                             svn_boolean_t *timestamp_sleep,
592                             svn_client_ctx_t *ctx,
593                             apr_pool_t *pool);
594 
595 /* ---------------------------------------------------------------- */
596 
597 
598 /*** Inheritable Properties ***/
599 
600 /* Convert any svn_prop_inherited_item_t elements in INHERITED_PROPS which
601    have repository root relative path PATH_OR_URL structure members to URLs
602    using REPOS_ROOT_URL.  Changes to the contents of INHERITED_PROPS are
603    allocated in RESULT_POOL.  SCRATCH_POOL is used for temporary
604    allocations. */
605 svn_error_t *
606 svn_client__iprop_relpaths_to_urls(apr_array_header_t *inherited_props,
607                                    const char *repos_root_url,
608                                    apr_pool_t *result_pool,
609                                    apr_pool_t *scratch_pool);
610 
611 /* Fetch the inherited properties for the base of LOCAL_ABSPATH as well
612    as any WC roots under LOCAL_ABSPATH (as limited by DEPTH) using
613    RA_SESSION.  Store the results in *WCROOT_IPROPS, a hash mapping
614    const char * absolute working copy paths to depth-first ordered arrays
615    of svn_prop_inherited_item_t * structures.
616 
617    Any svn_prop_inherited_item_t->path_or_url members returned in
618    *WCROOT_IPROPS are repository relative paths.
619 
620    If LOCAL_ABSPATH has no base then do nothing.
621 
622    RA_SESSION should be an open RA session pointing at the URL of PATH,
623    or NULL, in which case this function will use its own temporary session.
624 
625    Allocate *WCROOT_IPROPS in RESULT_POOL, use SCRATCH_POOL for temporary
626    allocations.
627 
628    If one or more of the paths are not available in the repository at the
629    specified revision, these paths will not be added to the hashtable.
630 */
631 svn_error_t *
632 svn_client__get_inheritable_props(apr_hash_t **wcroot_iprops,
633                                   const char *local_abspath,
634                                   svn_revnum_t revision,
635                                   svn_depth_t depth,
636                                   svn_ra_session_t *ra_session,
637                                   svn_client_ctx_t *ctx,
638                                   apr_pool_t *result_pool,
639                                   apr_pool_t *scratch_pool);
640 
641 /* ---------------------------------------------------------------- */
642 
643 
644 /*** Editor for repository diff ***/
645 
646 /* Create an editor for a pure repository comparison, i.e. comparing one
647    repository version against the other.
648 
649    DIFF_CALLBACKS/DIFF_CMD_BATON represent the callback that implements
650    the comparison.
651 
652    DEPTH is the depth to recurse.
653 
654    RA_SESSION is an RA session through which this editor may fetch
655    properties, file contents and directory listings of the 'old' side of the
656    diff. It is a separate RA session from the one through which this editor
657    is being driven. REVISION is the revision number of the 'old' side of
658    the diff.
659 
660    If TEXT_DELTAS is FALSE, then do not expect text deltas from the edit
661    drive, nor send the 'before' and 'after' texts to the diff callbacks;
662    instead, send empty files to the diff callbacks if there was a change.
663    This must be FALSE if the edit producer is not sending text deltas,
664    otherwise the file content checksum comparisons will fail.
665 
666    EDITOR/EDIT_BATON return the newly created editor and baton.
667 
668    @since New in 1.8.
669    */
670 svn_error_t *
671 svn_client__get_diff_editor2(const svn_delta_editor_t **editor,
672                              void **edit_baton,
673                              svn_ra_session_t *ra_session,
674                              svn_depth_t depth,
675                              svn_revnum_t revision,
676                              svn_boolean_t text_deltas,
677                              const svn_diff_tree_processor_t *processor,
678                              svn_cancel_func_t cancel_func,
679                              void *cancel_baton,
680                              apr_pool_t *result_pool);
681 
682 /* ---------------------------------------------------------------- */
683 
684 
685 /*** Copy Stuff ***/
686 
687 /* This structure is used to associate a specific copy or move SRC with a
688    specific copy or move destination.  It also contains information which
689    various helper functions may need.  Not every copy function uses every
690    field.
691 */
692 typedef struct svn_client__copy_pair_t
693 {
694     /* The absolute source path or url. */
695     const char *src_abspath_or_url;
696 
697     /* The base name of the object.  It should be the same for both src
698        and dst. */
699     const char *base_name;
700 
701     /* The node kind of the source */
702     svn_node_kind_t src_kind;
703 
704     /* The original source name.  (Used when the source gets overwritten by a
705        peg revision lookup.) */
706     const char *src_original;
707 
708     /* The source operational revision. */
709     svn_opt_revision_t src_op_revision;
710 
711     /* The source peg revision. */
712     svn_opt_revision_t src_peg_revision;
713 
714     /* The source revision number. */
715     svn_revnum_t src_revnum;
716 
717     /* The absolute destination path or url */
718     const char *dst_abspath_or_url;
719 
720     /* The absolute source path or url of the destination's parent. */
721     const char *dst_parent_abspath;
722 } svn_client__copy_pair_t;
723 
724 /* ---------------------------------------------------------------- */
725 
726 
727 /*** Commit Stuff ***/
728 
729 /* The "Harvest Committables" System
730 
731    The commit process requires, per repository, a single drive of a
732    commit editor which is based not on working copy paths, but on
733    URLs.  The on-disk working copy hierarchy does not, in general,
734    map to a similar in-repository hierarchy, due to switched subtrees
735    and disjoint working copies.
736 
737    Also we wish to know exactly what would be committed, in advance of
738    the commit, so that a log message editor can be initially populated
739    with this information.
740 
741    The primary goal of this system is very straightforward: harvest
742    all commit candidate information up front, and cache enough info in
743    the process to use this to drive a URL-sorted commit.
744 
745    The idea is that commit-y processes ('svn mkdir URL', 'svn delete URL',
746    'svn commit', 'svn copy WC_PATH URL', 'svn copy URL1 URL2', 'svn
747    move URL1 URL2', others?) generate the cached commit candidate
748    information, and hand this information off to a consumer which is
749    responsible for driving the RA layer's commit editor in a
750    URL-depth-first fashion and reporting back the post-commit
751    information.
752 
753 */
754 
755 /* Structure that contains an apr_hash_t * hash of apr_array_header_t *
756    arrays of svn_client_commit_item3_t * structures; keyed by the
757    canonical repository URLs. For faster lookup, it also provides
758    an hash index keyed by the local absolute path. */
759 typedef struct svn_client__committables_t
760 {
761   /* apr_array_header_t array of svn_client_commit_item3_t structures
762      keyed by canonical repository URL */
763   apr_hash_t *by_repository;
764 
765   /* svn_client_commit_item3_t structures keyed by local absolute path
766      (path member in the respective structures).
767 
768      This member is for fast lookup only, i.e. whether there is an
769      entry for the given path or not, but it will only allow for one
770      entry per absolute path (in case of duplicate entries in the
771      above arrays). The "canonical" data storage containing all item
772      is by_repository. */
773   apr_hash_t *by_path;
774 
775 } svn_client__committables_t;
776 
777 /* Callback for the commit harvester to check if a node exists at the specified
778    url */
779 typedef svn_error_t *(*svn_client__check_url_kind_t)(void *baton,
780                                                      svn_node_kind_t *kind,
781                                                      const char *url,
782                                                      svn_revnum_t revision,
783                                                      apr_pool_t *scratch_pool);
784 
785 /* Recursively crawl a set of working copy paths (BASE_DIR_ABSPATH + each
786    item in the TARGETS array) looking for commit candidates, locking
787    working copy directories as the crawl progresses.  For each
788    candidate found:
789 
790      - create svn_client_commit_item3_t for the candidate.
791 
792      - add the structure to an apr_array_header_t array of commit
793        items that are in the same repository, creating a new array if
794        necessary.
795 
796      - add (or update) a reference to this array to the by_repository
797        hash within COMMITTABLES and update the by_path member as well-
798 
799      - if the candidate has a lock token, add it to the LOCK_TOKENS hash.
800 
801      - if the candidate is a directory scheduled for deletion, crawl
802        the directory's children recursively for any lock tokens and
803        add them to the LOCK_TOKENS array.
804 
805    At the successful return of this function, COMMITTABLES will point
806    a new svn_client__committables_t*.  LOCK_TOKENS will point to a hash
807    table with const char * lock tokens, keyed on const char * URLs.
808 
809    If DEPTH is specified, descend (or not) into each target in TARGETS
810    as specified by DEPTH; the behavior is the same as that described
811    for svn_client_commit4().
812 
813    If DEPTH_EMPTY_START is >= 0, all targets after index DEPTH_EMPTY_START
814    in TARGETS are handled as having svn_depth_empty.
815 
816    If JUST_LOCKED is TRUE, treat unmodified items with lock tokens as
817    commit candidates.
818 
819    If CHANGELISTS is non-NULL, it is an array of const char *
820    changelist names used as a restrictive filter
821    when harvesting committables; that is, don't add a path to
822    COMMITTABLES unless it's a member of one of those changelists.
823 
824    If CTX->CANCEL_FUNC is non-null, it will be called with
825    CTX->CANCEL_BATON while harvesting to determine if the client has
826    cancelled the operation. */
827 svn_error_t *
828 svn_client__harvest_committables(svn_client__committables_t **committables,
829                                  apr_hash_t **lock_tokens,
830                                  const char *base_dir_abspath,
831                                  const apr_array_header_t *targets,
832                                  int depth_empty_start,
833                                  svn_depth_t depth,
834                                  svn_boolean_t just_locked,
835                                  const apr_array_header_t *changelists,
836                                  svn_client__check_url_kind_t check_url_func,
837                                  void *check_url_baton,
838                                  svn_client_ctx_t *ctx,
839                                  apr_pool_t *result_pool,
840                                  apr_pool_t *scratch_pool);
841 
842 
843 /* Recursively crawl each absolute working copy path SRC in COPY_PAIRS,
844    harvesting commit_items into a COMMITABLES structure as if every entry
845    at or below the SRC was to be committed as a set of adds (mostly with
846    history) to a new repository URL (DST in COPY_PAIRS).
847 
848    If CTX->CANCEL_FUNC is non-null, it will be called with
849    CTX->CANCEL_BATON while harvesting to determine if the client has
850    cancelled the operation.  */
851 svn_error_t *
852 svn_client__get_copy_committables(svn_client__committables_t **committables,
853                                   const apr_array_header_t *copy_pairs,
854                                   svn_client__check_url_kind_t check_url_func,
855                                   void *check_url_baton,
856                                   svn_client_ctx_t *ctx,
857                                   apr_pool_t *result_pool,
858                                   apr_pool_t *scratch_pool);
859 
860 /* Rewrite the COMMIT_ITEMS array to be sorted by URL.  Also, discover
861    a common *BASE_URL for the items in the array, and rewrite those
862    items' URLs to be relative to that *BASE_URL.
863 
864    COMMIT_ITEMS is an array of (svn_client_commit_item3_t *) items.
865 
866    Afterwards, some of the items in COMMIT_ITEMS may contain data
867    allocated in POOL. */
868 svn_error_t *
869 svn_client__condense_commit_items(const char **base_url,
870                                   apr_array_header_t *commit_items,
871                                   apr_pool_t *pool);
872 
873 /* Rewrite the COMMIT_ITEMS array to be sorted by URL.
874    Rewrite the items' URLs to be relative to BASE_URL.
875 
876    COMMIT_ITEMS is an array of (svn_client_commit_item3_t *) items.
877 
878    Afterwards, some of the items in COMMIT_ITEMS may contain data
879    allocated in POOL. */
880 svn_error_t *
881 svn_client__condense_commit_items2(const char *base_url,
882                                    apr_array_header_t *commit_items,
883                                    apr_pool_t *pool);
884 
885 /* Commit the items in the COMMIT_ITEMS array using EDITOR/EDIT_BATON
886    to describe the committed local mods.  Prior to this call,
887    COMMIT_ITEMS should have been run through (and BASE_URL generated
888    by) svn_client__condense_commit_items().
889 
890    COMMIT_ITEMS is an array of (svn_client_commit_item3_t *) items.
891 
892    CTX->NOTIFY_FUNC/CTX->BATON will be called as the commit progresses, as
893    a way of describing actions to the application layer (if non NULL).
894 
895    NOTIFY_PATH_PREFIX will be passed to CTX->notify_func2() as the
896    common absolute path prefix of the committed paths.  It can be NULL.
897 
898    If SHA1_CHECKSUMS is not NULL, set *SHA1_CHECKSUMS to a hash containing,
899    for each file transmitted, a mapping from the commit-item's (const
900    char *) path to the (const svn_checksum_t *) SHA1 checksum of its new text
901    base.
902 
903    Use RESULT_POOL for all allocating the resulting hashes and SCRATCH_POOL
904    for temporary allocations.
905    */
906 svn_error_t *
907 svn_client__do_commit(const char *base_url,
908                       const apr_array_header_t *commit_items,
909                       const svn_delta_editor_t *editor,
910                       void *edit_baton,
911                       const char *notify_path_prefix,
912                       apr_hash_t **sha1_checksums,
913                       svn_client_ctx_t *ctx,
914                       apr_pool_t *result_pool,
915                       apr_pool_t *scratch_pool);
916 
917 
918 
919 
920 /*** Externals (Modules) ***/
921 
922 /* Handle changes to the svn:externals property described by EXTERNALS_NEW,
923    and AMBIENT_DEPTHS.  The tree's top level directory
924    is at TARGET_ABSPATH which has a root URL of REPOS_ROOT_URL.
925    A write lock should be held.
926 
927    For each changed value of the property, discover the nature of the
928    change and behave appropriately -- either check a new "external"
929    subdir, or call svn_wc_remove_from_revision_control() on an
930    existing one, or both.
931 
932    TARGET_ABSPATH is the root of the driving operation and
933    REQUESTED_DEPTH is the requested depth of the driving operation
934    (e.g., update, switch, etc).  If it is neither svn_depth_infinity
935    nor svn_depth_unknown, then changes to svn:externals will have no
936    effect.  If REQUESTED_DEPTH is svn_depth_unknown, then the ambient
937    depth of each working copy directory holding an svn:externals value
938    will determine whether that value is interpreted there (the ambient
939    depth must be svn_depth_infinity).  If REQUESTED_DEPTH is
940    svn_depth_infinity, then it is presumed to be expanding any
941    shallower ambient depth, so changes to svn:externals values will be
942    interpreted.
943 
944    Pass NOTIFY_FUNC with NOTIFY_BATON along to svn_client_checkout().
945 
946    Set *TIMESTAMP_SLEEP to TRUE if a sleep is required; otherwise do not
947    change *TIMESTAMP_SLEEP.  The output will be valid even if the function
948    returns an error.
949 
950    If RA_SESSION is NOT NULL, it may be used to avoid creating a new
951    session. The session may point to a different URL after returning.
952 
953    Use POOL for temporary allocation. */
954 svn_error_t *
955 svn_client__handle_externals(apr_hash_t *externals_new,
956                              apr_hash_t *ambient_depths,
957                              const char *repos_root_url,
958                              const char *target_abspath,
959                              svn_depth_t requested_depth,
960                              svn_boolean_t *timestamp_sleep,
961                              svn_ra_session_t *ra_session,
962                              svn_client_ctx_t *ctx,
963                              apr_pool_t *pool);
964 
965 
966 /* Export externals definitions described by EXTERNALS, a hash of the
967    form returned by svn_wc_edited_externals() (which see). The external
968    items will be exported instead of checked out -- they will have no
969    administrative subdirectories.
970 
971    The checked out or exported tree's top level directory is at
972    TO_ABSPATH and corresponds to FROM_URL URL in the repository, which
973    has a root URL of REPOS_ROOT_URL.
974 
975    REQUESTED_DEPTH is the requested_depth of the driving operation; it
976    behaves as for svn_client__handle_externals(), except that ambient
977    depths are presumed to be svn_depth_infinity.
978 
979    NATIVE_EOL is the value passed as NATIVE_EOL when exporting.
980 
981    Use POOL for temporary allocation. */
982 svn_error_t *
983 svn_client__export_externals(apr_hash_t *externals,
984                              const char *from_url,
985                              const char *to_abspath,
986                              const char *repos_root_url,
987                              svn_depth_t requested_depth,
988                              const char *native_eol,
989                              svn_boolean_t ignore_keywords,
990                              svn_client_ctx_t *ctx,
991                              apr_pool_t *pool);
992 
993 /* Baton for svn_client__dirent_fetcher */
994 struct svn_client__dirent_fetcher_baton_t
995 {
996   svn_ra_session_t *ra_session;
997   svn_revnum_t target_revision;
998   const char *anchor_url;
999 };
1000 
1001 /* Implements svn_wc_dirents_func_t for update and switch handling. Assumes
1002    a struct svn_client__dirent_fetcher_baton_t * baton */
1003 svn_error_t *
1004 svn_client__dirent_fetcher(void *baton,
1005                            apr_hash_t **dirents,
1006                            const char *repos_root_url,
1007                            const char *repos_relpath,
1008                            apr_pool_t *result_pool,
1009                            apr_pool_t *scratch_pool);
1010 
1011 /* Retrieve log messages using the first provided (non-NULL) callback
1012    in the set of *CTX->log_msg_func3, CTX->log_msg_func2, or
1013    CTX->log_msg_func.  Other arguments same as
1014    svn_client_get_commit_log3_t. */
1015 svn_error_t *
1016 svn_client__get_log_msg(const char **log_msg,
1017                         const char **tmp_file,
1018                         const apr_array_header_t *commit_items,
1019                         svn_client_ctx_t *ctx,
1020                         apr_pool_t *pool);
1021 
1022 /* Return the revision properties stored in REVPROP_TABLE_IN, adding
1023    LOG_MSG as SVN_PROP_REVISION_LOG in *REVPROP_TABLE_OUT, allocated in
1024    POOL.  *REVPROP_TABLE_OUT will map const char * property names to
1025    svn_string_t values.  If REVPROP_TABLE_IN is non-NULL, check that
1026    it doesn't contain any of the standard Subversion properties.  In
1027    that case, return SVN_ERR_CLIENT_PROPERTY_NAME. */
1028 svn_error_t *
1029 svn_client__ensure_revprop_table(apr_hash_t **revprop_table_out,
1030                                  const apr_hash_t *revprop_table_in,
1031                                  const char *log_msg,
1032                                  svn_client_ctx_t *ctx,
1033                                  apr_pool_t *pool);
1034 
1035 /* Return a potentially translated version of local file LOCAL_ABSPATH
1036    in NORMAL_STREAM.  REVISION must be one of the following: BASE, COMMITTED,
1037    WORKING.
1038 
1039    EXPAND_KEYWORDS operates as per the EXPAND argument to
1040    svn_subst_stream_translated, which see.  If NORMALIZE_EOLS is TRUE and
1041    LOCAL_ABSPATH requires translation, then normalize the line endings in
1042    *NORMAL_STREAM to "\n" if the stream has svn:eol-style set.
1043 
1044    Note that this IS NOT the repository normal form of the stream as that
1045    would use "\r\n" if set to CRLF and "\r" if set to CR.
1046 
1047    The stream is allocated in RESULT_POOL and temporary SCRATCH_POOL is
1048    used for temporary allocations. */
1049 svn_error_t *
1050 svn_client__get_normalized_stream(svn_stream_t **normal_stream,
1051                                   svn_wc_context_t *wc_ctx,
1052                                   const char *local_abspath,
1053                                   const svn_opt_revision_t *revision,
1054                                   svn_boolean_t expand_keywords,
1055                                   svn_boolean_t normalize_eols,
1056                                   svn_cancel_func_t cancel_func,
1057                                   void *cancel_baton,
1058                                   apr_pool_t *result_pool,
1059                                   apr_pool_t *scratch_pool);
1060 
1061 /* Return a set of callbacks to use with the Ev2 shims. */
1062 svn_delta_shim_callbacks_t *
1063 svn_client__get_shim_callbacks(svn_wc_context_t *wc_ctx,
1064                                apr_hash_t *relpath_map,
1065                                apr_pool_t *result_pool);
1066 
1067 /* Return REVISION unless its kind is 'unspecified' in which case return
1068  * a pointer to a statically allocated revision structure of kind 'head'
1069  * if PATH_OR_URL is a URL or 'base' if it is a WC path. */
1070 const svn_opt_revision_t *
1071 svn_cl__rev_default_to_head_or_base(const svn_opt_revision_t *revision,
1072                                     const char *path_or_url);
1073 
1074 /* Return REVISION unless its kind is 'unspecified' in which case return
1075  * a pointer to a statically allocated revision structure of kind 'head'
1076  * if PATH_OR_URL is a URL or 'working' if it is a WC path. */
1077 const svn_opt_revision_t *
1078 svn_cl__rev_default_to_head_or_working(const svn_opt_revision_t *revision,
1079                                        const char *path_or_url);
1080 
1081 /* Return REVISION unless its kind is 'unspecified' in which case return
1082  * PEG_REVISION. */
1083 const svn_opt_revision_t *
1084 svn_cl__rev_default_to_peg(const svn_opt_revision_t *revision,
1085                            const svn_opt_revision_t *peg_revision);
1086 
1087 /* Call the conflict resolver callback in CTX for each conflict recorded
1088  * in CONFLICTED_PATHS (const char *abspath keys; ignored values).  If
1089  * CONFLICTS_REMAIN is not NULL, then set *CONFLICTS_REMAIN to true if
1090  * there are any conflicts among CONFLICTED_PATHS remaining unresolved
1091  * at the end of this operation, else set it to false.
1092  */
1093 svn_error_t *
1094 svn_client__resolve_conflicts(svn_boolean_t *conflicts_remain,
1095                               apr_hash_t *conflicted_paths,
1096                               svn_client_ctx_t *ctx,
1097                               apr_pool_t *scratch_pool);
1098 
1099 /* Produce a diff with depth DEPTH between the file or directory at
1100  * LEFT_ABSPATH and the file or directory at RIGHT_ABSPATH, reporting
1101  * differences to DIFF_PROCESSOR.
1102  *
1103  * The files and directories involved may be part of a working copy or
1104  * they may be unversioned. For versioned files, show property changes,
1105  * too.
1106  *
1107  * No copy or move information is reported to the diff processor.
1108  *
1109  * Anchor the DIFF_PROCESSOR at the requested diff targets (LEFT_ABSPATH,
1110  * RIGHT_ABSPATH). As any children reached by recursion are matched by
1111  * name, a diff processor relpath applies equally to both sides of the diff.
1112  */
1113 svn_error_t *
1114 svn_client__arbitrary_nodes_diff(const char *left_abspath,
1115                                  const char *right_abspath,
1116                                  svn_depth_t depth,
1117                                  const svn_diff_tree_processor_t *diff_processor,
1118                                  svn_client_ctx_t *ctx,
1119                                  apr_pool_t *scratch_pool);
1120 
1121 
1122 /* Helper for the remote case of svn_client_propget.
1123  *
1124  * If PROPS is not null, then get the value of property PROPNAME in
1125  * REVNUM, using RA_SESSION.  Store the value ('svn_string_t *') in
1126  * PROPS, under the path key "TARGET_PREFIX/TARGET_RELATIVE"
1127  * ('const char *').
1128  *
1129  * If INHERITED_PROPS is not null, then set *INHERITED_PROPS to a
1130  * depth-first ordered array of svn_prop_inherited_item_t * structures
1131  * representing the PROPNAME properties inherited by the target.  If
1132  * INHERITABLE_PROPS in not null and no inheritable properties are found,
1133  * then set *INHERITED_PROPS to an empty array.
1134  *
1135  * Recurse according to DEPTH, similarly to svn_client_propget3().
1136  *
1137  * KIND is the kind of the node at "TARGET_PREFIX/TARGET_RELATIVE".
1138  * Yes, caller passes this; it makes the recursion more efficient :-).
1139  *
1140  * Allocate PROPS and *INHERITED_PROPS in RESULT_POOL, but do all temporary
1141  * work in SCRATCH_POOL.  The two pools can be the same; recursive
1142  * calls may use a different SCRATCH_POOL, however.
1143  */
1144 svn_error_t *
1145 svn_client__remote_propget(apr_hash_t *props,
1146                            apr_array_header_t **inherited_props,
1147                            const char *propname,
1148                            const char *target_prefix,
1149                            const char *target_relative,
1150                            svn_node_kind_t kind,
1151                            svn_revnum_t revnum,
1152                            svn_ra_session_t *ra_session,
1153                            svn_depth_t depth,
1154                            apr_pool_t *result_pool,
1155                            apr_pool_t *scratch_pool);
1156 
1157 /* */
1158 typedef struct merge_source_t
1159 {
1160   /* "left" side URL and revision (inclusive iff youngest) */
1161   const svn_client__pathrev_t *loc1;
1162 
1163   /* "right" side URL and revision (inclusive iff youngest) */
1164   const svn_client__pathrev_t *loc2;
1165 
1166   /* True iff LOC1 is an ancestor of LOC2 or vice-versa (history-wise). */
1167   svn_boolean_t ancestral;
1168 } merge_source_t;
1169 
1170 /* Description of the merge target root node (a WC working node) */
1171 typedef struct merge_target_t
1172 {
1173   /* Absolute path to the WC node */
1174   const char *abspath;
1175 
1176   /* The repository location of the base node of the target WC.  If the node
1177    * is locally added, then URL & REV are NULL & SVN_INVALID_REVNUM.
1178    * REPOS_ROOT_URL and REPOS_UUID are always valid. */
1179   svn_client__pathrev_t loc;
1180 
1181 } merge_target_t;
1182 
1183 /*
1184  * Similar API to svn_client_merge_peg5().
1185  */
1186 svn_error_t *
1187 svn_client__merge_elements(svn_boolean_t *use_sleep,
1188                            apr_array_header_t *merge_sources,
1189                            merge_target_t *target,
1190                            svn_ra_session_t *ra_session,
1191                            svn_boolean_t diff_ignore_ancestry,
1192                            svn_boolean_t force_delete,
1193                            svn_boolean_t dry_run,
1194                            const apr_array_header_t *merge_options,
1195                            svn_client_ctx_t *ctx,
1196                            apr_pool_t *result_pool,
1197                            apr_pool_t *scratch_pool);
1198 
1199 /* Data for reporting when a merge aborted because of raising conflicts.
1200  *
1201  * ### TODO: More info, including the ranges (or other parameters) the user
1202  *     needs to complete the merge.
1203  */
1204 typedef struct svn_client__conflict_report_t
1205 {
1206   const char *target_abspath;
1207   /* The revision range during which conflicts were raised */
1208   const merge_source_t *conflicted_range;
1209   /* Was the conflicted range the last range in the whole requested merge? */
1210   svn_boolean_t was_last_range;
1211 } svn_client__conflict_report_t;
1212 
1213 /* Create and return an error structure appropriate for the unmerged
1214    revisions range(s). */
1215 svn_error_t *
1216 svn_client__make_merge_conflict_error(svn_client__conflict_report_t *report,
1217                                       apr_pool_t *scratch_pool);
1218 
1219 /* The body of svn_client_merge5(), which see for details. */
1220 svn_error_t *
1221 svn_client__merge_locked(svn_client__conflict_report_t **conflict_report,
1222                          const char *source1,
1223                          const svn_opt_revision_t *revision1,
1224                          const char *source2,
1225                          const svn_opt_revision_t *revision2,
1226                          const char *target_abspath,
1227                          svn_depth_t depth,
1228                          svn_boolean_t ignore_mergeinfo,
1229                          svn_boolean_t diff_ignore_ancestry,
1230                          svn_boolean_t force_delete,
1231                          svn_boolean_t record_only,
1232                          svn_boolean_t dry_run,
1233                          svn_boolean_t allow_mixed_rev,
1234                          const apr_array_header_t *merge_options,
1235                          svn_client_ctx_t *ctx,
1236                          apr_pool_t *result_pool,
1237                          apr_pool_t *scratch_pool);
1238 
1239 #ifdef __cplusplus
1240 }
1241 #endif /* __cplusplus */
1242 
1243 #endif /* SVN_LIBSVN_CLIENT_H */
1244