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