2 * deprecated.c: holding file for all deprecated APIs.
3 * "we can't lose 'em, but we can shun 'em!"
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
14 * http://www.apache.org/licenses/LICENSE-2.0
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
22 * ====================================================================
25 /* ==================================================================== */
31 /* We define this here to remove any further warnings about the usage of
32 deprecated functions in this file. */
33 #define SVN_DEPRECATED
36 #include "svn_client.h"
38 #include "svn_compat.h"
40 #include "svn_props.h"
42 #include "svn_string.h"
43 #include "svn_pools.h"
46 #include "mergeinfo.h"
48 #include "private/svn_opt_private.h"
49 #include "private/svn_wc_private.h"
50 #include "svn_private_config.h"
58 /* Baton for capture_commit_info() */
59 struct capture_baton_t {
60 svn_commit_info_t **info;
65 /* Callback which implements svn_commit_callback2_t for use with some
66 backward compat functions. */
68 capture_commit_info(const svn_commit_info_t *commit_info,
72 struct capture_baton_t *cb = baton;
74 *(cb->info) = svn_commit_info_dup(commit_info, cb->pool);
82 svn_client_add4(const char *path,
85 svn_boolean_t no_ignore,
86 svn_boolean_t add_parents,
87 svn_client_ctx_t *ctx,
90 return svn_client_add5(path, depth, force, no_ignore, FALSE, add_parents,
95 svn_client_add3(const char *path,
96 svn_boolean_t recursive,
98 svn_boolean_t no_ignore,
99 svn_client_ctx_t *ctx,
102 return svn_client_add4(path, SVN_DEPTH_INFINITY_OR_EMPTY(recursive),
103 force, no_ignore, FALSE, ctx,
108 svn_client_add2(const char *path,
109 svn_boolean_t recursive,
111 svn_client_ctx_t *ctx,
114 return svn_client_add3(path, recursive, force, FALSE, ctx, pool);
118 svn_client_add(const char *path,
119 svn_boolean_t recursive,
120 svn_client_ctx_t *ctx,
123 return svn_client_add3(path, recursive, FALSE, FALSE, ctx, 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,
134 struct capture_baton_t cb;
136 cb.info = commit_info_p;
139 return svn_client_mkdir4(paths, make_parents, revprop_table,
140 capture_commit_info, &cb, ctx, 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,
149 return svn_client_mkdir3(commit_info_p, paths, FALSE, NULL, ctx, 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,
159 svn_commit_info_t *commit_info = NULL;
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);
168 /*** From blame.c ***/
170 struct blame_receiver_wrapper_baton2 {
172 svn_client_blame_receiver2_t receiver;
176 blame_wrapper_receiver2(void *baton,
177 svn_revnum_t start_revnum,
178 svn_revnum_t end_revnum,
180 svn_revnum_t revision,
181 apr_hash_t *rev_props,
182 svn_revnum_t merged_revision,
183 apr_hash_t *merged_rev_props,
184 const char *merged_path,
186 svn_boolean_t local_change,
189 struct blame_receiver_wrapper_baton2 *brwb = baton;
190 const char *author = NULL;
191 const char *date = NULL;
192 const char *merged_author = NULL;
193 const char *merged_date = NULL;
195 if (rev_props != NULL)
197 author = svn_prop_get_value(rev_props, SVN_PROP_REVISION_AUTHOR);
198 date = svn_prop_get_value(rev_props, SVN_PROP_REVISION_DATE);
200 if (merged_rev_props != NULL)
202 merged_author = svn_prop_get_value(merged_rev_props,
203 SVN_PROP_REVISION_AUTHOR);
204 merged_date = svn_prop_get_value(merged_rev_props,
205 SVN_PROP_REVISION_DATE);
209 return brwb->receiver(brwb->baton, line_no, revision, author, date,
210 merged_revision, merged_author, merged_date,
211 merged_path, line, pool);
217 svn_client_blame4(const char *target,
218 const svn_opt_revision_t *peg_revision,
219 const svn_opt_revision_t *start,
220 const svn_opt_revision_t *end,
221 const svn_diff_file_options_t *diff_options,
222 svn_boolean_t ignore_mime_type,
223 svn_boolean_t include_merged_revisions,
224 svn_client_blame_receiver2_t receiver,
225 void *receiver_baton,
226 svn_client_ctx_t *ctx,
229 struct blame_receiver_wrapper_baton2 baton;
231 baton.receiver = receiver;
232 baton.baton = receiver_baton;
234 return svn_client_blame5(target, peg_revision, start, end, diff_options,
235 ignore_mime_type, include_merged_revisions,
236 blame_wrapper_receiver2, &baton, ctx, pool);
240 /* Baton for use with wrap_blame_receiver */
241 struct blame_receiver_wrapper_baton {
243 svn_client_blame_receiver_t receiver;
246 /* This implements svn_client_blame_receiver2_t */
248 blame_wrapper_receiver(void *baton,
250 svn_revnum_t revision,
253 svn_revnum_t merged_revision,
254 const char *merged_author,
255 const char *merged_date,
256 const char *merged_path,
260 struct blame_receiver_wrapper_baton *brwb = baton;
263 return brwb->receiver(brwb->baton,
264 line_no, revision, author, date, line, pool);
270 wrap_blame_receiver(svn_client_blame_receiver2_t *receiver2,
271 void **receiver2_baton,
272 svn_client_blame_receiver_t receiver,
273 void *receiver_baton,
276 struct blame_receiver_wrapper_baton *brwb = apr_palloc(pool, sizeof(*brwb));
278 /* Set the user provided old format callback in the baton. */
279 brwb->baton = receiver_baton;
280 brwb->receiver = receiver;
282 *receiver2_baton = brwb;
283 *receiver2 = blame_wrapper_receiver;
287 svn_client_blame3(const char *target,
288 const svn_opt_revision_t *peg_revision,
289 const svn_opt_revision_t *start,
290 const svn_opt_revision_t *end,
291 const svn_diff_file_options_t *diff_options,
292 svn_boolean_t ignore_mime_type,
293 svn_client_blame_receiver_t receiver,
294 void *receiver_baton,
295 svn_client_ctx_t *ctx,
298 svn_client_blame_receiver2_t receiver2;
299 void *receiver2_baton;
301 wrap_blame_receiver(&receiver2, &receiver2_baton, receiver, receiver_baton,
304 return svn_client_blame4(target, peg_revision, start, end, diff_options,
305 ignore_mime_type, FALSE, receiver2, receiver2_baton,
309 /* svn_client_blame3 guarantees 'no EOL chars' as part of the receiver
310 LINE argument. Older versions depend on the fact that if a CR is
311 required, that CR is already part of the LINE data.
313 Because of this difference, we need to trap old receivers and append
314 a CR to LINE before passing it on to the actual receiver on platforms
315 which want CRLF line termination.
319 struct wrapped_receiver_baton_s
321 svn_client_blame_receiver_t orig_receiver;
326 wrapped_receiver(void *baton,
328 svn_revnum_t revision,
334 struct wrapped_receiver_baton_s *b = baton;
335 svn_stringbuf_t *expanded_line = svn_stringbuf_create(line, pool);
337 svn_stringbuf_appendbyte(expanded_line, '\r');
339 return b->orig_receiver(b->orig_baton, line_no, revision, author,
340 date, expanded_line->data, pool);
344 wrap_pre_blame3_receiver(svn_client_blame_receiver_t *receiver,
345 void **receiver_baton,
348 if (sizeof(APR_EOL_STR) == 3)
350 struct wrapped_receiver_baton_s *b = apr_palloc(pool,sizeof(*b));
352 b->orig_receiver = *receiver;
353 b->orig_baton = *receiver_baton;
356 *receiver = wrapped_receiver;
361 svn_client_blame2(const char *target,
362 const svn_opt_revision_t *peg_revision,
363 const svn_opt_revision_t *start,
364 const svn_opt_revision_t *end,
365 svn_client_blame_receiver_t receiver,
366 void *receiver_baton,
367 svn_client_ctx_t *ctx,
370 wrap_pre_blame3_receiver(&receiver, &receiver_baton, pool);
371 return svn_client_blame3(target, peg_revision, start, end,
372 svn_diff_file_options_create(pool), FALSE,
373 receiver, receiver_baton, ctx, pool);
376 svn_client_blame(const char *target,
377 const svn_opt_revision_t *start,
378 const svn_opt_revision_t *end,
379 svn_client_blame_receiver_t receiver,
380 void *receiver_baton,
381 svn_client_ctx_t *ctx,
384 wrap_pre_blame3_receiver(&receiver, &receiver_baton, pool);
385 return svn_client_blame2(target, end, start, end,
386 receiver, receiver_baton, ctx, pool);
389 /*** From cmdline.c ***/
391 svn_client_args_to_target_array(apr_array_header_t **targets_p,
393 const apr_array_header_t *known_targets,
394 svn_client_ctx_t *ctx,
397 return svn_client_args_to_target_array2(targets_p, os, known_targets, ctx,
401 /*** From commit.c ***/
403 svn_client_import4(const char *path,
406 svn_boolean_t no_ignore,
407 svn_boolean_t ignore_unknown_node_types,
408 const apr_hash_t *revprop_table,
409 svn_commit_callback2_t commit_callback,
411 svn_client_ctx_t *ctx,
414 return svn_error_trace(svn_client_import5(path, url, depth, no_ignore,
415 FALSE, ignore_unknown_node_types,
418 commit_callback, commit_baton,
424 svn_client_import3(svn_commit_info_t **commit_info_p,
428 svn_boolean_t no_ignore,
429 svn_boolean_t ignore_unknown_node_types,
430 const apr_hash_t *revprop_table,
431 svn_client_ctx_t *ctx,
434 struct capture_baton_t cb;
436 cb.info = commit_info_p;
439 return svn_client_import4(path, url, depth, no_ignore,
440 ignore_unknown_node_types, revprop_table,
441 capture_commit_info, &cb, ctx, pool);
445 svn_client_import2(svn_commit_info_t **commit_info_p,
448 svn_boolean_t nonrecursive,
449 svn_boolean_t no_ignore,
450 svn_client_ctx_t *ctx,
453 return svn_client_import3(commit_info_p,
455 SVN_DEPTH_INFINITY_OR_FILES(! nonrecursive),
456 no_ignore, FALSE, NULL, ctx, pool);
460 svn_client_import(svn_client_commit_info_t **commit_info_p,
463 svn_boolean_t nonrecursive,
464 svn_client_ctx_t *ctx,
467 svn_commit_info_t *commit_info = NULL;
470 err = svn_client_import2(&commit_info,
471 path, url, nonrecursive,
473 /* These structs have the same layout for the common fields. */
474 *commit_info_p = (svn_client_commit_info_t *) commit_info;
475 return svn_error_trace(err);
479 /* Wrapper notify_func2 function and baton for downgrading
480 svn_wc_notify_commit_copied and svn_wc_notify_commit_copied_replaced
481 to svn_wc_notify_commit_added and svn_wc_notify_commit_replaced,
483 struct downgrade_commit_copied_notify_baton
485 svn_wc_notify_func2_t orig_notify_func2;
486 void *orig_notify_baton2;
490 downgrade_commit_copied_notify_func(void *baton,
491 const svn_wc_notify_t *notify,
494 struct downgrade_commit_copied_notify_baton *b = baton;
496 if (notify->action == svn_wc_notify_commit_copied)
498 svn_wc_notify_t *my_notify = svn_wc_dup_notify(notify, pool);
499 my_notify->action = svn_wc_notify_commit_added;
502 else if (notify->action == svn_wc_notify_commit_copied_replaced)
504 svn_wc_notify_t *my_notify = svn_wc_dup_notify(notify, pool);
505 my_notify->action = svn_wc_notify_commit_replaced;
509 /* Call the wrapped notification system (if any) with MY_NOTIFY,
510 which is either the original NOTIFY object, or a tweaked deep
512 if (b->orig_notify_func2)
513 b->orig_notify_func2(b->orig_notify_baton2, notify, pool);
517 svn_client_commit5(const apr_array_header_t *targets,
519 svn_boolean_t keep_locks,
520 svn_boolean_t keep_changelists,
521 svn_boolean_t commit_as_operations,
522 const apr_array_header_t *changelists,
523 const apr_hash_t *revprop_table,
524 svn_commit_callback2_t commit_callback,
526 svn_client_ctx_t *ctx,
529 return svn_client_commit6(targets, depth, keep_locks, keep_changelists,
530 commit_as_operations,
531 FALSE, /* include_file_externals */
532 FALSE, /* include_dir_externals */
533 changelists, revprop_table, commit_callback,
534 commit_baton, ctx, pool);
538 svn_client_commit4(svn_commit_info_t **commit_info_p,
539 const apr_array_header_t *targets,
541 svn_boolean_t keep_locks,
542 svn_boolean_t keep_changelists,
543 const apr_array_header_t *changelists,
544 const apr_hash_t *revprop_table,
545 svn_client_ctx_t *ctx,
548 struct capture_baton_t cb;
549 struct downgrade_commit_copied_notify_baton notify_baton;
552 notify_baton.orig_notify_func2 = ctx->notify_func2;
553 notify_baton.orig_notify_baton2 = ctx->notify_baton2;
555 *commit_info_p = NULL;
556 cb.info = commit_info_p;
559 /* Swap out the notification system (if any) with a thin filtering
561 if (ctx->notify_func2)
563 ctx->notify_func2 = downgrade_commit_copied_notify_func;
564 ctx->notify_baton2 = ¬ify_baton;
567 err = svn_client_commit5(targets, depth, keep_locks, keep_changelists, FALSE,
568 changelists, revprop_table,
569 capture_commit_info, &cb, ctx, pool);
571 /* Ensure that the original notification system is in place. */
572 ctx->notify_func2 = notify_baton.orig_notify_func2;
573 ctx->notify_baton2 = notify_baton.orig_notify_baton2;
577 if (! *commit_info_p)
578 *commit_info_p = svn_create_commit_info(pool);
584 svn_client_commit3(svn_commit_info_t **commit_info_p,
585 const apr_array_header_t *targets,
586 svn_boolean_t recurse,
587 svn_boolean_t keep_locks,
588 svn_client_ctx_t *ctx,
591 svn_depth_t depth = SVN_DEPTH_INFINITY_OR_EMPTY(recurse);
593 return svn_client_commit4(commit_info_p, targets, depth, keep_locks,
594 FALSE, NULL, NULL, ctx, pool);
598 svn_client_commit2(svn_client_commit_info_t **commit_info_p,
599 const apr_array_header_t *targets,
600 svn_boolean_t recurse,
601 svn_boolean_t keep_locks,
602 svn_client_ctx_t *ctx,
605 svn_commit_info_t *commit_info = NULL;
608 err = svn_client_commit3(&commit_info, targets, recurse, keep_locks,
610 /* These structs have the same layout for the common fields. */
611 *commit_info_p = (svn_client_commit_info_t *) commit_info;
612 return svn_error_trace(err);
616 svn_client_commit(svn_client_commit_info_t **commit_info_p,
617 const apr_array_header_t *targets,
618 svn_boolean_t nonrecursive,
619 svn_client_ctx_t *ctx,
622 return svn_client_commit2(commit_info_p, targets,
628 /*** From copy.c ***/
630 svn_client_copy6(const apr_array_header_t *sources,
631 const char *dst_path,
632 svn_boolean_t copy_as_child,
633 svn_boolean_t make_parents,
634 svn_boolean_t ignore_externals,
635 const apr_hash_t *revprop_table,
636 svn_commit_callback2_t commit_callback,
638 svn_client_ctx_t *ctx,
641 return svn_error_trace(svn_client_copy7(sources, dst_path, copy_as_child,
642 make_parents, ignore_externals,
643 FALSE /* metadata_only */,
644 FALSE /* pin_externals */,
645 NULL /* externals_to_pin */,
647 commit_callback, commit_baton,
652 svn_client_copy5(svn_commit_info_t **commit_info_p,
653 const apr_array_header_t *sources,
654 const char *dst_path,
655 svn_boolean_t copy_as_child,
656 svn_boolean_t make_parents,
657 svn_boolean_t ignore_externals,
658 const apr_hash_t *revprop_table,
659 svn_client_ctx_t *ctx,
662 struct capture_baton_t cb;
664 cb.info = commit_info_p;
667 return svn_client_copy6(sources, dst_path, copy_as_child, make_parents,
668 ignore_externals, revprop_table,
669 capture_commit_info, &cb, ctx, pool);
673 svn_client_copy4(svn_commit_info_t **commit_info_p,
674 const apr_array_header_t *sources,
675 const char *dst_path,
676 svn_boolean_t copy_as_child,
677 svn_boolean_t make_parents,
678 const apr_hash_t *revprop_table,
679 svn_client_ctx_t *ctx,
682 return svn_client_copy5(commit_info_p, sources, dst_path, copy_as_child,
683 make_parents, FALSE, revprop_table, ctx, pool);
687 svn_client_copy3(svn_commit_info_t **commit_info_p,
688 const char *src_path,
689 const svn_opt_revision_t *src_revision,
690 const char *dst_path,
691 svn_client_ctx_t *ctx,
694 apr_array_header_t *sources = apr_array_make(pool, 1,
695 sizeof(const svn_client_copy_source_t *));
696 svn_client_copy_source_t copy_source;
698 copy_source.path = src_path;
699 copy_source.revision = src_revision;
700 copy_source.peg_revision = src_revision;
702 APR_ARRAY_PUSH(sources, const svn_client_copy_source_t *) = ©_source;
704 return svn_client_copy4(commit_info_p, sources, dst_path, FALSE, FALSE,
709 svn_client_copy2(svn_commit_info_t **commit_info_p,
710 const char *src_path,
711 const svn_opt_revision_t *src_revision,
712 const char *dst_path,
713 svn_client_ctx_t *ctx,
718 err = svn_client_copy3(commit_info_p, src_path, src_revision,
719 dst_path, ctx, pool);
721 /* If the target exists, try to copy the source as a child of the target.
722 This will obviously fail if target is not a directory, but that's exactly
724 if (err && (err->apr_err == SVN_ERR_ENTRY_EXISTS
725 || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS))
727 const char *src_basename = svn_path_basename(src_path, pool);
729 svn_error_clear(err);
731 return svn_client_copy3(commit_info_p, src_path, src_revision,
732 svn_path_join(dst_path, src_basename, pool),
736 return svn_error_trace(err);
740 svn_client_copy(svn_client_commit_info_t **commit_info_p,
741 const char *src_path,
742 const svn_opt_revision_t *src_revision,
743 const char *dst_path,
744 svn_client_ctx_t *ctx,
747 svn_commit_info_t *commit_info = NULL;
750 err = svn_client_copy2(&commit_info, src_path, src_revision, dst_path,
752 /* These structs have the same layout for the common fields. */
753 *commit_info_p = (svn_client_commit_info_t *) commit_info;
754 return svn_error_trace(err);
758 svn_client_move6(const apr_array_header_t *src_paths,
759 const char *dst_path,
760 svn_boolean_t move_as_child,
761 svn_boolean_t make_parents,
762 const apr_hash_t *revprop_table,
763 svn_commit_callback2_t commit_callback,
765 svn_client_ctx_t *ctx,
768 return svn_error_trace(svn_client_move7(src_paths, dst_path,
769 move_as_child, make_parents,
770 TRUE /* allow_mixed_revisions */,
771 FALSE /* metadata_only */,
773 commit_callback, commit_baton,
778 svn_client_move5(svn_commit_info_t **commit_info_p,
779 const apr_array_header_t *src_paths,
780 const char *dst_path,
782 svn_boolean_t move_as_child,
783 svn_boolean_t make_parents,
784 const apr_hash_t *revprop_table,
785 svn_client_ctx_t *ctx,
788 struct capture_baton_t cb;
790 cb.info = commit_info_p;
793 return svn_client_move6(src_paths, dst_path, move_as_child,
794 make_parents, revprop_table,
795 capture_commit_info, &cb, ctx, pool);
799 svn_client_move4(svn_commit_info_t **commit_info_p,
800 const char *src_path,
801 const char *dst_path,
803 svn_client_ctx_t *ctx,
806 apr_array_header_t *src_paths =
807 apr_array_make(pool, 1, sizeof(const char *));
808 APR_ARRAY_PUSH(src_paths, const char *) = src_path;
811 return svn_client_move5(commit_info_p, src_paths, dst_path, force, FALSE,
812 FALSE, NULL, ctx, pool);
816 svn_client_move3(svn_commit_info_t **commit_info_p,
817 const char *src_path,
818 const char *dst_path,
820 svn_client_ctx_t *ctx,
825 err = svn_client_move4(commit_info_p, src_path, dst_path, force, ctx, pool);
827 /* If the target exists, try to move the source as a child of the target.
828 This will obviously fail if target is not a directory, but that's exactly
830 if (err && (err->apr_err == SVN_ERR_ENTRY_EXISTS
831 || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS))
833 const char *src_basename = svn_path_basename(src_path, pool);
835 svn_error_clear(err);
837 return svn_client_move4(commit_info_p, src_path,
838 svn_path_join(dst_path, src_basename, pool),
842 return svn_error_trace(err);
846 svn_client_move2(svn_client_commit_info_t **commit_info_p,
847 const char *src_path,
848 const char *dst_path,
850 svn_client_ctx_t *ctx,
853 svn_commit_info_t *commit_info = NULL;
856 err = svn_client_move3(&commit_info, src_path, dst_path, force, ctx, pool);
857 /* These structs have the same layout for the common fields. */
858 *commit_info_p = (svn_client_commit_info_t *) commit_info;
859 return svn_error_trace(err);
864 svn_client_move(svn_client_commit_info_t **commit_info_p,
865 const char *src_path,
866 const svn_opt_revision_t *src_revision,
867 const char *dst_path,
869 svn_client_ctx_t *ctx,
872 /* It doesn't make sense to specify revisions in a move. */
874 /* ### todo: this check could fail wrongly. For example,
875 someone could pass in an svn_opt_revision_number that just
876 happens to be the HEAD. It's fair enough to punt then, IMHO,
877 and just demand that the user not specify a revision at all;
878 beats mucking up this function with RA calls and such. */
879 if (src_revision->kind != svn_opt_revision_unspecified
880 && src_revision->kind != svn_opt_revision_head)
882 return svn_error_create
883 (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
884 _("Cannot specify revisions (except HEAD) with move operations"));
887 return svn_client_move2(commit_info_p, src_path, dst_path, force, ctx, pool);
890 /*** From delete.c ***/
892 svn_client_delete3(svn_commit_info_t **commit_info_p,
893 const apr_array_header_t *paths,
895 svn_boolean_t keep_local,
896 const apr_hash_t *revprop_table,
897 svn_client_ctx_t *ctx,
900 struct capture_baton_t cb;
902 cb.info = commit_info_p;
905 return svn_client_delete4(paths, force, keep_local, revprop_table,
906 capture_commit_info, &cb, ctx, pool);
910 svn_client_delete2(svn_commit_info_t **commit_info_p,
911 const apr_array_header_t *paths,
913 svn_client_ctx_t *ctx,
916 return svn_client_delete3(commit_info_p, paths, force, FALSE, NULL,
921 svn_client_delete(svn_client_commit_info_t **commit_info_p,
922 const apr_array_header_t *paths,
924 svn_client_ctx_t *ctx,
927 svn_commit_info_t *commit_info = NULL;
928 svn_error_t *err = NULL;
930 err = svn_client_delete2(&commit_info, paths, force, ctx, pool);
931 /* These structs have the same layout for the common fields. */
932 *commit_info_p = (svn_client_commit_info_t *) commit_info;
933 return svn_error_trace(err);
936 /*** From diff.c ***/
939 svn_client_diff5(const apr_array_header_t *diff_options,
941 const svn_opt_revision_t *revision1,
943 const svn_opt_revision_t *revision2,
944 const char *relative_to_dir,
946 svn_boolean_t ignore_ancestry,
947 svn_boolean_t no_diff_deleted,
948 svn_boolean_t show_copies_as_adds,
949 svn_boolean_t ignore_content_type,
950 svn_boolean_t use_git_diff_format,
951 const char *header_encoding,
954 const apr_array_header_t *changelists,
955 svn_client_ctx_t *ctx,
958 svn_stream_t *outstream = svn_stream_from_aprfile2(outfile, TRUE, pool);
959 svn_stream_t *errstream = svn_stream_from_aprfile2(errfile, TRUE, pool);
961 return svn_client_diff6(diff_options, path1, revision1, path2,
962 revision2, relative_to_dir, depth,
963 ignore_ancestry, FALSE /* no_diff_added */,
964 no_diff_deleted, show_copies_as_adds,
965 ignore_content_type, FALSE /* ignore_properties */,
966 FALSE /* properties_only */, use_git_diff_format,
968 outstream, errstream, changelists, ctx, pool);
972 svn_client_diff4(const apr_array_header_t *options,
974 const svn_opt_revision_t *revision1,
976 const svn_opt_revision_t *revision2,
977 const char *relative_to_dir,
979 svn_boolean_t ignore_ancestry,
980 svn_boolean_t no_diff_deleted,
981 svn_boolean_t ignore_content_type,
982 const char *header_encoding,
985 const apr_array_header_t *changelists,
986 svn_client_ctx_t *ctx,
989 return svn_client_diff5(options, path1, revision1, path2,
990 revision2, relative_to_dir, depth,
991 ignore_ancestry, no_diff_deleted, FALSE,
992 ignore_content_type, FALSE, header_encoding,
993 outfile, errfile, changelists, ctx, pool);
997 svn_client_diff3(const apr_array_header_t *options,
999 const svn_opt_revision_t *revision1,
1001 const svn_opt_revision_t *revision2,
1002 svn_boolean_t recurse,
1003 svn_boolean_t ignore_ancestry,
1004 svn_boolean_t no_diff_deleted,
1005 svn_boolean_t ignore_content_type,
1006 const char *header_encoding,
1007 apr_file_t *outfile,
1008 apr_file_t *errfile,
1009 svn_client_ctx_t *ctx,
1012 return svn_client_diff4(options, path1, revision1, path2,
1014 SVN_DEPTH_INFINITY_OR_FILES(recurse),
1015 ignore_ancestry, no_diff_deleted,
1016 ignore_content_type, header_encoding,
1017 outfile, errfile, NULL, ctx, pool);
1021 svn_client_diff2(const apr_array_header_t *options,
1023 const svn_opt_revision_t *revision1,
1025 const svn_opt_revision_t *revision2,
1026 svn_boolean_t recurse,
1027 svn_boolean_t ignore_ancestry,
1028 svn_boolean_t no_diff_deleted,
1029 svn_boolean_t ignore_content_type,
1030 apr_file_t *outfile,
1031 apr_file_t *errfile,
1032 svn_client_ctx_t *ctx,
1035 return svn_client_diff3(options, path1, revision1, path2, revision2,
1036 recurse, ignore_ancestry, no_diff_deleted,
1037 ignore_content_type, SVN_APR_LOCALE_CHARSET,
1038 outfile, errfile, ctx, pool);
1042 svn_client_diff(const apr_array_header_t *options,
1044 const svn_opt_revision_t *revision1,
1046 const svn_opt_revision_t *revision2,
1047 svn_boolean_t recurse,
1048 svn_boolean_t ignore_ancestry,
1049 svn_boolean_t no_diff_deleted,
1050 apr_file_t *outfile,
1051 apr_file_t *errfile,
1052 svn_client_ctx_t *ctx,
1055 return svn_client_diff2(options, path1, revision1, path2, revision2,
1056 recurse, ignore_ancestry, no_diff_deleted, FALSE,
1057 outfile, errfile, ctx, pool);
1061 svn_client_diff_peg5(const apr_array_header_t *diff_options,
1063 const svn_opt_revision_t *peg_revision,
1064 const svn_opt_revision_t *start_revision,
1065 const svn_opt_revision_t *end_revision,
1066 const char *relative_to_dir,
1068 svn_boolean_t ignore_ancestry,
1069 svn_boolean_t no_diff_deleted,
1070 svn_boolean_t show_copies_as_adds,
1071 svn_boolean_t ignore_content_type,
1072 svn_boolean_t use_git_diff_format,
1073 const char *header_encoding,
1074 apr_file_t *outfile,
1075 apr_file_t *errfile,
1076 const apr_array_header_t *changelists,
1077 svn_client_ctx_t *ctx,
1080 svn_stream_t *outstream = svn_stream_from_aprfile2(outfile, TRUE, pool);
1081 svn_stream_t *errstream = svn_stream_from_aprfile2(errfile, TRUE, pool);
1083 return svn_client_diff_peg6(diff_options,
1091 FALSE /* no_diff_added */,
1093 show_copies_as_adds,
1094 ignore_content_type,
1095 FALSE /* ignore_properties */,
1096 FALSE /* properties_only */,
1097 use_git_diff_format,
1107 svn_client_diff_peg4(const apr_array_header_t *options,
1109 const svn_opt_revision_t *peg_revision,
1110 const svn_opt_revision_t *start_revision,
1111 const svn_opt_revision_t *end_revision,
1112 const char *relative_to_dir,
1114 svn_boolean_t ignore_ancestry,
1115 svn_boolean_t no_diff_deleted,
1116 svn_boolean_t ignore_content_type,
1117 const char *header_encoding,
1118 apr_file_t *outfile,
1119 apr_file_t *errfile,
1120 const apr_array_header_t *changelists,
1121 svn_client_ctx_t *ctx,
1124 return svn_client_diff_peg5(options,
1134 ignore_content_type,
1145 svn_client_diff_peg3(const apr_array_header_t *options,
1147 const svn_opt_revision_t *peg_revision,
1148 const svn_opt_revision_t *start_revision,
1149 const svn_opt_revision_t *end_revision,
1150 svn_boolean_t recurse,
1151 svn_boolean_t ignore_ancestry,
1152 svn_boolean_t no_diff_deleted,
1153 svn_boolean_t ignore_content_type,
1154 const char *header_encoding,
1155 apr_file_t *outfile,
1156 apr_file_t *errfile,
1157 svn_client_ctx_t *ctx,
1160 return svn_client_diff_peg4(options,
1166 SVN_DEPTH_INFINITY_OR_FILES(recurse),
1169 ignore_content_type,
1179 svn_client_diff_peg2(const apr_array_header_t *options,
1181 const svn_opt_revision_t *peg_revision,
1182 const svn_opt_revision_t *start_revision,
1183 const svn_opt_revision_t *end_revision,
1184 svn_boolean_t recurse,
1185 svn_boolean_t ignore_ancestry,
1186 svn_boolean_t no_diff_deleted,
1187 svn_boolean_t ignore_content_type,
1188 apr_file_t *outfile,
1189 apr_file_t *errfile,
1190 svn_client_ctx_t *ctx,
1193 return svn_client_diff_peg3(options, path, peg_revision, start_revision,
1195 SVN_DEPTH_INFINITY_OR_FILES(recurse),
1196 ignore_ancestry, no_diff_deleted,
1197 ignore_content_type, SVN_APR_LOCALE_CHARSET,
1198 outfile, errfile, ctx, pool);
1202 svn_client_diff_peg(const apr_array_header_t *options,
1204 const svn_opt_revision_t *peg_revision,
1205 const svn_opt_revision_t *start_revision,
1206 const svn_opt_revision_t *end_revision,
1207 svn_boolean_t recurse,
1208 svn_boolean_t ignore_ancestry,
1209 svn_boolean_t no_diff_deleted,
1210 apr_file_t *outfile,
1211 apr_file_t *errfile,
1212 svn_client_ctx_t *ctx,
1215 return svn_client_diff_peg2(options, path, peg_revision,
1216 start_revision, end_revision, recurse,
1217 ignore_ancestry, no_diff_deleted, FALSE,
1218 outfile, errfile, ctx, pool);
1222 svn_client_diff_summarize(const char *path1,
1223 const svn_opt_revision_t *revision1,
1225 const svn_opt_revision_t *revision2,
1226 svn_boolean_t recurse,
1227 svn_boolean_t ignore_ancestry,
1228 svn_client_diff_summarize_func_t summarize_func,
1229 void *summarize_baton,
1230 svn_client_ctx_t *ctx,
1233 return svn_client_diff_summarize2(path1, revision1, path2,
1235 SVN_DEPTH_INFINITY_OR_FILES(recurse),
1236 ignore_ancestry, NULL, summarize_func,
1237 summarize_baton, ctx, pool);
1241 svn_client_diff_summarize_peg(const char *path,
1242 const svn_opt_revision_t *peg_revision,
1243 const svn_opt_revision_t *start_revision,
1244 const svn_opt_revision_t *end_revision,
1245 svn_boolean_t recurse,
1246 svn_boolean_t ignore_ancestry,
1247 svn_client_diff_summarize_func_t summarize_func,
1248 void *summarize_baton,
1249 svn_client_ctx_t *ctx,
1252 return svn_client_diff_summarize_peg2(path, peg_revision,
1253 start_revision, end_revision,
1254 SVN_DEPTH_INFINITY_OR_FILES(recurse),
1255 ignore_ancestry, NULL,
1256 summarize_func, summarize_baton,
1260 /*** From export.c ***/
1262 svn_client_export4(svn_revnum_t *result_rev,
1263 const char *from_path_or_url,
1264 const char *to_path,
1265 const svn_opt_revision_t *peg_revision,
1266 const svn_opt_revision_t *revision,
1267 svn_boolean_t overwrite,
1268 svn_boolean_t ignore_externals,
1270 const char *native_eol,
1271 svn_client_ctx_t *ctx,
1274 return svn_client_export5(result_rev, from_path_or_url, to_path,
1275 peg_revision, revision, overwrite, ignore_externals,
1276 FALSE, depth, native_eol, ctx, pool);
1280 svn_client_export3(svn_revnum_t *result_rev,
1281 const char *from_path_or_url,
1282 const char *to_path,
1283 const svn_opt_revision_t *peg_revision,
1284 const svn_opt_revision_t *revision,
1285 svn_boolean_t overwrite,
1286 svn_boolean_t ignore_externals,
1287 svn_boolean_t recurse,
1288 const char *native_eol,
1289 svn_client_ctx_t *ctx,
1292 return svn_client_export4(result_rev, from_path_or_url, to_path,
1293 peg_revision, revision, overwrite, ignore_externals,
1294 SVN_DEPTH_INFINITY_OR_FILES(recurse),
1295 native_eol, ctx, pool);
1299 svn_client_export2(svn_revnum_t *result_rev,
1300 const char *from_path_or_url,
1301 const char *to_path,
1302 svn_opt_revision_t *revision,
1303 svn_boolean_t force,
1304 const char *native_eol,
1305 svn_client_ctx_t *ctx,
1308 svn_opt_revision_t peg_revision;
1310 peg_revision.kind = svn_opt_revision_unspecified;
1312 return svn_client_export3(result_rev, from_path_or_url, to_path,
1313 &peg_revision, revision, force, FALSE, TRUE,
1314 native_eol, ctx, pool);
1319 svn_client_export(svn_revnum_t *result_rev,
1320 const char *from_path_or_url,
1321 const char *to_path,
1322 svn_opt_revision_t *revision,
1323 svn_boolean_t force,
1324 svn_client_ctx_t *ctx,
1327 return svn_client_export2(result_rev, from_path_or_url, to_path, revision,
1328 force, NULL, ctx, pool);
1331 /*** From list.c ***/
1333 /* Baton for use with wrap_list_func */
1334 struct list_func_wrapper_baton {
1335 void *list_func1_baton;
1336 svn_client_list_func_t list_func1;
1339 /* This implements svn_client_list_func2_t */
1340 static svn_error_t *
1341 list_func_wrapper(void *baton,
1343 const svn_dirent_t *dirent,
1344 const svn_lock_t *lock,
1345 const char *abs_path,
1346 const char *external_parent_url,
1347 const char *external_target,
1348 apr_pool_t *scratch_pool)
1350 struct list_func_wrapper_baton *lfwb = baton;
1352 if (lfwb->list_func1)
1353 return lfwb->list_func1(lfwb->list_func1_baton, path, dirent,
1354 lock, abs_path, scratch_pool);
1356 return SVN_NO_ERROR;
1359 /* Helper function for svn_client_list2(). It wraps old format baton
1360 and callback function in list_func_wrapper_baton and
1361 returns new baton and callback to use with svn_client_list3(). */
1363 wrap_list_func(svn_client_list_func2_t *list_func2,
1364 void **list_func2_baton,
1365 svn_client_list_func_t list_func,
1367 apr_pool_t *result_pool)
1369 struct list_func_wrapper_baton *lfwb = apr_palloc(result_pool,
1372 /* Set the user provided old format callback in the baton. */
1373 lfwb->list_func1_baton = baton;
1374 lfwb->list_func1 = list_func;
1376 *list_func2_baton = lfwb;
1377 *list_func2 = list_func_wrapper;
1381 svn_client_list2(const char *path_or_url,
1382 const svn_opt_revision_t *peg_revision,
1383 const svn_opt_revision_t *revision,
1385 apr_uint32_t dirent_fields,
1386 svn_boolean_t fetch_locks,
1387 svn_client_list_func_t list_func,
1389 svn_client_ctx_t *ctx,
1392 svn_client_list_func2_t list_func2;
1393 void *list_func2_baton;
1395 wrap_list_func(&list_func2, &list_func2_baton, list_func, baton, pool);
1397 return svn_client_list3(path_or_url, peg_revision, revision, depth,
1398 dirent_fields, fetch_locks,
1399 FALSE /* include externals */,
1400 list_func2, list_func2_baton, ctx, pool);
1404 svn_client_list(const char *path_or_url,
1405 const svn_opt_revision_t *peg_revision,
1406 const svn_opt_revision_t *revision,
1407 svn_boolean_t recurse,
1408 apr_uint32_t dirent_fields,
1409 svn_boolean_t fetch_locks,
1410 svn_client_list_func_t list_func,
1412 svn_client_ctx_t *ctx,
1415 return svn_client_list2(path_or_url,
1418 SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
1427 /* Baton used by compatibility wrapper svn_client_ls3. */
1429 apr_hash_t *dirents;
1434 /* This implements svn_client_list_func_t. */
1435 static svn_error_t *
1436 store_dirent(void *baton, const char *path, const svn_dirent_t *dirent,
1437 const svn_lock_t *lock, const char *abs_path, apr_pool_t *pool)
1439 struct ls_baton *lb = baton;
1441 /* The dirent is allocated in a temporary pool, so duplicate it into the
1442 correct pool. Note, however, that the locks are stored in the correct
1444 dirent = svn_dirent_dup(dirent, lb->pool);
1446 /* An empty path means we are called for the target of the operation.
1447 For compatibility, we only store the target if it is a file, and we
1448 store it under the basename of the URL. Note that this makes it
1449 impossible to differentiate between the target being a directory with a
1450 child with the same basename as the target and the target being a file,
1451 but that's how it was implemented. */
1452 if (path[0] == '\0')
1454 if (dirent->kind == svn_node_file)
1456 const char *base_name = svn_path_basename(abs_path, lb->pool);
1457 svn_hash_sets(lb->dirents, base_name, dirent);
1459 svn_hash_sets(lb->locks, base_name, lock);
1464 path = apr_pstrdup(lb->pool, path);
1465 svn_hash_sets(lb->dirents, path, dirent);
1467 svn_hash_sets(lb->locks, path, lock);
1470 return SVN_NO_ERROR;
1474 svn_client_ls3(apr_hash_t **dirents,
1476 const char *path_or_url,
1477 const svn_opt_revision_t *peg_revision,
1478 const svn_opt_revision_t *revision,
1479 svn_boolean_t recurse,
1480 svn_client_ctx_t *ctx,
1485 *dirents = lb.dirents = apr_hash_make(pool);
1487 *locks = lb.locks = apr_hash_make(pool);
1490 return svn_client_list(path_or_url, peg_revision, revision, recurse,
1491 SVN_DIRENT_ALL, locks != NULL,
1492 store_dirent, &lb, ctx, pool);
1496 svn_client_ls2(apr_hash_t **dirents,
1497 const char *path_or_url,
1498 const svn_opt_revision_t *peg_revision,
1499 const svn_opt_revision_t *revision,
1500 svn_boolean_t recurse,
1501 svn_client_ctx_t *ctx,
1505 return svn_client_ls3(dirents, NULL, path_or_url, peg_revision,
1506 revision, recurse, ctx, pool);
1511 svn_client_ls(apr_hash_t **dirents,
1512 const char *path_or_url,
1513 svn_opt_revision_t *revision,
1514 svn_boolean_t recurse,
1515 svn_client_ctx_t *ctx,
1518 return svn_client_ls2(dirents, path_or_url, revision,
1519 revision, recurse, ctx, pool);
1522 /*** From log.c ***/
1525 svn_client_log4(const apr_array_header_t *targets,
1526 const svn_opt_revision_t *peg_revision,
1527 const svn_opt_revision_t *start,
1528 const svn_opt_revision_t *end,
1530 svn_boolean_t discover_changed_paths,
1531 svn_boolean_t strict_node_history,
1532 svn_boolean_t include_merged_revisions,
1533 const apr_array_header_t *revprops,
1534 svn_log_entry_receiver_t receiver,
1535 void *receiver_baton,
1536 svn_client_ctx_t *ctx,
1539 apr_array_header_t *revision_ranges;
1541 revision_ranges = apr_array_make(pool, 1,
1542 sizeof(svn_opt_revision_range_t *));
1543 APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
1544 = svn_opt__revision_range_create(start, end, pool);
1546 return svn_client_log5(targets, peg_revision, revision_ranges, limit,
1547 discover_changed_paths, strict_node_history,
1548 include_merged_revisions, revprops, receiver,
1549 receiver_baton, ctx, pool);
1554 svn_client_log3(const apr_array_header_t *targets,
1555 const svn_opt_revision_t *peg_revision,
1556 const svn_opt_revision_t *start,
1557 const svn_opt_revision_t *end,
1559 svn_boolean_t discover_changed_paths,
1560 svn_boolean_t strict_node_history,
1561 svn_log_message_receiver_t receiver,
1562 void *receiver_baton,
1563 svn_client_ctx_t *ctx,
1566 svn_log_entry_receiver_t receiver2;
1567 void *receiver2_baton;
1569 svn_compat_wrap_log_receiver(&receiver2, &receiver2_baton,
1570 receiver, receiver_baton,
1573 return svn_client_log4(targets, peg_revision, start, end, limit,
1574 discover_changed_paths, strict_node_history, FALSE,
1575 svn_compat_log_revprops_in(pool),
1576 receiver2, receiver2_baton, ctx, pool);
1580 svn_client_log2(const apr_array_header_t *targets,
1581 const svn_opt_revision_t *start,
1582 const svn_opt_revision_t *end,
1584 svn_boolean_t discover_changed_paths,
1585 svn_boolean_t strict_node_history,
1586 svn_log_message_receiver_t receiver,
1587 void *receiver_baton,
1588 svn_client_ctx_t *ctx,
1591 svn_opt_revision_t peg_revision;
1592 peg_revision.kind = svn_opt_revision_unspecified;
1593 return svn_client_log3(targets, &peg_revision, start, end, limit,
1594 discover_changed_paths, strict_node_history,
1595 receiver, receiver_baton, ctx, pool);
1599 svn_client_log(const apr_array_header_t *targets,
1600 const svn_opt_revision_t *start,
1601 const svn_opt_revision_t *end,
1602 svn_boolean_t discover_changed_paths,
1603 svn_boolean_t strict_node_history,
1604 svn_log_message_receiver_t receiver,
1605 void *receiver_baton,
1606 svn_client_ctx_t *ctx,
1609 svn_error_t *err = SVN_NO_ERROR;
1611 err = svn_client_log2(targets, start, end, 0, discover_changed_paths,
1612 strict_node_history, receiver, receiver_baton, ctx,
1615 /* Special case: If there have been no commits, we'll get an error
1616 * for requesting log of a revision higher than 0. But the
1617 * default behavior of "svn log" is to give revisions HEAD through
1618 * 1, on the assumption that HEAD >= 1.
1620 * So if we got that error for that reason, and it looks like the
1621 * user was just depending on the defaults (rather than explicitly
1622 * requesting the log for revision 1), then we don't error. Instead
1623 * we just invoke the receiver manually on a hand-constructed log
1624 * message for revision 0.
1626 * See also http://subversion.tigris.org/issues/show_bug.cgi?id=692.
1628 if (err && (err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
1629 && (start->kind == svn_opt_revision_head)
1630 && ((end->kind == svn_opt_revision_number)
1631 && (end->value.number == 1)))
1634 /* We don't need to check if HEAD is 0, because that must be the case,
1635 * by logical deduction: The revision range specified is HEAD:1.
1636 * HEAD cannot not exist, so the revision to which "no such revision"
1637 * applies is 1. If revision 1 does not exist, then HEAD is 0.
1638 * Hence, we deduce the repository is empty without needing access
1639 * to further information. */
1641 svn_error_clear(err);
1644 /* Log receivers are free to handle revision 0 specially... But
1645 just in case some don't, we make up a message here. */
1646 SVN_ERR(receiver(receiver_baton,
1647 NULL, 0, "", "", _("No commits in repository"),
1651 return svn_error_trace(err);
1654 /*** From merge.c ***/
1657 svn_client_merge4(const char *source1,
1658 const svn_opt_revision_t *revision1,
1659 const char *source2,
1660 const svn_opt_revision_t *revision2,
1661 const char *target_wcpath,
1663 svn_boolean_t ignore_ancestry,
1664 svn_boolean_t force_delete,
1665 svn_boolean_t record_only,
1666 svn_boolean_t dry_run,
1667 svn_boolean_t allow_mixed_rev,
1668 const apr_array_header_t *merge_options,
1669 svn_client_ctx_t *ctx,
1672 SVN_ERR(svn_client_merge5(source1, revision1,
1676 ignore_ancestry /*ignore_mergeinfo*/,
1677 ignore_ancestry /*diff_ignore_ancestry*/,
1678 force_delete, record_only,
1679 dry_run, allow_mixed_rev,
1680 merge_options, ctx, pool));
1681 return SVN_NO_ERROR;
1685 svn_client_merge3(const char *source1,
1686 const svn_opt_revision_t *revision1,
1687 const char *source2,
1688 const svn_opt_revision_t *revision2,
1689 const char *target_wcpath,
1691 svn_boolean_t ignore_ancestry,
1692 svn_boolean_t force,
1693 svn_boolean_t record_only,
1694 svn_boolean_t dry_run,
1695 const apr_array_header_t *merge_options,
1696 svn_client_ctx_t *ctx,
1699 return svn_client_merge4(source1, revision1, source2, revision2,
1700 target_wcpath, depth, ignore_ancestry, force,
1701 record_only, dry_run, TRUE, merge_options,
1706 svn_client_merge2(const char *source1,
1707 const svn_opt_revision_t *revision1,
1708 const char *source2,
1709 const svn_opt_revision_t *revision2,
1710 const char *target_wcpath,
1711 svn_boolean_t recurse,
1712 svn_boolean_t ignore_ancestry,
1713 svn_boolean_t force,
1714 svn_boolean_t dry_run,
1715 const apr_array_header_t *merge_options,
1716 svn_client_ctx_t *ctx,
1719 return svn_client_merge3(source1, revision1, source2, revision2,
1721 SVN_DEPTH_INFINITY_OR_FILES(recurse),
1722 ignore_ancestry, force, FALSE, dry_run,
1723 merge_options, ctx, pool);
1727 svn_client_merge(const char *source1,
1728 const svn_opt_revision_t *revision1,
1729 const char *source2,
1730 const svn_opt_revision_t *revision2,
1731 const char *target_wcpath,
1732 svn_boolean_t recurse,
1733 svn_boolean_t ignore_ancestry,
1734 svn_boolean_t force,
1735 svn_boolean_t dry_run,
1736 svn_client_ctx_t *ctx,
1739 return svn_client_merge2(source1, revision1, source2, revision2,
1740 target_wcpath, recurse, ignore_ancestry, force,
1741 dry_run, NULL, ctx, pool);
1745 svn_client_merge_peg4(const char *source_path_or_url,
1746 const apr_array_header_t *ranges_to_merge,
1747 const svn_opt_revision_t *source_peg_revision,
1748 const char *target_wcpath,
1750 svn_boolean_t ignore_ancestry,
1751 svn_boolean_t force_delete,
1752 svn_boolean_t record_only,
1753 svn_boolean_t dry_run,
1754 svn_boolean_t allow_mixed_rev,
1755 const apr_array_header_t *merge_options,
1756 svn_client_ctx_t *ctx,
1759 SVN_ERR(svn_client_merge_peg5(source_path_or_url,
1761 source_peg_revision,
1764 ignore_ancestry /*ignore_mergeinfo*/,
1765 ignore_ancestry /*diff_ignore_ancestry*/,
1766 force_delete, record_only,
1767 dry_run, allow_mixed_rev,
1768 merge_options, ctx, pool));
1769 return SVN_NO_ERROR;
1773 svn_client_merge_peg3(const char *source,
1774 const apr_array_header_t *ranges_to_merge,
1775 const svn_opt_revision_t *peg_revision,
1776 const char *target_wcpath,
1778 svn_boolean_t ignore_ancestry,
1779 svn_boolean_t force,
1780 svn_boolean_t record_only,
1781 svn_boolean_t dry_run,
1782 const apr_array_header_t *merge_options,
1783 svn_client_ctx_t *ctx,
1786 return svn_client_merge_peg4(source, ranges_to_merge, peg_revision,
1787 target_wcpath, depth, ignore_ancestry, force,
1788 record_only, dry_run, TRUE, merge_options,
1793 svn_client_merge_peg2(const char *source,
1794 const svn_opt_revision_t *revision1,
1795 const svn_opt_revision_t *revision2,
1796 const svn_opt_revision_t *peg_revision,
1797 const char *target_wcpath,
1798 svn_boolean_t recurse,
1799 svn_boolean_t ignore_ancestry,
1800 svn_boolean_t force,
1801 svn_boolean_t dry_run,
1802 const apr_array_header_t *merge_options,
1803 svn_client_ctx_t *ctx,
1806 apr_array_header_t *ranges_to_merge =
1807 apr_array_make(pool, 1, sizeof(svn_opt_revision_range_t *));
1809 APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *)
1810 = svn_opt__revision_range_create(revision1, revision2, pool);
1811 return svn_client_merge_peg3(source, ranges_to_merge,
1814 SVN_DEPTH_INFINITY_OR_FILES(recurse),
1815 ignore_ancestry, force, FALSE, dry_run,
1816 merge_options, ctx, pool);
1820 svn_client_merge_peg(const char *source,
1821 const svn_opt_revision_t *revision1,
1822 const svn_opt_revision_t *revision2,
1823 const svn_opt_revision_t *peg_revision,
1824 const char *target_wcpath,
1825 svn_boolean_t recurse,
1826 svn_boolean_t ignore_ancestry,
1827 svn_boolean_t force,
1828 svn_boolean_t dry_run,
1829 svn_client_ctx_t *ctx,
1832 return svn_client_merge_peg2(source, revision1, revision2, peg_revision,
1833 target_wcpath, recurse, ignore_ancestry, force,
1834 dry_run, NULL, ctx, pool);
1837 /*** From prop_commands.c ***/
1839 svn_client_propset3(svn_commit_info_t **commit_info_p,
1840 const char *propname,
1841 const svn_string_t *propval,
1844 svn_boolean_t skip_checks,
1845 svn_revnum_t base_revision_for_url,
1846 const apr_array_header_t *changelists,
1847 const apr_hash_t *revprop_table,
1848 svn_client_ctx_t *ctx,
1851 if (svn_path_is_url(target))
1853 struct capture_baton_t cb;
1855 cb.info = commit_info_p;
1858 SVN_ERR(svn_client_propset_remote(propname, propval, target, skip_checks,
1859 base_revision_for_url, revprop_table,
1860 capture_commit_info, &cb, ctx, pool));
1864 apr_array_header_t *targets = apr_array_make(pool, 1,
1865 sizeof(const char *));
1867 APR_ARRAY_PUSH(targets, const char *) = target;
1868 SVN_ERR(svn_client_propset_local(propname, propval, targets, depth,
1869 skip_checks, changelists, ctx, pool));
1872 return SVN_NO_ERROR;
1876 svn_client_propset2(const char *propname,
1877 const svn_string_t *propval,
1879 svn_boolean_t recurse,
1880 svn_boolean_t skip_checks,
1881 svn_client_ctx_t *ctx,
1884 return svn_client_propset3(NULL, propname, propval, target,
1885 SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
1886 skip_checks, SVN_INVALID_REVNUM,
1887 NULL, NULL, ctx, pool);
1892 svn_client_propset(const char *propname,
1893 const svn_string_t *propval,
1895 svn_boolean_t recurse,
1898 svn_client_ctx_t *ctx;
1900 SVN_ERR(svn_client_create_context(&ctx, pool));
1902 return svn_client_propset2(propname, propval, target, recurse, FALSE,
1907 svn_client_revprop_set(const char *propname,
1908 const svn_string_t *propval,
1910 const svn_opt_revision_t *revision,
1911 svn_revnum_t *set_rev,
1912 svn_boolean_t force,
1913 svn_client_ctx_t *ctx,
1916 return svn_client_revprop_set2(propname, propval, NULL, URL,
1917 revision, set_rev, force, ctx, pool);
1922 svn_client_propget4(apr_hash_t **props,
1923 const char *propname,
1925 const svn_opt_revision_t *peg_revision,
1926 const svn_opt_revision_t *revision,
1927 svn_revnum_t *actual_revnum,
1929 const apr_array_header_t *changelists,
1930 svn_client_ctx_t *ctx,
1931 apr_pool_t *result_pool,
1932 apr_pool_t *scratch_pool)
1934 return svn_error_trace(svn_client_propget5(props, NULL, propname, target,
1935 peg_revision, revision,
1936 actual_revnum, depth,
1938 result_pool, scratch_pool));
1942 svn_client_propget3(apr_hash_t **props,
1943 const char *propname,
1944 const char *path_or_url,
1945 const svn_opt_revision_t *peg_revision,
1946 const svn_opt_revision_t *revision,
1947 svn_revnum_t *actual_revnum,
1949 const apr_array_header_t *changelists,
1950 svn_client_ctx_t *ctx,
1954 apr_hash_t *temp_props;
1957 if (svn_path_is_url(path_or_url))
1958 target = path_or_url;
1960 SVN_ERR(svn_dirent_get_absolute(&target, path_or_url, pool));
1962 err = svn_client_propget4(&temp_props, propname, target,
1963 peg_revision, revision, actual_revnum,
1964 depth, changelists, ctx, pool, pool);
1966 if (err && err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE)
1968 err->apr_err = SVN_ERR_ENTRY_NOT_FOUND;
1969 return svn_error_trace(err);
1975 && !svn_path_is_url(path_or_url)
1976 && !SVN_IS_VALID_REVNUM(*actual_revnum))
1978 /* Get the actual_revnum; added nodes have no revision yet, and old
1979 * callers expected the mock-up revision of 0. */
1980 svn_boolean_t added;
1982 SVN_ERR(svn_wc__node_is_added(&added, ctx->wc_ctx, target, pool));
1987 /* We may need to fix up our hash keys for legacy callers. */
1988 if (!svn_path_is_url(path_or_url) && strcmp(target, path_or_url) != 0)
1990 apr_hash_index_t *hi;
1992 *props = apr_hash_make(pool);
1993 for (hi = apr_hash_first(pool, temp_props); hi;
1994 hi = apr_hash_next(hi))
1996 const char *abspath = apr_hash_this_key(hi);
1997 svn_string_t *value = apr_hash_this_val(hi);
1998 const char *relpath = svn_dirent_join(path_or_url,
1999 svn_dirent_skip_ancestor(target, abspath),
2002 svn_hash_sets(*props, relpath, value);
2006 *props = temp_props;
2008 return SVN_NO_ERROR;
2012 svn_client_propget2(apr_hash_t **props,
2013 const char *propname,
2015 const svn_opt_revision_t *peg_revision,
2016 const svn_opt_revision_t *revision,
2017 svn_boolean_t recurse,
2018 svn_client_ctx_t *ctx,
2021 return svn_client_propget3(props,
2027 SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
2034 svn_client_propget(apr_hash_t **props,
2035 const char *propname,
2037 const svn_opt_revision_t *revision,
2038 svn_boolean_t recurse,
2039 svn_client_ctx_t *ctx,
2042 return svn_client_propget2(props, propname, target, revision, revision,
2043 recurse, ctx, pool);
2047 /* Duplicate a HASH containing (char * -> svn_string_t *) key/value
2048 pairs using POOL. */
2050 string_hash_dup(apr_hash_t *hash, apr_pool_t *pool)
2052 apr_hash_index_t *hi;
2053 apr_hash_t *new_hash = apr_hash_make(pool);
2055 for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
2057 const char *key = apr_pstrdup(pool, apr_hash_this_key(hi));
2058 apr_ssize_t klen = apr_hash_this_key_len(hi);
2059 svn_string_t *val = svn_string_dup(apr_hash_this_val(hi), pool);
2061 apr_hash_set(new_hash, key, klen, val);
2066 svn_client_proplist_item_t *
2067 svn_client_proplist_item_dup(const svn_client_proplist_item_t *item,
2070 svn_client_proplist_item_t *new_item = apr_pcalloc(pool, sizeof(*new_item));
2072 if (item->node_name)
2073 new_item->node_name = svn_stringbuf_dup(item->node_name, pool);
2075 if (item->prop_hash)
2076 new_item->prop_hash = string_hash_dup(item->prop_hash, pool);
2081 /* Baton for use with wrap_proplist_receiver */
2082 struct proplist_receiver_wrapper_baton {
2084 svn_proplist_receiver_t receiver;
2087 /* This implements svn_client_proplist_receiver2_t */
2088 static svn_error_t *
2089 proplist_wrapper_receiver(void *baton,
2091 apr_hash_t *prop_hash,
2092 apr_array_header_t *inherited_props,
2095 struct proplist_receiver_wrapper_baton *plrwb = baton;
2097 if (plrwb->receiver)
2098 return plrwb->receiver(plrwb->baton, path, prop_hash, pool);
2100 return SVN_NO_ERROR;
2104 wrap_proplist_receiver(svn_proplist_receiver2_t *receiver2,
2105 void **receiver2_baton,
2106 svn_proplist_receiver_t receiver,
2107 void *receiver_baton,
2110 struct proplist_receiver_wrapper_baton *plrwb = apr_palloc(pool,
2113 /* Set the user provided old format callback in the baton. */
2114 plrwb->baton = receiver_baton;
2115 plrwb->receiver = receiver;
2117 *receiver2_baton = plrwb;
2118 *receiver2 = proplist_wrapper_receiver;
2122 svn_client_proplist3(const char *target,
2123 const svn_opt_revision_t *peg_revision,
2124 const svn_opt_revision_t *revision,
2126 const apr_array_header_t *changelists,
2127 svn_proplist_receiver_t receiver,
2128 void *receiver_baton,
2129 svn_client_ctx_t *ctx,
2133 svn_proplist_receiver2_t receiver2;
2134 void *receiver2_baton;
2136 wrap_proplist_receiver(&receiver2, &receiver2_baton, receiver, receiver_baton,
2139 return svn_error_trace(svn_client_proplist4(target, peg_revision, revision,
2140 depth, changelists, FALSE,
2141 receiver2, receiver2_baton,
2145 /* Receiver baton used by proplist2() */
2146 struct proplist_receiver_baton {
2147 apr_array_header_t *props;
2151 /* Receiver function used by proplist2(). */
2152 static svn_error_t *
2153 proplist_receiver_cb(void *baton,
2155 apr_hash_t *prop_hash,
2158 struct proplist_receiver_baton *pl_baton =
2159 (struct proplist_receiver_baton *) baton;
2160 svn_client_proplist_item_t *tmp_item = apr_palloc(pool, sizeof(*tmp_item));
2161 svn_client_proplist_item_t *item;
2163 /* Because the pool passed to the receiver function is likely to be a
2164 temporary pool of some kind, we need to make copies of *path and
2165 *prop_hash in the pool provided by the baton. */
2166 tmp_item->node_name = svn_stringbuf_create(path, pl_baton->pool);
2167 tmp_item->prop_hash = prop_hash;
2169 item = svn_client_proplist_item_dup(tmp_item, pl_baton->pool);
2171 APR_ARRAY_PUSH(pl_baton->props, const svn_client_proplist_item_t *) = item;
2173 return SVN_NO_ERROR;
2177 svn_client_proplist2(apr_array_header_t **props,
2179 const svn_opt_revision_t *peg_revision,
2180 const svn_opt_revision_t *revision,
2181 svn_boolean_t recurse,
2182 svn_client_ctx_t *ctx,
2185 struct proplist_receiver_baton pl_baton;
2187 *props = apr_array_make(pool, 5, sizeof(svn_client_proplist_item_t *));
2188 pl_baton.props = *props;
2189 pl_baton.pool = pool;
2191 return svn_client_proplist3(target, peg_revision, revision,
2192 SVN_DEPTH_INFINITY_OR_EMPTY(recurse), NULL,
2193 proplist_receiver_cb, &pl_baton, ctx, pool);
2198 svn_client_proplist(apr_array_header_t **props,
2200 const svn_opt_revision_t *revision,
2201 svn_boolean_t recurse,
2202 svn_client_ctx_t *ctx,
2205 return svn_client_proplist2(props, target, revision, revision,
2206 recurse, ctx, pool);
2209 /*** From status.c ***/
2212 svn_client_status5(svn_revnum_t *result_rev,
2213 svn_client_ctx_t *ctx,
2215 const svn_opt_revision_t *revision,
2217 svn_boolean_t get_all,
2218 svn_boolean_t update,
2219 svn_boolean_t no_ignore,
2220 svn_boolean_t ignore_externals,
2221 svn_boolean_t depth_as_sticky,
2222 const apr_array_header_t *changelists,
2223 svn_client_status_func_t status_func,
2225 apr_pool_t *scratch_pool)
2227 return svn_client_status6(result_rev, ctx, path, revision, depth,
2228 get_all, update, TRUE, no_ignore,
2229 ignore_externals, depth_as_sticky, changelists,
2230 status_func, status_baton, scratch_pool);
2233 struct status4_wrapper_baton
2235 svn_wc_context_t *wc_ctx;
2236 svn_wc_status_func3_t old_func;
2240 /* Implements svn_client_status_func_t */
2241 static svn_error_t *
2242 status4_wrapper_func(void *baton,
2244 const svn_client_status_t *status,
2245 apr_pool_t *scratch_pool)
2247 struct status4_wrapper_baton *swb = baton;
2248 svn_wc_status2_t *dup;
2249 const char *local_abspath;
2250 const svn_wc_status3_t *wc_status = status->backwards_compatibility_baton;
2252 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
2253 SVN_ERR(svn_wc__status2_from_3(&dup, wc_status, swb->wc_ctx,
2254 local_abspath, scratch_pool,
2257 return (*swb->old_func)(swb->old_baton, path, dup, scratch_pool);
2261 svn_client_status4(svn_revnum_t *result_rev,
2263 const svn_opt_revision_t *revision,
2264 svn_wc_status_func3_t status_func,
2267 svn_boolean_t get_all,
2268 svn_boolean_t update,
2269 svn_boolean_t no_ignore,
2270 svn_boolean_t ignore_externals,
2271 const apr_array_header_t *changelists,
2272 svn_client_ctx_t *ctx,
2275 struct status4_wrapper_baton swb;
2277 swb.wc_ctx = ctx->wc_ctx;
2278 swb.old_func = status_func;
2279 swb.old_baton = status_baton;
2281 return svn_client_status5(result_rev, ctx, path, revision, depth, get_all,
2282 update, no_ignore, ignore_externals, TRUE,
2283 changelists, status4_wrapper_func, &swb, pool);
2286 struct status3_wrapper_baton
2288 svn_wc_status_func2_t old_func;
2292 static svn_error_t *
2293 status3_wrapper_func(void *baton,
2295 svn_wc_status2_t *status,
2298 struct status3_wrapper_baton *swb = baton;
2300 swb->old_func(swb->old_baton, path, status);
2301 return SVN_NO_ERROR;
2305 svn_client_status3(svn_revnum_t *result_rev,
2307 const svn_opt_revision_t *revision,
2308 svn_wc_status_func2_t status_func,
2311 svn_boolean_t get_all,
2312 svn_boolean_t update,
2313 svn_boolean_t no_ignore,
2314 svn_boolean_t ignore_externals,
2315 const apr_array_header_t *changelists,
2316 svn_client_ctx_t *ctx,
2319 struct status3_wrapper_baton swb = { 0 };
2320 swb.old_func = status_func;
2321 swb.old_baton = status_baton;
2322 return svn_client_status4(result_rev, path, revision, status3_wrapper_func,
2323 &swb, depth, get_all, update, no_ignore,
2324 ignore_externals, changelists, ctx, pool);
2328 svn_client_status2(svn_revnum_t *result_rev,
2330 const svn_opt_revision_t *revision,
2331 svn_wc_status_func2_t status_func,
2333 svn_boolean_t recurse,
2334 svn_boolean_t get_all,
2335 svn_boolean_t update,
2336 svn_boolean_t no_ignore,
2337 svn_boolean_t ignore_externals,
2338 svn_client_ctx_t *ctx,
2341 return svn_client_status3(result_rev, path, revision,
2342 status_func, status_baton,
2343 SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
2344 get_all, update, no_ignore, ignore_externals, NULL,
2349 /* Baton for old_status_func_cb; does what you think it does. */
2350 struct old_status_func_cb_baton
2352 svn_wc_status_func_t original_func;
2353 void *original_baton;
2356 /* Help svn_client_status() accept an old-style status func and baton,
2357 by wrapping them before passing along to svn_client_status2().
2359 This implements the 'svn_wc_status_func2_t' function type. */
2360 static void old_status_func_cb(void *baton,
2362 svn_wc_status2_t *status)
2364 struct old_status_func_cb_baton *b = baton;
2365 svn_wc_status_t *stat = (svn_wc_status_t *) status;
2367 b->original_func(b->original_baton, path, stat);
2372 svn_client_status(svn_revnum_t *result_rev,
2374 svn_opt_revision_t *revision,
2375 svn_wc_status_func_t status_func,
2377 svn_boolean_t recurse,
2378 svn_boolean_t get_all,
2379 svn_boolean_t update,
2380 svn_boolean_t no_ignore,
2381 svn_client_ctx_t *ctx,
2384 struct old_status_func_cb_baton *b = apr_pcalloc(pool, sizeof(*b));
2385 b->original_func = status_func;
2386 b->original_baton = status_baton;
2388 return svn_client_status2(result_rev, path, revision,
2389 old_status_func_cb, b,
2390 recurse, get_all, update, no_ignore, FALSE,
2394 /*** From update.c ***/
2396 svn_client_update3(apr_array_header_t **result_revs,
2397 const apr_array_header_t *paths,
2398 const svn_opt_revision_t *revision,
2400 svn_boolean_t depth_is_sticky,
2401 svn_boolean_t ignore_externals,
2402 svn_boolean_t allow_unver_obstructions,
2403 svn_client_ctx_t *ctx,
2406 return svn_client_update4(result_revs, paths, revision,
2407 depth, depth_is_sticky, ignore_externals,
2408 allow_unver_obstructions, TRUE, FALSE,
2413 svn_client_update2(apr_array_header_t **result_revs,
2414 const apr_array_header_t *paths,
2415 const svn_opt_revision_t *revision,
2416 svn_boolean_t recurse,
2417 svn_boolean_t ignore_externals,
2418 svn_client_ctx_t *ctx,
2421 return svn_client_update3(result_revs, paths, revision,
2422 SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE,
2423 ignore_externals, FALSE, ctx, pool);
2427 svn_client_update(svn_revnum_t *result_rev,
2429 const svn_opt_revision_t *revision,
2430 svn_boolean_t recurse,
2431 svn_client_ctx_t *ctx,
2434 apr_array_header_t *paths = apr_array_make(pool, 1, sizeof(const char *));
2435 apr_array_header_t *result_revs;
2437 APR_ARRAY_PUSH(paths, const char *) = path;
2439 SVN_ERR(svn_client_update2(&result_revs, paths, revision, recurse, FALSE,
2442 *result_rev = APR_ARRAY_IDX(result_revs, 0, svn_revnum_t);
2444 return SVN_NO_ERROR;
2447 /*** From switch.c ***/
2449 svn_client_switch2(svn_revnum_t *result_rev,
2451 const char *switch_url,
2452 const svn_opt_revision_t *peg_revision,
2453 const svn_opt_revision_t *revision,
2455 svn_boolean_t depth_is_sticky,
2456 svn_boolean_t ignore_externals,
2457 svn_boolean_t allow_unver_obstructions,
2458 svn_client_ctx_t *ctx,
2461 return svn_client_switch3(result_rev, path, switch_url, peg_revision,
2462 revision, depth, depth_is_sticky, ignore_externals,
2463 allow_unver_obstructions,
2464 TRUE /* ignore_ancestry */,
2469 svn_client_switch(svn_revnum_t *result_rev,
2471 const char *switch_url,
2472 const svn_opt_revision_t *revision,
2473 svn_boolean_t recurse,
2474 svn_client_ctx_t *ctx,
2477 svn_opt_revision_t peg_revision;
2478 peg_revision.kind = svn_opt_revision_unspecified;
2479 return svn_client_switch2(result_rev, path, switch_url,
2480 &peg_revision, revision,
2481 SVN_DEPTH_INFINITY_OR_FILES(recurse),
2482 FALSE, FALSE, FALSE, ctx, pool);
2485 /*** From cat.c ***/
2487 svn_client_cat2(svn_stream_t *out,
2488 const char *path_or_url,
2489 const svn_opt_revision_t *peg_revision,
2490 const svn_opt_revision_t *revision,
2491 svn_client_ctx_t *ctx,
2494 return svn_client_cat3(NULL /* props */,
2495 out, path_or_url, peg_revision, revision,
2496 TRUE /* expand_keywords */,
2502 svn_client_cat(svn_stream_t *out,
2503 const char *path_or_url,
2504 const svn_opt_revision_t *revision,
2505 svn_client_ctx_t *ctx,
2508 return svn_client_cat2(out, path_or_url, revision, revision,
2512 /*** From checkout.c ***/
2514 svn_client_checkout2(svn_revnum_t *result_rev,
2517 const svn_opt_revision_t *peg_revision,
2518 const svn_opt_revision_t *revision,
2519 svn_boolean_t recurse,
2520 svn_boolean_t ignore_externals,
2521 svn_client_ctx_t *ctx,
2524 return svn_error_trace(svn_client_checkout3(result_rev, URL, path,
2525 peg_revision, revision,
2526 SVN_DEPTH_INFINITY_OR_FILES(recurse),
2527 ignore_externals, FALSE, ctx, pool));
2531 svn_client_checkout(svn_revnum_t *result_rev,
2534 const svn_opt_revision_t *revision,
2535 svn_boolean_t recurse,
2536 svn_client_ctx_t *ctx,
2539 svn_opt_revision_t peg_revision;
2541 peg_revision.kind = svn_opt_revision_unspecified;
2543 return svn_error_trace(svn_client_checkout2(result_rev, URL, path,
2544 &peg_revision, revision, recurse,
2548 /*** From info.c ***/
2551 svn_client_info3(const char *abspath_or_url,
2552 const svn_opt_revision_t *peg_revision,
2553 const svn_opt_revision_t *revision,
2555 svn_boolean_t fetch_excluded,
2556 svn_boolean_t fetch_actual_only,
2557 const apr_array_header_t *changelists,
2558 svn_client_info_receiver2_t receiver,
2559 void *receiver_baton,
2560 svn_client_ctx_t *ctx,
2563 return svn_error_trace(
2564 svn_client_info4(abspath_or_url,
2570 FALSE /* include_externals */,
2572 receiver, receiver_baton,
2577 svn_info_dup(const svn_info_t *info, apr_pool_t *pool)
2579 svn_info_t *dupinfo = apr_palloc(pool, sizeof(*dupinfo));
2581 /* Perform a trivial copy ... */
2584 /* ...and then re-copy stuff that needs to be duped into our pool. */
2586 dupinfo->URL = apr_pstrdup(pool, info->URL);
2587 if (info->repos_root_URL)
2588 dupinfo->repos_root_URL = apr_pstrdup(pool, info->repos_root_URL);
2589 if (info->repos_UUID)
2590 dupinfo->repos_UUID = apr_pstrdup(pool, info->repos_UUID);
2591 if (info->last_changed_author)
2592 dupinfo->last_changed_author = apr_pstrdup(pool,
2593 info->last_changed_author);
2595 dupinfo->lock = svn_lock_dup(info->lock, pool);
2596 if (info->copyfrom_url)
2597 dupinfo->copyfrom_url = apr_pstrdup(pool, info->copyfrom_url);
2599 dupinfo->checksum = apr_pstrdup(pool, info->checksum);
2600 if (info->conflict_old)
2601 dupinfo->conflict_old = apr_pstrdup(pool, info->conflict_old);
2602 if (info->conflict_new)
2603 dupinfo->conflict_new = apr_pstrdup(pool, info->conflict_new);
2604 if (info->conflict_wrk)
2605 dupinfo->conflict_wrk = apr_pstrdup(pool, info->conflict_wrk);
2607 dupinfo->prejfile = apr_pstrdup(pool, info->prejfile);
2612 /* Convert an svn_client_info2_t to an svn_info_t, doing shallow copies. */
2613 static svn_error_t *
2614 info_from_info2(svn_info_t **new_info,
2615 svn_wc_context_t *wc_ctx,
2616 const svn_client_info2_t *info2,
2619 svn_info_t *info = apr_pcalloc(pool, sizeof(*info));
2621 info->URL = info2->URL;
2622 /* Goofy backward compat handling for added nodes. */
2623 if (SVN_IS_VALID_REVNUM(info2->rev))
2624 info->rev = info2->rev;
2628 info->kind = info2->kind;
2629 info->repos_root_URL = info2->repos_root_URL;
2630 info->repos_UUID = info2->repos_UUID;
2631 info->last_changed_rev = info2->last_changed_rev;
2632 info->last_changed_date = info2->last_changed_date;
2633 info->last_changed_author = info2->last_changed_author;
2635 /* Stupid old structure has a non-const LOCK member. Sigh. */
2636 info->lock = (svn_lock_t *)info2->lock;
2638 info->size64 = info2->size;
2639 if (info2->size == SVN_INVALID_FILESIZE)
2640 info->size = SVN_INFO_SIZE_UNKNOWN;
2641 else if (((svn_filesize_t)(apr_size_t)info->size64) == info->size64)
2642 info->size = (apr_size_t)info->size64;
2644 info->size = SVN_INFO_SIZE_UNKNOWN;
2648 info->has_wc_info = TRUE;
2649 info->schedule = info2->wc_info->schedule;
2650 info->copyfrom_url = info2->wc_info->copyfrom_url;
2651 info->copyfrom_rev = info2->wc_info->copyfrom_rev;
2652 info->text_time = info2->wc_info->recorded_time;
2653 info->prop_time = 0;
2654 if (info2->wc_info->checksum
2655 && info2->wc_info->checksum->kind == svn_checksum_md5)
2656 info->checksum = svn_checksum_to_cstring(
2657 info2->wc_info->checksum, pool);
2659 info->checksum = NULL;
2660 info->changelist = info2->wc_info->changelist;
2661 info->depth = info2->wc_info->depth;
2663 if (info->depth == svn_depth_unknown && info->kind == svn_node_file)
2664 info->depth = svn_depth_infinity;
2666 info->working_size64 = info2->wc_info->recorded_size;
2667 if (((svn_filesize_t)(apr_size_t)info->working_size64) == info->working_size64)
2668 info->working_size = (apr_size_t)info->working_size64;
2670 info->working_size = SVN_INFO_SIZE_UNKNOWN;
2674 info->has_wc_info = FALSE;
2675 info->working_size = SVN_INFO_SIZE_UNKNOWN;
2676 info->working_size64 = SVN_INVALID_FILESIZE;
2677 info->depth = svn_depth_unknown;
2680 /* Populate conflict fields. */
2681 if (info2->wc_info && info2->wc_info->conflicts)
2685 for (i = 0; i < info2->wc_info->conflicts->nelts; i++)
2687 const svn_wc_conflict_description2_t *conflict
2688 = APR_ARRAY_IDX(info2->wc_info->conflicts, i,
2689 const svn_wc_conflict_description2_t *);
2691 /* ### Not really sure what we should do if we get multiple
2692 ### conflicts of the same type. */
2693 switch (conflict->kind)
2695 case svn_wc_conflict_kind_tree:
2696 info->tree_conflict = svn_wc__cd2_to_cd(conflict, pool);
2699 case svn_wc_conflict_kind_text:
2700 info->conflict_old = conflict->base_abspath;
2701 info->conflict_new = conflict->my_abspath;
2702 info->conflict_wrk = conflict->their_abspath;
2705 case svn_wc_conflict_kind_property:
2706 info->prejfile = conflict->their_abspath;
2712 if (info2->wc_info && info2->wc_info->checksum)
2714 const svn_checksum_t *md5_checksum;
2716 SVN_ERR(svn_wc__node_get_md5_from_sha1(&md5_checksum,
2718 info2->wc_info->wcroot_abspath,
2719 info2->wc_info->checksum,
2722 info->checksum = svn_checksum_to_cstring(md5_checksum, pool);
2726 return SVN_NO_ERROR;
2729 struct info_to_relpath_baton
2731 const char *anchor_abspath;
2732 const char *anchor_relpath;
2733 svn_info_receiver_t info_receiver;
2735 svn_wc_context_t *wc_ctx;
2738 static svn_error_t *
2739 info_receiver_relpath_wrapper(void *baton,
2740 const char *abspath_or_url,
2741 const svn_client_info2_t *info2,
2742 apr_pool_t *scratch_pool)
2744 struct info_to_relpath_baton *rb = baton;
2745 const char *path = abspath_or_url;
2748 if (rb->anchor_relpath &&
2749 svn_dirent_is_ancestor(rb->anchor_abspath, abspath_or_url))
2751 path = svn_dirent_join(rb->anchor_relpath,
2752 svn_dirent_skip_ancestor(rb->anchor_abspath,
2757 SVN_ERR(info_from_info2(&info, rb->wc_ctx, info2, scratch_pool));
2759 SVN_ERR(rb->info_receiver(rb->info_baton,
2764 return SVN_NO_ERROR;
2768 svn_client_info2(const char *path_or_url,
2769 const svn_opt_revision_t *peg_revision,
2770 const svn_opt_revision_t *revision,
2771 svn_info_receiver_t receiver,
2772 void *receiver_baton,
2774 const apr_array_header_t *changelists,
2775 svn_client_ctx_t *ctx,
2778 struct info_to_relpath_baton rb;
2779 const char *abspath_or_url = path_or_url;
2781 rb.anchor_relpath = NULL;
2782 rb.info_receiver = receiver;
2783 rb.info_baton = receiver_baton;
2784 rb.wc_ctx = ctx->wc_ctx;
2786 if (!svn_path_is_url(path_or_url))
2788 SVN_ERR(svn_dirent_get_absolute(&abspath_or_url, path_or_url, pool));
2789 rb.anchor_abspath = abspath_or_url;
2790 rb.anchor_relpath = path_or_url;
2793 SVN_ERR(svn_client_info3(abspath_or_url,
2799 info_receiver_relpath_wrapper,
2804 return SVN_NO_ERROR;
2808 svn_client_info(const char *path_or_url,
2809 const svn_opt_revision_t *peg_revision,
2810 const svn_opt_revision_t *revision,
2811 svn_info_receiver_t receiver,
2812 void *receiver_baton,
2813 svn_boolean_t recurse,
2814 svn_client_ctx_t *ctx,
2817 return svn_client_info2(path_or_url, peg_revision, revision,
2818 receiver, receiver_baton,
2819 SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
2823 /*** From resolved.c ***/
2825 svn_client_resolved(const char *path,
2826 svn_boolean_t recursive,
2827 svn_client_ctx_t *ctx,
2830 svn_depth_t depth = SVN_DEPTH_INFINITY_OR_EMPTY(recursive);
2831 return svn_client_resolve(path, depth,
2832 svn_wc_conflict_choose_merged, ctx, pool);
2834 /*** From revert.c ***/
2836 svn_client_revert2(const apr_array_header_t *paths,
2838 const apr_array_header_t *changelists,
2839 svn_client_ctx_t *ctx,
2842 return svn_error_trace(svn_client_revert3(paths,
2845 FALSE /* clear_changelists */,
2846 FALSE /* metadata_only */,
2852 svn_client_revert(const apr_array_header_t *paths,
2853 svn_boolean_t recursive,
2854 svn_client_ctx_t *ctx,
2857 return svn_client_revert2(paths, SVN_DEPTH_INFINITY_OR_EMPTY(recursive),
2863 svn_client_open_ra_session(svn_ra_session_t **session,
2865 svn_client_ctx_t *ctx,
2868 return svn_error_trace(
2869 svn_client_open_ra_session2(session, url,
2875 svn_client_uuid_from_url(const char **uuid,
2877 svn_client_ctx_t *ctx,
2881 apr_pool_t *subpool = svn_pool_create(pool);
2883 err = svn_client_get_repos_root(NULL, uuid, url,
2884 ctx, pool, subpool);
2885 /* destroy the RA session */
2886 svn_pool_destroy(subpool);
2888 return svn_error_trace(err);
2892 svn_client_uuid_from_path2(const char **uuid,
2893 const char *local_abspath,
2894 svn_client_ctx_t *ctx,
2895 apr_pool_t *result_pool,
2896 apr_pool_t *scratch_pool)
2898 return svn_error_trace(
2899 svn_client_get_repos_root(NULL, uuid,
2901 result_pool, scratch_pool));
2905 svn_client_uuid_from_path(const char **uuid,
2907 svn_wc_adm_access_t *adm_access,
2908 svn_client_ctx_t *ctx,
2911 const char *local_abspath;
2913 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
2914 return svn_error_trace(
2915 svn_client_uuid_from_path2(uuid, local_abspath, ctx, pool, pool));
2918 /*** From url.c ***/
2920 svn_client_root_url_from_path(const char **url,
2921 const char *path_or_url,
2922 svn_client_ctx_t *ctx,
2925 apr_pool_t *subpool = svn_pool_create(pool);
2927 if (!svn_path_is_url(path_or_url))
2928 SVN_ERR(svn_dirent_get_absolute(&path_or_url, path_or_url, pool));
2930 err = svn_client_get_repos_root(url, NULL, path_or_url,
2931 ctx, pool, subpool);
2933 /* close ra session */
2934 svn_pool_destroy(subpool);
2935 return svn_error_trace(err);
2939 svn_client_url_from_path(const char **url,
2940 const char *path_or_url,
2943 svn_client_ctx_t *ctx;
2945 SVN_ERR(svn_client_create_context(&ctx, pool));
2947 return svn_client_url_from_path2(url, path_or_url, ctx, pool, pool);
2950 /*** From mergeinfo.c ***/
2952 svn_client_mergeinfo_log(svn_boolean_t finding_merged,
2953 const char *target_path_or_url,
2954 const svn_opt_revision_t *target_peg_revision,
2955 const char *source_path_or_url,
2956 const svn_opt_revision_t *source_peg_revision,
2957 svn_log_entry_receiver_t receiver,
2958 void *receiver_baton,
2959 svn_boolean_t discover_changed_paths,
2961 const apr_array_header_t *revprops,
2962 svn_client_ctx_t *ctx,
2963 apr_pool_t *scratch_pool)
2965 svn_opt_revision_t start_revision, end_revision;
2967 start_revision.kind = svn_opt_revision_unspecified;
2968 end_revision.kind = svn_opt_revision_unspecified;
2970 return svn_client_mergeinfo_log2(finding_merged,
2971 target_path_or_url, target_peg_revision,
2972 source_path_or_url, source_peg_revision,
2973 &start_revision, &end_revision,
2974 receiver, receiver_baton,
2975 discover_changed_paths, depth, revprops,
2980 svn_client_mergeinfo_log_merged(const char *path_or_url,
2981 const svn_opt_revision_t *peg_revision,
2982 const char *merge_source_path_or_url,
2983 const svn_opt_revision_t *src_peg_revision,
2984 svn_log_entry_receiver_t log_receiver,
2985 void *log_receiver_baton,
2986 svn_boolean_t discover_changed_paths,
2987 const apr_array_header_t *revprops,
2988 svn_client_ctx_t *ctx,
2991 return svn_client_mergeinfo_log(TRUE, path_or_url, peg_revision,
2992 merge_source_path_or_url,
2994 log_receiver, log_receiver_baton,
2995 discover_changed_paths,
2996 svn_depth_empty, revprops, ctx,
3001 svn_client_mergeinfo_log_eligible(const char *path_or_url,
3002 const svn_opt_revision_t *peg_revision,
3003 const char *merge_source_path_or_url,
3004 const svn_opt_revision_t *src_peg_revision,
3005 svn_log_entry_receiver_t log_receiver,
3006 void *log_receiver_baton,
3007 svn_boolean_t discover_changed_paths,
3008 const apr_array_header_t *revprops,
3009 svn_client_ctx_t *ctx,
3012 return svn_client_mergeinfo_log(FALSE, path_or_url, peg_revision,
3013 merge_source_path_or_url,
3015 log_receiver, log_receiver_baton,
3016 discover_changed_paths,
3017 svn_depth_empty, revprops, ctx,
3021 /*** From relocate.c ***/
3023 svn_client_relocate(const char *path,
3024 const char *from_prefix,
3025 const char *to_prefix,
3026 svn_boolean_t recurse,
3027 svn_client_ctx_t *ctx,
3031 SVN_ERR(svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
3032 _("Non-recursive relocation not supported")));
3033 return svn_client_relocate2(path, from_prefix, to_prefix, TRUE, ctx, pool);
3036 /*** From util.c ***/
3038 svn_client_commit_item_create(const svn_client_commit_item3_t **item,
3041 *item = svn_client_commit_item3_create(pool);
3042 return SVN_NO_ERROR;
3045 svn_client_commit_item2_t *
3046 svn_client_commit_item2_dup(const svn_client_commit_item2_t *item,
3049 svn_client_commit_item2_t *new_item = apr_palloc(pool, sizeof(*new_item));
3054 new_item->path = apr_pstrdup(pool, new_item->path);
3057 new_item->url = apr_pstrdup(pool, new_item->url);
3059 if (new_item->copyfrom_url)
3060 new_item->copyfrom_url = apr_pstrdup(pool, new_item->copyfrom_url);
3062 if (new_item->wcprop_changes)
3063 new_item->wcprop_changes = svn_prop_array_dup(new_item->wcprop_changes,
3070 svn_client_cleanup(const char *path,
3071 svn_client_ctx_t *ctx,
3072 apr_pool_t *scratch_pool)
3074 const char *local_abspath;
3076 if (svn_path_is_url(path))
3077 return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
3078 _("'%s' is not a local path"), path);
3080 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
3082 return svn_error_trace(svn_client_cleanup2(local_abspath,
3083 TRUE /* break_locks */,
3084 TRUE /* fix_recorded_timestamps */,
3085 TRUE /* clear_dav_cache */,
3086 TRUE /* vacuum_pristines */,
3087 FALSE /* include_externals */,
3088 ctx, scratch_pool));