xref: /freebsd-13-stable/contrib/subversion/subversion/libsvn_client/deprecated.c (revision b7ec5dea64b6513b41316a38cc72efa9139bc4ae)
1 /*
2  * deprecated.c:  holding file for all deprecated APIs.
3  *                "we can't lose 'em, but we can shun 'em!"
4  *
5  * ====================================================================
6  *    Licensed to the Apache Software Foundation (ASF) under one
7  *    or more contributor license agreements.  See the NOTICE file
8  *    distributed with this work for additional information
9  *    regarding copyright ownership.  The ASF licenses this file
10  *    to you under the Apache License, Version 2.0 (the
11  *    "License"); you may not use this file except in compliance
12  *    with the License.  You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  *    Unless required by applicable law or agreed to in writing,
17  *    software distributed under the License is distributed on an
18  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19  *    KIND, either express or implied.  See the License for the
20  *    specific language governing permissions and limitations
21  *    under the License.
22  * ====================================================================
23  */
24 
25 /* ==================================================================== */
26 
27 
28 
29 /*** Includes. ***/
30 
31 /* We define this here to remove any further warnings about the usage of
32    deprecated functions in this file. */
33 #define SVN_DEPRECATED
34 
35 #include <string.h>
36 #include "svn_client.h"
37 #include "svn_path.h"
38 #include "svn_compat.h"
39 #include "svn_hash.h"
40 #include "svn_props.h"
41 #include "svn_utf.h"
42 #include "svn_string.h"
43 #include "svn_pools.h"
44 
45 #include "client.h"
46 #include "mergeinfo.h"
47 
48 #include "private/svn_opt_private.h"
49 #include "private/svn_wc_private.h"
50 #include "svn_private_config.h"
51 
52 
53 
54 
55 /*** Code. ***/
56 
57 
58 /* Baton for capture_commit_info() */
59 struct capture_baton_t {
60   svn_commit_info_t **info;
61   apr_pool_t *pool;
62 };
63 
64 
65 /* Callback which implements svn_commit_callback2_t for use with some
66    backward compat functions. */
67 static svn_error_t *
capture_commit_info(const svn_commit_info_t * commit_info,void * baton,apr_pool_t * pool)68 capture_commit_info(const svn_commit_info_t *commit_info,
69                     void *baton,
70                     apr_pool_t *pool)
71 {
72   struct capture_baton_t *cb = baton;
73 
74   *(cb->info) = svn_commit_info_dup(commit_info, cb->pool);
75 
76   return SVN_NO_ERROR;
77 }
78 
79 
80 /*** From add.c ***/
81 svn_error_t *
svn_client_add4(const char * path,svn_depth_t depth,svn_boolean_t force,svn_boolean_t no_ignore,svn_boolean_t add_parents,svn_client_ctx_t * ctx,apr_pool_t * pool)82 svn_client_add4(const char *path,
83                 svn_depth_t depth,
84                 svn_boolean_t force,
85                 svn_boolean_t no_ignore,
86                 svn_boolean_t add_parents,
87                 svn_client_ctx_t *ctx,
88                 apr_pool_t *pool)
89 {
90   return svn_client_add5(path, depth, force, no_ignore, FALSE, add_parents,
91                          ctx, pool);
92 }
93 
94 svn_error_t *
svn_client_add3(const char * path,svn_boolean_t recursive,svn_boolean_t force,svn_boolean_t no_ignore,svn_client_ctx_t * ctx,apr_pool_t * pool)95 svn_client_add3(const char *path,
96                 svn_boolean_t recursive,
97                 svn_boolean_t force,
98                 svn_boolean_t no_ignore,
99                 svn_client_ctx_t *ctx,
100                 apr_pool_t *pool)
101 {
102   return svn_client_add4(path, SVN_DEPTH_INFINITY_OR_EMPTY(recursive),
103                          force, no_ignore, FALSE, ctx,
104                          pool);
105 }
106 
107 svn_error_t *
svn_client_add2(const char * path,svn_boolean_t recursive,svn_boolean_t force,svn_client_ctx_t * ctx,apr_pool_t * pool)108 svn_client_add2(const char *path,
109                 svn_boolean_t recursive,
110                 svn_boolean_t force,
111                 svn_client_ctx_t *ctx,
112                 apr_pool_t *pool)
113 {
114   return svn_client_add3(path, recursive, force, FALSE, ctx, pool);
115 }
116 
117 svn_error_t *
svn_client_add(const char * path,svn_boolean_t recursive,svn_client_ctx_t * ctx,apr_pool_t * pool)118 svn_client_add(const char *path,
119                svn_boolean_t recursive,
120                svn_client_ctx_t *ctx,
121                apr_pool_t *pool)
122 {
123   return svn_client_add3(path, recursive, FALSE, FALSE, ctx, pool);
124 }
125 
126 svn_error_t *
svn_client_mkdir3(svn_commit_info_t ** commit_info_p,const apr_array_header_t * paths,svn_boolean_t make_parents,const apr_hash_t * revprop_table,svn_client_ctx_t * ctx,apr_pool_t * pool)127 svn_client_mkdir3(svn_commit_info_t **commit_info_p,
128                   const apr_array_header_t *paths,
129                   svn_boolean_t make_parents,
130                   const apr_hash_t *revprop_table,
131                   svn_client_ctx_t *ctx,
132                   apr_pool_t *pool)
133 {
134   struct capture_baton_t cb;
135 
136   cb.info = commit_info_p;
137   cb.pool = pool;
138 
139   return svn_client_mkdir4(paths, make_parents, revprop_table,
140                            capture_commit_info, &cb, ctx, pool);
141 }
142 
143 svn_error_t *
svn_client_mkdir2(svn_commit_info_t ** commit_info_p,const apr_array_header_t * paths,svn_client_ctx_t * ctx,apr_pool_t * pool)144 svn_client_mkdir2(svn_commit_info_t **commit_info_p,
145                   const apr_array_header_t *paths,
146                   svn_client_ctx_t *ctx,
147                   apr_pool_t *pool)
148 {
149   return svn_client_mkdir3(commit_info_p, paths, FALSE, NULL, ctx, pool);
150 }
151 
152 
153 svn_error_t *
svn_client_mkdir(svn_client_commit_info_t ** commit_info_p,const apr_array_header_t * paths,svn_client_ctx_t * ctx,apr_pool_t * pool)154 svn_client_mkdir(svn_client_commit_info_t **commit_info_p,
155                  const apr_array_header_t *paths,
156                  svn_client_ctx_t *ctx,
157                  apr_pool_t *pool)
158 {
159   svn_commit_info_t *commit_info = NULL;
160   svn_error_t *err;
161 
162   err = svn_client_mkdir2(&commit_info, paths, ctx, pool);
163   /* These structs have the same layout for the common fields. */
164   *commit_info_p = (svn_client_commit_info_t *) commit_info;
165   return svn_error_trace(err);
166 }
167 
168 /*** From blame.c ***/
169 struct blame_receiver_wrapper_baton3 {
170   void *baton;
171   svn_client_blame_receiver3_t receiver;
172   svn_revnum_t start_revnum;
173   svn_revnum_t end_revnum;
174 };
175 
176 static svn_error_t *
blame_wrapper_receiver3(void * baton,apr_int64_t line_no,svn_revnum_t revision,apr_hash_t * rev_props,svn_revnum_t merged_revision,apr_hash_t * merged_rev_props,const char * merged_path,const svn_string_t * line,svn_boolean_t local_change,apr_pool_t * pool)177 blame_wrapper_receiver3(void *baton,
178    apr_int64_t line_no,
179    svn_revnum_t revision,
180    apr_hash_t *rev_props,
181    svn_revnum_t merged_revision,
182    apr_hash_t *merged_rev_props,
183    const char *merged_path,
184    const svn_string_t *line,
185    svn_boolean_t local_change,
186    apr_pool_t *pool)
187 {
188   struct blame_receiver_wrapper_baton3 *brwb = baton;
189 
190   if (brwb->receiver)
191     return brwb->receiver(brwb->baton, brwb->start_revnum, brwb->end_revnum,
192                           line_no,
193                           revision, rev_props, merged_revision,
194                           merged_rev_props, merged_path, line->data,
195                           local_change, pool);
196 
197   return SVN_NO_ERROR;
198 }
199 
200 svn_error_t *
svn_client_blame5(const char * target,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start,const svn_opt_revision_t * end,const svn_diff_file_options_t * diff_options,svn_boolean_t ignore_mime_type,svn_boolean_t include_merged_revisions,svn_client_blame_receiver3_t receiver,void * receiver_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)201 svn_client_blame5(const char *target,
202                   const svn_opt_revision_t *peg_revision,
203                   const svn_opt_revision_t *start,
204                   const svn_opt_revision_t *end,
205                   const svn_diff_file_options_t *diff_options,
206                   svn_boolean_t ignore_mime_type,
207                   svn_boolean_t include_merged_revisions,
208                   svn_client_blame_receiver3_t receiver,
209                   void *receiver_baton,
210                   svn_client_ctx_t *ctx,
211                   apr_pool_t *pool)
212 {
213   struct blame_receiver_wrapper_baton3 baton;
214 
215   baton.receiver = receiver;
216   baton.baton = receiver_baton;
217 
218   return svn_client_blame6(&baton.start_revnum, &baton.end_revnum,
219                            target, peg_revision, start, end,
220                            diff_options,
221                            ignore_mime_type, include_merged_revisions,
222                            blame_wrapper_receiver3, &baton, ctx, pool);
223 }
224 
225 struct blame_receiver_wrapper_baton2 {
226   void *baton;
227   svn_client_blame_receiver2_t receiver;
228 };
229 
230 static svn_error_t *
blame_wrapper_receiver2(void * baton,svn_revnum_t start_revnum,svn_revnum_t end_revnum,apr_int64_t line_no,svn_revnum_t revision,apr_hash_t * rev_props,svn_revnum_t merged_revision,apr_hash_t * merged_rev_props,const char * merged_path,const char * line,svn_boolean_t local_change,apr_pool_t * pool)231 blame_wrapper_receiver2(void *baton,
232    svn_revnum_t start_revnum,
233    svn_revnum_t end_revnum,
234    apr_int64_t line_no,
235    svn_revnum_t revision,
236    apr_hash_t *rev_props,
237    svn_revnum_t merged_revision,
238    apr_hash_t *merged_rev_props,
239    const char *merged_path,
240    const char *line,
241    svn_boolean_t local_change,
242    apr_pool_t *pool)
243 {
244   struct blame_receiver_wrapper_baton2 *brwb = baton;
245   const char *author = NULL;
246   const char *date = NULL;
247   const char *merged_author = NULL;
248   const char *merged_date = NULL;
249 
250   if (rev_props != NULL)
251     {
252       author = svn_prop_get_value(rev_props, SVN_PROP_REVISION_AUTHOR);
253       date = svn_prop_get_value(rev_props, SVN_PROP_REVISION_DATE);
254     }
255   if (merged_rev_props != NULL)
256     {
257       merged_author = svn_prop_get_value(merged_rev_props,
258                                          SVN_PROP_REVISION_AUTHOR);
259       merged_date = svn_prop_get_value(merged_rev_props,
260                                        SVN_PROP_REVISION_DATE);
261     }
262 
263   if (brwb->receiver)
264     return brwb->receiver(brwb->baton, line_no, revision, author, date,
265                           merged_revision, merged_author, merged_date,
266                           merged_path, line, pool);
267 
268   return SVN_NO_ERROR;
269 }
270 
271 svn_error_t *
svn_client_blame4(const char * target,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start,const svn_opt_revision_t * end,const svn_diff_file_options_t * diff_options,svn_boolean_t ignore_mime_type,svn_boolean_t include_merged_revisions,svn_client_blame_receiver2_t receiver,void * receiver_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)272 svn_client_blame4(const char *target,
273                   const svn_opt_revision_t *peg_revision,
274                   const svn_opt_revision_t *start,
275                   const svn_opt_revision_t *end,
276                   const svn_diff_file_options_t *diff_options,
277                   svn_boolean_t ignore_mime_type,
278                   svn_boolean_t include_merged_revisions,
279                   svn_client_blame_receiver2_t receiver,
280                   void *receiver_baton,
281                   svn_client_ctx_t *ctx,
282                   apr_pool_t *pool)
283 {
284   struct blame_receiver_wrapper_baton2 baton;
285 
286   baton.receiver = receiver;
287   baton.baton = receiver_baton;
288 
289   return svn_client_blame5(target, peg_revision, start, end, diff_options,
290                            ignore_mime_type, include_merged_revisions,
291                            blame_wrapper_receiver2, &baton, ctx, pool);
292 }
293 
294 
295 /* Baton for use with wrap_blame_receiver */
296 struct blame_receiver_wrapper_baton {
297   void *baton;
298   svn_client_blame_receiver_t receiver;
299 };
300 
301 /* This implements svn_client_blame_receiver2_t */
302 static svn_error_t *
blame_wrapper_receiver(void * baton,apr_int64_t line_no,svn_revnum_t revision,const char * author,const char * date,svn_revnum_t merged_revision,const char * merged_author,const char * merged_date,const char * merged_path,const char * line,apr_pool_t * pool)303 blame_wrapper_receiver(void *baton,
304                        apr_int64_t line_no,
305                        svn_revnum_t revision,
306                        const char *author,
307                        const char *date,
308                        svn_revnum_t merged_revision,
309                        const char *merged_author,
310                        const char *merged_date,
311                        const char *merged_path,
312                        const char *line,
313                        apr_pool_t *pool)
314 {
315   struct blame_receiver_wrapper_baton *brwb = baton;
316 
317   if (brwb->receiver)
318     return brwb->receiver(brwb->baton,
319                           line_no, revision, author, date, line, pool);
320 
321   return SVN_NO_ERROR;
322 }
323 
324 static void
wrap_blame_receiver(svn_client_blame_receiver2_t * receiver2,void ** receiver2_baton,svn_client_blame_receiver_t receiver,void * receiver_baton,apr_pool_t * pool)325 wrap_blame_receiver(svn_client_blame_receiver2_t *receiver2,
326                     void **receiver2_baton,
327                     svn_client_blame_receiver_t receiver,
328                     void *receiver_baton,
329                     apr_pool_t *pool)
330 {
331   struct blame_receiver_wrapper_baton *brwb = apr_palloc(pool, sizeof(*brwb));
332 
333   /* Set the user provided old format callback in the baton. */
334   brwb->baton = receiver_baton;
335   brwb->receiver = receiver;
336 
337   *receiver2_baton = brwb;
338   *receiver2 = blame_wrapper_receiver;
339 }
340 
341 svn_error_t *
svn_client_blame3(const char * target,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start,const svn_opt_revision_t * end,const svn_diff_file_options_t * diff_options,svn_boolean_t ignore_mime_type,svn_client_blame_receiver_t receiver,void * receiver_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)342 svn_client_blame3(const char *target,
343                   const svn_opt_revision_t *peg_revision,
344                   const svn_opt_revision_t *start,
345                   const svn_opt_revision_t *end,
346                   const svn_diff_file_options_t *diff_options,
347                   svn_boolean_t ignore_mime_type,
348                   svn_client_blame_receiver_t receiver,
349                   void *receiver_baton,
350                   svn_client_ctx_t *ctx,
351                   apr_pool_t *pool)
352 {
353   svn_client_blame_receiver2_t receiver2;
354   void *receiver2_baton;
355 
356   wrap_blame_receiver(&receiver2, &receiver2_baton, receiver, receiver_baton,
357                       pool);
358 
359   return svn_client_blame4(target, peg_revision, start, end, diff_options,
360                            ignore_mime_type, FALSE, receiver2, receiver2_baton,
361                            ctx, pool);
362 }
363 
364 /* svn_client_blame3 guarantees 'no EOL chars' as part of the receiver
365    LINE argument.  Older versions depend on the fact that if a CR is
366    required, that CR is already part of the LINE data.
367 
368    Because of this difference, we need to trap old receivers and append
369    a CR to LINE before passing it on to the actual receiver on platforms
370    which want CRLF line termination.
371 
372 */
373 
374 struct wrapped_receiver_baton_s
375 {
376   svn_client_blame_receiver_t orig_receiver;
377   void *orig_baton;
378 };
379 
380 static svn_error_t *
wrapped_receiver(void * baton,apr_int64_t line_no,svn_revnum_t revision,const char * author,const char * date,const char * line,apr_pool_t * pool)381 wrapped_receiver(void *baton,
382                  apr_int64_t line_no,
383                  svn_revnum_t revision,
384                  const char *author,
385                  const char *date,
386                  const char *line,
387                  apr_pool_t *pool)
388 {
389   struct wrapped_receiver_baton_s *b = baton;
390   svn_stringbuf_t *expanded_line = svn_stringbuf_create(line, pool);
391 
392   svn_stringbuf_appendbyte(expanded_line, '\r');
393 
394   return b->orig_receiver(b->orig_baton, line_no, revision, author,
395                           date, expanded_line->data, pool);
396 }
397 
398 static void
wrap_pre_blame3_receiver(svn_client_blame_receiver_t * receiver,void ** receiver_baton,apr_pool_t * pool)399 wrap_pre_blame3_receiver(svn_client_blame_receiver_t *receiver,
400                          void **receiver_baton,
401                          apr_pool_t *pool)
402 {
403   if (sizeof(APR_EOL_STR) == 3)
404     {
405       struct wrapped_receiver_baton_s *b = apr_palloc(pool,sizeof(*b));
406 
407       b->orig_receiver = *receiver;
408       b->orig_baton = *receiver_baton;
409 
410       *receiver_baton = b;
411       *receiver = wrapped_receiver;
412     }
413 }
414 
415 svn_error_t *
svn_client_blame2(const char * target,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start,const svn_opt_revision_t * end,svn_client_blame_receiver_t receiver,void * receiver_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)416 svn_client_blame2(const char *target,
417                   const svn_opt_revision_t *peg_revision,
418                   const svn_opt_revision_t *start,
419                   const svn_opt_revision_t *end,
420                   svn_client_blame_receiver_t receiver,
421                   void *receiver_baton,
422                   svn_client_ctx_t *ctx,
423                   apr_pool_t *pool)
424 {
425   wrap_pre_blame3_receiver(&receiver, &receiver_baton, pool);
426   return svn_client_blame3(target, peg_revision, start, end,
427                            svn_diff_file_options_create(pool), FALSE,
428                            receiver, receiver_baton, ctx, pool);
429 }
430 svn_error_t *
svn_client_blame(const char * target,const svn_opt_revision_t * start,const svn_opt_revision_t * end,svn_client_blame_receiver_t receiver,void * receiver_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)431 svn_client_blame(const char *target,
432                  const svn_opt_revision_t *start,
433                  const svn_opt_revision_t *end,
434                  svn_client_blame_receiver_t receiver,
435                  void *receiver_baton,
436                  svn_client_ctx_t *ctx,
437                  apr_pool_t *pool)
438 {
439   wrap_pre_blame3_receiver(&receiver, &receiver_baton, pool);
440   return svn_client_blame2(target, end, start, end,
441                            receiver, receiver_baton, ctx, pool);
442 }
443 
444 /*** From cmdline.c ***/
445 svn_error_t *
svn_client_args_to_target_array(apr_array_header_t ** targets_p,apr_getopt_t * os,const apr_array_header_t * known_targets,svn_client_ctx_t * ctx,apr_pool_t * pool)446 svn_client_args_to_target_array(apr_array_header_t **targets_p,
447                                 apr_getopt_t *os,
448                                 const apr_array_header_t *known_targets,
449                                 svn_client_ctx_t *ctx,
450                                 apr_pool_t *pool)
451 {
452   return svn_client_args_to_target_array2(targets_p, os, known_targets, ctx,
453                                           FALSE, pool);
454 }
455 
456 /*** From commit.c ***/
457 svn_error_t *
svn_client_import4(const char * path,const char * url,svn_depth_t depth,svn_boolean_t no_ignore,svn_boolean_t ignore_unknown_node_types,const apr_hash_t * revprop_table,svn_commit_callback2_t commit_callback,void * commit_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)458 svn_client_import4(const char *path,
459                    const char *url,
460                    svn_depth_t depth,
461                    svn_boolean_t no_ignore,
462                    svn_boolean_t ignore_unknown_node_types,
463                    const apr_hash_t *revprop_table,
464                    svn_commit_callback2_t commit_callback,
465                    void *commit_baton,
466                    svn_client_ctx_t *ctx,
467                    apr_pool_t *pool)
468 {
469   return svn_error_trace(svn_client_import5(path, url, depth, no_ignore,
470                                             FALSE, ignore_unknown_node_types,
471                                             revprop_table,
472                                             NULL, NULL,
473                                             commit_callback, commit_baton,
474                                             ctx, pool));
475 }
476 
477 
478 svn_error_t *
svn_client_import3(svn_commit_info_t ** commit_info_p,const char * path,const char * url,svn_depth_t depth,svn_boolean_t no_ignore,svn_boolean_t ignore_unknown_node_types,const apr_hash_t * revprop_table,svn_client_ctx_t * ctx,apr_pool_t * pool)479 svn_client_import3(svn_commit_info_t **commit_info_p,
480                    const char *path,
481                    const char *url,
482                    svn_depth_t depth,
483                    svn_boolean_t no_ignore,
484                    svn_boolean_t ignore_unknown_node_types,
485                    const apr_hash_t *revprop_table,
486                    svn_client_ctx_t *ctx,
487                    apr_pool_t *pool)
488 {
489   struct capture_baton_t cb;
490 
491   cb.info = commit_info_p;
492   cb.pool = pool;
493 
494   return svn_client_import4(path, url, depth, no_ignore,
495                             ignore_unknown_node_types, revprop_table,
496                             capture_commit_info, &cb, ctx, pool);
497 }
498 
499 svn_error_t *
svn_client_import2(svn_commit_info_t ** commit_info_p,const char * path,const char * url,svn_boolean_t nonrecursive,svn_boolean_t no_ignore,svn_client_ctx_t * ctx,apr_pool_t * pool)500 svn_client_import2(svn_commit_info_t **commit_info_p,
501                    const char *path,
502                    const char *url,
503                    svn_boolean_t nonrecursive,
504                    svn_boolean_t no_ignore,
505                    svn_client_ctx_t *ctx,
506                    apr_pool_t *pool)
507 {
508   return svn_client_import3(commit_info_p,
509                             path, url,
510                             SVN_DEPTH_INFINITY_OR_FILES(! nonrecursive),
511                             no_ignore, FALSE, NULL, ctx, pool);
512 }
513 
514 svn_error_t *
svn_client_import(svn_client_commit_info_t ** commit_info_p,const char * path,const char * url,svn_boolean_t nonrecursive,svn_client_ctx_t * ctx,apr_pool_t * pool)515 svn_client_import(svn_client_commit_info_t **commit_info_p,
516                   const char *path,
517                   const char *url,
518                   svn_boolean_t nonrecursive,
519                   svn_client_ctx_t *ctx,
520                   apr_pool_t *pool)
521 {
522   svn_commit_info_t *commit_info = NULL;
523   svn_error_t *err;
524 
525   err = svn_client_import2(&commit_info,
526                            path, url, nonrecursive,
527                            FALSE, ctx, pool);
528   /* These structs have the same layout for the common fields. */
529   *commit_info_p = (svn_client_commit_info_t *) commit_info;
530   return svn_error_trace(err);
531 }
532 
533 
534 /* Wrapper notify_func2 function and baton for downgrading
535    svn_wc_notify_commit_copied and svn_wc_notify_commit_copied_replaced
536    to svn_wc_notify_commit_added and svn_wc_notify_commit_replaced,
537    respectively. */
538 struct downgrade_commit_copied_notify_baton
539 {
540   svn_wc_notify_func2_t orig_notify_func2;
541   void *orig_notify_baton2;
542 };
543 
544 static void
downgrade_commit_copied_notify_func(void * baton,const svn_wc_notify_t * notify,apr_pool_t * pool)545 downgrade_commit_copied_notify_func(void *baton,
546                                     const svn_wc_notify_t *notify,
547                                     apr_pool_t *pool)
548 {
549   struct downgrade_commit_copied_notify_baton *b = baton;
550 
551   if (notify->action == svn_wc_notify_commit_copied)
552     {
553       svn_wc_notify_t *my_notify = svn_wc_dup_notify(notify, pool);
554       my_notify->action = svn_wc_notify_commit_added;
555       notify = my_notify;
556     }
557   else if (notify->action == svn_wc_notify_commit_copied_replaced)
558     {
559       svn_wc_notify_t *my_notify = svn_wc_dup_notify(notify, pool);
560       my_notify->action = svn_wc_notify_commit_replaced;
561       notify = my_notify;
562     }
563 
564   /* Call the wrapped notification system (if any) with MY_NOTIFY,
565      which is either the original NOTIFY object, or a tweaked deep
566      copy thereof. */
567   if (b->orig_notify_func2)
568     b->orig_notify_func2(b->orig_notify_baton2, notify, pool);
569 }
570 
571 svn_error_t *
svn_client_commit5(const apr_array_header_t * targets,svn_depth_t depth,svn_boolean_t keep_locks,svn_boolean_t keep_changelists,svn_boolean_t commit_as_operations,const apr_array_header_t * changelists,const apr_hash_t * revprop_table,svn_commit_callback2_t commit_callback,void * commit_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)572 svn_client_commit5(const apr_array_header_t *targets,
573                    svn_depth_t depth,
574                    svn_boolean_t keep_locks,
575                    svn_boolean_t keep_changelists,
576                    svn_boolean_t commit_as_operations,
577                    const apr_array_header_t *changelists,
578                    const apr_hash_t *revprop_table,
579                    svn_commit_callback2_t commit_callback,
580                    void *commit_baton,
581                    svn_client_ctx_t *ctx,
582                    apr_pool_t *pool)
583 {
584   return svn_client_commit6(targets, depth, keep_locks, keep_changelists,
585                             commit_as_operations,
586                             FALSE,  /* include_file_externals */
587                             FALSE, /* include_dir_externals */
588                             changelists, revprop_table, commit_callback,
589                             commit_baton, ctx, pool);
590 }
591 
592 svn_error_t *
svn_client_commit4(svn_commit_info_t ** commit_info_p,const apr_array_header_t * targets,svn_depth_t depth,svn_boolean_t keep_locks,svn_boolean_t keep_changelists,const apr_array_header_t * changelists,const apr_hash_t * revprop_table,svn_client_ctx_t * ctx,apr_pool_t * pool)593 svn_client_commit4(svn_commit_info_t **commit_info_p,
594                    const apr_array_header_t *targets,
595                    svn_depth_t depth,
596                    svn_boolean_t keep_locks,
597                    svn_boolean_t keep_changelists,
598                    const apr_array_header_t *changelists,
599                    const apr_hash_t *revprop_table,
600                    svn_client_ctx_t *ctx,
601                    apr_pool_t *pool)
602 {
603   struct capture_baton_t cb;
604   struct downgrade_commit_copied_notify_baton notify_baton;
605   svn_error_t *err;
606 
607   notify_baton.orig_notify_func2 = ctx->notify_func2;
608   notify_baton.orig_notify_baton2 = ctx->notify_baton2;
609 
610   *commit_info_p = NULL;
611   cb.info = commit_info_p;
612   cb.pool = pool;
613 
614   /* Swap out the notification system (if any) with a thin filtering
615      wrapper. */
616   if (ctx->notify_func2)
617     {
618       ctx->notify_func2 = downgrade_commit_copied_notify_func;
619       ctx->notify_baton2 = &notify_baton;
620     }
621 
622   err = svn_client_commit5(targets, depth, keep_locks, keep_changelists, FALSE,
623                            changelists, revprop_table,
624                            capture_commit_info, &cb, ctx, pool);
625 
626   /* Ensure that the original notification system is in place. */
627   ctx->notify_func2 = notify_baton.orig_notify_func2;
628   ctx->notify_baton2 = notify_baton.orig_notify_baton2;
629 
630   SVN_ERR(err);
631 
632   if (! *commit_info_p)
633     *commit_info_p = svn_create_commit_info(pool);
634 
635   return SVN_NO_ERROR;
636 }
637 
638 svn_error_t *
svn_client_commit3(svn_commit_info_t ** commit_info_p,const apr_array_header_t * targets,svn_boolean_t recurse,svn_boolean_t keep_locks,svn_client_ctx_t * ctx,apr_pool_t * pool)639 svn_client_commit3(svn_commit_info_t **commit_info_p,
640                    const apr_array_header_t *targets,
641                    svn_boolean_t recurse,
642                    svn_boolean_t keep_locks,
643                    svn_client_ctx_t *ctx,
644                    apr_pool_t *pool)
645 {
646   svn_depth_t depth = SVN_DEPTH_INFINITY_OR_EMPTY(recurse);
647 
648   return svn_client_commit4(commit_info_p, targets, depth, keep_locks,
649                             FALSE, NULL, NULL, ctx, pool);
650 }
651 
652 svn_error_t *
svn_client_commit2(svn_client_commit_info_t ** commit_info_p,const apr_array_header_t * targets,svn_boolean_t recurse,svn_boolean_t keep_locks,svn_client_ctx_t * ctx,apr_pool_t * pool)653 svn_client_commit2(svn_client_commit_info_t **commit_info_p,
654                    const apr_array_header_t *targets,
655                    svn_boolean_t recurse,
656                    svn_boolean_t keep_locks,
657                    svn_client_ctx_t *ctx,
658                    apr_pool_t *pool)
659 {
660   svn_commit_info_t *commit_info = NULL;
661   svn_error_t *err;
662 
663   err = svn_client_commit3(&commit_info, targets, recurse, keep_locks,
664                            ctx, pool);
665   /* These structs have the same layout for the common fields. */
666   *commit_info_p = (svn_client_commit_info_t *) commit_info;
667   return svn_error_trace(err);
668 }
669 
670 svn_error_t *
svn_client_commit(svn_client_commit_info_t ** commit_info_p,const apr_array_header_t * targets,svn_boolean_t nonrecursive,svn_client_ctx_t * ctx,apr_pool_t * pool)671 svn_client_commit(svn_client_commit_info_t **commit_info_p,
672                   const apr_array_header_t *targets,
673                   svn_boolean_t nonrecursive,
674                   svn_client_ctx_t *ctx,
675                   apr_pool_t *pool)
676 {
677   return svn_client_commit2(commit_info_p, targets,
678                             ! nonrecursive,
679                             TRUE,
680                             ctx, pool);
681 }
682 
683 /*** From copy.c ***/
684 svn_error_t *
svn_client_copy6(const apr_array_header_t * sources,const char * dst_path,svn_boolean_t copy_as_child,svn_boolean_t make_parents,svn_boolean_t ignore_externals,const apr_hash_t * revprop_table,svn_commit_callback2_t commit_callback,void * commit_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)685 svn_client_copy6(const apr_array_header_t *sources,
686                  const char *dst_path,
687                  svn_boolean_t copy_as_child,
688                  svn_boolean_t make_parents,
689                  svn_boolean_t ignore_externals,
690                  const apr_hash_t *revprop_table,
691                  svn_commit_callback2_t commit_callback,
692                  void *commit_baton,
693                  svn_client_ctx_t *ctx,
694                  apr_pool_t *pool)
695 {
696   return svn_error_trace(svn_client_copy7(sources, dst_path, copy_as_child,
697                                           make_parents, ignore_externals,
698                                           FALSE /* metadata_only */,
699                                           FALSE /* pin_externals */,
700                                           NULL /* externals_to_pin */,
701                                           revprop_table,
702                                           commit_callback, commit_baton,
703                                           ctx, pool));
704 }
705 
706 svn_error_t *
svn_client_copy5(svn_commit_info_t ** commit_info_p,const apr_array_header_t * sources,const char * dst_path,svn_boolean_t copy_as_child,svn_boolean_t make_parents,svn_boolean_t ignore_externals,const apr_hash_t * revprop_table,svn_client_ctx_t * ctx,apr_pool_t * pool)707 svn_client_copy5(svn_commit_info_t **commit_info_p,
708                  const apr_array_header_t *sources,
709                  const char *dst_path,
710                  svn_boolean_t copy_as_child,
711                  svn_boolean_t make_parents,
712                  svn_boolean_t ignore_externals,
713                  const apr_hash_t *revprop_table,
714                  svn_client_ctx_t *ctx,
715                  apr_pool_t *pool)
716 {
717   struct capture_baton_t cb;
718 
719   cb.info = commit_info_p;
720   cb.pool = pool;
721 
722   return svn_client_copy6(sources, dst_path, copy_as_child, make_parents,
723                           ignore_externals, revprop_table,
724                           capture_commit_info, &cb, ctx, pool);
725 }
726 
727 svn_error_t *
svn_client_copy4(svn_commit_info_t ** commit_info_p,const apr_array_header_t * sources,const char * dst_path,svn_boolean_t copy_as_child,svn_boolean_t make_parents,const apr_hash_t * revprop_table,svn_client_ctx_t * ctx,apr_pool_t * pool)728 svn_client_copy4(svn_commit_info_t **commit_info_p,
729                  const apr_array_header_t *sources,
730                  const char *dst_path,
731                  svn_boolean_t copy_as_child,
732                  svn_boolean_t make_parents,
733                  const apr_hash_t *revprop_table,
734                  svn_client_ctx_t *ctx,
735                  apr_pool_t *pool)
736 {
737   return svn_client_copy5(commit_info_p, sources, dst_path, copy_as_child,
738                           make_parents, FALSE, revprop_table, ctx, pool);
739 }
740 
741 svn_error_t *
svn_client_copy3(svn_commit_info_t ** commit_info_p,const char * src_path,const svn_opt_revision_t * src_revision,const char * dst_path,svn_client_ctx_t * ctx,apr_pool_t * pool)742 svn_client_copy3(svn_commit_info_t **commit_info_p,
743                  const char *src_path,
744                  const svn_opt_revision_t *src_revision,
745                  const char *dst_path,
746                  svn_client_ctx_t *ctx,
747                  apr_pool_t *pool)
748 {
749   apr_array_header_t *sources = apr_array_make(pool, 1,
750                                   sizeof(const svn_client_copy_source_t *));
751   svn_client_copy_source_t copy_source;
752 
753   copy_source.path = src_path;
754   copy_source.revision = src_revision;
755   copy_source.peg_revision = src_revision;
756 
757   APR_ARRAY_PUSH(sources, const svn_client_copy_source_t *) = &copy_source;
758 
759   return svn_client_copy4(commit_info_p, sources, dst_path, FALSE, FALSE,
760                           NULL, ctx, pool);
761 }
762 
763 svn_error_t *
svn_client_copy2(svn_commit_info_t ** commit_info_p,const char * src_path,const svn_opt_revision_t * src_revision,const char * dst_path,svn_client_ctx_t * ctx,apr_pool_t * pool)764 svn_client_copy2(svn_commit_info_t **commit_info_p,
765                  const char *src_path,
766                  const svn_opt_revision_t *src_revision,
767                  const char *dst_path,
768                  svn_client_ctx_t *ctx,
769                  apr_pool_t *pool)
770 {
771   svn_error_t *err;
772 
773   err = svn_client_copy3(commit_info_p, src_path, src_revision,
774                          dst_path, ctx, pool);
775 
776   /* If the target exists, try to copy the source as a child of the target.
777      This will obviously fail if target is not a directory, but that's exactly
778      what we want. */
779   if (err && (err->apr_err == SVN_ERR_ENTRY_EXISTS
780               || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS))
781     {
782       const char *src_basename = svn_path_basename(src_path, pool);
783 
784       svn_error_clear(err);
785 
786       return svn_client_copy3(commit_info_p, src_path, src_revision,
787                               svn_path_join(dst_path, src_basename, pool),
788                               ctx, pool);
789     }
790 
791   return svn_error_trace(err);
792 }
793 
794 svn_error_t *
svn_client_copy(svn_client_commit_info_t ** commit_info_p,const char * src_path,const svn_opt_revision_t * src_revision,const char * dst_path,svn_client_ctx_t * ctx,apr_pool_t * pool)795 svn_client_copy(svn_client_commit_info_t **commit_info_p,
796                 const char *src_path,
797                 const svn_opt_revision_t *src_revision,
798                 const char *dst_path,
799                 svn_client_ctx_t *ctx,
800                 apr_pool_t *pool)
801 {
802   svn_commit_info_t *commit_info = NULL;
803   svn_error_t *err;
804 
805   err = svn_client_copy2(&commit_info, src_path, src_revision, dst_path,
806                          ctx, pool);
807   /* These structs have the same layout for the common fields. */
808   *commit_info_p = (svn_client_commit_info_t *) commit_info;
809   return svn_error_trace(err);
810 }
811 
812 svn_error_t *
svn_client_move6(const apr_array_header_t * src_paths,const char * dst_path,svn_boolean_t move_as_child,svn_boolean_t make_parents,const apr_hash_t * revprop_table,svn_commit_callback2_t commit_callback,void * commit_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)813 svn_client_move6(const apr_array_header_t *src_paths,
814                  const char *dst_path,
815                  svn_boolean_t move_as_child,
816                  svn_boolean_t make_parents,
817                  const apr_hash_t *revprop_table,
818                  svn_commit_callback2_t commit_callback,
819                  void *commit_baton,
820                  svn_client_ctx_t *ctx,
821                  apr_pool_t *pool)
822 {
823   return svn_error_trace(svn_client_move7(src_paths, dst_path,
824                                           move_as_child, make_parents,
825                                           TRUE /* allow_mixed_revisions */,
826                                           FALSE /* metadata_only */,
827                                           revprop_table,
828                                           commit_callback, commit_baton,
829                                           ctx, pool));
830 }
831 
832 svn_error_t *
svn_client_move5(svn_commit_info_t ** commit_info_p,const apr_array_header_t * src_paths,const char * dst_path,svn_boolean_t force,svn_boolean_t move_as_child,svn_boolean_t make_parents,const apr_hash_t * revprop_table,svn_client_ctx_t * ctx,apr_pool_t * pool)833 svn_client_move5(svn_commit_info_t **commit_info_p,
834                  const apr_array_header_t *src_paths,
835                  const char *dst_path,
836                  svn_boolean_t force,
837                  svn_boolean_t move_as_child,
838                  svn_boolean_t make_parents,
839                  const apr_hash_t *revprop_table,
840                  svn_client_ctx_t *ctx,
841                  apr_pool_t *pool)
842 {
843   struct capture_baton_t cb;
844 
845   cb.info = commit_info_p;
846   cb.pool = pool;
847 
848   return svn_client_move6(src_paths, dst_path, move_as_child,
849                           make_parents, revprop_table,
850                           capture_commit_info, &cb, ctx, pool);
851 }
852 
853 svn_error_t *
svn_client_move4(svn_commit_info_t ** commit_info_p,const char * src_path,const char * dst_path,svn_boolean_t force,svn_client_ctx_t * ctx,apr_pool_t * pool)854 svn_client_move4(svn_commit_info_t **commit_info_p,
855                  const char *src_path,
856                  const char *dst_path,
857                  svn_boolean_t force,
858                  svn_client_ctx_t *ctx,
859                  apr_pool_t *pool)
860 {
861   apr_array_header_t *src_paths =
862     apr_array_make(pool, 1, sizeof(const char *));
863   APR_ARRAY_PUSH(src_paths, const char *) = src_path;
864 
865 
866   return svn_client_move5(commit_info_p, src_paths, dst_path, force, FALSE,
867                           FALSE, NULL, ctx, pool);
868 }
869 
870 svn_error_t *
svn_client_move3(svn_commit_info_t ** commit_info_p,const char * src_path,const char * dst_path,svn_boolean_t force,svn_client_ctx_t * ctx,apr_pool_t * pool)871 svn_client_move3(svn_commit_info_t **commit_info_p,
872                  const char *src_path,
873                  const char *dst_path,
874                  svn_boolean_t force,
875                  svn_client_ctx_t *ctx,
876                  apr_pool_t *pool)
877 {
878   svn_error_t *err;
879 
880   err = svn_client_move4(commit_info_p, src_path, dst_path, force, ctx, pool);
881 
882   /* If the target exists, try to move the source as a child of the target.
883      This will obviously fail if target is not a directory, but that's exactly
884      what we want. */
885   if (err && (err->apr_err == SVN_ERR_ENTRY_EXISTS
886               || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS))
887     {
888       const char *src_basename = svn_path_basename(src_path, pool);
889 
890       svn_error_clear(err);
891 
892       return svn_client_move4(commit_info_p, src_path,
893                               svn_path_join(dst_path, src_basename, pool),
894                               force, ctx, pool);
895     }
896 
897   return svn_error_trace(err);
898 }
899 
900 svn_error_t *
svn_client_move2(svn_client_commit_info_t ** commit_info_p,const char * src_path,const char * dst_path,svn_boolean_t force,svn_client_ctx_t * ctx,apr_pool_t * pool)901 svn_client_move2(svn_client_commit_info_t **commit_info_p,
902                  const char *src_path,
903                  const char *dst_path,
904                  svn_boolean_t force,
905                  svn_client_ctx_t *ctx,
906                  apr_pool_t *pool)
907 {
908   svn_commit_info_t *commit_info = NULL;
909   svn_error_t *err;
910 
911   err = svn_client_move3(&commit_info, src_path, dst_path, force, ctx, pool);
912   /* These structs have the same layout for the common fields. */
913   *commit_info_p = (svn_client_commit_info_t *) commit_info;
914   return svn_error_trace(err);
915 }
916 
917 
918 svn_error_t *
svn_client_move(svn_client_commit_info_t ** commit_info_p,const char * src_path,const svn_opt_revision_t * src_revision,const char * dst_path,svn_boolean_t force,svn_client_ctx_t * ctx,apr_pool_t * pool)919 svn_client_move(svn_client_commit_info_t **commit_info_p,
920                 const char *src_path,
921                 const svn_opt_revision_t *src_revision,
922                 const char *dst_path,
923                 svn_boolean_t force,
924                 svn_client_ctx_t *ctx,
925                 apr_pool_t *pool)
926 {
927   /* It doesn't make sense to specify revisions in a move. */
928 
929   /* ### todo: this check could fail wrongly.  For example,
930      someone could pass in an svn_opt_revision_number that just
931      happens to be the HEAD.  It's fair enough to punt then, IMHO,
932      and just demand that the user not specify a revision at all;
933      beats mucking up this function with RA calls and such. */
934   if (src_revision->kind != svn_opt_revision_unspecified
935       && src_revision->kind != svn_opt_revision_head)
936     {
937       return svn_error_create
938         (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
939          _("Cannot specify revisions (except HEAD) with move operations"));
940     }
941 
942   return svn_client_move2(commit_info_p, src_path, dst_path, force, ctx, pool);
943 }
944 
945 /*** From delete.c ***/
946 svn_error_t *
svn_client_delete3(svn_commit_info_t ** commit_info_p,const apr_array_header_t * paths,svn_boolean_t force,svn_boolean_t keep_local,const apr_hash_t * revprop_table,svn_client_ctx_t * ctx,apr_pool_t * pool)947 svn_client_delete3(svn_commit_info_t **commit_info_p,
948                    const apr_array_header_t *paths,
949                    svn_boolean_t force,
950                    svn_boolean_t keep_local,
951                    const apr_hash_t *revprop_table,
952                    svn_client_ctx_t *ctx,
953                    apr_pool_t *pool)
954 {
955   struct capture_baton_t cb;
956 
957   cb.info = commit_info_p;
958   cb.pool = pool;
959 
960   return svn_client_delete4(paths, force, keep_local, revprop_table,
961                             capture_commit_info, &cb, ctx, pool);
962 }
963 
964 svn_error_t *
svn_client_delete2(svn_commit_info_t ** commit_info_p,const apr_array_header_t * paths,svn_boolean_t force,svn_client_ctx_t * ctx,apr_pool_t * pool)965 svn_client_delete2(svn_commit_info_t **commit_info_p,
966                    const apr_array_header_t *paths,
967                    svn_boolean_t force,
968                    svn_client_ctx_t *ctx,
969                    apr_pool_t *pool)
970 {
971   return svn_client_delete3(commit_info_p, paths, force, FALSE, NULL,
972                             ctx, pool);
973 }
974 
975 svn_error_t *
svn_client_delete(svn_client_commit_info_t ** commit_info_p,const apr_array_header_t * paths,svn_boolean_t force,svn_client_ctx_t * ctx,apr_pool_t * pool)976 svn_client_delete(svn_client_commit_info_t **commit_info_p,
977                   const apr_array_header_t *paths,
978                   svn_boolean_t force,
979                   svn_client_ctx_t *ctx,
980                   apr_pool_t *pool)
981 {
982   svn_commit_info_t *commit_info = NULL;
983   svn_error_t *err = NULL;
984 
985   err = svn_client_delete2(&commit_info, paths, force, ctx, pool);
986   /* These structs have the same layout for the common fields. */
987   *commit_info_p = (svn_client_commit_info_t *) commit_info;
988   return svn_error_trace(err);
989 }
990 
991 /*** From diff.c ***/
992 
993 svn_error_t *
svn_client_diff6(const apr_array_header_t * diff_options,const char * path_or_url1,const svn_opt_revision_t * revision1,const char * path_or_url2,const svn_opt_revision_t * revision2,const char * relative_to_dir,svn_depth_t depth,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_added,svn_boolean_t no_diff_deleted,svn_boolean_t show_copies_as_adds,svn_boolean_t ignore_content_type,svn_boolean_t ignore_properties,svn_boolean_t properties_only,svn_boolean_t use_git_diff_format,const char * header_encoding,svn_stream_t * outstream,svn_stream_t * errstream,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * pool)994 svn_client_diff6(const apr_array_header_t *diff_options,
995                  const char *path_or_url1,
996                  const svn_opt_revision_t *revision1,
997                  const char *path_or_url2,
998                  const svn_opt_revision_t *revision2,
999                  const char *relative_to_dir,
1000                  svn_depth_t depth,
1001                  svn_boolean_t ignore_ancestry,
1002                  svn_boolean_t no_diff_added,
1003                  svn_boolean_t no_diff_deleted,
1004                  svn_boolean_t show_copies_as_adds,
1005                  svn_boolean_t ignore_content_type,
1006                  svn_boolean_t ignore_properties,
1007                  svn_boolean_t properties_only,
1008                  svn_boolean_t use_git_diff_format,
1009                  const char *header_encoding,
1010                  svn_stream_t *outstream,
1011                  svn_stream_t *errstream,
1012                  const apr_array_header_t *changelists,
1013                  svn_client_ctx_t *ctx,
1014                  apr_pool_t *pool)
1015 {
1016   return svn_client_diff7(diff_options,
1017                           path_or_url1, revision1,
1018                           path_or_url2, revision2,
1019                           relative_to_dir, depth,
1020                           ignore_ancestry, no_diff_added,
1021                           no_diff_deleted, show_copies_as_adds,
1022                           ignore_content_type, ignore_properties,
1023                           properties_only, use_git_diff_format,
1024                           TRUE /*pretty_print_mergeinfo*/,
1025                           header_encoding,
1026                           outstream, errstream, changelists, ctx, pool);
1027 }
1028 
1029 svn_error_t *
svn_client_diff5(const apr_array_header_t * diff_options,const char * path1,const svn_opt_revision_t * revision1,const char * path2,const svn_opt_revision_t * revision2,const char * relative_to_dir,svn_depth_t depth,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_deleted,svn_boolean_t show_copies_as_adds,svn_boolean_t ignore_content_type,svn_boolean_t use_git_diff_format,const char * header_encoding,apr_file_t * outfile,apr_file_t * errfile,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * pool)1030 svn_client_diff5(const apr_array_header_t *diff_options,
1031                  const char *path1,
1032                  const svn_opt_revision_t *revision1,
1033                  const char *path2,
1034                  const svn_opt_revision_t *revision2,
1035                  const char *relative_to_dir,
1036                  svn_depth_t depth,
1037                  svn_boolean_t ignore_ancestry,
1038                  svn_boolean_t no_diff_deleted,
1039                  svn_boolean_t show_copies_as_adds,
1040                  svn_boolean_t ignore_content_type,
1041                  svn_boolean_t use_git_diff_format,
1042                  const char *header_encoding,
1043                  apr_file_t *outfile,
1044                  apr_file_t *errfile,
1045                  const apr_array_header_t *changelists,
1046                  svn_client_ctx_t *ctx,
1047                  apr_pool_t *pool)
1048 {
1049   svn_stream_t *outstream = svn_stream_from_aprfile2(outfile, TRUE, pool);
1050   svn_stream_t *errstream = svn_stream_from_aprfile2(errfile, TRUE, pool);
1051 
1052   return svn_client_diff6(diff_options, path1, revision1, path2,
1053                           revision2, relative_to_dir, depth,
1054                           ignore_ancestry, FALSE /* no_diff_added */,
1055                           no_diff_deleted, show_copies_as_adds,
1056                           ignore_content_type, FALSE /* ignore_properties */,
1057                           FALSE /* properties_only */, use_git_diff_format,
1058                           header_encoding,
1059                           outstream, errstream, changelists, ctx, pool);
1060 }
1061 
1062 svn_error_t *
svn_client_diff4(const apr_array_header_t * options,const char * path1,const svn_opt_revision_t * revision1,const char * path2,const svn_opt_revision_t * revision2,const char * relative_to_dir,svn_depth_t depth,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_deleted,svn_boolean_t ignore_content_type,const char * header_encoding,apr_file_t * outfile,apr_file_t * errfile,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * pool)1063 svn_client_diff4(const apr_array_header_t *options,
1064                  const char *path1,
1065                  const svn_opt_revision_t *revision1,
1066                  const char *path2,
1067                  const svn_opt_revision_t *revision2,
1068                  const char *relative_to_dir,
1069                  svn_depth_t depth,
1070                  svn_boolean_t ignore_ancestry,
1071                  svn_boolean_t no_diff_deleted,
1072                  svn_boolean_t ignore_content_type,
1073                  const char *header_encoding,
1074                  apr_file_t *outfile,
1075                  apr_file_t *errfile,
1076                  const apr_array_header_t *changelists,
1077                  svn_client_ctx_t *ctx,
1078                  apr_pool_t *pool)
1079 {
1080   return svn_client_diff5(options, path1, revision1, path2,
1081                           revision2, relative_to_dir, depth,
1082                           ignore_ancestry, no_diff_deleted, FALSE,
1083                           ignore_content_type, FALSE, header_encoding,
1084                           outfile, errfile, changelists, ctx, pool);
1085 }
1086 
1087 svn_error_t *
svn_client_diff3(const apr_array_header_t * options,const char * path1,const svn_opt_revision_t * revision1,const char * path2,const svn_opt_revision_t * revision2,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_deleted,svn_boolean_t ignore_content_type,const char * header_encoding,apr_file_t * outfile,apr_file_t * errfile,svn_client_ctx_t * ctx,apr_pool_t * pool)1088 svn_client_diff3(const apr_array_header_t *options,
1089                  const char *path1,
1090                  const svn_opt_revision_t *revision1,
1091                  const char *path2,
1092                  const svn_opt_revision_t *revision2,
1093                  svn_boolean_t recurse,
1094                  svn_boolean_t ignore_ancestry,
1095                  svn_boolean_t no_diff_deleted,
1096                  svn_boolean_t ignore_content_type,
1097                  const char *header_encoding,
1098                  apr_file_t *outfile,
1099                  apr_file_t *errfile,
1100                  svn_client_ctx_t *ctx,
1101                  apr_pool_t *pool)
1102 {
1103   return svn_client_diff4(options, path1, revision1, path2,
1104                           revision2, NULL,
1105                           SVN_DEPTH_INFINITY_OR_FILES(recurse),
1106                           ignore_ancestry, no_diff_deleted,
1107                           ignore_content_type, header_encoding,
1108                           outfile, errfile, NULL, ctx, pool);
1109 }
1110 
1111 svn_error_t *
svn_client_diff2(const apr_array_header_t * options,const char * path1,const svn_opt_revision_t * revision1,const char * path2,const svn_opt_revision_t * revision2,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_deleted,svn_boolean_t ignore_content_type,apr_file_t * outfile,apr_file_t * errfile,svn_client_ctx_t * ctx,apr_pool_t * pool)1112 svn_client_diff2(const apr_array_header_t *options,
1113                  const char *path1,
1114                  const svn_opt_revision_t *revision1,
1115                  const char *path2,
1116                  const svn_opt_revision_t *revision2,
1117                  svn_boolean_t recurse,
1118                  svn_boolean_t ignore_ancestry,
1119                  svn_boolean_t no_diff_deleted,
1120                  svn_boolean_t ignore_content_type,
1121                  apr_file_t *outfile,
1122                  apr_file_t *errfile,
1123                  svn_client_ctx_t *ctx,
1124                  apr_pool_t *pool)
1125 {
1126   return svn_client_diff3(options, path1, revision1, path2, revision2,
1127                           recurse, ignore_ancestry, no_diff_deleted,
1128                           ignore_content_type, SVN_APR_LOCALE_CHARSET,
1129                           outfile, errfile, ctx, pool);
1130 }
1131 
1132 svn_error_t *
svn_client_diff(const apr_array_header_t * options,const char * path1,const svn_opt_revision_t * revision1,const char * path2,const svn_opt_revision_t * revision2,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_deleted,apr_file_t * outfile,apr_file_t * errfile,svn_client_ctx_t * ctx,apr_pool_t * pool)1133 svn_client_diff(const apr_array_header_t *options,
1134                 const char *path1,
1135                 const svn_opt_revision_t *revision1,
1136                 const char *path2,
1137                 const svn_opt_revision_t *revision2,
1138                 svn_boolean_t recurse,
1139                 svn_boolean_t ignore_ancestry,
1140                 svn_boolean_t no_diff_deleted,
1141                 apr_file_t *outfile,
1142                 apr_file_t *errfile,
1143                 svn_client_ctx_t *ctx,
1144                 apr_pool_t *pool)
1145 {
1146   return svn_client_diff2(options, path1, revision1, path2, revision2,
1147                           recurse, ignore_ancestry, no_diff_deleted, FALSE,
1148                           outfile, errfile, ctx, pool);
1149 }
1150 
1151 svn_error_t *
svn_client_diff_peg6(const apr_array_header_t * options,const char * path_or_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start_revision,const svn_opt_revision_t * end_revision,const char * relative_to_dir,svn_depth_t depth,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_added,svn_boolean_t no_diff_deleted,svn_boolean_t show_copies_as_adds,svn_boolean_t ignore_content_type,svn_boolean_t ignore_properties,svn_boolean_t properties_only,svn_boolean_t use_git_diff_format,const char * header_encoding,svn_stream_t * outstream,svn_stream_t * errstream,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * pool)1152 svn_client_diff_peg6(const apr_array_header_t *options,
1153                      const char *path_or_url,
1154                      const svn_opt_revision_t *peg_revision,
1155                      const svn_opt_revision_t *start_revision,
1156                      const svn_opt_revision_t *end_revision,
1157                      const char *relative_to_dir,
1158                      svn_depth_t depth,
1159                      svn_boolean_t ignore_ancestry,
1160                      svn_boolean_t no_diff_added,
1161                      svn_boolean_t no_diff_deleted,
1162                      svn_boolean_t show_copies_as_adds,
1163                      svn_boolean_t ignore_content_type,
1164                      svn_boolean_t ignore_properties,
1165                      svn_boolean_t properties_only,
1166                      svn_boolean_t use_git_diff_format,
1167                      const char *header_encoding,
1168                      svn_stream_t *outstream,
1169                      svn_stream_t *errstream,
1170                      const apr_array_header_t *changelists,
1171                      svn_client_ctx_t *ctx,
1172                      apr_pool_t *pool)
1173 {
1174   return svn_client_diff_peg7(options,
1175                               path_or_url,
1176                               peg_revision,
1177                               start_revision,
1178                               end_revision,
1179                               relative_to_dir,
1180                               depth,
1181                               ignore_ancestry,
1182                               no_diff_added,
1183                               no_diff_deleted,
1184                               show_copies_as_adds,
1185                               ignore_content_type,
1186                               ignore_properties,
1187                               properties_only,
1188                               use_git_diff_format,
1189                               TRUE /*pretty_print_mergeinfo*/,
1190                               header_encoding,
1191                               outstream,
1192                               errstream,
1193                               changelists,
1194                               ctx,
1195                               pool);
1196 }
1197 
1198 svn_error_t *
svn_client_diff_peg5(const apr_array_header_t * diff_options,const char * path,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start_revision,const svn_opt_revision_t * end_revision,const char * relative_to_dir,svn_depth_t depth,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_deleted,svn_boolean_t show_copies_as_adds,svn_boolean_t ignore_content_type,svn_boolean_t use_git_diff_format,const char * header_encoding,apr_file_t * outfile,apr_file_t * errfile,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * pool)1199 svn_client_diff_peg5(const apr_array_header_t *diff_options,
1200                      const char *path,
1201                      const svn_opt_revision_t *peg_revision,
1202                      const svn_opt_revision_t *start_revision,
1203                      const svn_opt_revision_t *end_revision,
1204                      const char *relative_to_dir,
1205                      svn_depth_t depth,
1206                      svn_boolean_t ignore_ancestry,
1207                      svn_boolean_t no_diff_deleted,
1208                      svn_boolean_t show_copies_as_adds,
1209                      svn_boolean_t ignore_content_type,
1210                      svn_boolean_t use_git_diff_format,
1211                      const char *header_encoding,
1212                      apr_file_t *outfile,
1213                      apr_file_t *errfile,
1214                      const apr_array_header_t *changelists,
1215                      svn_client_ctx_t *ctx,
1216                      apr_pool_t *pool)
1217 {
1218   svn_stream_t *outstream = svn_stream_from_aprfile2(outfile, TRUE, pool);
1219   svn_stream_t *errstream = svn_stream_from_aprfile2(errfile, TRUE, pool);
1220 
1221   return svn_client_diff_peg6(diff_options,
1222                               path,
1223                               peg_revision,
1224                               start_revision,
1225                               end_revision,
1226                               relative_to_dir,
1227                               depth,
1228                               ignore_ancestry,
1229                               FALSE /* no_diff_added */,
1230                               no_diff_deleted,
1231                               show_copies_as_adds,
1232                               ignore_content_type,
1233                               FALSE /* ignore_properties */,
1234                               FALSE /* properties_only */,
1235                               use_git_diff_format,
1236                               header_encoding,
1237                               outstream,
1238                               errstream,
1239                               changelists,
1240                               ctx,
1241                               pool);
1242 }
1243 
1244 svn_error_t *
svn_client_diff_peg4(const apr_array_header_t * options,const char * path,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start_revision,const svn_opt_revision_t * end_revision,const char * relative_to_dir,svn_depth_t depth,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_deleted,svn_boolean_t ignore_content_type,const char * header_encoding,apr_file_t * outfile,apr_file_t * errfile,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * pool)1245 svn_client_diff_peg4(const apr_array_header_t *options,
1246                      const char *path,
1247                      const svn_opt_revision_t *peg_revision,
1248                      const svn_opt_revision_t *start_revision,
1249                      const svn_opt_revision_t *end_revision,
1250                      const char *relative_to_dir,
1251                      svn_depth_t depth,
1252                      svn_boolean_t ignore_ancestry,
1253                      svn_boolean_t no_diff_deleted,
1254                      svn_boolean_t ignore_content_type,
1255                      const char *header_encoding,
1256                      apr_file_t *outfile,
1257                      apr_file_t *errfile,
1258                      const apr_array_header_t *changelists,
1259                      svn_client_ctx_t *ctx,
1260                      apr_pool_t *pool)
1261 {
1262   return svn_client_diff_peg5(options,
1263                               path,
1264                               peg_revision,
1265                               start_revision,
1266                               end_revision,
1267                               relative_to_dir,
1268                               depth,
1269                               ignore_ancestry,
1270                               no_diff_deleted,
1271                               FALSE,
1272                               ignore_content_type,
1273                               FALSE,
1274                               header_encoding,
1275                               outfile,
1276                               errfile,
1277                               changelists,
1278                               ctx,
1279                               pool);
1280 }
1281 
1282 svn_error_t *
svn_client_diff_peg3(const apr_array_header_t * options,const char * path,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start_revision,const svn_opt_revision_t * end_revision,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_deleted,svn_boolean_t ignore_content_type,const char * header_encoding,apr_file_t * outfile,apr_file_t * errfile,svn_client_ctx_t * ctx,apr_pool_t * pool)1283 svn_client_diff_peg3(const apr_array_header_t *options,
1284                      const char *path,
1285                      const svn_opt_revision_t *peg_revision,
1286                      const svn_opt_revision_t *start_revision,
1287                      const svn_opt_revision_t *end_revision,
1288                      svn_boolean_t recurse,
1289                      svn_boolean_t ignore_ancestry,
1290                      svn_boolean_t no_diff_deleted,
1291                      svn_boolean_t ignore_content_type,
1292                      const char *header_encoding,
1293                      apr_file_t *outfile,
1294                      apr_file_t *errfile,
1295                      svn_client_ctx_t *ctx,
1296                      apr_pool_t *pool)
1297 {
1298   return svn_client_diff_peg4(options,
1299                               path,
1300                               peg_revision,
1301                               start_revision,
1302                               end_revision,
1303                               NULL,
1304                               SVN_DEPTH_INFINITY_OR_FILES(recurse),
1305                               ignore_ancestry,
1306                               no_diff_deleted,
1307                               ignore_content_type,
1308                               header_encoding,
1309                               outfile,
1310                               errfile,
1311                               NULL,
1312                               ctx,
1313                               pool);
1314 }
1315 
1316 svn_error_t *
svn_client_diff_peg2(const apr_array_header_t * options,const char * path,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start_revision,const svn_opt_revision_t * end_revision,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_deleted,svn_boolean_t ignore_content_type,apr_file_t * outfile,apr_file_t * errfile,svn_client_ctx_t * ctx,apr_pool_t * pool)1317 svn_client_diff_peg2(const apr_array_header_t *options,
1318                      const char *path,
1319                      const svn_opt_revision_t *peg_revision,
1320                      const svn_opt_revision_t *start_revision,
1321                      const svn_opt_revision_t *end_revision,
1322                      svn_boolean_t recurse,
1323                      svn_boolean_t ignore_ancestry,
1324                      svn_boolean_t no_diff_deleted,
1325                      svn_boolean_t ignore_content_type,
1326                      apr_file_t *outfile,
1327                      apr_file_t *errfile,
1328                      svn_client_ctx_t *ctx,
1329                      apr_pool_t *pool)
1330 {
1331   return svn_client_diff_peg3(options, path, peg_revision, start_revision,
1332                               end_revision,
1333                               SVN_DEPTH_INFINITY_OR_FILES(recurse),
1334                               ignore_ancestry, no_diff_deleted,
1335                               ignore_content_type, SVN_APR_LOCALE_CHARSET,
1336                               outfile, errfile, ctx, pool);
1337 }
1338 
1339 svn_error_t *
svn_client_diff_peg(const apr_array_header_t * options,const char * path,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start_revision,const svn_opt_revision_t * end_revision,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_boolean_t no_diff_deleted,apr_file_t * outfile,apr_file_t * errfile,svn_client_ctx_t * ctx,apr_pool_t * pool)1340 svn_client_diff_peg(const apr_array_header_t *options,
1341                     const char *path,
1342                     const svn_opt_revision_t *peg_revision,
1343                     const svn_opt_revision_t *start_revision,
1344                     const svn_opt_revision_t *end_revision,
1345                     svn_boolean_t recurse,
1346                     svn_boolean_t ignore_ancestry,
1347                     svn_boolean_t no_diff_deleted,
1348                     apr_file_t *outfile,
1349                     apr_file_t *errfile,
1350                     svn_client_ctx_t *ctx,
1351                     apr_pool_t *pool)
1352 {
1353   return svn_client_diff_peg2(options, path, peg_revision,
1354                               start_revision, end_revision, recurse,
1355                               ignore_ancestry, no_diff_deleted, FALSE,
1356                               outfile, errfile, ctx, pool);
1357 }
1358 
1359 svn_error_t *
svn_client_diff_summarize(const char * path1,const svn_opt_revision_t * revision1,const char * path2,const svn_opt_revision_t * revision2,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_client_diff_summarize_func_t summarize_func,void * summarize_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)1360 svn_client_diff_summarize(const char *path1,
1361                           const svn_opt_revision_t *revision1,
1362                           const char *path2,
1363                           const svn_opt_revision_t *revision2,
1364                           svn_boolean_t recurse,
1365                           svn_boolean_t ignore_ancestry,
1366                           svn_client_diff_summarize_func_t summarize_func,
1367                           void *summarize_baton,
1368                           svn_client_ctx_t *ctx,
1369                           apr_pool_t *pool)
1370 {
1371   return svn_client_diff_summarize2(path1, revision1, path2,
1372                                     revision2,
1373                                     SVN_DEPTH_INFINITY_OR_FILES(recurse),
1374                                     ignore_ancestry, NULL, summarize_func,
1375                                     summarize_baton, ctx, pool);
1376 }
1377 
1378 svn_error_t *
svn_client_diff_summarize_peg(const char * path,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start_revision,const svn_opt_revision_t * end_revision,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_client_diff_summarize_func_t summarize_func,void * summarize_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)1379 svn_client_diff_summarize_peg(const char *path,
1380                               const svn_opt_revision_t *peg_revision,
1381                               const svn_opt_revision_t *start_revision,
1382                               const svn_opt_revision_t *end_revision,
1383                               svn_boolean_t recurse,
1384                               svn_boolean_t ignore_ancestry,
1385                               svn_client_diff_summarize_func_t summarize_func,
1386                               void *summarize_baton,
1387                               svn_client_ctx_t *ctx,
1388                               apr_pool_t *pool)
1389 {
1390   return svn_client_diff_summarize_peg2(path, peg_revision,
1391                                         start_revision, end_revision,
1392                                         SVN_DEPTH_INFINITY_OR_FILES(recurse),
1393                                         ignore_ancestry, NULL,
1394                                         summarize_func, summarize_baton,
1395                                         ctx, pool);
1396 }
1397 
1398 /*** From export.c ***/
1399 svn_error_t *
svn_client_export4(svn_revnum_t * result_rev,const char * from_path_or_url,const char * to_path,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_boolean_t overwrite,svn_boolean_t ignore_externals,svn_depth_t depth,const char * native_eol,svn_client_ctx_t * ctx,apr_pool_t * pool)1400 svn_client_export4(svn_revnum_t *result_rev,
1401                    const char *from_path_or_url,
1402                    const char *to_path,
1403                    const svn_opt_revision_t *peg_revision,
1404                    const svn_opt_revision_t *revision,
1405                    svn_boolean_t overwrite,
1406                    svn_boolean_t ignore_externals,
1407                    svn_depth_t depth,
1408                    const char *native_eol,
1409                    svn_client_ctx_t *ctx,
1410                    apr_pool_t *pool)
1411 {
1412   return svn_client_export5(result_rev, from_path_or_url, to_path,
1413                             peg_revision, revision, overwrite, ignore_externals,
1414                             FALSE, depth, native_eol, ctx, pool);
1415 }
1416 
1417 svn_error_t *
svn_client_export3(svn_revnum_t * result_rev,const char * from_path_or_url,const char * to_path,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_boolean_t overwrite,svn_boolean_t ignore_externals,svn_boolean_t recurse,const char * native_eol,svn_client_ctx_t * ctx,apr_pool_t * pool)1418 svn_client_export3(svn_revnum_t *result_rev,
1419                    const char *from_path_or_url,
1420                    const char *to_path,
1421                    const svn_opt_revision_t *peg_revision,
1422                    const svn_opt_revision_t *revision,
1423                    svn_boolean_t overwrite,
1424                    svn_boolean_t ignore_externals,
1425                    svn_boolean_t recurse,
1426                    const char *native_eol,
1427                    svn_client_ctx_t *ctx,
1428                    apr_pool_t *pool)
1429 {
1430   return svn_client_export4(result_rev, from_path_or_url, to_path,
1431                             peg_revision, revision, overwrite, ignore_externals,
1432                             SVN_DEPTH_INFINITY_OR_FILES(recurse),
1433                             native_eol, ctx, pool);
1434 }
1435 
1436 svn_error_t *
svn_client_export2(svn_revnum_t * result_rev,const char * from_path_or_url,const char * to_path,svn_opt_revision_t * revision,svn_boolean_t force,const char * native_eol,svn_client_ctx_t * ctx,apr_pool_t * pool)1437 svn_client_export2(svn_revnum_t *result_rev,
1438                    const char *from_path_or_url,
1439                    const char *to_path,
1440                    svn_opt_revision_t *revision,
1441                    svn_boolean_t force,
1442                    const char *native_eol,
1443                    svn_client_ctx_t *ctx,
1444                    apr_pool_t *pool)
1445 {
1446   svn_opt_revision_t peg_revision;
1447 
1448   peg_revision.kind = svn_opt_revision_unspecified;
1449 
1450   return svn_client_export3(result_rev, from_path_or_url, to_path,
1451                             &peg_revision, revision, force, FALSE, TRUE,
1452                             native_eol, ctx, pool);
1453 }
1454 
1455 
1456 svn_error_t *
svn_client_export(svn_revnum_t * result_rev,const char * from_path_or_url,const char * to_path,svn_opt_revision_t * revision,svn_boolean_t force,svn_client_ctx_t * ctx,apr_pool_t * pool)1457 svn_client_export(svn_revnum_t *result_rev,
1458                   const char *from_path_or_url,
1459                   const char *to_path,
1460                   svn_opt_revision_t *revision,
1461                   svn_boolean_t force,
1462                   svn_client_ctx_t *ctx,
1463                   apr_pool_t *pool)
1464 {
1465   return svn_client_export2(result_rev, from_path_or_url, to_path, revision,
1466                             force, NULL, ctx, pool);
1467 }
1468 
1469 /*** From list.c ***/
1470 
1471 svn_error_t *
svn_client_list3(const char * path_or_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_depth_t depth,apr_uint32_t dirent_fields,svn_boolean_t fetch_locks,svn_boolean_t include_externals,svn_client_list_func2_t list_func,void * baton,svn_client_ctx_t * ctx,apr_pool_t * pool)1472 svn_client_list3(const char *path_or_url,
1473                  const svn_opt_revision_t *peg_revision,
1474                  const svn_opt_revision_t *revision,
1475                  svn_depth_t depth,
1476                  apr_uint32_t dirent_fields,
1477                  svn_boolean_t fetch_locks,
1478                  svn_boolean_t include_externals,
1479                  svn_client_list_func2_t list_func,
1480                  void *baton,
1481                  svn_client_ctx_t *ctx,
1482                  apr_pool_t *pool)
1483 {
1484   return svn_error_trace(svn_client_list4(path_or_url, peg_revision,
1485                                           revision, NULL, depth,
1486                                           dirent_fields, fetch_locks,
1487                                           include_externals,
1488                                           list_func, baton, ctx, pool));
1489 }
1490 
1491 /* Baton for use with wrap_list_func */
1492 struct list_func_wrapper_baton {
1493     void *list_func1_baton;
1494     svn_client_list_func_t list_func1;
1495 };
1496 
1497 /* This implements svn_client_list_func2_t */
1498 static svn_error_t *
list_func_wrapper(void * baton,const char * path,const svn_dirent_t * dirent,const svn_lock_t * lock,const char * abs_path,const char * external_parent_url,const char * external_target,apr_pool_t * scratch_pool)1499 list_func_wrapper(void *baton,
1500                   const char *path,
1501                   const svn_dirent_t *dirent,
1502                   const svn_lock_t *lock,
1503                   const char *abs_path,
1504                   const char *external_parent_url,
1505                   const char *external_target,
1506                   apr_pool_t *scratch_pool)
1507 {
1508   struct list_func_wrapper_baton *lfwb = baton;
1509 
1510   if (lfwb->list_func1)
1511     return lfwb->list_func1(lfwb->list_func1_baton, path, dirent,
1512                            lock, abs_path, scratch_pool);
1513 
1514   return SVN_NO_ERROR;
1515 }
1516 
1517 /* Helper function for svn_client_list2().  It wraps old format baton
1518    and callback function in list_func_wrapper_baton and
1519    returns new baton and callback to use with svn_client_list3(). */
1520 static void
wrap_list_func(svn_client_list_func2_t * list_func2,void ** list_func2_baton,svn_client_list_func_t list_func,void * baton,apr_pool_t * result_pool)1521 wrap_list_func(svn_client_list_func2_t *list_func2,
1522                void **list_func2_baton,
1523                svn_client_list_func_t list_func,
1524                void *baton,
1525                apr_pool_t *result_pool)
1526 {
1527   struct list_func_wrapper_baton *lfwb = apr_palloc(result_pool,
1528                                                     sizeof(*lfwb));
1529 
1530   /* Set the user provided old format callback in the baton. */
1531   lfwb->list_func1_baton = baton;
1532   lfwb->list_func1 = list_func;
1533 
1534   *list_func2_baton = lfwb;
1535   *list_func2 = list_func_wrapper;
1536 }
1537 
1538 svn_error_t *
svn_client_list2(const char * path_or_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_depth_t depth,apr_uint32_t dirent_fields,svn_boolean_t fetch_locks,svn_client_list_func_t list_func,void * baton,svn_client_ctx_t * ctx,apr_pool_t * pool)1539 svn_client_list2(const char *path_or_url,
1540                  const svn_opt_revision_t *peg_revision,
1541                  const svn_opt_revision_t *revision,
1542                  svn_depth_t depth,
1543                  apr_uint32_t dirent_fields,
1544                  svn_boolean_t fetch_locks,
1545                  svn_client_list_func_t list_func,
1546                  void *baton,
1547                  svn_client_ctx_t *ctx,
1548                  apr_pool_t *pool)
1549 {
1550   svn_client_list_func2_t list_func2;
1551   void *list_func2_baton;
1552 
1553   wrap_list_func(&list_func2, &list_func2_baton, list_func, baton, pool);
1554 
1555   return svn_client_list3(path_or_url, peg_revision, revision, depth,
1556                           dirent_fields, fetch_locks,
1557                           FALSE /* include externals */,
1558                           list_func2, list_func2_baton, ctx, pool);
1559 }
1560 
1561 svn_error_t *
svn_client_list(const char * path_or_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_boolean_t recurse,apr_uint32_t dirent_fields,svn_boolean_t fetch_locks,svn_client_list_func_t list_func,void * baton,svn_client_ctx_t * ctx,apr_pool_t * pool)1562 svn_client_list(const char *path_or_url,
1563                 const svn_opt_revision_t *peg_revision,
1564                 const svn_opt_revision_t *revision,
1565                 svn_boolean_t recurse,
1566                 apr_uint32_t dirent_fields,
1567                 svn_boolean_t fetch_locks,
1568                 svn_client_list_func_t list_func,
1569                 void *baton,
1570                 svn_client_ctx_t *ctx,
1571                 apr_pool_t *pool)
1572 {
1573   return svn_client_list2(path_or_url,
1574                           peg_revision,
1575                           revision,
1576                           SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
1577                           dirent_fields,
1578                           fetch_locks,
1579                           list_func,
1580                           baton,
1581                           ctx,
1582                           pool);
1583 }
1584 
1585 /* Baton used by compatibility wrapper svn_client_ls3. */
1586 struct ls_baton {
1587   apr_hash_t *dirents;
1588   apr_hash_t *locks;
1589   apr_pool_t *pool;
1590 };
1591 
1592 /* This implements svn_client_list_func_t. */
1593 static svn_error_t *
store_dirent(void * baton,const char * path,const svn_dirent_t * dirent,const svn_lock_t * lock,const char * abs_path,apr_pool_t * pool)1594 store_dirent(void *baton, const char *path, const svn_dirent_t *dirent,
1595              const svn_lock_t *lock, const char *abs_path, apr_pool_t *pool)
1596 {
1597   struct ls_baton *lb = baton;
1598 
1599   /* The dirent is allocated in a temporary pool, so duplicate it into the
1600      correct pool.  Note, however, that the locks are stored in the correct
1601      pool already. */
1602   dirent = svn_dirent_dup(dirent, lb->pool);
1603 
1604   /* An empty path means we are called for the target of the operation.
1605      For compatibility, we only store the target if it is a file, and we
1606      store it under the basename of the URL.  Note that this makes it
1607      impossible to differentiate between the target being a directory with a
1608      child with the same basename as the target and the target being a file,
1609      but that's how it was implemented. */
1610   if (path[0] == '\0')
1611     {
1612       if (dirent->kind == svn_node_file)
1613         {
1614           const char *base_name = svn_path_basename(abs_path, lb->pool);
1615           svn_hash_sets(lb->dirents, base_name, dirent);
1616           if (lock)
1617             svn_hash_sets(lb->locks, base_name, lock);
1618         }
1619     }
1620   else
1621     {
1622       path = apr_pstrdup(lb->pool, path);
1623       svn_hash_sets(lb->dirents, path, dirent);
1624       if (lock)
1625         svn_hash_sets(lb->locks, path, lock);
1626     }
1627 
1628   return SVN_NO_ERROR;
1629 }
1630 
1631 svn_error_t *
svn_client_ls3(apr_hash_t ** dirents,apr_hash_t ** locks,const char * path_or_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)1632 svn_client_ls3(apr_hash_t **dirents,
1633                apr_hash_t **locks,
1634                const char *path_or_url,
1635                const svn_opt_revision_t *peg_revision,
1636                const svn_opt_revision_t *revision,
1637                svn_boolean_t recurse,
1638                svn_client_ctx_t *ctx,
1639                apr_pool_t *pool)
1640 {
1641   struct ls_baton lb;
1642 
1643   *dirents = lb.dirents = apr_hash_make(pool);
1644   if (locks)
1645     *locks = lb.locks = apr_hash_make(pool);
1646   lb.pool = pool;
1647 
1648   return svn_client_list(path_or_url, peg_revision, revision, recurse,
1649                          SVN_DIRENT_ALL, locks != NULL,
1650                          store_dirent, &lb, ctx, pool);
1651 }
1652 
1653 svn_error_t *
svn_client_ls2(apr_hash_t ** dirents,const char * path_or_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)1654 svn_client_ls2(apr_hash_t **dirents,
1655                const char *path_or_url,
1656                const svn_opt_revision_t *peg_revision,
1657                const svn_opt_revision_t *revision,
1658                svn_boolean_t recurse,
1659                svn_client_ctx_t *ctx,
1660                apr_pool_t *pool)
1661 {
1662 
1663   return svn_client_ls3(dirents, NULL, path_or_url, peg_revision,
1664                         revision, recurse, ctx, pool);
1665 }
1666 
1667 
1668 svn_error_t *
svn_client_ls(apr_hash_t ** dirents,const char * path_or_url,svn_opt_revision_t * revision,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)1669 svn_client_ls(apr_hash_t **dirents,
1670               const char *path_or_url,
1671               svn_opt_revision_t *revision,
1672               svn_boolean_t recurse,
1673               svn_client_ctx_t *ctx,
1674               apr_pool_t *pool)
1675 {
1676   return svn_client_ls2(dirents, path_or_url, revision,
1677                         revision, recurse, ctx, pool);
1678 }
1679 
1680 /*** From log.c ***/
1681 
1682 svn_error_t *
svn_client_log4(const apr_array_header_t * targets,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start,const svn_opt_revision_t * end,int limit,svn_boolean_t discover_changed_paths,svn_boolean_t strict_node_history,svn_boolean_t include_merged_revisions,const apr_array_header_t * revprops,svn_log_entry_receiver_t receiver,void * receiver_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)1683 svn_client_log4(const apr_array_header_t *targets,
1684                 const svn_opt_revision_t *peg_revision,
1685                 const svn_opt_revision_t *start,
1686                 const svn_opt_revision_t *end,
1687                 int limit,
1688                 svn_boolean_t discover_changed_paths,
1689                 svn_boolean_t strict_node_history,
1690                 svn_boolean_t include_merged_revisions,
1691                 const apr_array_header_t *revprops,
1692                 svn_log_entry_receiver_t receiver,
1693                 void *receiver_baton,
1694                 svn_client_ctx_t *ctx,
1695                 apr_pool_t *pool)
1696 {
1697   apr_array_header_t *revision_ranges;
1698 
1699   revision_ranges = apr_array_make(pool, 1,
1700                                    sizeof(svn_opt_revision_range_t *));
1701   APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
1702     = svn_opt__revision_range_create(start, end, pool);
1703 
1704   return svn_client_log5(targets, peg_revision, revision_ranges, limit,
1705                          discover_changed_paths, strict_node_history,
1706                          include_merged_revisions, revprops, receiver,
1707                          receiver_baton, ctx, pool);
1708 }
1709 
1710 
1711 svn_error_t *
svn_client_log3(const apr_array_header_t * targets,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * start,const svn_opt_revision_t * end,int limit,svn_boolean_t discover_changed_paths,svn_boolean_t strict_node_history,svn_log_message_receiver_t receiver,void * receiver_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)1712 svn_client_log3(const apr_array_header_t *targets,
1713                 const svn_opt_revision_t *peg_revision,
1714                 const svn_opt_revision_t *start,
1715                 const svn_opt_revision_t *end,
1716                 int limit,
1717                 svn_boolean_t discover_changed_paths,
1718                 svn_boolean_t strict_node_history,
1719                 svn_log_message_receiver_t receiver,
1720                 void *receiver_baton,
1721                 svn_client_ctx_t *ctx,
1722                 apr_pool_t *pool)
1723 {
1724   svn_log_entry_receiver_t receiver2;
1725   void *receiver2_baton;
1726 
1727   svn_compat_wrap_log_receiver(&receiver2, &receiver2_baton,
1728                                receiver, receiver_baton,
1729                                pool);
1730 
1731   return svn_client_log4(targets, peg_revision, start, end, limit,
1732                          discover_changed_paths, strict_node_history, FALSE,
1733                          svn_compat_log_revprops_in(pool),
1734                          receiver2, receiver2_baton, ctx, pool);
1735 }
1736 
1737 svn_error_t *
svn_client_log2(const apr_array_header_t * targets,const svn_opt_revision_t * start,const svn_opt_revision_t * end,int limit,svn_boolean_t discover_changed_paths,svn_boolean_t strict_node_history,svn_log_message_receiver_t receiver,void * receiver_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)1738 svn_client_log2(const apr_array_header_t *targets,
1739                 const svn_opt_revision_t *start,
1740                 const svn_opt_revision_t *end,
1741                 int limit,
1742                 svn_boolean_t discover_changed_paths,
1743                 svn_boolean_t strict_node_history,
1744                 svn_log_message_receiver_t receiver,
1745                 void *receiver_baton,
1746                 svn_client_ctx_t *ctx,
1747                 apr_pool_t *pool)
1748 {
1749   svn_opt_revision_t peg_revision;
1750   peg_revision.kind = svn_opt_revision_unspecified;
1751   return svn_client_log3(targets, &peg_revision, start, end, limit,
1752                          discover_changed_paths, strict_node_history,
1753                          receiver, receiver_baton, ctx, pool);
1754 }
1755 
1756 svn_error_t *
svn_client_log(const apr_array_header_t * targets,const svn_opt_revision_t * start,const svn_opt_revision_t * end,svn_boolean_t discover_changed_paths,svn_boolean_t strict_node_history,svn_log_message_receiver_t receiver,void * receiver_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)1757 svn_client_log(const apr_array_header_t *targets,
1758                const svn_opt_revision_t *start,
1759                const svn_opt_revision_t *end,
1760                svn_boolean_t discover_changed_paths,
1761                svn_boolean_t strict_node_history,
1762                svn_log_message_receiver_t receiver,
1763                void *receiver_baton,
1764                svn_client_ctx_t *ctx,
1765                apr_pool_t *pool)
1766 {
1767   svn_error_t *err = SVN_NO_ERROR;
1768 
1769   err = svn_client_log2(targets, start, end, 0, discover_changed_paths,
1770                         strict_node_history, receiver, receiver_baton, ctx,
1771                         pool);
1772 
1773   /* Special case: If there have been no commits, we'll get an error
1774    * for requesting log of a revision higher than 0.  But the
1775    * default behavior of "svn log" is to give revisions HEAD through
1776    * 1, on the assumption that HEAD >= 1.
1777    *
1778    * So if we got that error for that reason, and it looks like the
1779    * user was just depending on the defaults (rather than explicitly
1780    * requesting the log for revision 1), then we don't error.  Instead
1781    * we just invoke the receiver manually on a hand-constructed log
1782    * message for revision 0.
1783    *
1784    * See also https://issues.apache.org/jira/browse/SVN-692.
1785    */
1786   if (err && (err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
1787       && (start->kind == svn_opt_revision_head)
1788       && ((end->kind == svn_opt_revision_number)
1789           && (end->value.number == 1)))
1790     {
1791 
1792       /* We don't need to check if HEAD is 0, because that must be the case,
1793        * by logical deduction: The revision range specified is HEAD:1.
1794        * HEAD cannot not exist, so the revision to which "no such revision"
1795        * applies is 1. If revision 1 does not exist, then HEAD is 0.
1796        * Hence, we deduce the repository is empty without needing access
1797        * to further information. */
1798 
1799       svn_error_clear(err);
1800       err = SVN_NO_ERROR;
1801 
1802       /* Log receivers are free to handle revision 0 specially... But
1803          just in case some don't, we make up a message here. */
1804       SVN_ERR(receiver(receiver_baton,
1805                        NULL, 0, "", "", _("No commits in repository"),
1806                        pool));
1807     }
1808 
1809   return svn_error_trace(err);
1810 }
1811 
1812 /*** From merge.c ***/
1813 
1814 svn_error_t *
svn_client_merge4(const char * source1,const svn_opt_revision_t * revision1,const char * source2,const svn_opt_revision_t * revision2,const char * target_wcpath,svn_depth_t depth,svn_boolean_t ignore_ancestry,svn_boolean_t force_delete,svn_boolean_t record_only,svn_boolean_t dry_run,svn_boolean_t allow_mixed_rev,const apr_array_header_t * merge_options,svn_client_ctx_t * ctx,apr_pool_t * pool)1815 svn_client_merge4(const char *source1,
1816                   const svn_opt_revision_t *revision1,
1817                   const char *source2,
1818                   const svn_opt_revision_t *revision2,
1819                   const char *target_wcpath,
1820                   svn_depth_t depth,
1821                   svn_boolean_t ignore_ancestry,
1822                   svn_boolean_t force_delete,
1823                   svn_boolean_t record_only,
1824                   svn_boolean_t dry_run,
1825                   svn_boolean_t allow_mixed_rev,
1826                   const apr_array_header_t *merge_options,
1827                   svn_client_ctx_t *ctx,
1828                   apr_pool_t *pool)
1829 {
1830   SVN_ERR(svn_client_merge5(source1, revision1,
1831                             source2, revision2,
1832                             target_wcpath,
1833                             depth,
1834                             ignore_ancestry /*ignore_mergeinfo*/,
1835                             ignore_ancestry /*diff_ignore_ancestry*/,
1836                             force_delete, record_only,
1837                             dry_run, allow_mixed_rev,
1838                             merge_options, ctx, pool));
1839   return SVN_NO_ERROR;
1840 }
1841 
1842 svn_error_t *
svn_client_merge3(const char * source1,const svn_opt_revision_t * revision1,const char * source2,const svn_opt_revision_t * revision2,const char * target_wcpath,svn_depth_t depth,svn_boolean_t ignore_ancestry,svn_boolean_t force,svn_boolean_t record_only,svn_boolean_t dry_run,const apr_array_header_t * merge_options,svn_client_ctx_t * ctx,apr_pool_t * pool)1843 svn_client_merge3(const char *source1,
1844                   const svn_opt_revision_t *revision1,
1845                   const char *source2,
1846                   const svn_opt_revision_t *revision2,
1847                   const char *target_wcpath,
1848                   svn_depth_t depth,
1849                   svn_boolean_t ignore_ancestry,
1850                   svn_boolean_t force,
1851                   svn_boolean_t record_only,
1852                   svn_boolean_t dry_run,
1853                   const apr_array_header_t *merge_options,
1854                   svn_client_ctx_t *ctx,
1855                   apr_pool_t *pool)
1856 {
1857   return svn_client_merge4(source1, revision1, source2, revision2,
1858                            target_wcpath, depth, ignore_ancestry, force,
1859                            record_only, dry_run, TRUE, merge_options,
1860                            ctx, pool);
1861 }
1862 
1863 svn_error_t *
svn_client_merge2(const char * source1,const svn_opt_revision_t * revision1,const char * source2,const svn_opt_revision_t * revision2,const char * target_wcpath,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_boolean_t force,svn_boolean_t dry_run,const apr_array_header_t * merge_options,svn_client_ctx_t * ctx,apr_pool_t * pool)1864 svn_client_merge2(const char *source1,
1865                   const svn_opt_revision_t *revision1,
1866                   const char *source2,
1867                   const svn_opt_revision_t *revision2,
1868                   const char *target_wcpath,
1869                   svn_boolean_t recurse,
1870                   svn_boolean_t ignore_ancestry,
1871                   svn_boolean_t force,
1872                   svn_boolean_t dry_run,
1873                   const apr_array_header_t *merge_options,
1874                   svn_client_ctx_t *ctx,
1875                   apr_pool_t *pool)
1876 {
1877   return svn_client_merge3(source1, revision1, source2, revision2,
1878                            target_wcpath,
1879                            SVN_DEPTH_INFINITY_OR_FILES(recurse),
1880                            ignore_ancestry, force, FALSE, dry_run,
1881                            merge_options, ctx, pool);
1882 }
1883 
1884 svn_error_t *
svn_client_merge(const char * source1,const svn_opt_revision_t * revision1,const char * source2,const svn_opt_revision_t * revision2,const char * target_wcpath,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_boolean_t force,svn_boolean_t dry_run,svn_client_ctx_t * ctx,apr_pool_t * pool)1885 svn_client_merge(const char *source1,
1886                  const svn_opt_revision_t *revision1,
1887                  const char *source2,
1888                  const svn_opt_revision_t *revision2,
1889                  const char *target_wcpath,
1890                  svn_boolean_t recurse,
1891                  svn_boolean_t ignore_ancestry,
1892                  svn_boolean_t force,
1893                  svn_boolean_t dry_run,
1894                  svn_client_ctx_t *ctx,
1895                  apr_pool_t *pool)
1896 {
1897   return svn_client_merge2(source1, revision1, source2, revision2,
1898                            target_wcpath, recurse, ignore_ancestry, force,
1899                            dry_run, NULL, ctx, pool);
1900 }
1901 
1902 svn_error_t *
svn_client_merge_peg4(const char * source_path_or_url,const apr_array_header_t * ranges_to_merge,const svn_opt_revision_t * source_peg_revision,const char * target_wcpath,svn_depth_t depth,svn_boolean_t ignore_ancestry,svn_boolean_t force_delete,svn_boolean_t record_only,svn_boolean_t dry_run,svn_boolean_t allow_mixed_rev,const apr_array_header_t * merge_options,svn_client_ctx_t * ctx,apr_pool_t * pool)1903 svn_client_merge_peg4(const char *source_path_or_url,
1904                       const apr_array_header_t *ranges_to_merge,
1905                       const svn_opt_revision_t *source_peg_revision,
1906                       const char *target_wcpath,
1907                       svn_depth_t depth,
1908                       svn_boolean_t ignore_ancestry,
1909                       svn_boolean_t force_delete,
1910                       svn_boolean_t record_only,
1911                       svn_boolean_t dry_run,
1912                       svn_boolean_t allow_mixed_rev,
1913                       const apr_array_header_t *merge_options,
1914                       svn_client_ctx_t *ctx,
1915                       apr_pool_t *pool)
1916 {
1917   SVN_ERR(svn_client_merge_peg5(source_path_or_url,
1918                                 ranges_to_merge,
1919                                 source_peg_revision,
1920                                 target_wcpath,
1921                                 depth,
1922                                 ignore_ancestry /*ignore_mergeinfo*/,
1923                                 ignore_ancestry /*diff_ignore_ancestry*/,
1924                                 force_delete, record_only,
1925                                 dry_run, allow_mixed_rev,
1926                                 merge_options, ctx, pool));
1927   return SVN_NO_ERROR;
1928 }
1929 
1930 svn_error_t *
svn_client_merge_peg3(const char * source,const apr_array_header_t * ranges_to_merge,const svn_opt_revision_t * peg_revision,const char * target_wcpath,svn_depth_t depth,svn_boolean_t ignore_ancestry,svn_boolean_t force,svn_boolean_t record_only,svn_boolean_t dry_run,const apr_array_header_t * merge_options,svn_client_ctx_t * ctx,apr_pool_t * pool)1931 svn_client_merge_peg3(const char *source,
1932                       const apr_array_header_t *ranges_to_merge,
1933                       const svn_opt_revision_t *peg_revision,
1934                       const char *target_wcpath,
1935                       svn_depth_t depth,
1936                       svn_boolean_t ignore_ancestry,
1937                       svn_boolean_t force,
1938                       svn_boolean_t record_only,
1939                       svn_boolean_t dry_run,
1940                       const apr_array_header_t *merge_options,
1941                       svn_client_ctx_t *ctx,
1942                       apr_pool_t *pool)
1943 {
1944   return svn_client_merge_peg4(source, ranges_to_merge, peg_revision,
1945                                target_wcpath, depth, ignore_ancestry, force,
1946                                record_only, dry_run, TRUE, merge_options,
1947                                ctx, pool);
1948 }
1949 
1950 svn_error_t *
svn_client_merge_peg2(const char * source,const svn_opt_revision_t * revision1,const svn_opt_revision_t * revision2,const svn_opt_revision_t * peg_revision,const char * target_wcpath,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_boolean_t force,svn_boolean_t dry_run,const apr_array_header_t * merge_options,svn_client_ctx_t * ctx,apr_pool_t * pool)1951 svn_client_merge_peg2(const char *source,
1952                       const svn_opt_revision_t *revision1,
1953                       const svn_opt_revision_t *revision2,
1954                       const svn_opt_revision_t *peg_revision,
1955                       const char *target_wcpath,
1956                       svn_boolean_t recurse,
1957                       svn_boolean_t ignore_ancestry,
1958                       svn_boolean_t force,
1959                       svn_boolean_t dry_run,
1960                       const apr_array_header_t *merge_options,
1961                       svn_client_ctx_t *ctx,
1962                       apr_pool_t *pool)
1963 {
1964   apr_array_header_t *ranges_to_merge =
1965     apr_array_make(pool, 1, sizeof(svn_opt_revision_range_t *));
1966 
1967   APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *)
1968     = svn_opt__revision_range_create(revision1, revision2, pool);
1969   return svn_client_merge_peg3(source, ranges_to_merge,
1970                                peg_revision,
1971                                target_wcpath,
1972                                SVN_DEPTH_INFINITY_OR_FILES(recurse),
1973                                ignore_ancestry, force, FALSE, dry_run,
1974                                merge_options, ctx, pool);
1975 }
1976 
1977 svn_error_t *
svn_client_merge_peg(const char * source,const svn_opt_revision_t * revision1,const svn_opt_revision_t * revision2,const svn_opt_revision_t * peg_revision,const char * target_wcpath,svn_boolean_t recurse,svn_boolean_t ignore_ancestry,svn_boolean_t force,svn_boolean_t dry_run,svn_client_ctx_t * ctx,apr_pool_t * pool)1978 svn_client_merge_peg(const char *source,
1979                      const svn_opt_revision_t *revision1,
1980                      const svn_opt_revision_t *revision2,
1981                      const svn_opt_revision_t *peg_revision,
1982                      const char *target_wcpath,
1983                      svn_boolean_t recurse,
1984                      svn_boolean_t ignore_ancestry,
1985                      svn_boolean_t force,
1986                      svn_boolean_t dry_run,
1987                      svn_client_ctx_t *ctx,
1988                      apr_pool_t *pool)
1989 {
1990   return svn_client_merge_peg2(source, revision1, revision2, peg_revision,
1991                                target_wcpath, recurse, ignore_ancestry, force,
1992                                dry_run, NULL, ctx, pool);
1993 }
1994 
1995 /*** From prop_commands.c ***/
1996 svn_error_t *
svn_client_propset3(svn_commit_info_t ** commit_info_p,const char * propname,const svn_string_t * propval,const char * target,svn_depth_t depth,svn_boolean_t skip_checks,svn_revnum_t base_revision_for_url,const apr_array_header_t * changelists,const apr_hash_t * revprop_table,svn_client_ctx_t * ctx,apr_pool_t * pool)1997 svn_client_propset3(svn_commit_info_t **commit_info_p,
1998                     const char *propname,
1999                     const svn_string_t *propval,
2000                     const char *target,
2001                     svn_depth_t depth,
2002                     svn_boolean_t skip_checks,
2003                     svn_revnum_t base_revision_for_url,
2004                     const apr_array_header_t *changelists,
2005                     const apr_hash_t *revprop_table,
2006                     svn_client_ctx_t *ctx,
2007                     apr_pool_t *pool)
2008 {
2009   if (svn_path_is_url(target))
2010     {
2011       struct capture_baton_t cb;
2012 
2013       cb.info = commit_info_p;
2014       cb.pool = pool;
2015 
2016       SVN_ERR(svn_client_propset_remote(propname, propval, target, skip_checks,
2017                                         base_revision_for_url, revprop_table,
2018                                         capture_commit_info, &cb, ctx, pool));
2019     }
2020   else
2021     {
2022       apr_array_header_t *targets = apr_array_make(pool, 1,
2023                                                    sizeof(const char *));
2024 
2025       APR_ARRAY_PUSH(targets, const char *) = target;
2026       SVN_ERR(svn_client_propset_local(propname, propval, targets, depth,
2027                                        skip_checks, changelists, ctx, pool));
2028     }
2029 
2030   return SVN_NO_ERROR;
2031 }
2032 
2033 svn_error_t *
svn_client_propset2(const char * propname,const svn_string_t * propval,const char * target,svn_boolean_t recurse,svn_boolean_t skip_checks,svn_client_ctx_t * ctx,apr_pool_t * pool)2034 svn_client_propset2(const char *propname,
2035                     const svn_string_t *propval,
2036                     const char *target,
2037                     svn_boolean_t recurse,
2038                     svn_boolean_t skip_checks,
2039                     svn_client_ctx_t *ctx,
2040                     apr_pool_t *pool)
2041 {
2042   return svn_client_propset3(NULL, propname, propval, target,
2043                              SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
2044                              skip_checks, SVN_INVALID_REVNUM,
2045                              NULL, NULL, ctx, pool);
2046 }
2047 
2048 
2049 svn_error_t *
svn_client_propset(const char * propname,const svn_string_t * propval,const char * target,svn_boolean_t recurse,apr_pool_t * pool)2050 svn_client_propset(const char *propname,
2051                    const svn_string_t *propval,
2052                    const char *target,
2053                    svn_boolean_t recurse,
2054                    apr_pool_t *pool)
2055 {
2056   svn_client_ctx_t *ctx;
2057 
2058   SVN_ERR(svn_client_create_context(&ctx, pool));
2059 
2060   return svn_client_propset2(propname, propval, target, recurse, FALSE,
2061                              ctx, pool);
2062 }
2063 
2064 svn_error_t *
svn_client_revprop_set(const char * propname,const svn_string_t * propval,const char * URL,const svn_opt_revision_t * revision,svn_revnum_t * set_rev,svn_boolean_t force,svn_client_ctx_t * ctx,apr_pool_t * pool)2065 svn_client_revprop_set(const char *propname,
2066                        const svn_string_t *propval,
2067                        const char *URL,
2068                        const svn_opt_revision_t *revision,
2069                        svn_revnum_t *set_rev,
2070                        svn_boolean_t force,
2071                        svn_client_ctx_t *ctx,
2072                        apr_pool_t *pool)
2073 {
2074   return svn_client_revprop_set2(propname, propval, NULL, URL,
2075                                  revision, set_rev, force, ctx, pool);
2076 
2077 }
2078 
2079 svn_error_t *
svn_client_propget4(apr_hash_t ** props,const char * propname,const char * target,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_revnum_t * actual_revnum,svn_depth_t depth,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * result_pool,apr_pool_t * scratch_pool)2080 svn_client_propget4(apr_hash_t **props,
2081                     const char *propname,
2082                     const char *target,
2083                     const svn_opt_revision_t *peg_revision,
2084                     const svn_opt_revision_t *revision,
2085                     svn_revnum_t *actual_revnum,
2086                     svn_depth_t depth,
2087                     const apr_array_header_t *changelists,
2088                     svn_client_ctx_t *ctx,
2089                     apr_pool_t *result_pool,
2090                     apr_pool_t *scratch_pool)
2091 {
2092   return svn_error_trace(svn_client_propget5(props, NULL, propname, target,
2093                                              peg_revision, revision,
2094                                              actual_revnum, depth,
2095                                              changelists, ctx,
2096                                              result_pool, scratch_pool));
2097 }
2098 
2099 svn_error_t *
svn_client_propget3(apr_hash_t ** props,const char * propname,const char * path_or_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_revnum_t * actual_revnum,svn_depth_t depth,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * pool)2100 svn_client_propget3(apr_hash_t **props,
2101                     const char *propname,
2102                     const char *path_or_url,
2103                     const svn_opt_revision_t *peg_revision,
2104                     const svn_opt_revision_t *revision,
2105                     svn_revnum_t *actual_revnum,
2106                     svn_depth_t depth,
2107                     const apr_array_header_t *changelists,
2108                     svn_client_ctx_t *ctx,
2109                     apr_pool_t *pool)
2110 {
2111   const char *target;
2112   apr_hash_t *temp_props;
2113   svn_error_t *err;
2114 
2115   if (svn_path_is_url(path_or_url))
2116     target = path_or_url;
2117   else
2118     SVN_ERR(svn_dirent_get_absolute(&target, path_or_url, pool));
2119 
2120   err = svn_client_propget4(&temp_props, propname, target,
2121                             peg_revision, revision, actual_revnum,
2122                             depth, changelists, ctx, pool, pool);
2123 
2124   if (err && err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE)
2125     {
2126       err->apr_err = SVN_ERR_ENTRY_NOT_FOUND;
2127       return svn_error_trace(err);
2128     }
2129   else
2130     SVN_ERR(err);
2131 
2132   if (actual_revnum
2133         && !svn_path_is_url(path_or_url)
2134         && !SVN_IS_VALID_REVNUM(*actual_revnum))
2135     {
2136       /* Get the actual_revnum; added nodes have no revision yet, and old
2137        * callers expected the mock-up revision of 0. */
2138       svn_boolean_t added;
2139 
2140       SVN_ERR(svn_wc__node_is_added(&added, ctx->wc_ctx, target, pool));
2141       if (added)
2142         *actual_revnum = 0;
2143     }
2144 
2145   /* We may need to fix up our hash keys for legacy callers. */
2146   if (!svn_path_is_url(path_or_url) && strcmp(target, path_or_url) != 0)
2147     {
2148       apr_hash_index_t *hi;
2149 
2150       *props = apr_hash_make(pool);
2151       for (hi = apr_hash_first(pool, temp_props); hi;
2152             hi = apr_hash_next(hi))
2153         {
2154           const char *abspath = apr_hash_this_key(hi);
2155           svn_string_t *value = apr_hash_this_val(hi);
2156           const char *relpath = svn_dirent_join(path_or_url,
2157                                      svn_dirent_skip_ancestor(target, abspath),
2158                                      pool);
2159 
2160           svn_hash_sets(*props, relpath, value);
2161         }
2162     }
2163   else
2164     *props = temp_props;
2165 
2166   return SVN_NO_ERROR;
2167 }
2168 
2169 svn_error_t *
svn_client_propget2(apr_hash_t ** props,const char * propname,const char * target,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)2170 svn_client_propget2(apr_hash_t **props,
2171                     const char *propname,
2172                     const char *target,
2173                     const svn_opt_revision_t *peg_revision,
2174                     const svn_opt_revision_t *revision,
2175                     svn_boolean_t recurse,
2176                     svn_client_ctx_t *ctx,
2177                     apr_pool_t *pool)
2178 {
2179   return svn_client_propget3(props,
2180                              propname,
2181                              target,
2182                              peg_revision,
2183                              revision,
2184                              NULL,
2185                              SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
2186                              NULL,
2187                              ctx,
2188                              pool);
2189 }
2190 
2191 svn_error_t *
svn_client_propget(apr_hash_t ** props,const char * propname,const char * target,const svn_opt_revision_t * revision,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)2192 svn_client_propget(apr_hash_t **props,
2193                    const char *propname,
2194                    const char *target,
2195                    const svn_opt_revision_t *revision,
2196                    svn_boolean_t recurse,
2197                    svn_client_ctx_t *ctx,
2198                    apr_pool_t *pool)
2199 {
2200   return svn_client_propget2(props, propname, target, revision, revision,
2201                              recurse, ctx, pool);
2202 }
2203 
2204 
2205 /* Duplicate a HASH containing (char * -> svn_string_t *) key/value
2206    pairs using POOL. */
2207 static apr_hash_t *
string_hash_dup(apr_hash_t * hash,apr_pool_t * pool)2208 string_hash_dup(apr_hash_t *hash, apr_pool_t *pool)
2209 {
2210   apr_hash_index_t *hi;
2211   apr_hash_t *new_hash = apr_hash_make(pool);
2212 
2213   for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
2214     {
2215       const char *key = apr_pstrdup(pool, apr_hash_this_key(hi));
2216       apr_ssize_t klen = apr_hash_this_key_len(hi);
2217       svn_string_t *val = svn_string_dup(apr_hash_this_val(hi), pool);
2218 
2219       apr_hash_set(new_hash, key, klen, val);
2220     }
2221   return new_hash;
2222 }
2223 
2224 svn_client_proplist_item_t *
svn_client_proplist_item_dup(const svn_client_proplist_item_t * item,apr_pool_t * pool)2225 svn_client_proplist_item_dup(const svn_client_proplist_item_t *item,
2226                              apr_pool_t * pool)
2227 {
2228   svn_client_proplist_item_t *new_item = apr_pcalloc(pool, sizeof(*new_item));
2229 
2230   if (item->node_name)
2231     new_item->node_name = svn_stringbuf_dup(item->node_name, pool);
2232 
2233   if (item->prop_hash)
2234     new_item->prop_hash = string_hash_dup(item->prop_hash, pool);
2235 
2236   return new_item;
2237 }
2238 
2239 /* Baton for use with wrap_proplist_receiver */
2240 struct proplist_receiver_wrapper_baton {
2241   void *baton;
2242   svn_proplist_receiver_t receiver;
2243 };
2244 
2245 /* This implements svn_client_proplist_receiver2_t */
2246 static svn_error_t *
proplist_wrapper_receiver(void * baton,const char * path,apr_hash_t * prop_hash,apr_array_header_t * inherited_props,apr_pool_t * pool)2247 proplist_wrapper_receiver(void *baton,
2248                           const char *path,
2249                           apr_hash_t *prop_hash,
2250                           apr_array_header_t *inherited_props,
2251                           apr_pool_t *pool)
2252 {
2253   struct proplist_receiver_wrapper_baton *plrwb = baton;
2254 
2255   if (plrwb->receiver)
2256     return plrwb->receiver(plrwb->baton, path, prop_hash, pool);
2257 
2258   return SVN_NO_ERROR;
2259 }
2260 
2261 static void
wrap_proplist_receiver(svn_proplist_receiver2_t * receiver2,void ** receiver2_baton,svn_proplist_receiver_t receiver,void * receiver_baton,apr_pool_t * pool)2262 wrap_proplist_receiver(svn_proplist_receiver2_t *receiver2,
2263                        void **receiver2_baton,
2264                        svn_proplist_receiver_t receiver,
2265                        void *receiver_baton,
2266                        apr_pool_t *pool)
2267 {
2268   struct proplist_receiver_wrapper_baton *plrwb = apr_palloc(pool,
2269                                                              sizeof(*plrwb));
2270 
2271   /* Set the user provided old format callback in the baton. */
2272   plrwb->baton = receiver_baton;
2273   plrwb->receiver = receiver;
2274 
2275   *receiver2_baton = plrwb;
2276   *receiver2 = proplist_wrapper_receiver;
2277 }
2278 
2279 svn_error_t *
svn_client_proplist3(const char * target,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_depth_t depth,const apr_array_header_t * changelists,svn_proplist_receiver_t receiver,void * receiver_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)2280 svn_client_proplist3(const char *target,
2281                      const svn_opt_revision_t *peg_revision,
2282                      const svn_opt_revision_t *revision,
2283                      svn_depth_t depth,
2284                      const apr_array_header_t *changelists,
2285                      svn_proplist_receiver_t receiver,
2286                      void *receiver_baton,
2287                      svn_client_ctx_t *ctx,
2288                      apr_pool_t *pool)
2289 {
2290 
2291   svn_proplist_receiver2_t receiver2;
2292   void *receiver2_baton;
2293 
2294   wrap_proplist_receiver(&receiver2, &receiver2_baton, receiver, receiver_baton,
2295                          pool);
2296 
2297   return svn_error_trace(svn_client_proplist4(target, peg_revision, revision,
2298                                               depth, changelists, FALSE,
2299                                               receiver2, receiver2_baton,
2300                                               ctx, pool));
2301 }
2302 
2303 /* Receiver baton used by proplist2() */
2304 struct proplist_receiver_baton {
2305   apr_array_header_t *props;
2306   apr_pool_t *pool;
2307 };
2308 
2309 /* Receiver function used by proplist2(). */
2310 static svn_error_t *
proplist_receiver_cb(void * baton,const char * path,apr_hash_t * prop_hash,apr_pool_t * pool)2311 proplist_receiver_cb(void *baton,
2312                      const char *path,
2313                      apr_hash_t *prop_hash,
2314                      apr_pool_t *pool)
2315 {
2316   struct proplist_receiver_baton *pl_baton =
2317     (struct proplist_receiver_baton *) baton;
2318   svn_client_proplist_item_t *tmp_item = apr_palloc(pool, sizeof(*tmp_item));
2319   svn_client_proplist_item_t *item;
2320 
2321   /* Because the pool passed to the receiver function is likely to be a
2322      temporary pool of some kind, we need to make copies of *path and
2323      *prop_hash in the pool provided by the baton. */
2324   tmp_item->node_name = svn_stringbuf_create(path, pl_baton->pool);
2325   tmp_item->prop_hash = prop_hash;
2326 
2327   item = svn_client_proplist_item_dup(tmp_item, pl_baton->pool);
2328 
2329   APR_ARRAY_PUSH(pl_baton->props, const svn_client_proplist_item_t *) = item;
2330 
2331   return SVN_NO_ERROR;
2332 }
2333 
2334 svn_error_t *
svn_client_proplist2(apr_array_header_t ** props,const char * target,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)2335 svn_client_proplist2(apr_array_header_t **props,
2336                      const char *target,
2337                      const svn_opt_revision_t *peg_revision,
2338                      const svn_opt_revision_t *revision,
2339                      svn_boolean_t recurse,
2340                      svn_client_ctx_t *ctx,
2341                      apr_pool_t *pool)
2342 {
2343   struct proplist_receiver_baton pl_baton;
2344 
2345   *props = apr_array_make(pool, 5, sizeof(svn_client_proplist_item_t *));
2346   pl_baton.props = *props;
2347   pl_baton.pool = pool;
2348 
2349   return svn_client_proplist3(target, peg_revision, revision,
2350                               SVN_DEPTH_INFINITY_OR_EMPTY(recurse), NULL,
2351                               proplist_receiver_cb, &pl_baton, ctx, pool);
2352 }
2353 
2354 
2355 svn_error_t *
svn_client_proplist(apr_array_header_t ** props,const char * target,const svn_opt_revision_t * revision,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)2356 svn_client_proplist(apr_array_header_t **props,
2357                     const char *target,
2358                     const svn_opt_revision_t *revision,
2359                     svn_boolean_t recurse,
2360                     svn_client_ctx_t *ctx,
2361                     apr_pool_t *pool)
2362 {
2363   return svn_client_proplist2(props, target, revision, revision,
2364                               recurse, ctx, pool);
2365 }
2366 
2367 /*** From status.c ***/
2368 
2369 svn_error_t *
svn_client_status5(svn_revnum_t * result_rev,svn_client_ctx_t * ctx,const char * path,const svn_opt_revision_t * revision,svn_depth_t depth,svn_boolean_t get_all,svn_boolean_t update,svn_boolean_t no_ignore,svn_boolean_t ignore_externals,svn_boolean_t depth_as_sticky,const apr_array_header_t * changelists,svn_client_status_func_t status_func,void * status_baton,apr_pool_t * scratch_pool)2370 svn_client_status5(svn_revnum_t *result_rev,
2371                    svn_client_ctx_t *ctx,
2372                    const char *path,
2373                    const svn_opt_revision_t *revision,
2374                    svn_depth_t depth,
2375                    svn_boolean_t get_all,
2376                    svn_boolean_t update,
2377                    svn_boolean_t no_ignore,
2378                    svn_boolean_t ignore_externals,
2379                    svn_boolean_t depth_as_sticky,
2380                    const apr_array_header_t *changelists,
2381                    svn_client_status_func_t status_func,
2382                    void *status_baton,
2383                    apr_pool_t *scratch_pool)
2384 {
2385   return svn_client_status6(result_rev, ctx, path, revision, depth,
2386                             get_all, update, TRUE, no_ignore,
2387                             ignore_externals, depth_as_sticky, changelists,
2388                             status_func, status_baton, scratch_pool);
2389 }
2390 
2391 struct status4_wrapper_baton
2392 {
2393   svn_wc_context_t *wc_ctx;
2394   svn_wc_status_func3_t old_func;
2395   void *old_baton;
2396 };
2397 
2398 /* Implements svn_client_status_func_t */
2399 static svn_error_t *
status4_wrapper_func(void * baton,const char * path,const svn_client_status_t * status,apr_pool_t * scratch_pool)2400 status4_wrapper_func(void *baton,
2401                      const char *path,
2402                      const svn_client_status_t *status,
2403                      apr_pool_t *scratch_pool)
2404 {
2405   struct status4_wrapper_baton *swb = baton;
2406   svn_wc_status2_t *dup;
2407   const char *local_abspath;
2408   const svn_wc_status3_t *wc_status = status->backwards_compatibility_baton;
2409 
2410   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
2411   SVN_ERR(svn_wc__status2_from_3(&dup, wc_status, swb->wc_ctx,
2412                                  local_abspath, scratch_pool,
2413                                  scratch_pool));
2414 
2415   return (*swb->old_func)(swb->old_baton, path, dup, scratch_pool);
2416 }
2417 
2418 svn_error_t *
svn_client_status4(svn_revnum_t * result_rev,const char * path,const svn_opt_revision_t * revision,svn_wc_status_func3_t status_func,void * status_baton,svn_depth_t depth,svn_boolean_t get_all,svn_boolean_t update,svn_boolean_t no_ignore,svn_boolean_t ignore_externals,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * pool)2419 svn_client_status4(svn_revnum_t *result_rev,
2420                    const char *path,
2421                    const svn_opt_revision_t *revision,
2422                    svn_wc_status_func3_t status_func,
2423                    void *status_baton,
2424                    svn_depth_t depth,
2425                    svn_boolean_t get_all,
2426                    svn_boolean_t update,
2427                    svn_boolean_t no_ignore,
2428                    svn_boolean_t ignore_externals,
2429                    const apr_array_header_t *changelists,
2430                    svn_client_ctx_t *ctx,
2431                    apr_pool_t *pool)
2432 {
2433   struct status4_wrapper_baton swb;
2434 
2435   swb.wc_ctx = ctx->wc_ctx;
2436   swb.old_func = status_func;
2437   swb.old_baton = status_baton;
2438 
2439   return svn_client_status5(result_rev, ctx, path, revision, depth, get_all,
2440                             update, no_ignore, ignore_externals, TRUE,
2441                             changelists, status4_wrapper_func, &swb, pool);
2442 }
2443 
2444 struct status3_wrapper_baton
2445 {
2446   svn_wc_status_func2_t old_func;
2447   void *old_baton;
2448 };
2449 
2450 static svn_error_t *
status3_wrapper_func(void * baton,const char * path,svn_wc_status2_t * status,apr_pool_t * pool)2451 status3_wrapper_func(void *baton,
2452                      const char *path,
2453                      svn_wc_status2_t *status,
2454                      apr_pool_t *pool)
2455 {
2456   struct status3_wrapper_baton *swb = baton;
2457 
2458   swb->old_func(swb->old_baton, path, status);
2459   return SVN_NO_ERROR;
2460 }
2461 
2462 svn_error_t *
svn_client_status3(svn_revnum_t * result_rev,const char * path,const svn_opt_revision_t * revision,svn_wc_status_func2_t status_func,void * status_baton,svn_depth_t depth,svn_boolean_t get_all,svn_boolean_t update,svn_boolean_t no_ignore,svn_boolean_t ignore_externals,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * pool)2463 svn_client_status3(svn_revnum_t *result_rev,
2464                    const char *path,
2465                    const svn_opt_revision_t *revision,
2466                    svn_wc_status_func2_t status_func,
2467                    void *status_baton,
2468                    svn_depth_t depth,
2469                    svn_boolean_t get_all,
2470                    svn_boolean_t update,
2471                    svn_boolean_t no_ignore,
2472                    svn_boolean_t ignore_externals,
2473                    const apr_array_header_t *changelists,
2474                    svn_client_ctx_t *ctx,
2475                    apr_pool_t *pool)
2476 {
2477   struct status3_wrapper_baton swb = { 0 };
2478   swb.old_func = status_func;
2479   swb.old_baton = status_baton;
2480   return svn_client_status4(result_rev, path, revision, status3_wrapper_func,
2481                             &swb, depth, get_all, update, no_ignore,
2482                             ignore_externals, changelists, ctx, pool);
2483 }
2484 
2485 svn_error_t *
svn_client_status2(svn_revnum_t * result_rev,const char * path,const svn_opt_revision_t * revision,svn_wc_status_func2_t status_func,void * status_baton,svn_boolean_t recurse,svn_boolean_t get_all,svn_boolean_t update,svn_boolean_t no_ignore,svn_boolean_t ignore_externals,svn_client_ctx_t * ctx,apr_pool_t * pool)2486 svn_client_status2(svn_revnum_t *result_rev,
2487                    const char *path,
2488                    const svn_opt_revision_t *revision,
2489                    svn_wc_status_func2_t status_func,
2490                    void *status_baton,
2491                    svn_boolean_t recurse,
2492                    svn_boolean_t get_all,
2493                    svn_boolean_t update,
2494                    svn_boolean_t no_ignore,
2495                    svn_boolean_t ignore_externals,
2496                    svn_client_ctx_t *ctx,
2497                    apr_pool_t *pool)
2498 {
2499   return svn_client_status3(result_rev, path, revision,
2500                             status_func, status_baton,
2501                             SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
2502                             get_all, update, no_ignore, ignore_externals, NULL,
2503                             ctx, pool);
2504 }
2505 
2506 
2507 /* Baton for old_status_func_cb; does what you think it does. */
2508 struct old_status_func_cb_baton
2509 {
2510   svn_wc_status_func_t original_func;
2511   void *original_baton;
2512 };
2513 
2514 /* Help svn_client_status() accept an old-style status func and baton,
2515    by wrapping them before passing along to svn_client_status2().
2516 
2517    This implements the 'svn_wc_status_func2_t' function type. */
old_status_func_cb(void * baton,const char * path,svn_wc_status2_t * status)2518 static void old_status_func_cb(void *baton,
2519                                const char *path,
2520                                svn_wc_status2_t *status)
2521 {
2522   struct old_status_func_cb_baton *b = baton;
2523   svn_wc_status_t *stat = (svn_wc_status_t *) status;
2524 
2525   b->original_func(b->original_baton, path, stat);
2526 }
2527 
2528 
2529 svn_error_t *
svn_client_status(svn_revnum_t * result_rev,const char * path,svn_opt_revision_t * revision,svn_wc_status_func_t status_func,void * status_baton,svn_boolean_t recurse,svn_boolean_t get_all,svn_boolean_t update,svn_boolean_t no_ignore,svn_client_ctx_t * ctx,apr_pool_t * pool)2530 svn_client_status(svn_revnum_t *result_rev,
2531                   const char *path,
2532                   svn_opt_revision_t *revision,
2533                   svn_wc_status_func_t status_func,
2534                   void *status_baton,
2535                   svn_boolean_t recurse,
2536                   svn_boolean_t get_all,
2537                   svn_boolean_t update,
2538                   svn_boolean_t no_ignore,
2539                   svn_client_ctx_t *ctx,
2540                   apr_pool_t *pool)
2541 {
2542   struct old_status_func_cb_baton *b = apr_pcalloc(pool, sizeof(*b));
2543   b->original_func = status_func;
2544   b->original_baton = status_baton;
2545 
2546   return svn_client_status2(result_rev, path, revision,
2547                             old_status_func_cb, b,
2548                             recurse, get_all, update, no_ignore, FALSE,
2549                             ctx, pool);
2550 }
2551 
2552 /*** From update.c ***/
2553 svn_error_t *
svn_client_update3(apr_array_header_t ** result_revs,const apr_array_header_t * paths,const svn_opt_revision_t * revision,svn_depth_t depth,svn_boolean_t depth_is_sticky,svn_boolean_t ignore_externals,svn_boolean_t allow_unver_obstructions,svn_client_ctx_t * ctx,apr_pool_t * pool)2554 svn_client_update3(apr_array_header_t **result_revs,
2555                    const apr_array_header_t *paths,
2556                    const svn_opt_revision_t *revision,
2557                    svn_depth_t depth,
2558                    svn_boolean_t depth_is_sticky,
2559                    svn_boolean_t ignore_externals,
2560                    svn_boolean_t allow_unver_obstructions,
2561                    svn_client_ctx_t *ctx,
2562                    apr_pool_t *pool)
2563 {
2564   return svn_client_update4(result_revs, paths, revision,
2565                             depth, depth_is_sticky, ignore_externals,
2566                             allow_unver_obstructions, TRUE, FALSE,
2567                             ctx, pool);
2568 }
2569 
2570 svn_error_t *
svn_client_update2(apr_array_header_t ** result_revs,const apr_array_header_t * paths,const svn_opt_revision_t * revision,svn_boolean_t recurse,svn_boolean_t ignore_externals,svn_client_ctx_t * ctx,apr_pool_t * pool)2571 svn_client_update2(apr_array_header_t **result_revs,
2572                    const apr_array_header_t *paths,
2573                    const svn_opt_revision_t *revision,
2574                    svn_boolean_t recurse,
2575                    svn_boolean_t ignore_externals,
2576                    svn_client_ctx_t *ctx,
2577                    apr_pool_t *pool)
2578 {
2579   return svn_client_update3(result_revs, paths, revision,
2580                             SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE,
2581                             ignore_externals, FALSE, ctx, pool);
2582 }
2583 
2584 svn_error_t *
svn_client_update(svn_revnum_t * result_rev,const char * path,const svn_opt_revision_t * revision,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)2585 svn_client_update(svn_revnum_t *result_rev,
2586                   const char *path,
2587                   const svn_opt_revision_t *revision,
2588                   svn_boolean_t recurse,
2589                   svn_client_ctx_t *ctx,
2590                   apr_pool_t *pool)
2591 {
2592   apr_array_header_t *paths = apr_array_make(pool, 1, sizeof(const char *));
2593   apr_array_header_t *result_revs;
2594 
2595   APR_ARRAY_PUSH(paths, const char *) = path;
2596 
2597   SVN_ERR(svn_client_update2(&result_revs, paths, revision, recurse, FALSE,
2598                              ctx, pool));
2599 
2600   *result_rev = APR_ARRAY_IDX(result_revs, 0, svn_revnum_t);
2601 
2602   return SVN_NO_ERROR;
2603 }
2604 
2605 /*** From switch.c ***/
2606 svn_error_t *
svn_client_switch2(svn_revnum_t * result_rev,const char * path,const char * switch_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_depth_t depth,svn_boolean_t depth_is_sticky,svn_boolean_t ignore_externals,svn_boolean_t allow_unver_obstructions,svn_client_ctx_t * ctx,apr_pool_t * pool)2607 svn_client_switch2(svn_revnum_t *result_rev,
2608                    const char *path,
2609                    const char *switch_url,
2610                    const svn_opt_revision_t *peg_revision,
2611                    const svn_opt_revision_t *revision,
2612                    svn_depth_t depth,
2613                    svn_boolean_t depth_is_sticky,
2614                    svn_boolean_t ignore_externals,
2615                    svn_boolean_t allow_unver_obstructions,
2616                    svn_client_ctx_t *ctx,
2617                    apr_pool_t *pool)
2618 {
2619   return svn_client_switch3(result_rev, path, switch_url, peg_revision,
2620                             revision, depth, depth_is_sticky, ignore_externals,
2621                             allow_unver_obstructions,
2622                             TRUE /* ignore_ancestry */,
2623                             ctx, pool);
2624 }
2625 
2626 svn_error_t *
svn_client_switch(svn_revnum_t * result_rev,const char * path,const char * switch_url,const svn_opt_revision_t * revision,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)2627 svn_client_switch(svn_revnum_t *result_rev,
2628                   const char *path,
2629                   const char *switch_url,
2630                   const svn_opt_revision_t *revision,
2631                   svn_boolean_t recurse,
2632                   svn_client_ctx_t *ctx,
2633                   apr_pool_t *pool)
2634 {
2635   svn_opt_revision_t peg_revision;
2636   peg_revision.kind = svn_opt_revision_unspecified;
2637   return svn_client_switch2(result_rev, path, switch_url,
2638                             &peg_revision, revision,
2639                             SVN_DEPTH_INFINITY_OR_FILES(recurse),
2640                             FALSE, FALSE, FALSE, ctx, pool);
2641 }
2642 
2643 /*** From cat.c ***/
2644 svn_error_t *
svn_client_cat2(svn_stream_t * out,const char * path_or_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_client_ctx_t * ctx,apr_pool_t * pool)2645 svn_client_cat2(svn_stream_t *out,
2646                 const char *path_or_url,
2647                 const svn_opt_revision_t *peg_revision,
2648                 const svn_opt_revision_t *revision,
2649                 svn_client_ctx_t *ctx,
2650                 apr_pool_t *pool)
2651 {
2652   return svn_client_cat3(NULL /* props */,
2653                          out, path_or_url, peg_revision, revision,
2654                          TRUE /* expand_keywords */,
2655                          ctx, pool, pool);
2656 }
2657 
2658 
2659 svn_error_t *
svn_client_cat(svn_stream_t * out,const char * path_or_url,const svn_opt_revision_t * revision,svn_client_ctx_t * ctx,apr_pool_t * pool)2660 svn_client_cat(svn_stream_t *out,
2661                const char *path_or_url,
2662                const svn_opt_revision_t *revision,
2663                svn_client_ctx_t *ctx,
2664                apr_pool_t *pool)
2665 {
2666   return svn_client_cat2(out, path_or_url, revision, revision,
2667                          ctx, pool);
2668 }
2669 
2670 /*** From checkout.c ***/
2671 svn_error_t *
svn_client_checkout2(svn_revnum_t * result_rev,const char * URL,const char * path,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_boolean_t recurse,svn_boolean_t ignore_externals,svn_client_ctx_t * ctx,apr_pool_t * pool)2672 svn_client_checkout2(svn_revnum_t *result_rev,
2673                      const char *URL,
2674                      const char *path,
2675                      const svn_opt_revision_t *peg_revision,
2676                      const svn_opt_revision_t *revision,
2677                      svn_boolean_t recurse,
2678                      svn_boolean_t ignore_externals,
2679                      svn_client_ctx_t *ctx,
2680                      apr_pool_t *pool)
2681 {
2682   return svn_error_trace(svn_client_checkout3(result_rev, URL, path,
2683                                         peg_revision, revision,
2684                                         SVN_DEPTH_INFINITY_OR_FILES(recurse),
2685                                         ignore_externals, FALSE, ctx, pool));
2686 }
2687 
2688 svn_error_t *
svn_client_checkout(svn_revnum_t * result_rev,const char * URL,const char * path,const svn_opt_revision_t * revision,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)2689 svn_client_checkout(svn_revnum_t *result_rev,
2690                     const char *URL,
2691                     const char *path,
2692                     const svn_opt_revision_t *revision,
2693                     svn_boolean_t recurse,
2694                     svn_client_ctx_t *ctx,
2695                     apr_pool_t *pool)
2696 {
2697   svn_opt_revision_t peg_revision;
2698 
2699   peg_revision.kind = svn_opt_revision_unspecified;
2700 
2701   return svn_error_trace(svn_client_checkout2(result_rev, URL, path,
2702                                               &peg_revision, revision, recurse,
2703                                               FALSE, ctx, pool));
2704 }
2705 
2706 /*** From info.c ***/
2707 
2708 svn_error_t *
svn_client_info3(const char * abspath_or_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_depth_t depth,svn_boolean_t fetch_excluded,svn_boolean_t fetch_actual_only,const apr_array_header_t * changelists,svn_client_info_receiver2_t receiver,void * receiver_baton,svn_client_ctx_t * ctx,apr_pool_t * pool)2709 svn_client_info3(const char *abspath_or_url,
2710                  const svn_opt_revision_t *peg_revision,
2711                  const svn_opt_revision_t *revision,
2712                  svn_depth_t depth,
2713                  svn_boolean_t fetch_excluded,
2714                  svn_boolean_t fetch_actual_only,
2715                  const apr_array_header_t *changelists,
2716                  svn_client_info_receiver2_t receiver,
2717                  void *receiver_baton,
2718                  svn_client_ctx_t *ctx,
2719                  apr_pool_t *pool)
2720 {
2721   return svn_error_trace(
2722             svn_client_info4(abspath_or_url,
2723                              peg_revision,
2724                              revision,
2725                              depth,
2726                              fetch_excluded,
2727                              fetch_actual_only,
2728                              FALSE /* include_externals */,
2729                              changelists,
2730                              receiver, receiver_baton,
2731                              ctx, pool));
2732 }
2733 
2734 svn_info_t *
svn_info_dup(const svn_info_t * info,apr_pool_t * pool)2735 svn_info_dup(const svn_info_t *info, apr_pool_t *pool)
2736 {
2737   svn_info_t *dupinfo = apr_palloc(pool, sizeof(*dupinfo));
2738 
2739   /* Perform a trivial copy ... */
2740   *dupinfo = *info;
2741 
2742   /* ...and then re-copy stuff that needs to be duped into our pool. */
2743   if (info->URL)
2744     dupinfo->URL = apr_pstrdup(pool, info->URL);
2745   if (info->repos_root_URL)
2746     dupinfo->repos_root_URL = apr_pstrdup(pool, info->repos_root_URL);
2747   if (info->repos_UUID)
2748     dupinfo->repos_UUID = apr_pstrdup(pool, info->repos_UUID);
2749   if (info->last_changed_author)
2750     dupinfo->last_changed_author = apr_pstrdup(pool,
2751                                                info->last_changed_author);
2752   if (info->lock)
2753     dupinfo->lock = svn_lock_dup(info->lock, pool);
2754   if (info->copyfrom_url)
2755     dupinfo->copyfrom_url = apr_pstrdup(pool, info->copyfrom_url);
2756   if (info->checksum)
2757     dupinfo->checksum = apr_pstrdup(pool, info->checksum);
2758   if (info->conflict_old)
2759     dupinfo->conflict_old = apr_pstrdup(pool, info->conflict_old);
2760   if (info->conflict_new)
2761     dupinfo->conflict_new = apr_pstrdup(pool, info->conflict_new);
2762   if (info->conflict_wrk)
2763     dupinfo->conflict_wrk = apr_pstrdup(pool, info->conflict_wrk);
2764   if (info->prejfile)
2765     dupinfo->prejfile = apr_pstrdup(pool, info->prejfile);
2766 
2767   return dupinfo;
2768 }
2769 
2770 /* Convert an svn_client_info2_t to an svn_info_t, doing shallow copies. */
2771 static svn_error_t *
info_from_info2(svn_info_t ** new_info,svn_wc_context_t * wc_ctx,const svn_client_info2_t * info2,apr_pool_t * pool)2772 info_from_info2(svn_info_t **new_info,
2773                 svn_wc_context_t *wc_ctx,
2774                 const svn_client_info2_t *info2,
2775                 apr_pool_t *pool)
2776 {
2777   svn_info_t *info = apr_pcalloc(pool, sizeof(*info));
2778 
2779   info->URL                 = info2->URL;
2780   /* Goofy backward compat handling for added nodes. */
2781   if (SVN_IS_VALID_REVNUM(info2->rev))
2782     info->rev               = info2->rev;
2783   else
2784     info->rev               = 0;
2785 
2786   info->kind                = info2->kind;
2787   info->repos_root_URL      = info2->repos_root_URL;
2788   info->repos_UUID          = info2->repos_UUID;
2789   info->last_changed_rev    = info2->last_changed_rev;
2790   info->last_changed_date   = info2->last_changed_date;
2791   info->last_changed_author = info2->last_changed_author;
2792 
2793   /* Stupid old structure has a non-const LOCK member. Sigh.  */
2794   info->lock                = (svn_lock_t *)info2->lock;
2795 
2796   info->size64              = info2->size;
2797   if (info2->size == SVN_INVALID_FILESIZE)
2798     info->size               = SVN_INFO_SIZE_UNKNOWN;
2799   else if (((svn_filesize_t)(apr_size_t)info->size64) == info->size64)
2800     info->size               = (apr_size_t)info->size64;
2801   else /* >= 4GB */
2802     info->size               = SVN_INFO_SIZE_UNKNOWN;
2803 
2804   if (info2->wc_info)
2805     {
2806       info->has_wc_info         = TRUE;
2807       info->schedule            = info2->wc_info->schedule;
2808       info->copyfrom_url        = info2->wc_info->copyfrom_url;
2809       info->copyfrom_rev        = info2->wc_info->copyfrom_rev;
2810       info->text_time           = info2->wc_info->recorded_time;
2811       info->prop_time           = 0;
2812       if (info2->wc_info->checksum
2813             && info2->wc_info->checksum->kind == svn_checksum_md5)
2814         info->checksum          = svn_checksum_to_cstring(
2815                                         info2->wc_info->checksum, pool);
2816       else
2817         info->checksum          = NULL;
2818       info->changelist          = info2->wc_info->changelist;
2819       info->depth               = info2->wc_info->depth;
2820 
2821       if (info->depth == svn_depth_unknown && info->kind == svn_node_file)
2822         info->depth = svn_depth_infinity;
2823 
2824       info->working_size64      = info2->wc_info->recorded_size;
2825       if (((svn_filesize_t)(apr_size_t)info->working_size64) == info->working_size64)
2826         info->working_size       = (apr_size_t)info->working_size64;
2827       else /* >= 4GB */
2828         info->working_size       = SVN_INFO_SIZE_UNKNOWN;
2829     }
2830   else
2831     {
2832       info->has_wc_info           = FALSE;
2833       info->working_size          = SVN_INFO_SIZE_UNKNOWN;
2834       info->working_size64        = SVN_INVALID_FILESIZE;
2835       info->depth                 = svn_depth_unknown;
2836     }
2837 
2838   /* Populate conflict fields. */
2839   if (info2->wc_info && info2->wc_info->conflicts)
2840     {
2841       int i;
2842 
2843       for (i = 0; i < info2->wc_info->conflicts->nelts; i++)
2844         {
2845           const svn_wc_conflict_description2_t *conflict
2846                               = APR_ARRAY_IDX(info2->wc_info->conflicts, i,
2847                                     const svn_wc_conflict_description2_t *);
2848 
2849           /* ### Not really sure what we should do if we get multiple
2850              ### conflicts of the same type. */
2851           switch (conflict->kind)
2852             {
2853               case svn_wc_conflict_kind_tree:
2854                 info->tree_conflict = svn_wc__cd2_to_cd(conflict, pool);
2855                 break;
2856 
2857               case svn_wc_conflict_kind_text:
2858                 info->conflict_old = conflict->base_abspath;
2859                 info->conflict_new = conflict->my_abspath;
2860                 info->conflict_wrk = conflict->their_abspath;
2861                 break;
2862 
2863               case svn_wc_conflict_kind_property:
2864                 info->prejfile = conflict->their_abspath;
2865                 break;
2866             }
2867         }
2868     }
2869 
2870   if (info2->wc_info && info2->wc_info->checksum)
2871     {
2872       const svn_checksum_t *md5_checksum;
2873 
2874       SVN_ERR(svn_wc__node_get_md5_from_sha1(&md5_checksum,
2875                                              wc_ctx,
2876                                              info2->wc_info->wcroot_abspath,
2877                                              info2->wc_info->checksum,
2878                                              pool, pool));
2879 
2880       info->checksum = svn_checksum_to_cstring(md5_checksum, pool);
2881     }
2882 
2883   *new_info = info;
2884   return SVN_NO_ERROR;
2885 }
2886 
2887 struct info_to_relpath_baton
2888 {
2889   const char *anchor_abspath;
2890   const char *anchor_relpath;
2891   svn_info_receiver_t info_receiver;
2892   void *info_baton;
2893   svn_wc_context_t *wc_ctx;
2894 };
2895 
2896 static svn_error_t *
info_receiver_relpath_wrapper(void * baton,const char * abspath_or_url,const svn_client_info2_t * info2,apr_pool_t * scratch_pool)2897 info_receiver_relpath_wrapper(void *baton,
2898                               const char *abspath_or_url,
2899                               const svn_client_info2_t *info2,
2900                               apr_pool_t *scratch_pool)
2901 {
2902   struct info_to_relpath_baton *rb = baton;
2903   const char *path = abspath_or_url;
2904   svn_info_t *info;
2905 
2906   if (rb->anchor_relpath &&
2907       svn_dirent_is_ancestor(rb->anchor_abspath, abspath_or_url))
2908     {
2909       path = svn_dirent_join(rb->anchor_relpath,
2910                              svn_dirent_skip_ancestor(rb->anchor_abspath,
2911                                                       abspath_or_url),
2912                              scratch_pool);
2913     }
2914 
2915   SVN_ERR(info_from_info2(&info, rb->wc_ctx, info2, scratch_pool));
2916 
2917   SVN_ERR(rb->info_receiver(rb->info_baton,
2918                             path,
2919                             info,
2920                             scratch_pool));
2921 
2922   return SVN_NO_ERROR;
2923 }
2924 
2925 svn_error_t *
svn_client_info2(const char * path_or_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_info_receiver_t receiver,void * receiver_baton,svn_depth_t depth,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * pool)2926 svn_client_info2(const char *path_or_url,
2927                  const svn_opt_revision_t *peg_revision,
2928                  const svn_opt_revision_t *revision,
2929                  svn_info_receiver_t receiver,
2930                  void *receiver_baton,
2931                  svn_depth_t depth,
2932                  const apr_array_header_t *changelists,
2933                  svn_client_ctx_t *ctx,
2934                  apr_pool_t *pool)
2935 {
2936   struct info_to_relpath_baton rb;
2937   const char *abspath_or_url = path_or_url;
2938 
2939   rb.anchor_relpath = NULL;
2940   rb.info_receiver = receiver;
2941   rb.info_baton = receiver_baton;
2942   rb.wc_ctx = ctx->wc_ctx;
2943 
2944   if (!svn_path_is_url(path_or_url))
2945     {
2946       SVN_ERR(svn_dirent_get_absolute(&abspath_or_url, path_or_url, pool));
2947       rb.anchor_abspath = abspath_or_url;
2948       rb.anchor_relpath = path_or_url;
2949     }
2950 
2951   SVN_ERR(svn_client_info3(abspath_or_url,
2952                            peg_revision,
2953                            revision,
2954                            depth,
2955                            FALSE, TRUE,
2956                            changelists,
2957                            info_receiver_relpath_wrapper,
2958                            &rb,
2959                            ctx,
2960                            pool));
2961 
2962   return SVN_NO_ERROR;
2963 }
2964 
2965 svn_error_t *
svn_client_info(const char * path_or_url,const svn_opt_revision_t * peg_revision,const svn_opt_revision_t * revision,svn_info_receiver_t receiver,void * receiver_baton,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)2966 svn_client_info(const char *path_or_url,
2967                 const svn_opt_revision_t *peg_revision,
2968                 const svn_opt_revision_t *revision,
2969                 svn_info_receiver_t receiver,
2970                 void *receiver_baton,
2971                 svn_boolean_t recurse,
2972                 svn_client_ctx_t *ctx,
2973                 apr_pool_t *pool)
2974 {
2975   return svn_client_info2(path_or_url, peg_revision, revision,
2976                           receiver, receiver_baton,
2977                           SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
2978                           NULL, ctx, pool);
2979 }
2980 
2981 /*** From resolved.c ***/
2982 svn_error_t *
svn_client_resolved(const char * path,svn_boolean_t recursive,svn_client_ctx_t * ctx,apr_pool_t * pool)2983 svn_client_resolved(const char *path,
2984                     svn_boolean_t recursive,
2985                     svn_client_ctx_t *ctx,
2986                     apr_pool_t *pool)
2987 {
2988   svn_depth_t depth = SVN_DEPTH_INFINITY_OR_EMPTY(recursive);
2989   return svn_client_resolve(path, depth,
2990                             svn_wc_conflict_choose_merged, ctx, pool);
2991 }
2992 /*** From revert.c ***/
2993 svn_error_t *
svn_client_revert3(const apr_array_header_t * paths,svn_depth_t depth,const apr_array_header_t * changelists,svn_boolean_t clear_changelists,svn_boolean_t metadata_only,svn_client_ctx_t * ctx,apr_pool_t * pool)2994 svn_client_revert3(const apr_array_header_t *paths,
2995                    svn_depth_t depth,
2996                    const apr_array_header_t *changelists,
2997                    svn_boolean_t clear_changelists,
2998                    svn_boolean_t metadata_only,
2999                    svn_client_ctx_t *ctx,
3000                    apr_pool_t *pool)
3001 {
3002   SVN_ERR(svn_client_revert4(paths, depth, changelists,
3003                              clear_changelists, metadata_only,
3004                              TRUE /*added_keep_local*/,
3005                              ctx, pool));
3006   return SVN_NO_ERROR;
3007 }
3008 
3009 svn_error_t *
svn_client_revert2(const apr_array_header_t * paths,svn_depth_t depth,const apr_array_header_t * changelists,svn_client_ctx_t * ctx,apr_pool_t * pool)3010 svn_client_revert2(const apr_array_header_t *paths,
3011                    svn_depth_t depth,
3012                    const apr_array_header_t *changelists,
3013                    svn_client_ctx_t *ctx,
3014                    apr_pool_t *pool)
3015 {
3016   return svn_error_trace(svn_client_revert3(paths,
3017                                             depth,
3018                                             changelists,
3019                                             FALSE /* clear_changelists */,
3020                                             FALSE /* metadata_only */,
3021                                             ctx,
3022                                             pool));
3023 }
3024 
3025 svn_error_t *
svn_client_revert(const apr_array_header_t * paths,svn_boolean_t recursive,svn_client_ctx_t * ctx,apr_pool_t * pool)3026 svn_client_revert(const apr_array_header_t *paths,
3027                   svn_boolean_t recursive,
3028                   svn_client_ctx_t *ctx,
3029                   apr_pool_t *pool)
3030 {
3031   return svn_client_revert2(paths, SVN_DEPTH_INFINITY_OR_EMPTY(recursive),
3032                             NULL, ctx, pool);
3033 }
3034 
3035 /*** From ra.c ***/
3036 svn_error_t *
svn_client_open_ra_session(svn_ra_session_t ** session,const char * url,svn_client_ctx_t * ctx,apr_pool_t * pool)3037 svn_client_open_ra_session(svn_ra_session_t **session,
3038                            const char *url,
3039                            svn_client_ctx_t *ctx,
3040                            apr_pool_t *pool)
3041 {
3042   return svn_error_trace(
3043              svn_client_open_ra_session2(session, url,
3044                                          NULL, ctx,
3045                                          pool, pool));
3046 }
3047 
3048 svn_error_t *
svn_client_uuid_from_url(const char ** uuid,const char * url,svn_client_ctx_t * ctx,apr_pool_t * pool)3049 svn_client_uuid_from_url(const char **uuid,
3050                          const char *url,
3051                          svn_client_ctx_t *ctx,
3052                          apr_pool_t *pool)
3053 {
3054   svn_error_t *err;
3055   apr_pool_t *subpool = svn_pool_create(pool);
3056 
3057   err = svn_client_get_repos_root(NULL, uuid, url,
3058                                   ctx, pool, subpool);
3059   /* destroy the RA session */
3060   svn_pool_destroy(subpool);
3061 
3062   return svn_error_trace(err);
3063 }
3064 
3065 svn_error_t *
svn_client_uuid_from_path2(const char ** uuid,const char * local_abspath,svn_client_ctx_t * ctx,apr_pool_t * result_pool,apr_pool_t * scratch_pool)3066 svn_client_uuid_from_path2(const char **uuid,
3067                            const char *local_abspath,
3068                            svn_client_ctx_t *ctx,
3069                            apr_pool_t *result_pool,
3070                            apr_pool_t *scratch_pool)
3071 {
3072   return svn_error_trace(
3073       svn_client_get_repos_root(NULL, uuid,
3074                                 local_abspath, ctx,
3075                                 result_pool, scratch_pool));
3076 }
3077 
3078 svn_error_t *
svn_client_uuid_from_path(const char ** uuid,const char * path,svn_wc_adm_access_t * adm_access,svn_client_ctx_t * ctx,apr_pool_t * pool)3079 svn_client_uuid_from_path(const char **uuid,
3080                           const char *path,
3081                           svn_wc_adm_access_t *adm_access,
3082                           svn_client_ctx_t *ctx,
3083                           apr_pool_t *pool)
3084 {
3085   const char *local_abspath;
3086 
3087   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
3088   return svn_error_trace(
3089     svn_client_uuid_from_path2(uuid, local_abspath, ctx, pool, pool));
3090 }
3091 
3092 /*** From url.c ***/
3093 svn_error_t *
svn_client_root_url_from_path(const char ** url,const char * path_or_url,svn_client_ctx_t * ctx,apr_pool_t * pool)3094 svn_client_root_url_from_path(const char **url,
3095                               const char *path_or_url,
3096                               svn_client_ctx_t *ctx,
3097                               apr_pool_t *pool)
3098 {
3099   apr_pool_t *subpool = svn_pool_create(pool);
3100   svn_error_t *err;
3101   if (!svn_path_is_url(path_or_url))
3102     SVN_ERR(svn_dirent_get_absolute(&path_or_url, path_or_url, pool));
3103 
3104   err = svn_client_get_repos_root(url, NULL, path_or_url,
3105                                   ctx, pool, subpool);
3106 
3107   /* close ra session */
3108   svn_pool_destroy(subpool);
3109   return svn_error_trace(err);
3110 }
3111 
3112 svn_error_t *
svn_client_url_from_path(const char ** url,const char * path_or_url,apr_pool_t * pool)3113 svn_client_url_from_path(const char **url,
3114                          const char *path_or_url,
3115                          apr_pool_t *pool)
3116 {
3117   svn_client_ctx_t *ctx;
3118 
3119   SVN_ERR(svn_client_create_context(&ctx, pool));
3120 
3121   return svn_client_url_from_path2(url, path_or_url, ctx, pool, pool);
3122 }
3123 
3124 /*** From mergeinfo.c ***/
3125 svn_error_t *
svn_client_mergeinfo_log(svn_boolean_t finding_merged,const char * target_path_or_url,const svn_opt_revision_t * target_peg_revision,const char * source_path_or_url,const svn_opt_revision_t * source_peg_revision,svn_log_entry_receiver_t receiver,void * receiver_baton,svn_boolean_t discover_changed_paths,svn_depth_t depth,const apr_array_header_t * revprops,svn_client_ctx_t * ctx,apr_pool_t * scratch_pool)3126 svn_client_mergeinfo_log(svn_boolean_t finding_merged,
3127                          const char *target_path_or_url,
3128                          const svn_opt_revision_t *target_peg_revision,
3129                          const char *source_path_or_url,
3130                          const svn_opt_revision_t *source_peg_revision,
3131                          svn_log_entry_receiver_t receiver,
3132                          void *receiver_baton,
3133                          svn_boolean_t discover_changed_paths,
3134                          svn_depth_t depth,
3135                          const apr_array_header_t *revprops,
3136                          svn_client_ctx_t *ctx,
3137                          apr_pool_t *scratch_pool)
3138 {
3139   svn_opt_revision_t start_revision, end_revision;
3140 
3141   start_revision.kind = svn_opt_revision_unspecified;
3142   end_revision.kind = svn_opt_revision_unspecified;
3143 
3144   return svn_client_mergeinfo_log2(finding_merged,
3145                                    target_path_or_url, target_peg_revision,
3146                                    source_path_or_url, source_peg_revision,
3147                                    &start_revision, &end_revision,
3148                                    receiver, receiver_baton,
3149                                    discover_changed_paths, depth, revprops,
3150                                    ctx, scratch_pool);
3151 }
3152 
3153 svn_error_t *
svn_client_mergeinfo_log_merged(const char * path_or_url,const svn_opt_revision_t * peg_revision,const char * merge_source_path_or_url,const svn_opt_revision_t * src_peg_revision,svn_log_entry_receiver_t log_receiver,void * log_receiver_baton,svn_boolean_t discover_changed_paths,const apr_array_header_t * revprops,svn_client_ctx_t * ctx,apr_pool_t * pool)3154 svn_client_mergeinfo_log_merged(const char *path_or_url,
3155                                 const svn_opt_revision_t *peg_revision,
3156                                 const char *merge_source_path_or_url,
3157                                 const svn_opt_revision_t *src_peg_revision,
3158                                 svn_log_entry_receiver_t log_receiver,
3159                                 void *log_receiver_baton,
3160                                 svn_boolean_t discover_changed_paths,
3161                                 const apr_array_header_t *revprops,
3162                                 svn_client_ctx_t *ctx,
3163                                 apr_pool_t *pool)
3164 {
3165   return svn_client_mergeinfo_log(TRUE, path_or_url, peg_revision,
3166                                   merge_source_path_or_url,
3167                                   src_peg_revision,
3168                                   log_receiver, log_receiver_baton,
3169                                   discover_changed_paths,
3170                                   svn_depth_empty, revprops, ctx,
3171                                   pool);
3172 }
3173 
3174 svn_error_t *
svn_client_mergeinfo_log_eligible(const char * path_or_url,const svn_opt_revision_t * peg_revision,const char * merge_source_path_or_url,const svn_opt_revision_t * src_peg_revision,svn_log_entry_receiver_t log_receiver,void * log_receiver_baton,svn_boolean_t discover_changed_paths,const apr_array_header_t * revprops,svn_client_ctx_t * ctx,apr_pool_t * pool)3175 svn_client_mergeinfo_log_eligible(const char *path_or_url,
3176                                   const svn_opt_revision_t *peg_revision,
3177                                   const char *merge_source_path_or_url,
3178                                   const svn_opt_revision_t *src_peg_revision,
3179                                   svn_log_entry_receiver_t log_receiver,
3180                                   void *log_receiver_baton,
3181                                   svn_boolean_t discover_changed_paths,
3182                                   const apr_array_header_t *revprops,
3183                                   svn_client_ctx_t *ctx,
3184                                   apr_pool_t *pool)
3185 {
3186   return svn_client_mergeinfo_log(FALSE, path_or_url, peg_revision,
3187                                   merge_source_path_or_url,
3188                                   src_peg_revision,
3189                                   log_receiver, log_receiver_baton,
3190                                   discover_changed_paths,
3191                                   svn_depth_empty, revprops, ctx,
3192                                   pool);
3193 }
3194 
3195 /*** From relocate.c ***/
3196 svn_error_t *
svn_client_relocate(const char * path,const char * from_prefix,const char * to_prefix,svn_boolean_t recurse,svn_client_ctx_t * ctx,apr_pool_t * pool)3197 svn_client_relocate(const char *path,
3198                     const char *from_prefix,
3199                     const char *to_prefix,
3200                     svn_boolean_t recurse,
3201                     svn_client_ctx_t *ctx,
3202                     apr_pool_t *pool)
3203 {
3204   if (! recurse)
3205     SVN_ERR(svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
3206                              _("Non-recursive relocation not supported")));
3207   return svn_client_relocate2(path, from_prefix, to_prefix, TRUE, ctx, pool);
3208 }
3209 
3210 /*** From util.c ***/
3211 svn_error_t *
svn_client_commit_item_create(const svn_client_commit_item3_t ** item,apr_pool_t * pool)3212 svn_client_commit_item_create(const svn_client_commit_item3_t **item,
3213                               apr_pool_t *pool)
3214 {
3215   *item = svn_client_commit_item3_create(pool);
3216   return SVN_NO_ERROR;
3217 }
3218 
3219 svn_client_commit_item2_t *
svn_client_commit_item2_dup(const svn_client_commit_item2_t * item,apr_pool_t * pool)3220 svn_client_commit_item2_dup(const svn_client_commit_item2_t *item,
3221                             apr_pool_t *pool)
3222 {
3223   svn_client_commit_item2_t *new_item = apr_palloc(pool, sizeof(*new_item));
3224 
3225   *new_item = *item;
3226 
3227   if (new_item->path)
3228     new_item->path = apr_pstrdup(pool, new_item->path);
3229 
3230   if (new_item->url)
3231     new_item->url = apr_pstrdup(pool, new_item->url);
3232 
3233   if (new_item->copyfrom_url)
3234     new_item->copyfrom_url = apr_pstrdup(pool, new_item->copyfrom_url);
3235 
3236   if (new_item->wcprop_changes)
3237     new_item->wcprop_changes = svn_prop_array_dup(new_item->wcprop_changes,
3238                                                   pool);
3239 
3240   return new_item;
3241 }
3242 
3243 svn_error_t *
svn_client_cleanup(const char * path,svn_client_ctx_t * ctx,apr_pool_t * scratch_pool)3244 svn_client_cleanup(const char *path,
3245                    svn_client_ctx_t *ctx,
3246                    apr_pool_t *scratch_pool)
3247 {
3248   const char *local_abspath;
3249 
3250   if (svn_path_is_url(path))
3251     return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
3252                              _("'%s' is not a local path"), path);
3253 
3254   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
3255 
3256   return svn_error_trace(svn_client_cleanup2(local_abspath,
3257                                              TRUE /* break_locks */,
3258                                              TRUE /* fix_recorded_timestamps */,
3259                                              TRUE /* clear_dav_cache */,
3260                                              TRUE /* vacuum_pristines */,
3261                                              FALSE /* include_externals */,
3262                                              ctx, scratch_pool));
3263 }
3264