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() */ 59struct 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. */ 67static svn_error_t * 68capture_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 ***/ 81svn_error_t * 82svn_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 94svn_error_t * 95svn_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 107svn_error_t * 108svn_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 117svn_error_t * 118svn_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 126svn_error_t * 127svn_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 143svn_error_t * 144svn_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 153svn_error_t * 154svn_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 ***/ 169struct 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 176static svn_error_t * 177blame_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 200svn_error_t * 201svn_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 225struct blame_receiver_wrapper_baton2 { 226 void *baton; 227 svn_client_blame_receiver2_t receiver; 228}; 229 230static svn_error_t * 231blame_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 271svn_error_t * 272svn_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 */ 296struct blame_receiver_wrapper_baton { 297 void *baton; 298 svn_client_blame_receiver_t receiver; 299}; 300 301/* This implements svn_client_blame_receiver2_t */ 302static svn_error_t * 303blame_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 324static void 325wrap_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 341svn_error_t * 342svn_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 374struct wrapped_receiver_baton_s 375{ 376 svn_client_blame_receiver_t orig_receiver; 377 void *orig_baton; 378}; 379 380static svn_error_t * 381wrapped_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 398static void 399wrap_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 415svn_error_t * 416svn_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} 430svn_error_t * 431svn_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 ***/ 445svn_error_t * 446svn_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 ***/ 457svn_error_t * 458svn_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 478svn_error_t * 479svn_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 499svn_error_t * 500svn_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 514svn_error_t * 515svn_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. */ 538struct downgrade_commit_copied_notify_baton 539{ 540 svn_wc_notify_func2_t orig_notify_func2; 541 void *orig_notify_baton2; 542}; 543 544static void 545downgrade_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 571svn_error_t * 572svn_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 592svn_error_t * 593svn_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 638svn_error_t * 639svn_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 652svn_error_t * 653svn_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 670svn_error_t * 671svn_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 ***/ 684svn_error_t * 685svn_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 706svn_error_t * 707svn_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 727svn_error_t * 728svn_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 741svn_error_t * 742svn_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 763svn_error_t * 764svn_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 794svn_error_t * 795svn_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 812svn_error_t * 813svn_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 832svn_error_t * 833svn_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 853svn_error_t * 854svn_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 870svn_error_t * 871svn_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 900svn_error_t * 901svn_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 918svn_error_t * 919svn_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 ***/ 946svn_error_t * 947svn_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 964svn_error_t * 965svn_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 975svn_error_t * 976svn_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 993svn_error_t * 994svn_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 1029svn_error_t * 1030svn_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 1062svn_error_t * 1063svn_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 1087svn_error_t * 1088svn_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 1111svn_error_t * 1112svn_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 1132svn_error_t * 1133svn_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 1151svn_error_t * 1152svn_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 1198svn_error_t * 1199svn_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 1244svn_error_t * 1245svn_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 1282svn_error_t * 1283svn_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 1316svn_error_t * 1317svn_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 1339svn_error_t * 1340svn_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 1359svn_error_t * 1360svn_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 1378svn_error_t * 1379svn_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 ***/ 1399svn_error_t * 1400svn_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 1417svn_error_t * 1418svn_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 1436svn_error_t * 1437svn_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 1456svn_error_t * 1457svn_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 1471svn_error_t * 1472svn_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 */ 1492struct 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 */ 1498static svn_error_t * 1499list_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(). */ 1520static void 1521wrap_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 1538svn_error_t * 1539svn_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 1561svn_error_t * 1562svn_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. */ 1586struct 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. */ 1593static svn_error_t * 1594store_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 1631svn_error_t * 1632svn_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 1653svn_error_t * 1654svn_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 1668svn_error_t * 1669svn_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 1682svn_error_t * 1683svn_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 1711svn_error_t * 1712svn_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 1737svn_error_t * 1738svn_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 1756svn_error_t * 1757svn_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 1814svn_error_t * 1815svn_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 1842svn_error_t * 1843svn_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 1863svn_error_t * 1864svn_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 1884svn_error_t * 1885svn_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 1902svn_error_t * 1903svn_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 1930svn_error_t * 1931svn_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 1950svn_error_t * 1951svn_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 1977svn_error_t * 1978svn_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 ***/ 1996svn_error_t * 1997svn_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 2033svn_error_t * 2034svn_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 2049svn_error_t * 2050svn_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 2064svn_error_t * 2065svn_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 2079svn_error_t * 2080svn_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 2099svn_error_t * 2100svn_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 2169svn_error_t * 2170svn_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 2191svn_error_t * 2192svn_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. */ 2207static apr_hash_t * 2208string_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 2224svn_client_proplist_item_t * 2225svn_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 */ 2240struct proplist_receiver_wrapper_baton { 2241 void *baton; 2242 svn_proplist_receiver_t receiver; 2243}; 2244 2245/* This implements svn_client_proplist_receiver2_t */ 2246static svn_error_t * 2247proplist_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 2261static void 2262wrap_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 2279svn_error_t * 2280svn_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() */ 2304struct proplist_receiver_baton { 2305 apr_array_header_t *props; 2306 apr_pool_t *pool; 2307}; 2308 2309/* Receiver function used by proplist2(). */ 2310static svn_error_t * 2311proplist_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 2334svn_error_t * 2335svn_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 2355svn_error_t * 2356svn_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 2369svn_error_t * 2370svn_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 2391struct 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 */ 2399static svn_error_t * 2400status4_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 2418svn_error_t * 2419svn_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 2444struct status3_wrapper_baton 2445{ 2446 svn_wc_status_func2_t old_func; 2447 void *old_baton; 2448}; 2449 2450static svn_error_t * 2451status3_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 2462svn_error_t * 2463svn_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 2485svn_error_t * 2486svn_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. */ 2508struct 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. */ 2518static 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 2529svn_error_t * 2530svn_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 ***/ 2553svn_error_t * 2554svn_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 2570svn_error_t * 2571svn_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 2584svn_error_t * 2585svn_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 ***/ 2606svn_error_t * 2607svn_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 2626svn_error_t * 2627svn_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 ***/ 2644svn_error_t * 2645svn_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 2659svn_error_t * 2660svn_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 ***/ 2671svn_error_t * 2672svn_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 2688svn_error_t * 2689svn_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 2708svn_error_t * 2709svn_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 2734svn_info_t * 2735svn_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. */ 2771static svn_error_t * 2772info_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 2887struct 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 2896static svn_error_t * 2897info_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 2925svn_error_t * 2926svn_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 2965svn_error_t * 2966svn_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 ***/ 2982svn_error_t * 2983svn_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 ***/ 2993svn_error_t * 2994svn_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 3009svn_error_t * 3010svn_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 3025svn_error_t * 3026svn_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 ***/ 3036svn_error_t * 3037svn_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 3048svn_error_t * 3049svn_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 3065svn_error_t * 3066svn_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 3078svn_error_t * 3079svn_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 ***/ 3093svn_error_t * 3094svn_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 3112svn_error_t * 3113svn_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 ***/ 3125svn_error_t * 3126svn_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 3153svn_error_t * 3154svn_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 3174svn_error_t * 3175svn_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 ***/ 3196svn_error_t * 3197svn_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 ***/ 3211svn_error_t * 3212svn_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 3219svn_client_commit_item2_t * 3220svn_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 3243svn_error_t * 3244svn_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