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